]> git.saurik.com Git - apple/shell_cmds.git/blob - id/open_directory.c
fb34de996c993b9f269f51969c6e7430e31efe3e
[apple/shell_cmds.git] / id / open_directory.c
1 #include <membership.h>
2
3 #include "open_directory.h"
4
5 ODNodeRef
6 CreateNode(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
21 static ODRecordRef
22 CopyRecordWithUUID(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
60 ODRecordRef
61 CopyGroupRecordWithGID(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
70 ODRecordRef
71 CopyUserRecordWithUID(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
80 ODRecordRef
81 CopyUserRecordWithUsername(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
96 CFStringRef
97 CopyAttrFromRecord(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
114 int
115 GetIntAttrFromRecord(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
129 uid_t
130 GetUIDFromRecord(ODRecordRef record)
131 {
132 int uid = -1;
133
134 GetIntAttrFromRecord(record, CFSTR(kDS1AttrUniqueID), &uid);
135
136 return uid;
137 }
138
139 gid_t
140 GetGIDFromRecord(ODRecordRef record)
141 {
142 int gid = -1;
143
144 GetIntAttrFromRecord(record, CFSTR(kDS1AttrPrimaryGroupID), &gid);
145
146 return gid;
147 }
148
149 CFArrayRef
150 CopyGroupRecordsForUser(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
185 static int
186 cvfprintf(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
207 int
208 cfprintf(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
219 int
220 cprintf(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 }