]> git.saurik.com Git - apple/configd.git/blobdiff - scselect.tproj/scselect.c
configd-1061.101.1.tar.gz
[apple/configd.git] / scselect.tproj / scselect.c
index 5c42fb3780f65fd6608598e634f86e0a5c4b3e21..8140cbdef6e2d58e35cb230a2c0f3424ca5fc1e6 100644 (file)
@@ -1,15 +1,15 @@
 /*
- * Copyright (c) 2000-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2009, 2011, 2012, 2014, 2015, 2018 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * compliance with the License. Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this
  * file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -17,7 +17,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_LICENSE_HEADER_END@
  */
 
@@ -49,7 +49,7 @@
 #include <SystemConfiguration/SCPrivate.h>
 
 #if    !TARGET_OS_IPHONE
-#include <Security/AuthSession.h>
+#include <Security/Authorization.h>
 #endif /* !TARGET_OS_IPHONE */
 
 
@@ -73,94 +73,6 @@ usage(const char *command)
 }
 
 
-static Boolean
-isAdmin()
-{
-       gid_t   groups[NGROUPS_MAX];
-       int     ngroups;
-
-       if (getuid() == 0) {
-               return TRUE;    // if "root"
-       }
-
-       ngroups = getgroups(NGROUPS_MAX, groups);
-       if(ngroups > 0) {
-               struct group    *adminGroup;
-
-               adminGroup = getgrnam("admin");
-               if (adminGroup != NULL) {
-                       gid_t   adminGid = adminGroup->gr_gid;
-                       int     i;
-
-                       for (i = 0; i < ngroups; i++) {
-                               if (groups[i] == adminGid) {
-                                       return TRUE;    // if a member of group "admin"
-                               }
-                       }
-               }
-       }
-
-       return FALSE;
-}
-
-
-#if    !TARGET_OS_IPHONE
-static void *
-__loadSecurity(void) {
-       static void *image = NULL;
-       if (NULL == image) {
-               const char      *framework              = "/System/Library/Frameworks/Security.framework/Versions/A/Security";
-               struct stat     statbuf;
-               const char      *suffix                 = getenv("DYLD_IMAGE_SUFFIX");
-               char            path[MAXPATHLEN];
-
-               strlcpy(path, framework, sizeof(path));
-               if (suffix) strlcat(path, suffix, sizeof(path));
-               if (0 <= stat(path, &statbuf)) {
-                       image = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
-               } else {
-                       image = dlopen(framework, RTLD_LAZY | RTLD_LOCAL);
-               }
-       }
-       return (void *)image;
-}
-
-
-static OSStatus
-_SessionGetInfo(SecuritySessionId session, SecuritySessionId *sessionId, SessionAttributeBits *attributes)
-{
-       #undef SessionGetInfo
-       static typeof (SessionGetInfo) *dyfunc = NULL;
-       if (!dyfunc) {
-               void *image = __loadSecurity();
-               if (image) dyfunc = dlsym(image, "SessionGetInfo");
-       }
-       return dyfunc ? dyfunc(session, sessionId, attributes) : -1;
-}
-#define SessionGetInfo _SessionGetInfo
-#endif /* !TARGET_OS_IPHONE */
-
-static Boolean
-hasLocalConsoleAccess()
-{
-#if    !TARGET_OS_IPHONE
-       OSStatus                error;
-       SecuritySessionId       sessionID       = 0;
-       SessionAttributeBits    attributeBits   = 0;
-
-       error = SessionGetInfo(callerSecuritySession, &sessionID, &attributeBits);
-       if (error != noErr) {
-               /* Security check failed, must not permit access */
-               return FALSE;
-       }
-
-       return (attributeBits & (sessionHasGraphicAccess|sessionIsRemote)) == sessionHasGraphicAccess;
-#else  /* !TARGET_OS_IPHONE */
-       return TRUE;
-#endif /* !TARGET_OS_IPHONE */
-}
-
-
 int
 main(int argc, char **argv)
 {
@@ -179,57 +91,94 @@ main(int argc, char **argv)
        const void              **setVals       = NULL;
        CFIndex                 i;
 
+#if    !TARGET_OS_IPHONE
+       AuthorizationRef        authorization   = NULL;
+       AuthorizationFlags      flags           = kAuthorizationFlagDefaults;
+       CFMutableDictionaryRef  options;
+       OSStatus                status;
+#endif // !TARGET_OS_IPHONE
+
        /* process any arguments */
 
-       while ((opt = getopt_long(argc, argv, "dvn", longopts, NULL)) != -1)
+       while ((opt = getopt_long(argc, argv, "dvn", longopts, NULL)) != -1) {
                switch(opt) {
-               case 'd':
-                       _sc_debug = TRUE;
-                       _sc_log   = FALSE;      /* enable framework logging */
-                       break;
-               case 'v':
-                       _sc_verbose = TRUE;
-                       break;
-               case 'n':
-                       apply = FALSE;
-                       break;
-               case '?':
-               default :
-                       usage(command);
+                       case 'd':
+                               _sc_debug = TRUE;
+                               _sc_log   = FALSE;      /* enable framework logging */
+                               break;
+                       case 'v':
+                               _sc_verbose = TRUE;
+                               break;
+                       case 'n':
+                               apply = FALSE;
+                               break;
+                       case '?':
+                       default :
+                               usage(command);
+               }
        }
        argc -= optind;
        argv += optind;
 
        prefix = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/"), kSCPrefSets);
 
-       newSet = (argc == 1)
-                       ? CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman)
-                       : CFRetain(CFSTR(""));
+       if (argc == 1) {
+               newSet = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
 
-       prefs = SCPreferencesCreate(NULL, CFSTR("Select Set Command"), NULL);
-       if (prefs == NULL) {
-               SCPrint(TRUE, stderr, CFSTR("SCPreferencesCreate() failed\n"));
-               exit (1);
-       }
+               /* check if a full path to the new "set" was specified */
+               if ((CFStringGetLength(newSet) > 0) && CFStringHasPrefix(newSet, prefix)) {
+                       CFRange                 range;
+                       CFMutableStringRef      str;
 
-       /* check if a full path to the new "set" was specified */
-       if ((CFStringGetLength(newSet) > 0) && CFStringHasPrefix(newSet, prefix)) {
-               CFRange                 range;
-               CFMutableStringRef      str;
+                       str = CFStringCreateMutableCopy(NULL, 0, newSet);
+                       CFRelease(newSet);
 
-               str = CFStringCreateMutableCopy(NULL, 0, newSet);
-               CFStringDelete(str, CFRangeMake(0, CFStringGetLength(prefix)));
+                       CFStringDelete(str, CFRangeMake(0, CFStringGetLength(prefix)));
+                       newSet = CFStringCreateCopy(NULL, str);
+                       CFRelease(str);
 
-               range = CFStringFind(str, CFSTR("/"), 0);
-               if (range.location != kCFNotFound) {
-                       SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available\n."), newSet);
-                       exit (1);
+                       range = CFStringFind(newSet, CFSTR("/"), 0);
+                       if (range.location != kCFNotFound) {
+                               SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available\n"), newSet);
+                               exit (1);
+                       }
                }
+       } else {
+               newSet = CFRetain(CFSTR(""));
+       }
 
-               CFRelease(newSet);
-               newSet = str;
+#if    !TARGET_OS_IPHONE
+       status = AuthorizationCreate(NULL,
+                                    kAuthorizationEmptyEnvironment,
+                                    flags,
+                                    &authorization);
+       if (status != errAuthorizationSuccess) {
+               SCPrint(TRUE,
+                       stderr,
+                       CFSTR("AuthorizationCreate() failed: status = %d\n"),
+                       (int)status);
+               exit (1);
        }
 
+       options = CFDictionaryCreateMutable(NULL,
+                                           0,
+                                           &kCFTypeDictionaryKeyCallBacks,
+                                           &kCFTypeDictionaryValueCallBacks);
+       CFDictionarySetValue(options, kSCPreferencesOptionChangeNetworkSet, kCFBooleanTrue);
+       prefs = SCPreferencesCreateWithOptions(NULL, CFSTR("scselect"), NULL, authorization, options);
+       CFRelease(options);
+       if (prefs == NULL) {
+               SCPrint(TRUE, stderr, CFSTR("SCPreferencesCreate() failed\n"));
+               exit (1);
+       }
+#else  // !TARGET_OS_IPHONE
+       prefs = SCPreferencesCreate(NULL, CFSTR("scselect"), NULL);
+       if (prefs == NULL) {
+               SCPrint(TRUE, stderr, CFSTR("SCPreferencesCreate() failed\n"));
+               exit (1);
+       }
+#endif // !TARGET_OS_IPHONE
+
        sets = SCPreferencesGetValue(prefs, kSCPrefSets);
        if (sets == NULL) {
                SCPrint(TRUE, stderr, CFSTR("No network sets defined.\n"));
@@ -291,10 +240,11 @@ main(int argc, char **argv)
        }
 
        if (argc == 1) {
-               SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available.\n\n"), newSet);
+               SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available.\n"), newSet);
+               exit(1);
        }
 
-       SCPrint(TRUE, stderr,
+       SCPrint(TRUE, stdout,
                CFSTR("Defined sets include:%s\n"),
                (currentMatched > 0) ? " (* == current set)" : "");
 
@@ -303,7 +253,7 @@ main(int argc, char **argv)
                CFDictionaryRef dict = (CFDictionaryRef)setVals[i];
                CFStringRef     udn  = CFDictionaryGetValue(dict, kSCPropUserDefinedName);
 
-               SCPrint(TRUE, stderr,
+               SCPrint(TRUE, stdout,
                        CFSTR(" %s %@\t(%@)\n"),
                        ((currentMatched > 0) && CFEqual(key, current)) ? "*" : " ",
                        key,
@@ -312,47 +262,48 @@ main(int argc, char **argv)
 
        switch (currentMatched) {
                case -2 :
-                       SCPrint(TRUE, stderr, CFSTR("\nCurrentSet not defined.\n"));
+                       SCPrint(TRUE, stdout, CFSTR("\nCurrent set not defined.\n"));
                        break;
                case -1 :
-                       SCPrint(TRUE, stderr, CFSTR("\nCurrentSet \"%@\" may not be valid\n"), current);
+                       SCPrint(TRUE, stdout, CFSTR("\nCurrent set \"%@\" may not be valid\n"), current);
                        break;
                case  0 :
-                       SCPrint(TRUE, stderr, CFSTR("\nCurrentSet \"%@\" not valid\n"), current);
+                       SCPrint(TRUE, stdout, CFSTR("\nCurrent set \"%@\" not valid\n"), current);
                        break;
                default :
                        break;
        }
 
-       exit (1);
+       CFRelease(prefix);
+       exit (0);
 
     found :
 
-       if (!(isAdmin() || hasLocalConsoleAccess())) {
-               SCPrint(TRUE, stderr,
-                       CFSTR("Only local console users and administrators can change locations\n"));
-               exit (EX_NOPERM);
-       }
-
        CFRelease(current);
        current = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), prefix, newSet);
 
-       if (!SCPreferencesSetValue(prefs, kSCPrefCurrentSet, current)) {
-               SCPrint(TRUE, stderr,
-                       CFSTR("SCPreferencesSetValue(...,%@,%@) failed\n"),
-                       kSCPrefCurrentSet,
-                       current);
-               exit (1);
-       }
+       SCPreferencesSetValue(prefs, kSCPrefCurrentSet, current);
 
        if (!SCPreferencesCommitChanges(prefs)) {
-               SCPrint(TRUE, stderr, CFSTR("SCPreferencesCommitChanges() failed\n"));
-               exit (1);
+               int     sc_status       = SCError();
+
+               if (sc_status == kSCStatusAccessError) {
+                       SCPrint(TRUE, stderr,
+                               CFSTR("Only local console users and administrators can change locations\n"));
+                       exit (EX_NOPERM);
+               } else {
+                       SCPrint(TRUE, stderr,
+                               CFSTR("SCPreferencesCommitChanges() failed: %s\n"),
+                               SCErrorString(sc_status));
+                       exit (1);
+               }
        }
 
        if (apply) {
                if (!SCPreferencesApplyChanges(prefs)) {
-                       SCPrint(TRUE, stderr, CFSTR("SCPreferencesApplyChanges() failed\n"));
+                       SCPrint(TRUE, stderr,
+                               CFSTR("SCPreferencesApplyChanges() failed %s\n"),
+                               SCErrorString(SCError()));
                        exit (1);
                }
        }
@@ -369,6 +320,11 @@ main(int argc, char **argv)
        CFRelease(prefix);
        CFRelease(prefs);
 
+#if    !TARGET_OS_IPHONE
+       AuthorizationFree(authorization, kAuthorizationFlagDefaults);
+//     AuthorizationFree(authorization, kAuthorizationFlagDestroyRights);
+#endif /* !TARGET_OS_IPHONE */
+
        exit (0);
        return 0;
 }