/*
- * 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,
* 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@
*/
#include <SystemConfiguration/SCPrivate.h>
#if !TARGET_OS_IPHONE
-#include <Security/AuthSession.h>
+#include <Security/Authorization.h>
#endif /* !TARGET_OS_IPHONE */
}
-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)
{
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"));
}
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)" : "");
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,
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);
}
}
CFRelease(prefix);
CFRelease(prefs);
+#if !TARGET_OS_IPHONE
+ AuthorizationFree(authorization, kAuthorizationFlagDefaults);
+// AuthorizationFree(authorization, kAuthorizationFlagDestroyRights);
+#endif /* !TARGET_OS_IPHONE */
+
exit (0);
return 0;
}