1#include <membership.h> 2 3#include "open_directory.h" 4 5ODNodeRef 6CreateNode(void) 7{ 8 CFErrorRef error = NULL; 9 ODNodeRef node = NULL; 10 11 node = ODNodeCreateWithNodeType(NULL, kODSessionDefault, kODTypeAuthenticationSearchNode, &error); 12 13 if (node == NULL) { 14 CFShow(error); 15 exit(1); 16 } 17 18 return node; 19} 20 21static ODRecordRef 22CopyRecordWithUUID(ODNodeRef node, CFStringRef type, uuid_t uuid) 23{ 24 CFErrorRef error = NULL; 25 char uuidstr[37]; 26 CFStringRef uuidref; 27 ODQueryRef query = NULL; 28 CFTypeRef vals[] = { CFSTR(kDSAttributesStandardAll) }; 29 CFArrayRef attributes = CFArrayCreate(NULL, vals, 1, &kCFTypeArrayCallBacks); 30 CFArrayRef results = NULL; 31 ODRecordRef record = NULL; 32 33 uuid_unparse(uuid, uuidstr); 34 uuidref = CFStringCreateWithCString(NULL, uuidstr, kCFStringEncodingUTF8); 35 36 if (uuidref) { 37 query = ODQueryCreateWithNode(NULL, node, type, CFSTR(kDS1AttrGeneratedUID), kODMatchEqualTo, uuidref, attributes, 100, &error); 38 39 if (query) { 40 results = ODQueryCopyResults(query, false, &error); 41 42 if (results) { 43 if (CFArrayGetCount(results) == 1) { 44 record = (ODRecordRef)CFArrayGetValueAtIndex(results, 0); 45 CFRetain(record); 46 } 47 48 CFRelease(results); 49 } 50 51 CFRelease(query); 52 } 53 54 CFRelease(uuidref); 55 } 56 57 return record; 58} 59 60ODRecordRef 61CopyGroupRecordWithGID(ODNodeRef node, gid_t gid) 62{ 63 uuid_t uuid; 64 65 mbr_gid_to_uuid(gid, uuid); 66 67 return CopyRecordWithUUID(node, CFSTR(kDSStdRecordTypeGroups), uuid); 68} 69 70ODRecordRef 71CopyUserRecordWithUID(ODNodeRef node, uid_t uid) 72{ 73 uuid_t uuid; 74 75 mbr_uid_to_uuid(uid, uuid); 76 77 return CopyRecordWithUUID(node, CFSTR(kDSStdRecordTypeUsers), uuid); 78} 79 80ODRecordRef 81CopyUserRecordWithUsername(ODNodeRef node, char *name) 82{ 83 CFStringRef nameref; 84 CFTypeRef vals[] = { CFSTR(kDSAttributesStandardAll) }; 85 CFArrayRef attributes = CFArrayCreate(NULL, vals, 1, &kCFTypeArrayCallBacks); 86 CFErrorRef error; 87 88 nameref = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8); 89 90 if (nameref == NULL) 91 return NULL; 92 93 return ODNodeCopyRecord(node, CFSTR(kDSStdRecordTypeUsers), nameref, attributes, &error); 94} 95 96CFStringRef 97CopyAttrFromRecord(ODRecordRef record, CFStringRef attribute) 98{ 99 CFErrorRef error = NULL; 100 CFArrayRef values = ODRecordCopyValues(record, attribute, &error); 101 CFStringRef result = NULL; 102 103 if (values) { 104 if (CFArrayGetCount(values) == 1) { 105 result = CFArrayGetValueAtIndex(values, 0); 106 CFRetain(result); 107 } 108 CFRelease(values); 109 } 110 111 return result; 112} 113 114int 115GetIntAttrFromRecord(ODRecordRef record, CFStringRef attribute, int *output) 116{ 117 int status = 1; 118 CFStringRef str = CopyAttrFromRecord(record, attribute); 119 120 if (str) { 121 *output = CFStringGetIntValue(str); 122 status = 0; 123 CFRelease(str); 124 } 125 126 return status; 127} 128 129uid_t 130GetUIDFromRecord(ODRecordRef record) 131{ 132 int uid = -1; 133 134 GetIntAttrFromRecord(record, CFSTR(kDS1AttrUniqueID), &uid); 135 136 return uid; 137} 138 139gid_t 140GetGIDFromRecord(ODRecordRef record) 141{ 142 int gid = -1; 143 144 GetIntAttrFromRecord(record, CFSTR(kDS1AttrPrimaryGroupID), &gid); 145 146 return gid; 147} 148 149CFArrayRef 150CopyGroupRecordsForUser(ODNodeRef node, ODRecordRef user, CFIndex limit) 151{ 152 CFMutableArrayRef groups; 153 gid_t primary_gid; 154 ODRecordRef primary_group; 155 CFErrorRef error = NULL; 156 ODQueryRef query; 157 CFArrayRef results; 158 int i; 159 ODRecordRef gr; 160 161 query = ODQueryCreateWithNode(NULL, node, CFSTR(kDSStdRecordTypeGroups), 162 CFSTR(kDSNAttrMember), kODMatchContains, ODRecordGetRecordName(user), NULL, limit, &error); 163 results = ODQueryCopyResults(query, false, &error); 164 CFRelease(query); 165 166 groups = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); 167 168 primary_gid = GetGIDFromRecord(user); 169 primary_group = CopyGroupRecordWithGID(node, primary_gid); 170 CFArrayAppendValue(groups, primary_group); 171 CFRelease(primary_group); 172 173 for (i = 0; i < CFArrayGetCount(results); i++) { 174 gr = (ODRecordRef)CFArrayGetValueAtIndex(results, i); 175 if (GetGIDFromRecord(gr) != primary_gid) { 176 CFArrayAppendValue(groups, gr); 177 } 178 } 179 180 CFRelease(results); 181 182 return groups; 183} 184 185static int 186cvfprintf(FILE *file, const char *format, va_list args) 187{ 188 char* cstr; 189 int result = 0; 190 CFStringRef formatStr = CFStringCreateWithCStringNoCopy(NULL, format, kCFStringEncodingUTF8, kCFAllocatorNull); 191 if (formatStr) { 192 CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, formatStr, args); 193 if (str) { 194 size_t size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8) + 1; 195 cstr = malloc(size); 196 if (cstr && CFStringGetCString(str, cstr, size, kCFStringEncodingUTF8)) { 197 result = fprintf(file, "%s", cstr); 198 free(cstr); 199 } 200 CFRelease(str); 201 } 202 CFRelease(formatStr); 203 } 204 return result; 205} 206 207int 208cfprintf(FILE *file, const char *format, ...) 209{ 210 int result; 211 va_list args; 212 213 va_start(args, format); 214 result = cvfprintf(file, format, args); 215 va_end(args); 216 return result; 217} 218 219int 220cprintf(const char *format, ...) 221{ 222 int result; 223 va_list args; 224 225 va_start(args, format); 226 result = cvfprintf(stdout, format, args); 227 va_end(args); 228 return result; 229} 230