+++ /dev/null
-/* Copyright (c) 2012-2013 Apple Inc. All Rights Reserved. */
-
-#include "credential.h"
-#include "authutilities.h"
-#include "debugging.h"
-#include "crc.h"
-
-#include <pwd.h>
-#include <membership.h>
-#include <membershipPriv.h>
-
-struct _credential_s {
- __AUTH_BASE_STRUCT_HEADER__;
-
- bool right; // is least-privileged credential
-
- uid_t uid;
- char * name;
- char * realName;
-
- CFAbsoluteTime creationTime;
- bool valid;
- bool shared;
-
- CFMutableSetRef cachedGroups;
-};
-
-static void
-_credential_finalize(CFTypeRef value)
-{
- credential_t cred = (credential_t)value;
-
- free_safe(cred->name);
- free_safe(cred->realName);
- CFReleaseSafe(cred->cachedGroups);
-}
-
-static CFStringRef
-_credential_copy_description(CFTypeRef value)
-{
- credential_t cred = (credential_t)value;
- CFStringRef str = NULL;
- CFTimeZoneRef sys_tz = CFTimeZoneCopySystem();
- CFGregorianDate date = CFAbsoluteTimeGetGregorianDate(cred->creationTime, sys_tz);
- CFReleaseSafe(sys_tz);
- if (cred->right) {
- 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);
- } else {
- 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);
- }
- return str;
-}
-
-static CFHashCode
-_credential_hash(CFTypeRef value)
-{
- credential_t cred = (credential_t)value;
- uint64_t crc = crc64_init();
- if (cred->right) {
- crc = crc64_update(crc, cred->name, strlen(cred->name));
- } else {
- crc = crc64_update(crc, &cred->uid, sizeof(cred->uid));
- }
- crc = crc64_update(crc, &cred->shared, sizeof(cred->shared));
- crc = crc64_final(crc);
-
- return crc;
-}
-
-static Boolean
-_credential_equal(CFTypeRef value1, CFTypeRef value2)
-{
- credential_t cred1 = (credential_t)value1;
- credential_t cred2 = (credential_t)value2;
-
- return _credential_hash(cred1) == _credential_hash(cred2);
-}
-
-AUTH_TYPE_INSTANCE(credential,
- .init = NULL,
- .copy = NULL,
- .finalize = _credential_finalize,
- .equal = _credential_equal,
- .hash = _credential_hash,
- .copyFormattingDesc = NULL,
- .copyDebugDesc = _credential_copy_description
- );
-
-static CFTypeID credential_get_type_id() {
- static CFTypeID type_id = _kCFRuntimeNotATypeID;
- static dispatch_once_t onceToken;
-
- dispatch_once(&onceToken, ^{
- type_id = _CFRuntimeRegisterClass(&_auth_type_credential);
- });
-
- return type_id;
-}
-
-static credential_t
-_credential_create()
-{
- credential_t cred = NULL;
-
- cred = (credential_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, credential_get_type_id(), AUTH_CLASS_SIZE(credential), NULL);
- require(cred != NULL, done);
-
- cred->creationTime = CFAbsoluteTimeGetCurrent();
- cred->cachedGroups = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks);;
-
-done:
- return cred;
-}
-
-credential_t
-credential_create(uid_t uid)
-{
- credential_t cred = NULL;
-
- cred = _credential_create();
- require(cred != NULL, done);
-
- struct passwd *pw = getpwuid(uid);
- if (pw != NULL) {
- // avoid hinting a locked account
- if ( (pw->pw_passwd == NULL) || strcmp(pw->pw_passwd, "*") ) {
- cred->uid = pw->pw_uid;
- cred->name = _copy_string(pw->pw_name);
- cred->realName = _copy_string(pw->pw_gecos);
- cred->valid = true;
- } else {
- cred->uid = (uid_t)-2;
- cred->valid = false;
- }
- endpwent();
- }
-
-done:
- return cred;
-}
-
-credential_t
-credential_create_with_credential(credential_t srcCred, bool shared)
-{
- credential_t cred = NULL;
-
- cred = _credential_create();
- require(cred != NULL, done);
-
- cred->uid = srcCred->uid;
- cred->name = _copy_string(srcCred->name);
- cred->realName = _copy_string(srcCred->realName);
- cred->valid = srcCred->valid;
- cred->right = srcCred->right;
- cred->shared = shared;
-
-done:
- return cred;
-}
-
-credential_t
-credential_create_with_right(const char * right)
-{
- credential_t cred = NULL;
-
- cred = _credential_create();
- require(cred != NULL, done);
-
- cred->right = true;
- cred->name = _copy_string(right);
- cred->uid = (uid_t)-2;
- cred->valid = true;
-
-done:
- return cred;
-}
-
-uid_t
-credential_get_uid(credential_t cred)
-{
- return cred->uid;
-}
-
-const char *
-credential_get_name(credential_t cred)
-{
- return cred->name;
-}
-
-const char *
-credential_get_realname(credential_t cred)
-{
- return cred->realName;
-}
-
-CFAbsoluteTime
-credential_get_creation_time(credential_t cred)
-{
- return cred->creationTime;
-}
-
-bool
-credential_get_valid(credential_t cred)
-{
- return cred->valid;
-}
-
-bool
-credential_get_shared(credential_t cred)
-{
- return cred->shared;
-}
-
-bool
-credential_is_right(credential_t cred)
-{
- return cred->right;
-}
-
-bool
-credential_check_membership(credential_t cred,const char* group)
-{
- bool result = false;
- CFStringRef cachedGroup = NULL;
- require(group != NULL, done);
- require(cred->uid != 0 || cred->uid != (uid_t)-2, done);
- require(cred->right != true, done);
-
- cachedGroup = CFStringCreateWithCString(kCFAllocatorDefault, group, kCFStringEncodingUTF8);
- require(cachedGroup != NULL, done);
-
- if (CFSetGetValue(cred->cachedGroups, cachedGroup) != NULL) {
- result = true;
- goto done;
- }
-
- int rc, ismember;
- uuid_t group_uuid, user_uuid;
- rc = mbr_group_name_to_uuid(group, group_uuid);
- require_noerr(rc, done);
-
- rc = mbr_uid_to_uuid(cred->uid, user_uuid);
- require_noerr(rc, done);
-
- rc = mbr_check_membership(user_uuid, group_uuid, &ismember);
- require_noerr(rc, done);
-
- result = ismember;
-
- if (ismember) {
- CFSetSetValue(cred->cachedGroups, cachedGroup);
- }
-
-done:
- CFReleaseSafe(cachedGroup);
- return result;
-}
-
-void
-credential_invalidate(credential_t cred)
-{
- cred->valid = false;
-}