]> git.saurik.com Git - apple/libinfo.git/blame - membership.subproj/membership.c
Libinfo-222.3.6.tar.gz
[apple/libinfo.git] / membership.subproj / membership.c
CommitLineData
c29f2fcc 1/*
162e9b63 2 * Copyright (c) 2004-2007 Apple Computer, Inc. All rights reserved.
c29f2fcc
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23#include "membership.h"
24#include "membershipPriv.h"
25#include "memberd.h"
26
27#include <sys/errno.h>
28#include <servers/bootstrap.h>
29#include <mach/mach.h>
30#include <stdlib.h>
162e9b63 31#include <libkern/OSByteOrder.h>
c29f2fcc
A
32
33static mach_port_t GetServerPort()
34{
35 kern_return_t result;
162e9b63
A
36 static mach_port_t bsPort = 0;
37 static mach_port_t fServerPort = 0;
38
c29f2fcc
A
39 if (bsPort == 0)
40 {
162e9b63
A
41 result = task_get_bootstrap_port(mach_task_self(), &bsPort);
42 result = bootstrap_look_up(bsPort, "com.apple.memberd", &fServerPort);
c29f2fcc
A
43 }
44
45 return fServerPort;
46}
47
48int mbr_uid_to_uuid(uid_t id, uuid_t uu)
49{
50 struct kauth_identity_extlookup request;
162e9b63 51 security_token_t token;
c29f2fcc
A
52 int result = 0;
53
162e9b63
A
54 token.val[0] = -1;
55 token.val[1] = -1;
56
c29f2fcc
A
57 request.el_flags = KAUTH_EXTLOOKUP_VALID_UID | KAUTH_EXTLOOKUP_WANT_UGUID;
58 request.el_uid = id;
162e9b63
A
59 result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
60 if (result != KERN_SUCCESS) return EIO;
61 if (token.val[0] != 0) return EAUTH;
62
c29f2fcc
A
63 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_UGUID) != 0)
64 memcpy(uu, &request.el_uguid, sizeof(guid_t));
65 else
66 result = ENOENT;
67
68 return result;
69}
70
71int mbr_gid_to_uuid(gid_t id, uuid_t uu)
72{
73 struct kauth_identity_extlookup request;
162e9b63 74 security_token_t token;
c29f2fcc
A
75 kern_return_t result;
76 int error = 0;
77
162e9b63
A
78 token.val[0] = -1;
79 token.val[1] = -1;
80
c29f2fcc
A
81 request.el_flags = KAUTH_EXTLOOKUP_VALID_GID | KAUTH_EXTLOOKUP_WANT_GGUID;
82 request.el_gid = id;
162e9b63
A
83 result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
84 if (result != KERN_SUCCESS) return EIO;
85 if (token.val[0] != 0) return EAUTH;
86
c29f2fcc
A
87 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_GGUID) != 0)
88 memcpy(uu, &request.el_gguid, sizeof(guid_t));
89 else
90 error = ENOENT;
162e9b63 91
c29f2fcc
A
92 return error;
93}
94
162e9b63 95int mbr_uuid_to_id(const uuid_t uu, uid_t *id, int *id_type)
c29f2fcc
A
96{
97 struct kauth_identity_extlookup request;
162e9b63 98 security_token_t token;
c29f2fcc
A
99 kern_return_t result;
100 int error = 0;
101
162e9b63
A
102 token.val[0] = -1;
103 token.val[1] = -1;
104
105 request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GGUID | KAUTH_EXTLOOKUP_WANT_UID | KAUTH_EXTLOOKUP_WANT_GID;
c29f2fcc
A
106 memcpy(&request.el_uguid, uu, sizeof(guid_t));
107 memcpy(&request.el_gguid, uu, sizeof(guid_t));
162e9b63
A
108 result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
109 if (result != KERN_SUCCESS) return EIO;
110 if (token.val[0] != 0) return EAUTH;
111
c29f2fcc
A
112 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_UID) != 0)
113 {
114 *id = request.el_uid;
115 *id_type = ID_TYPE_UID;
116 }
117 else if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_GID) != 0)
118 {
119 *id = request.el_gid;
120 *id_type = ID_TYPE_GID;
121 }
122 else
162e9b63 123 {
c29f2fcc 124 error = ENOENT;
162e9b63
A
125 }
126
c29f2fcc
A
127 return error;
128}
129
162e9b63 130int mbr_sid_to_uuid(const nt_sid_t *sid, uuid_t uu)
c29f2fcc
A
131{
132 struct kauth_identity_extlookup request;
162e9b63 133 security_token_t token;
c29f2fcc
A
134 kern_return_t result;
135 int error = 0;
136
162e9b63
A
137 token.val[0] = -1;
138 token.val[1] = -1;
139
c29f2fcc
A
140 request.el_flags = KAUTH_EXTLOOKUP_VALID_GSID | KAUTH_EXTLOOKUP_WANT_GGUID;
141 memset(&request.el_gsid, 0, sizeof(ntsid_t));
142 memcpy(&request.el_gsid, sid, KAUTH_NTSID_SIZE(sid));
162e9b63
A
143 result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
144 if (result != KERN_SUCCESS) return EIO;
145 if (token.val[0] != 0) return EAUTH;
146
c29f2fcc
A
147 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_GGUID) != 0)
148 memcpy(uu, &request.el_gguid, sizeof(guid_t));
149 else
150 error = ENOENT;
162e9b63 151
c29f2fcc
A
152 return error;
153}
154
162e9b63 155int mbr_uuid_to_sid(const uuid_t uu, nt_sid_t *sid)
c29f2fcc
A
156{
157 struct kauth_identity_extlookup request;
162e9b63 158 security_token_t token;
c29f2fcc
A
159 kern_return_t result;
160 int error = 0;
161
162e9b63
A
162 token.val[0] = -1;
163 token.val[1] = -1;
164
c29f2fcc
A
165 request.el_flags = KAUTH_EXTLOOKUP_VALID_GGUID | KAUTH_EXTLOOKUP_WANT_GSID;
166 memcpy(&request.el_gguid, uu, sizeof(guid_t));
162e9b63
A
167 result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
168 if (result != KERN_SUCCESS) return EIO;
169 if (token.val[0] != 0) return EAUTH;
170
c29f2fcc
A
171 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_GSID) != 0)
172 memcpy(sid, &request.el_gsid, sizeof(nt_sid_t));
173 else
174 error = ENOENT;
162e9b63 175
c29f2fcc
A
176 return error;
177}
178
162e9b63 179int mbr_check_membership(uuid_t user, uuid_t group, int *ismember)
c29f2fcc
A
180{
181 struct kauth_identity_extlookup request;
162e9b63 182 security_token_t token;
c29f2fcc
A
183 kern_return_t result;
184 int error = 0;
185
162e9b63
A
186 token.val[0] = -1;
187 token.val[1] = -1;
188
189 request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GGUID | KAUTH_EXTLOOKUP_WANT_MEMBERSHIP;
c29f2fcc
A
190 memcpy(&request.el_uguid, user, sizeof(guid_t));
191 memcpy(&request.el_gguid, group, sizeof(guid_t));
162e9b63
A
192 result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
193 if (result != KERN_SUCCESS) return EIO;
194 if (token.val[0] != 0) return EAUTH;
195
c29f2fcc 196 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_MEMBERSHIP) != 0)
c29f2fcc 197 *ismember = ((request.el_flags & KAUTH_EXTLOOKUP_ISMEMBER) != 0);
c29f2fcc
A
198 else
199 error = ENOENT;
162e9b63 200
c29f2fcc
A
201 return error;
202}
203
162e9b63 204int mbr_check_membership_refresh(uuid_t user, uuid_t group, int *ismember)
918ca66e
A
205{
206 struct kauth_identity_extlookup request;
162e9b63 207 security_token_t token;
918ca66e
A
208 kern_return_t result;
209 int error = 0;
210
162e9b63
A
211 token.val[0] = -1;
212 token.val[1] = -1;
213
214 request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GGUID | KAUTH_EXTLOOKUP_WANT_MEMBERSHIP | (1 << 15);
918ca66e
A
215 memcpy(&request.el_uguid, user, sizeof(guid_t));
216 memcpy(&request.el_gguid, group, sizeof(guid_t));
162e9b63
A
217 result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
218 if (result != KERN_SUCCESS) return EIO;
219 if (token.val[0] != 0) return EAUTH;
220
918ca66e 221 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_MEMBERSHIP) != 0)
918ca66e 222 *ismember = ((request.el_flags & KAUTH_EXTLOOKUP_ISMEMBER) != 0);
918ca66e
A
223 else
224 error = ENOENT;
162e9b63 225
918ca66e
A
226 return error;
227}
228
162e9b63 229int mbr_check_membership_by_id(uuid_t user, gid_t group, int *ismember)
c29f2fcc
A
230{
231 struct kauth_identity_extlookup request;
162e9b63 232 security_token_t token;
c29f2fcc
A
233 kern_return_t result;
234 int error = 0;
235
162e9b63
A
236 token.val[0] = -1;
237 token.val[1] = -1;
238
239 request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GID | KAUTH_EXTLOOKUP_WANT_MEMBERSHIP;
c29f2fcc
A
240 memcpy(&request.el_uguid, user, sizeof(guid_t));
241 request.el_gid = group;
162e9b63
A
242 result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
243 if (result != KERN_SUCCESS) return EIO;
244 if (token.val[0] != 0) return EAUTH;
245
c29f2fcc 246 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_MEMBERSHIP) != 0)
c29f2fcc 247 *ismember = ((request.el_flags & KAUTH_EXTLOOKUP_ISMEMBER) != 0);
c29f2fcc
A
248 else
249 error = ENOENT;
162e9b63 250
c29f2fcc
A
251 return error;
252}
253
254int mbr_reset_cache()
255{
162e9b63 256 security_token_t token;
c29f2fcc 257 kern_return_t result;
162e9b63
A
258
259 token.val[0] = -1;
260 token.val[1] = -1;
261
262 result = _mbr_ClearCache(GetServerPort(), &token);
263 if (result != KERN_SUCCESS) return EIO;
264 if (token.val[0] != 0) return EAUTH;
265
c29f2fcc
A
266 return 0;
267}
268
162e9b63 269int mbr_user_name_to_uuid(const char *name, uuid_t uu)
c29f2fcc 270{
162e9b63 271 security_token_t token;
c29f2fcc 272 kern_return_t result;
162e9b63
A
273
274 if (name == NULL) return EINVAL;
275 if (strlen(name) > 255) return EINVAL;
276
277 token.val[0] = -1;
278 token.val[1] = -1;
279
280 result = _mbr_MapName(GetServerPort(), 1, (char *)name, (guid_t *)uu, &token);
281 if (result == KERN_FAILURE) return ENOENT;
282 else if (result != KERN_SUCCESS) return EIO;
283
284 if (token.val[0] != 0) return EAUTH;
285
c29f2fcc
A
286 return 0;
287}
288
162e9b63 289int mbr_group_name_to_uuid(const char *name, uuid_t uu)
c29f2fcc 290{
162e9b63 291 security_token_t token;
c29f2fcc 292 kern_return_t result;
162e9b63
A
293
294 if (name == NULL) return EINVAL;
295 if (strlen(name) > 255) return EINVAL;
296
297 token.val[0] = -1;
298 token.val[1] = -1;
299
300 result = _mbr_MapName(GetServerPort(), 0, (char *)name, (guid_t *)uu, &token);
301 if (result == KERN_FAILURE) return ENOENT;
302 else if (result != KERN_SUCCESS) return EIO;
303
304 if (token.val[0] != 0) return EAUTH;
305
c29f2fcc
A
306 return 0;
307}
308
162e9b63 309int mbr_check_service_membership(const uuid_t user, const char *servicename, int *ismember)
c29f2fcc 310{
162e9b63
A
311 char *prefix = "com.apple.access_";
312 char *all_services = "com.apple.access_all_services";
c29f2fcc
A
313 char groupName[256];
314 uuid_t group_uu;
918ca66e 315 int result, dummy;
162e9b63
A
316
317 if (servicename == NULL) return EINVAL;
318 if (strlen(servicename) > (255 - strlen(prefix))) return EINVAL;
319
320 /* start by checking "all services" */
c29f2fcc 321 result = mbr_group_name_to_uuid(all_services, group_uu);
162e9b63
A
322
323 if (result == EAUTH) return result;
324
c29f2fcc
A
325 if (result == ENOENT)
326 {
162e9b63 327 /* all_services group didn't exist, check individual group */
c29f2fcc
A
328 memcpy(groupName, prefix, strlen(prefix));
329 strcpy(groupName + strlen(prefix), servicename);
330 result = mbr_group_name_to_uuid(groupName, group_uu);
331 }
162e9b63 332
c29f2fcc 333 if (result == 0)
162e9b63 334 {
918ca66e 335 result = mbr_check_membership_refresh(user, group_uu, ismember);
162e9b63
A
336 }
337 else if (result == EAUTH)
338 {
339 return result;
340 }
918ca66e
A
341 else
342 {
162e9b63 343 /* just force cache update with bogus membership check */
918ca66e
A
344 memset(group_uu, 0, sizeof(group_uu));
345 mbr_check_membership_refresh(user, group_uu, &dummy);
346 }
162e9b63 347
c29f2fcc
A
348 return result;
349}
350
162e9b63 351static char *ConvertBytesToDecimal(char *buffer, unsigned long long value)
c29f2fcc 352{
162e9b63 353 char *temp;
c29f2fcc
A
354 buffer[24] = '\0';
355 buffer[23] = '0';
162e9b63
A
356
357 if (value == 0) return &buffer[23];
358
c29f2fcc
A
359 temp = &buffer[24];
360 while (value != 0)
361 {
362 temp--;
363 *temp = '0' + (value % 10);
364 value /= 10;
365 }
162e9b63 366
c29f2fcc
A
367 return temp;
368}
369
162e9b63 370int mbr_sid_to_string(const nt_sid_t *sid, char *string)
c29f2fcc 371{
162e9b63 372 char *current = string;
c29f2fcc
A
373 long long temp = 0;
374 int i;
375 char tempBuffer[25];
162e9b63
A
376
377 if (sid->sid_authcount > NTSID_MAX_AUTHORITIES) return EINVAL;
378
918ca66e
A
379 for (i = 0; i < 6; i++)
380 temp = (temp << 8) | sid->sid_authority[i];
162e9b63 381
c29f2fcc
A
382 current[0] = 'S';
383 current[1] = '-';
384 current += 2;
385 strcpy(current, ConvertBytesToDecimal(tempBuffer, sid->sid_kind));
386 current = current + strlen(current);
387 *current = '-';
388 current++;
389 strcpy(current, ConvertBytesToDecimal(tempBuffer, temp));
162e9b63
A
390
391 for (i = 0; i < sid->sid_authcount; i++)
c29f2fcc
A
392 {
393 current = current + strlen(current);
394 *current = '-';
395 current++;
396 strcpy(current, ConvertBytesToDecimal(tempBuffer, sid->sid_authorities[i]));
397 }
162e9b63 398
c29f2fcc
A
399 return 0;
400}
401
162e9b63 402int mbr_string_to_sid(const char *string, nt_sid_t *sid)
c29f2fcc 403{
162e9b63 404 char *current = string+2;
c29f2fcc
A
405 int count = 0;
406 long long temp;
407
408 memset(sid, 0, sizeof(nt_sid_t));
162e9b63
A
409 if ((string[0] != 'S') || (string[1] != '-')) return EINVAL;
410
c29f2fcc
A
411 sid->sid_kind = strtol(current, &current, 10);
412 if (*current == '\0') return EINVAL;
413 current++;
414 temp = strtoll(current, &current, 10);
162e9b63
A
415
416 /* convert to BigEndian before copying */
918ca66e 417 temp = OSSwapHostToBigInt64(temp);
c29f2fcc 418 memcpy(sid->sid_authority, ((char*)&temp)+2, 6);
162e9b63 419 while ((*current != '\0') && (count < NTSID_MAX_AUTHORITIES))
c29f2fcc
A
420 {
421 current++;
422 sid->sid_authorities[count] = strtol(current, &current, 10);
423 count++;
424 }
162e9b63
A
425
426 if (*current != '\0') return EINVAL;
427
c29f2fcc 428 sid->sid_authcount = count;
162e9b63 429
c29f2fcc
A
430 return 0;
431}
432
162e9b63 433static void ConvertBytesToHex(char **string, char **data, int numBytes)
c29f2fcc
A
434{
435 int i;
162e9b63
A
436
437 for (i = 0; i < numBytes; i++)
c29f2fcc
A
438 {
439 unsigned char hi = ((**data) >> 4) & 0xf;
440 unsigned char low = (**data) & 0xf;
441 if (hi < 10)
442 **string = '0' + hi;
443 else
444 **string = 'A' + hi - 10;
162e9b63 445
c29f2fcc
A
446 (*string)++;
447
448 if (low < 10)
449 **string = '0' + low;
450 else
451 **string = 'A' + low - 10;
452
453 (*string)++;
454 (*data)++;
455 }
456}
457
162e9b63 458int mbr_uuid_to_string(const uuid_t uu, char *string)
c29f2fcc 459{
162e9b63
A
460 char *guid = (char *)uu;
461 char *strPtr = string;
c29f2fcc
A
462 ConvertBytesToHex(&strPtr, &guid, 4);
463 *strPtr = '-'; strPtr++;
464 ConvertBytesToHex(&strPtr, &guid, 2);
465 *strPtr = '-'; strPtr++;
466 ConvertBytesToHex(&strPtr, &guid, 2);
467 *strPtr = '-'; strPtr++;
468 ConvertBytesToHex(&strPtr, &guid, 2);
469 *strPtr = '-'; strPtr++;
470 ConvertBytesToHex(&strPtr, &guid, 6);
471 *strPtr = '\0';
162e9b63 472
c29f2fcc
A
473 return 0;
474}
475
162e9b63 476int mbr_string_to_uuid(const char *string, uuid_t uu)
c29f2fcc
A
477{
478 short dataIndex = 0;
479 int isFirstNibble = 1;
162e9b63 480
c29f2fcc
A
481 if (strlen(string) > MBR_UU_STRING_SIZE)
482 return EINVAL;
162e9b63 483
c29f2fcc
A
484 while (*string != '\0' && dataIndex < 16)
485 {
486 char nibble;
162e9b63
A
487
488 if ((*string >= '0') && (*string <= '9'))
489 {
c29f2fcc 490 nibble = *string - '0';
162e9b63
A
491 }
492 else if ((*string >= 'A') && (*string <= 'F'))
493 {
c29f2fcc 494 nibble = *string - 'A' + 10;
162e9b63
A
495 }
496 else if ((*string >= 'a') && (*string <= 'f'))
497 {
c29f2fcc 498 nibble = *string - 'a' + 10;
162e9b63 499 }
c29f2fcc
A
500 else
501 {
162e9b63 502 if (*string != '-') return EINVAL;
c29f2fcc
A
503 string++;
504 continue;
505 }
162e9b63 506
c29f2fcc
A
507 if (isFirstNibble)
508 {
509 uu[dataIndex] = nibble << 4;
510 isFirstNibble = 0;
511 }
512 else
513 {
514 uu[dataIndex] |= nibble;
515 dataIndex++;
516 isFirstNibble = 1;
517 }
162e9b63 518
c29f2fcc
A
519 string++;
520 }
162e9b63
A
521
522 if (dataIndex != 16) return EINVAL;
523
c29f2fcc
A
524 return 0;
525}