diff options
author | 2021-05-09 14:20:58 -0400 | |
---|---|---|
committer | 2021-05-09 14:20:58 -0400 | |
commit | 5fd83771641d15c418f747bd343ba6738d3875f7 (patch) | |
tree | 5abf0f78f680d9837dbd93d4d4c3933bb7509599 /shell_cmds/id/open_directory.c | |
download | apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.gz apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.zst apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.zip |
Import macOS userland
adv_cmds-176
basic_cmds-55
bootstrap_cmds-116.100.1
developer_cmds-66
diskdev_cmds-667.40.1
doc_cmds-53.60.1
file_cmds-321.40.3
mail_cmds-35
misc_cmds-34
network_cmds-606.40.1
patch_cmds-17
remote_cmds-63
shell_cmds-216.60.1
system_cmds-880.60.2
text_cmds-106
Diffstat (limited to 'shell_cmds/id/open_directory.c')
-rw-r--r-- | shell_cmds/id/open_directory.c | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/shell_cmds/id/open_directory.c b/shell_cmds/id/open_directory.c new file mode 100644 index 0000000..fb34de9 --- /dev/null +++ b/shell_cmds/id/open_directory.c @@ -0,0 +1,229 @@ +#include <membership.h> + +#include "open_directory.h" + +ODNodeRef +CreateNode(void) +{ + CFErrorRef error = NULL; + ODNodeRef node = NULL; + + node = ODNodeCreateWithNodeType(NULL, kODSessionDefault, kODTypeAuthenticationSearchNode, &error); + + if (node == NULL) { + CFShow(error); + exit(1); + } + + return node; +} + +static ODRecordRef +CopyRecordWithUUID(ODNodeRef node, CFStringRef type, uuid_t uuid) +{ + CFErrorRef error = NULL; + char uuidstr[37]; + CFStringRef uuidref; + ODQueryRef query = NULL; + CFTypeRef vals[] = { CFSTR(kDSAttributesStandardAll) }; + CFArrayRef attributes = CFArrayCreate(NULL, vals, 1, &kCFTypeArrayCallBacks); + CFArrayRef results = NULL; + ODRecordRef record = NULL; + + uuid_unparse(uuid, uuidstr); + uuidref = CFStringCreateWithCString(NULL, uuidstr, kCFStringEncodingUTF8); + + if (uuidref) { + query = ODQueryCreateWithNode(NULL, node, type, CFSTR(kDS1AttrGeneratedUID), kODMatchEqualTo, uuidref, attributes, 100, &error); + + if (query) { + results = ODQueryCopyResults(query, false, &error); + + if (results) { + if (CFArrayGetCount(results) == 1) { + record = (ODRecordRef)CFArrayGetValueAtIndex(results, 0); + CFRetain(record); + } + + CFRelease(results); + } + + CFRelease(query); + } + + CFRelease(uuidref); + } + + return record; +} + +ODRecordRef +CopyGroupRecordWithGID(ODNodeRef node, gid_t gid) +{ + uuid_t uuid; + + mbr_gid_to_uuid(gid, uuid); + + return CopyRecordWithUUID(node, CFSTR(kDSStdRecordTypeGroups), uuid); +} + +ODRecordRef +CopyUserRecordWithUID(ODNodeRef node, uid_t uid) +{ + uuid_t uuid; + + mbr_uid_to_uuid(uid, uuid); + + return CopyRecordWithUUID(node, CFSTR(kDSStdRecordTypeUsers), uuid); +} + +ODRecordRef +CopyUserRecordWithUsername(ODNodeRef node, char *name) +{ + CFStringRef nameref; + CFTypeRef vals[] = { CFSTR(kDSAttributesStandardAll) }; + CFArrayRef attributes = CFArrayCreate(NULL, vals, 1, &kCFTypeArrayCallBacks); + CFErrorRef error; + + nameref = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8); + + if (nameref == NULL) + return NULL; + + return ODNodeCopyRecord(node, CFSTR(kDSStdRecordTypeUsers), nameref, attributes, &error); +} + +CFStringRef +CopyAttrFromRecord(ODRecordRef record, CFStringRef attribute) +{ + CFErrorRef error = NULL; + CFArrayRef values = ODRecordCopyValues(record, attribute, &error); + CFStringRef result = NULL; + + if (values) { + if (CFArrayGetCount(values) == 1) { + result = CFArrayGetValueAtIndex(values, 0); + CFRetain(result); + } + CFRelease(values); + } + + return result; +} + +int +GetIntAttrFromRecord(ODRecordRef record, CFStringRef attribute, int *output) +{ + int status = 1; + CFStringRef str = CopyAttrFromRecord(record, attribute); + + if (str) { + *output = CFStringGetIntValue(str); + status = 0; + CFRelease(str); + } + + return status; +} + +uid_t +GetUIDFromRecord(ODRecordRef record) +{ + int uid = -1; + + GetIntAttrFromRecord(record, CFSTR(kDS1AttrUniqueID), &uid); + + return uid; +} + +gid_t +GetGIDFromRecord(ODRecordRef record) +{ + int gid = -1; + + GetIntAttrFromRecord(record, CFSTR(kDS1AttrPrimaryGroupID), &gid); + + return gid; +} + +CFArrayRef +CopyGroupRecordsForUser(ODNodeRef node, ODRecordRef user, CFIndex limit) +{ + CFMutableArrayRef groups; + gid_t primary_gid; + ODRecordRef primary_group; + CFErrorRef error = NULL; + ODQueryRef query; + CFArrayRef results; + int i; + ODRecordRef gr; + + query = ODQueryCreateWithNode(NULL, node, CFSTR(kDSStdRecordTypeGroups), + CFSTR(kDSNAttrMember), kODMatchContains, ODRecordGetRecordName(user), NULL, limit, &error); + results = ODQueryCopyResults(query, false, &error); + CFRelease(query); + + groups = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + primary_gid = GetGIDFromRecord(user); + primary_group = CopyGroupRecordWithGID(node, primary_gid); + CFArrayAppendValue(groups, primary_group); + CFRelease(primary_group); + + for (i = 0; i < CFArrayGetCount(results); i++) { + gr = (ODRecordRef)CFArrayGetValueAtIndex(results, i); + if (GetGIDFromRecord(gr) != primary_gid) { + CFArrayAppendValue(groups, gr); + } + } + + CFRelease(results); + + return groups; +} + +static int +cvfprintf(FILE *file, const char *format, va_list args) +{ + char* cstr; + int result = 0; + CFStringRef formatStr = CFStringCreateWithCStringNoCopy(NULL, format, kCFStringEncodingUTF8, kCFAllocatorNull); + if (formatStr) { + CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, formatStr, args); + if (str) { + size_t size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8) + 1; + cstr = malloc(size); + if (cstr && CFStringGetCString(str, cstr, size, kCFStringEncodingUTF8)) { + result = fprintf(file, "%s", cstr); + free(cstr); + } + CFRelease(str); + } + CFRelease(formatStr); + } + return result; +} + +int +cfprintf(FILE *file, const char *format, ...) +{ + int result; + va_list args; + + va_start(args, format); + result = cvfprintf(file, format, args); + va_end(args); + return result; +} + +int +cprintf(const char *format, ...) +{ + int result; + va_list args; + + va_start(args, format); + result = cvfprintf(stdout, format, args); + va_end(args); + return result; +} |