1/* 2 * Copyright (c) 2000-2005, 2009, 2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * Modification History 26 * 27 * May 1, 2003 Allan Nathanson <ajn@apple.com> 28 * - add console [session] information SPIs 29 * 30 * June 1, 2001 Allan Nathanson <ajn@apple.com> 31 * - public API conversion 32 * 33 * January 2, 2001 Allan Nathanson <ajn@apple.com> 34 * - initial revision 35 */ 36 37#include <SystemConfiguration/SystemConfiguration.h> 38#include <SystemConfiguration/SCValidation.h> 39#include <SystemConfiguration/SCPrivate.h> 40 41 42#undef kSCPropUsersConsoleUserName 43#define kSCPropUsersConsoleUserName CFSTR("Name") 44 45#undef kSCPropUsersConsoleUserUID 46#define kSCPropUsersConsoleUserUID CFSTR("UID") 47 48#undef kSCPropUsersConsoleUserGID 49#define kSCPropUsersConsoleUserGID CFSTR("GID") 50 51#undef kSCPropUsersConsoleSessionInfo 52#define kSCPropUsersConsoleSessionInfo CFSTR("SessionInfo") 53 54 55// from CoreGraphics (CGSession.h) 56const CFStringRef kSCConsoleSessionUserName = CFSTR("kCGSSessionUserNameKey"); /* value is CFString */ 57const CFStringRef kSCConsoleSessionUID = CFSTR("kCGSSessionUserIDKey"); /* value is CFNumber (a uid_t) */ 58const CFStringRef kSCConsoleSessionConsoleSet = CFSTR("kCGSSessionConsoleSetKey"); /* value is CFNumber */ 59const CFStringRef kSCConsoleSessionOnConsole = CFSTR("kCGSSessionOnConsoleKey"); /* value is CFBoolean */ 60const CFStringRef kSCConsoleSessionLoginDone = CFSTR("kCGSessionLoginDoneKey"); /* value is CFBoolean */ 61 62// from CoreGraphics (CGSSession.h) 63const CFStringRef kSCConsoleSessionID = CFSTR("kCGSSessionIDKey"); /* value is CFNumber */ 64 65// for loginwindow 66const CFStringRef kSCConsoleSessionSystemSafeBoot = CFSTR("kCGSSessionSystemSafeBoot"); /* value is CFBoolean */ 67const CFStringRef kSCConsoleSessionLoginwindowSafeLogin = CFSTR("kCGSSessionLoginwindowSafeLogin"); /* value is CFBoolean */ 68 69 70CFStringRef 71SCDynamicStoreKeyCreateConsoleUser(CFAllocatorRef allocator) 72{ 73 return SCDynamicStoreKeyCreate(allocator, 74 CFSTR("%@/%@/%@"), 75 kSCDynamicStoreDomainState, 76 kSCCompUsers, 77 kSCEntUsersConsoleUser); 78} 79 80 81CFStringRef 82SCDynamicStoreCopyConsoleUser(SCDynamicStoreRef store, 83 uid_t *uid, 84 gid_t *gid) 85{ 86 CFStringRef consoleUser = NULL; 87 CFDictionaryRef dict = NULL; 88 CFStringRef key; 89 90 key = SCDynamicStoreKeyCreateConsoleUser(NULL); 91 dict = SCDynamicStoreCopyValue(store, key); 92 CFRelease(key); 93 if (!isA_CFDictionary(dict)) { 94 _SCErrorSet(kSCStatusNoKey); 95 goto done; 96 } 97 98 consoleUser = CFDictionaryGetValue(dict, kSCPropUsersConsoleUserName); 99 consoleUser = isA_CFString(consoleUser); 100 if (!consoleUser) { 101 _SCErrorSet(kSCStatusNoKey); 102 goto done; 103 } 104 105 CFRetain(consoleUser); 106 107 if (uid) { 108 CFNumberRef num; 109 SInt32 val; 110 111 num = CFDictionaryGetValue(dict, kSCPropUsersConsoleUserUID); 112 if (isA_CFNumber(num)) { 113 if (CFNumberGetValue(num, kCFNumberSInt32Type, &val)) { 114 *uid = (uid_t)val; 115 } 116 } 117 } 118 119 if (gid) { 120 CFNumberRef num; 121 SInt32 val; 122 123 num = CFDictionaryGetValue(dict, kSCPropUsersConsoleUserGID); 124 if (isA_CFNumber(num)) { 125 if (CFNumberGetValue(num, kCFNumberSInt32Type, &val)) { 126 *gid = (gid_t)val; 127 } 128 } 129 } 130 131 done : 132 133 if (dict) CFRelease(dict); 134 return consoleUser; 135} 136 137 138CFArrayRef 139SCDynamicStoreCopyConsoleInformation(SCDynamicStoreRef store) 140{ 141 CFDictionaryRef dict = NULL; 142 CFArrayRef info = NULL; 143 CFStringRef key; 144 145 key = SCDynamicStoreKeyCreateConsoleUser(NULL); 146 dict = SCDynamicStoreCopyValue(store, key); 147 CFRelease(key); 148 if (!isA_CFDictionary(dict)) { 149 _SCErrorSet(kSCStatusNoKey); 150 goto done; 151 } 152 153 info = CFDictionaryGetValue(dict, kSCPropUsersConsoleSessionInfo); 154 info = isA_CFArray(info); 155 if (!info) { 156 _SCErrorSet(kSCStatusNoKey); 157 goto done; 158 } 159 160 CFRetain(info); 161 162 done : 163 164 if (dict) CFRelease(dict); 165 return info; 166} 167 168 169Boolean 170SCDynamicStoreSetConsoleInformation(SCDynamicStoreRef store, 171 const char *user, 172 uid_t uid, 173 gid_t gid, 174 CFArrayRef sessions) 175{ 176 CFStringRef consoleUser; 177 CFMutableDictionaryRef dict = NULL; 178 CFStringRef key = SCDynamicStoreKeyCreateConsoleUser(NULL); 179 Boolean ok = FALSE; 180 181 if ((user == NULL) && (sessions == NULL)) { 182 ok = SCDynamicStoreRemoveValue(store, key); 183 goto done; 184 } 185 186 dict = CFDictionaryCreateMutable(NULL, 187 0, 188 &kCFTypeDictionaryKeyCallBacks, 189 &kCFTypeDictionaryValueCallBacks); 190 191 if (user != NULL) { 192 CFNumberRef num; 193 194 consoleUser = CFStringCreateWithCString(NULL, user, kCFStringEncodingMacRoman); 195 CFDictionarySetValue(dict, kSCPropUsersConsoleUserName, consoleUser); 196 CFRelease(consoleUser); 197 198 num = CFNumberCreate(NULL, kCFNumberSInt32Type, (SInt32 *)&uid); 199 CFDictionarySetValue(dict, kSCPropUsersConsoleUserUID, num); 200 CFRelease(num); 201 202 num = CFNumberCreate(NULL, kCFNumberSInt32Type, (SInt32 *)&gid); 203 CFDictionarySetValue(dict, kSCPropUsersConsoleUserGID, num); 204 CFRelease(num); 205 } 206 207 if (sessions != NULL) { 208 CFDictionarySetValue(dict, kSCPropUsersConsoleSessionInfo, sessions); 209 } 210 211 ok = SCDynamicStoreSetValue(store, key, dict); 212 213 done : 214 215 if (dict) CFRelease(dict); 216 if (key) CFRelease(key); 217 return ok; 218} 219 220 221Boolean 222SCDynamicStoreSetConsoleUser(SCDynamicStoreRef store, 223 const char *user, 224 uid_t uid, 225 gid_t gid) 226{ 227 CFStringRef consoleUser; 228 CFMutableDictionaryRef dict = NULL; 229 CFStringRef key = SCDynamicStoreKeyCreateConsoleUser(NULL); 230 CFNumberRef num; 231 Boolean ok = FALSE; 232 233 if (user == NULL) { 234 ok = SCDynamicStoreRemoveValue(store, key); 235 goto done; 236 } 237 238 dict = CFDictionaryCreateMutable(NULL, 239 0, 240 &kCFTypeDictionaryKeyCallBacks, 241 &kCFTypeDictionaryValueCallBacks); 242 243 consoleUser = CFStringCreateWithCString(NULL, user, kCFStringEncodingMacRoman); 244 CFDictionarySetValue(dict, kSCPropUsersConsoleUserName, consoleUser); 245 CFRelease(consoleUser); 246 247 num = CFNumberCreate(NULL, kCFNumberSInt32Type, (SInt32 *)&uid); 248 CFDictionarySetValue(dict, kSCPropUsersConsoleUserUID, num); 249 CFRelease(num); 250 251 num = CFNumberCreate(NULL, kCFNumberSInt32Type, (SInt32 *)&gid); 252 CFDictionarySetValue(dict, kSCPropUsersConsoleUserGID, num); 253 CFRelease(num); 254 255 ok = SCDynamicStoreSetValue(store, key, dict); 256 257 done : 258 259 if (dict) CFRelease(dict); 260 if (key) CFRelease(key); 261 return ok; 262} 263