]> git.saurik.com Git - apple/libinfo.git/blame - membership.subproj/membership.c
Libinfo-222.4.9.tar.gz
[apple/libinfo.git] / membership.subproj / membership.c
CommitLineData
c29f2fcc 1/*
1d9e5cb8 2 * Copyright (c) 2004 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>
1d9e5cb8 31#import <libkern/OSByteOrder.h>
c29f2fcc
A
32
33static mach_port_t GetServerPort()
34{
35 kern_return_t result;
1d9e5cb8
A
36 static mach_port_t bsPort = 0;
37 static mach_port_t fServerPort = 0;
38
c29f2fcc
A
39 if (bsPort == 0)
40 {
1d9e5cb8
A
41 result = task_get_bootstrap_port( mach_task_self(), &bsPort );
42 result = bootstrap_look_up( bsPort, "com.apple.memberd", &fServerPort );
43
44// if the port lookup failed, the rpc will fail and we will return EIO
45// if (result != MACH_MSG_SUCCESS)
46// {
47// printf("Got error %d on lookup (is memberd running?)\n", result);
48// }
c29f2fcc
A
49 }
50
51 return fServerPort;
52}
53
54int mbr_uid_to_uuid(uid_t id, uuid_t uu)
55{
56 struct kauth_identity_extlookup request;
57 int result = 0;
58
1d9e5cb8 59 request.el_seqno = 1; // used as byte order field
c29f2fcc
A
60 request.el_flags = KAUTH_EXTLOOKUP_VALID_UID | KAUTH_EXTLOOKUP_WANT_UGUID;
61 request.el_uid = id;
1d9e5cb8
A
62 result = _mbr_DoMembershipCall(GetServerPort(), &request);
63 if (result != KERN_SUCCESS)
64 return EIO;
65
c29f2fcc
A
66 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_UGUID) != 0)
67 memcpy(uu, &request.el_uguid, sizeof(guid_t));
68 else
69 result = ENOENT;
70
71 return result;
72}
73
74int mbr_gid_to_uuid(gid_t id, uuid_t uu)
75{
76 struct kauth_identity_extlookup request;
77 kern_return_t result;
78 int error = 0;
79
1d9e5cb8 80 request.el_seqno = 1; // used as byte order field
c29f2fcc
A
81 request.el_flags = KAUTH_EXTLOOKUP_VALID_GID | KAUTH_EXTLOOKUP_WANT_GGUID;
82 request.el_gid = id;
1d9e5cb8
A
83 result = _mbr_DoMembershipCall(GetServerPort(), &request);
84 if (result != KERN_SUCCESS)
85 return EIO;
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;
1d9e5cb8 91
c29f2fcc
A
92 return error;
93}
94
1d9e5cb8 95int mbr_uuid_to_id( const uuid_t uu, uid_t* id, int* id_type)
c29f2fcc
A
96{
97 struct kauth_identity_extlookup request;
98 kern_return_t result;
99 int error = 0;
100
1d9e5cb8
A
101 request.el_seqno = 1; // used as byte order field
102 request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GGUID |
103 KAUTH_EXTLOOKUP_WANT_UID | KAUTH_EXTLOOKUP_WANT_GID;
c29f2fcc
A
104 memcpy(&request.el_uguid, uu, sizeof(guid_t));
105 memcpy(&request.el_gguid, uu, sizeof(guid_t));
1d9e5cb8
A
106 result = _mbr_DoMembershipCall(GetServerPort(), &request);
107 if (result != KERN_SUCCESS)
108 return EIO;
109
c29f2fcc
A
110 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_UID) != 0)
111 {
112 *id = request.el_uid;
113 *id_type = ID_TYPE_UID;
114 }
115 else if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_GID) != 0)
116 {
117 *id = request.el_gid;
118 *id_type = ID_TYPE_GID;
119 }
120 else
121 error = ENOENT;
1d9e5cb8 122
c29f2fcc
A
123 return error;
124}
125
1d9e5cb8 126int mbr_sid_to_uuid(const nt_sid_t* sid, uuid_t uu)
c29f2fcc
A
127{
128 struct kauth_identity_extlookup request;
129 kern_return_t result;
130 int error = 0;
131
1d9e5cb8 132 request.el_seqno = 1; // used as byte order field
c29f2fcc
A
133 request.el_flags = KAUTH_EXTLOOKUP_VALID_GSID | KAUTH_EXTLOOKUP_WANT_GGUID;
134 memset(&request.el_gsid, 0, sizeof(ntsid_t));
135 memcpy(&request.el_gsid, sid, KAUTH_NTSID_SIZE(sid));
1d9e5cb8
A
136 result = _mbr_DoMembershipCall(GetServerPort(), &request);
137 if (result != KERN_SUCCESS)
138 return EIO;
139
c29f2fcc
A
140 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_GGUID) != 0)
141 memcpy(uu, &request.el_gguid, sizeof(guid_t));
142 else
143 error = ENOENT;
1d9e5cb8 144
c29f2fcc
A
145 return error;
146}
147
1d9e5cb8 148int mbr_uuid_to_sid(const uuid_t uu, nt_sid_t* sid)
c29f2fcc
A
149{
150 struct kauth_identity_extlookup request;
151 kern_return_t result;
152 int error = 0;
153
1d9e5cb8 154 request.el_seqno = 1; // used as byte order field
c29f2fcc
A
155 request.el_flags = KAUTH_EXTLOOKUP_VALID_GGUID | KAUTH_EXTLOOKUP_WANT_GSID;
156 memcpy(&request.el_gguid, uu, sizeof(guid_t));
1d9e5cb8
A
157 result = _mbr_DoMembershipCall(GetServerPort(), &request);
158 if (result != KERN_SUCCESS)
159 return EIO;
160
c29f2fcc
A
161 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_GSID) != 0)
162 memcpy(sid, &request.el_gsid, sizeof(nt_sid_t));
163 else
164 error = ENOENT;
1d9e5cb8 165
c29f2fcc
A
166 return error;
167}
168
1d9e5cb8 169int mbr_check_membership(uuid_t user, uuid_t group, int* ismember)
c29f2fcc
A
170{
171 struct kauth_identity_extlookup request;
172 kern_return_t result;
173 int error = 0;
174
1d9e5cb8
A
175 request.el_seqno = 1; // used as byte order field
176 request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GGUID |
177 KAUTH_EXTLOOKUP_WANT_MEMBERSHIP;
c29f2fcc
A
178 memcpy(&request.el_uguid, user, sizeof(guid_t));
179 memcpy(&request.el_gguid, group, sizeof(guid_t));
1d9e5cb8
A
180 result = _mbr_DoMembershipCall(GetServerPort(), &request);
181 if (result != KERN_SUCCESS)
182 return EIO;
183
c29f2fcc 184 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_MEMBERSHIP) != 0)
1d9e5cb8 185 {
c29f2fcc 186 *ismember = ((request.el_flags & KAUTH_EXTLOOKUP_ISMEMBER) != 0);
1d9e5cb8 187 }
c29f2fcc
A
188 else
189 error = ENOENT;
1d9e5cb8 190
c29f2fcc
A
191 return error;
192}
193
1d9e5cb8 194int mbr_check_membership_refresh(uuid_t user, uuid_t group, int* ismember)
918ca66e
A
195{
196 struct kauth_identity_extlookup request;
197 kern_return_t result;
198 int error = 0;
199
1d9e5cb8
A
200 request.el_seqno = 1; // used as byte order field
201 request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GGUID |
202 KAUTH_EXTLOOKUP_WANT_MEMBERSHIP | (1<<15);
918ca66e
A
203 memcpy(&request.el_uguid, user, sizeof(guid_t));
204 memcpy(&request.el_gguid, group, sizeof(guid_t));
1d9e5cb8
A
205 result = _mbr_DoMembershipCall(GetServerPort(), &request);
206 if (result != KERN_SUCCESS)
207 return EIO;
208
918ca66e 209 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_MEMBERSHIP) != 0)
1d9e5cb8 210 {
918ca66e 211 *ismember = ((request.el_flags & KAUTH_EXTLOOKUP_ISMEMBER) != 0);
1d9e5cb8 212 }
918ca66e
A
213 else
214 error = ENOENT;
1d9e5cb8 215
918ca66e
A
216 return error;
217}
218
1d9e5cb8 219int mbr_check_membership_by_id(uuid_t user, gid_t group, int* ismember)
c29f2fcc
A
220{
221 struct kauth_identity_extlookup request;
222 kern_return_t result;
223 int error = 0;
224
1d9e5cb8
A
225 request.el_seqno = 1; // used as byte order field
226 request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GID |
227 KAUTH_EXTLOOKUP_WANT_MEMBERSHIP;
c29f2fcc
A
228 memcpy(&request.el_uguid, user, sizeof(guid_t));
229 request.el_gid = group;
1d9e5cb8
A
230 result = _mbr_DoMembershipCall(GetServerPort(), &request);
231 if (result != KERN_SUCCESS)
232 return EIO;
233
c29f2fcc 234 if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_MEMBERSHIP) != 0)
1d9e5cb8 235 {
c29f2fcc 236 *ismember = ((request.el_flags & KAUTH_EXTLOOKUP_ISMEMBER) != 0);
1d9e5cb8 237 }
c29f2fcc
A
238 else
239 error = ENOENT;
1d9e5cb8 240
c29f2fcc
A
241 return error;
242}
243
244int mbr_reset_cache()
245{
246 kern_return_t result;
1d9e5cb8
A
247 result = _mbr_ClearCache(GetServerPort());
248 if (result != KERN_SUCCESS)
249 return EIO;
c29f2fcc
A
250 return 0;
251}
252
1d9e5cb8 253int mbr_user_name_to_uuid(const char* name, uuid_t uu)
c29f2fcc
A
254{
255 kern_return_t result;
1d9e5cb8
A
256
257 if (strlen(name) > 255)
258 return EINVAL;
259
260 result = _mbr_MapName(GetServerPort(), 1, (char*)name, (guid_t*)uu);
261
262 if (result == KERN_FAILURE)
263 return ENOENT;
264 else if (result != KERN_SUCCESS)
265 return EIO;
266
c29f2fcc
A
267 return 0;
268}
269
1d9e5cb8 270int mbr_group_name_to_uuid(const char* name, uuid_t uu)
c29f2fcc
A
271{
272 kern_return_t result;
1d9e5cb8
A
273
274 if (strlen(name) > 255)
275 return EINVAL;
276
277 result = _mbr_MapName(GetServerPort(), 0, (char*)name, (guid_t*)uu);
278
279 if (result == KERN_FAILURE)
280 return ENOENT;
281 else if (result != KERN_SUCCESS)
282 return EIO;
283
c29f2fcc
A
284 return 0;
285}
286
1d9e5cb8 287int mbr_check_service_membership(const uuid_t user, const char* servicename, int* ismember)
c29f2fcc 288{
1d9e5cb8
A
289 char* prefix = "com.apple.access_";
290 char* all_services = "com.apple.access_all_services";
c29f2fcc
A
291 char groupName[256];
292 uuid_t group_uu;
918ca66e 293 int result, dummy;
1d9e5cb8
A
294
295 if (strlen(servicename) > 255 - strlen(prefix))
296 return EINVAL;
297
298 // start by checking "all services"
c29f2fcc 299 result = mbr_group_name_to_uuid(all_services, group_uu);
1d9e5cb8 300
c29f2fcc
A
301 if (result == ENOENT)
302 {
1d9e5cb8 303 // all_services group didn't exist, check individual group
c29f2fcc
A
304 memcpy(groupName, prefix, strlen(prefix));
305 strcpy(groupName + strlen(prefix), servicename);
306 result = mbr_group_name_to_uuid(groupName, group_uu);
307 }
1d9e5cb8 308
c29f2fcc 309 if (result == 0)
918ca66e
A
310 result = mbr_check_membership_refresh(user, group_uu, ismember);
311 else
312 {
1d9e5cb8 313 // just force cache update with bogus membership check
918ca66e
A
314 memset(group_uu, 0, sizeof(group_uu));
315 mbr_check_membership_refresh(user, group_uu, &dummy);
316 }
1d9e5cb8 317
c29f2fcc
A
318 return result;
319}
320
1d9e5cb8 321static char* ConvertBytesToDecimal(char* buffer, unsigned long long value)
c29f2fcc 322{
1d9e5cb8 323 char* temp;
c29f2fcc
A
324 buffer[24] = '\0';
325 buffer[23] = '0';
1d9e5cb8
A
326
327 if (value == 0)
328 return &buffer[23];
329
c29f2fcc
A
330 temp = &buffer[24];
331 while (value != 0)
332 {
333 temp--;
334 *temp = '0' + (value % 10);
335 value /= 10;
336 }
1d9e5cb8 337
c29f2fcc
A
338 return temp;
339}
340
1d9e5cb8 341int mbr_sid_to_string(const nt_sid_t* sid, char* string)
c29f2fcc 342{
1d9e5cb8 343 char* current = string;
c29f2fcc
A
344 long long temp = 0;
345 int i;
346 char tempBuffer[25];
1d9e5cb8
A
347
348 if (sid->sid_authcount > NTSID_MAX_AUTHORITIES)
349 return EINVAL;
350
918ca66e
A
351 for (i = 0; i < 6; i++)
352 temp = (temp << 8) | sid->sid_authority[i];
1d9e5cb8 353
c29f2fcc
A
354 current[0] = 'S';
355 current[1] = '-';
356 current += 2;
357 strcpy(current, ConvertBytesToDecimal(tempBuffer, sid->sid_kind));
358 current = current + strlen(current);
359 *current = '-';
360 current++;
361 strcpy(current, ConvertBytesToDecimal(tempBuffer, temp));
1d9e5cb8
A
362
363 for(i=0; i < sid->sid_authcount; i++)
c29f2fcc
A
364 {
365 current = current + strlen(current);
366 *current = '-';
367 current++;
368 strcpy(current, ConvertBytesToDecimal(tempBuffer, sid->sid_authorities[i]));
369 }
1d9e5cb8 370
c29f2fcc
A
371 return 0;
372}
373
1d9e5cb8 374int mbr_string_to_sid(const char* string, nt_sid_t* sid)
c29f2fcc 375{
1d9e5cb8 376 char* current = string+2;
c29f2fcc
A
377 int count = 0;
378 long long temp;
379
380 memset(sid, 0, sizeof(nt_sid_t));
1d9e5cb8
A
381 if (string[0] != 'S' || string[1] != '-') return EINVAL;
382
c29f2fcc
A
383 sid->sid_kind = strtol(current, &current, 10);
384 if (*current == '\0') return EINVAL;
385 current++;
386 temp = strtoll(current, &current, 10);
1d9e5cb8 387 // convert to BigEndian before copying
918ca66e 388 temp = OSSwapHostToBigInt64(temp);
c29f2fcc 389 memcpy(sid->sid_authority, ((char*)&temp)+2, 6);
1d9e5cb8 390 while (*current != '\0' && count < NTSID_MAX_AUTHORITIES)
c29f2fcc
A
391 {
392 current++;
393 sid->sid_authorities[count] = strtol(current, &current, 10);
394 count++;
395 }
1d9e5cb8
A
396
397 if (*current != '\0')
398 return EINVAL;
399
c29f2fcc 400 sid->sid_authcount = count;
1d9e5cb8 401
c29f2fcc
A
402 return 0;
403}
404
1d9e5cb8 405static void ConvertBytesToHex(char** string, char** data, int numBytes)
c29f2fcc
A
406{
407 int i;
1d9e5cb8
A
408
409 for (i=0; i < numBytes; i++)
c29f2fcc
A
410 {
411 unsigned char hi = ((**data) >> 4) & 0xf;
412 unsigned char low = (**data) & 0xf;
413 if (hi < 10)
414 **string = '0' + hi;
415 else
416 **string = 'A' + hi - 10;
1d9e5cb8 417
c29f2fcc
A
418 (*string)++;
419
420 if (low < 10)
421 **string = '0' + low;
422 else
423 **string = 'A' + low - 10;
424
425 (*string)++;
426 (*data)++;
427 }
428}
429
1d9e5cb8 430int mbr_uuid_to_string(const uuid_t uu, char* string)
c29f2fcc 431{
1d9e5cb8
A
432 char* guid = (char*)uu;
433 char* strPtr = string;
c29f2fcc
A
434 ConvertBytesToHex(&strPtr, &guid, 4);
435 *strPtr = '-'; strPtr++;
436 ConvertBytesToHex(&strPtr, &guid, 2);
437 *strPtr = '-'; strPtr++;
438 ConvertBytesToHex(&strPtr, &guid, 2);
439 *strPtr = '-'; strPtr++;
440 ConvertBytesToHex(&strPtr, &guid, 2);
441 *strPtr = '-'; strPtr++;
442 ConvertBytesToHex(&strPtr, &guid, 6);
443 *strPtr = '\0';
1d9e5cb8 444
c29f2fcc
A
445 return 0;
446}
447
1d9e5cb8 448int mbr_string_to_uuid(const char* string, uuid_t uu)
c29f2fcc
A
449{
450 short dataIndex = 0;
451 int isFirstNibble = 1;
1d9e5cb8 452
c29f2fcc
A
453 if (strlen(string) > MBR_UU_STRING_SIZE)
454 return EINVAL;
1d9e5cb8 455
c29f2fcc
A
456 while (*string != '\0' && dataIndex < 16)
457 {
458 char nibble;
1d9e5cb8
A
459
460 if (*string >= '0' && *string <= '9')
c29f2fcc 461 nibble = *string - '0';
1d9e5cb8 462 else if (*string >= 'A' && *string <= 'F')
c29f2fcc 463 nibble = *string - 'A' + 10;
1d9e5cb8 464 else if (*string >= 'a' && *string <= 'f')
c29f2fcc
A
465 nibble = *string - 'a' + 10;
466 else
467 {
1d9e5cb8
A
468 if (*string != '-')
469 return EINVAL;
c29f2fcc
A
470 string++;
471 continue;
472 }
1d9e5cb8 473
c29f2fcc
A
474 if (isFirstNibble)
475 {
476 uu[dataIndex] = nibble << 4;
477 isFirstNibble = 0;
478 }
479 else
480 {
481 uu[dataIndex] |= nibble;
482 dataIndex++;
483 isFirstNibble = 1;
484 }
1d9e5cb8 485
c29f2fcc
A
486 string++;
487 }
1d9e5cb8
A
488
489 if (dataIndex != 16)
490 return EINVAL;
491
c29f2fcc
A
492 return 0;
493}
1d9e5cb8 494