1 /* Copyright (c) 2012 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 CFReleaseSafe(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
);
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 if ( (pw
->pw_passwd
== NULL
) || strcmp(pw
->pw_passwd
, "*") ) {
127 cred
->uid
= pw
->pw_uid
;
128 cred
->name
= _copy_string(pw
->pw_name
);
129 cred
->realName
= _copy_string(pw
->pw_gecos
);
132 cred
->uid
= (uid_t
)-2;
143 credential_create_with_credential(credential_t srcCred
, bool shared
)
145 credential_t cred
= NULL
;
147 cred
= _credential_create();
148 require(cred
!= NULL
, done
);
150 cred
->uid
= srcCred
->uid
;
151 cred
->name
= _copy_string(srcCred
->name
);
152 cred
->realName
= _copy_string(srcCred
->realName
);
153 cred
->valid
= srcCred
->valid
;
154 cred
->right
= srcCred
->right
;
155 cred
->shared
= shared
;
162 credential_create_with_right(const char * right
)
164 credential_t cred
= NULL
;
166 cred
= _credential_create();
167 require(cred
!= NULL
, done
);
170 cred
->name
= _copy_string(right
);
171 cred
->uid
= (uid_t
)-2;
179 credential_get_uid(credential_t cred
)
185 credential_get_name(credential_t cred
)
191 credential_get_realname(credential_t cred
)
193 return cred
->realName
;
197 credential_get_creation_time(credential_t cred
)
199 return cred
->creationTime
;
203 credential_get_valid(credential_t cred
)
209 credential_get_shared(credential_t cred
)
215 credential_is_right(credential_t cred
)
221 credential_check_membership(credential_t cred
,const char* group
)
224 CFStringRef cachedGroup
= NULL
;
225 require(group
!= NULL
, done
);
226 require(cred
->uid
!= 0 || cred
->uid
!= (uid_t
)-2, done
);
227 require(cred
->right
!= true, done
);
229 cachedGroup
= CFStringCreateWithCString(kCFAllocatorDefault
, group
, kCFStringEncodingUTF8
);
230 require(cachedGroup
!= NULL
, done
);
232 if (CFSetGetValue(cred
->cachedGroups
, cachedGroup
) != NULL
) {
238 uuid_t group_uuid
, user_uuid
;
239 rc
= mbr_group_name_to_uuid(group
, group_uuid
);
240 require_noerr(rc
, done
);
242 rc
= mbr_uid_to_uuid(cred
->uid
, user_uuid
);
243 require_noerr(rc
, done
);
245 rc
= mbr_check_membership(user_uuid
, group_uuid
, &ismember
);
246 require_noerr(rc
, done
);
251 CFSetSetValue(cred
->cachedGroups
, cachedGroup
);
255 CFReleaseSafe(cachedGroup
);
260 credential_invalidate(credential_t cred
)