1 /* Copyright (c) 2012-2013 Apple Inc. All Rights Reserved. */
3 #include "credential.h"
4 #include "authutilities.h"
9 #include <membership.h>
10 #include <membershipPriv.h>
12 struct _credential_s
{
13 __AUTH_BASE_STRUCT_HEADER__
;
15 bool right
; // is least-privileged credential
21 CFAbsoluteTime creationTime
;
25 CFMutableSetRef cachedGroups
;
29 _credential_finalize(CFTypeRef value
)
31 credential_t cred
= (credential_t
)value
;
33 free_safe(cred
->name
);
34 free_safe(cred
->realName
);
35 CFReleaseNull(cred
->cachedGroups
);
39 _credential_copy_description(CFTypeRef value
)
41 credential_t cred
= (credential_t
)value
;
42 CFStringRef str
= NULL
;
43 CFTimeZoneRef sys_tz
= CFTimeZoneCopySystem();
44 CFGregorianDate date
= CFAbsoluteTimeGetGregorianDate(cred
->creationTime
, sys_tz
);
45 CFReleaseSafe(sys_tz
);
47 str
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("credential: right=%s, shared=%i, creation=%01i:%01i:%01i, valid=%i"), cred
->name
, cred
->shared
, date
.hour
,date
.minute
,(int32_t)date
.second
, cred
->valid
);
49 str
= CFStringCreateWithFormat(kCFAllocatorDefault
, NULL
, CFSTR("credential: uid=%i, name=%s, shared=%i, creation=%01i:%01i:%01i valid=%i"), cred
->uid
, cred
->name
, cred
->shared
, date
.hour
,date
.minute
,(int32_t)date
.second
, cred
->valid
);
55 _credential_hash(CFTypeRef value
)
57 credential_t cred
= (credential_t
)value
;
58 uint64_t crc
= crc64_init();
60 crc
= crc64_update(crc
, cred
->name
, strlen(cred
->name
));
62 crc
= crc64_update(crc
, &cred
->uid
, sizeof(cred
->uid
));
64 crc
= crc64_update(crc
, &cred
->shared
, sizeof(cred
->shared
));
65 crc
= crc64_final(crc
);
67 return (CFHashCode
)crc
;
71 _credential_equal(CFTypeRef value1
, CFTypeRef value2
)
73 credential_t cred1
= (credential_t
)value1
;
74 credential_t cred2
= (credential_t
)value2
;
76 return _credential_hash(cred1
) == _credential_hash(cred2
);
79 AUTH_TYPE_INSTANCE(credential
,
82 .finalize
= _credential_finalize
,
83 .equal
= _credential_equal
,
84 .hash
= _credential_hash
,
85 .copyFormattingDesc
= NULL
,
86 .copyDebugDesc
= _credential_copy_description
89 static CFTypeID
credential_get_type_id() {
90 static CFTypeID type_id
= _kCFRuntimeNotATypeID
;
91 static dispatch_once_t onceToken
;
93 dispatch_once(&onceToken
, ^{
94 type_id
= _CFRuntimeRegisterClass(&_auth_type_credential
);
103 credential_t cred
= NULL
;
105 cred
= (credential_t
)_CFRuntimeCreateInstance(kCFAllocatorDefault
, credential_get_type_id(), AUTH_CLASS_SIZE(credential
), NULL
);
106 require(cred
!= NULL
, done
);
108 cred
->creationTime
= CFAbsoluteTimeGetCurrent();
109 cred
->cachedGroups
= CFSetCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeSetCallBacks
);;
116 credential_create(uid_t uid
)
118 credential_t cred
= NULL
;
120 cred
= _credential_create();
121 require(cred
!= NULL
, done
);
123 struct passwd
*pw
= getpwuid(uid
);
125 // avoid hinting a locked account
126 // LibInfo started to return asterisk for system accounts in <rdar://problem/31633690> J93: 17a240: Hang during boot (opendirectoryd/powerd deadlock)
127 // so do not make this check for those system accounts
128 if ( (uid
< 500) || (pw
->pw_passwd
== NULL
) || strcmp(pw
->pw_passwd
, "*") ) {
129 cred
->uid
= pw
->pw_uid
;
130 cred
->name
= _copy_string(pw
->pw_name
);
131 cred
->realName
= _copy_string(pw
->pw_gecos
);
134 cred
->uid
= (uid_t
)-2;
145 credential_create_with_credential(credential_t srcCred
, bool shared
)
147 credential_t cred
= NULL
;
149 cred
= _credential_create();
150 require(cred
!= NULL
, done
);
152 cred
->uid
= srcCred
->uid
;
153 cred
->name
= _copy_string(srcCred
->name
);
154 cred
->realName
= _copy_string(srcCred
->realName
);
155 cred
->valid
= srcCred
->valid
;
156 cred
->right
= srcCred
->right
;
157 cred
->shared
= shared
;
164 credential_create_with_right(const char * right
)
166 credential_t cred
= NULL
;
168 cred
= _credential_create();
169 require(cred
!= NULL
, done
);
172 cred
->name
= _copy_string(right
);
173 cred
->uid
= (uid_t
)-2;
181 credential_get_uid(credential_t cred
)
187 credential_get_name(credential_t cred
)
193 credential_get_realname(credential_t cred
)
195 return cred
->realName
;
199 credential_get_creation_time(credential_t cred
)
201 return cred
->creationTime
;
205 credential_get_valid(credential_t cred
)
211 credential_get_shared(credential_t cred
)
217 credential_is_right(credential_t cred
)
223 credential_check_membership(credential_t cred
,const char* group
)
226 CFStringRef cachedGroup
= NULL
;
227 require(group
!= NULL
, done
);
228 require(cred
->uid
!= 0 || cred
->uid
!= (uid_t
)-2, done
);
229 require(cred
->right
!= true, done
);
231 cachedGroup
= CFStringCreateWithCString(kCFAllocatorDefault
, group
, kCFStringEncodingUTF8
);
232 require(cachedGroup
!= NULL
, done
);
234 if (CFSetGetValue(cred
->cachedGroups
, cachedGroup
) != NULL
) {
240 uuid_t group_uuid
, user_uuid
;
241 rc
= mbr_group_name_to_uuid(group
, group_uuid
);
242 require_noerr(rc
, done
);
244 rc
= mbr_uid_to_uuid(cred
->uid
, user_uuid
);
245 require_noerr(rc
, done
);
247 rc
= mbr_check_membership(user_uuid
, group_uuid
, &ismember
);
248 require_noerr(rc
, done
);
253 CFSetSetValue(cred
->cachedGroups
, cachedGroup
);
257 CFReleaseSafe(cachedGroup
);
262 credential_invalidate(credential_t cred
)