2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 #include "membership.h"
24 #include "membershipPriv.h"
27 #include <sys/errno.h>
28 #include <servers/bootstrap.h>
29 #include <mach/mach.h>
31 #import <libkern/OSByteOrder.h>
33 static mach_port_t
GetServerPort()
36 static mach_port_t bsPort
= 0;
37 static mach_port_t fServerPort
= 0;
41 result
= task_get_bootstrap_port( mach_task_self(), &bsPort
);
42 result
= bootstrap_look_up( bsPort
, "com.apple.memberd", &fServerPort
);
44 // if the port lookup failed, the rpc will fail and we will return EIO
45 // if (result != MACH_MSG_SUCCESS)
47 // printf("Got error %d on lookup (is memberd running?)\n", result);
54 int mbr_uid_to_uuid(uid_t id
, uuid_t uu
)
56 struct kauth_identity_extlookup request
;
59 request
.el_seqno
= 1; // used as byte order field
60 request
.el_flags
= KAUTH_EXTLOOKUP_VALID_UID
| KAUTH_EXTLOOKUP_WANT_UGUID
;
62 result
= _mbr_DoMembershipCall(GetServerPort(), &request
);
63 if (result
!= KERN_SUCCESS
)
66 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_UGUID
) != 0)
67 memcpy(uu
, &request
.el_uguid
, sizeof(guid_t
));
74 int mbr_gid_to_uuid(gid_t id
, uuid_t uu
)
76 struct kauth_identity_extlookup request
;
80 request
.el_seqno
= 1; // used as byte order field
81 request
.el_flags
= KAUTH_EXTLOOKUP_VALID_GID
| KAUTH_EXTLOOKUP_WANT_GGUID
;
83 result
= _mbr_DoMembershipCall(GetServerPort(), &request
);
84 if (result
!= KERN_SUCCESS
)
87 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_GGUID
) != 0)
88 memcpy(uu
, &request
.el_gguid
, sizeof(guid_t
));
95 int mbr_uuid_to_id( const uuid_t uu
, uid_t
* id
, int* id_type
)
97 struct kauth_identity_extlookup request
;
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
;
104 memcpy(&request
.el_uguid
, uu
, sizeof(guid_t
));
105 memcpy(&request
.el_gguid
, uu
, sizeof(guid_t
));
106 result
= _mbr_DoMembershipCall(GetServerPort(), &request
);
107 if (result
!= KERN_SUCCESS
)
110 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_UID
) != 0)
112 *id
= request
.el_uid
;
113 *id_type
= ID_TYPE_UID
;
115 else if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_GID
) != 0)
117 *id
= request
.el_gid
;
118 *id_type
= ID_TYPE_GID
;
126 int mbr_sid_to_uuid(const nt_sid_t
* sid
, uuid_t uu
)
128 struct kauth_identity_extlookup request
;
129 kern_return_t result
;
132 request
.el_seqno
= 1; // used as byte order field
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
));
136 result
= _mbr_DoMembershipCall(GetServerPort(), &request
);
137 if (result
!= KERN_SUCCESS
)
140 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_GGUID
) != 0)
141 memcpy(uu
, &request
.el_gguid
, sizeof(guid_t
));
148 int mbr_uuid_to_sid(const uuid_t uu
, nt_sid_t
* sid
)
150 struct kauth_identity_extlookup request
;
151 kern_return_t result
;
154 request
.el_seqno
= 1; // used as byte order field
155 request
.el_flags
= KAUTH_EXTLOOKUP_VALID_GGUID
| KAUTH_EXTLOOKUP_WANT_GSID
;
156 memcpy(&request
.el_gguid
, uu
, sizeof(guid_t
));
157 result
= _mbr_DoMembershipCall(GetServerPort(), &request
);
158 if (result
!= KERN_SUCCESS
)
161 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_GSID
) != 0)
162 memcpy(sid
, &request
.el_gsid
, sizeof(nt_sid_t
));
169 int mbr_check_membership(uuid_t user
, uuid_t group
, int* ismember
)
171 struct kauth_identity_extlookup request
;
172 kern_return_t result
;
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
;
178 memcpy(&request
.el_uguid
, user
, sizeof(guid_t
));
179 memcpy(&request
.el_gguid
, group
, sizeof(guid_t
));
180 result
= _mbr_DoMembershipCall(GetServerPort(), &request
);
181 if (result
!= KERN_SUCCESS
)
184 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_MEMBERSHIP
) != 0)
186 *ismember
= ((request
.el_flags
& KAUTH_EXTLOOKUP_ISMEMBER
) != 0);
194 int mbr_check_membership_refresh(uuid_t user
, uuid_t group
, int* ismember
)
196 struct kauth_identity_extlookup request
;
197 kern_return_t result
;
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);
203 memcpy(&request
.el_uguid
, user
, sizeof(guid_t
));
204 memcpy(&request
.el_gguid
, group
, sizeof(guid_t
));
205 result
= _mbr_DoMembershipCall(GetServerPort(), &request
);
206 if (result
!= KERN_SUCCESS
)
209 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_MEMBERSHIP
) != 0)
211 *ismember
= ((request
.el_flags
& KAUTH_EXTLOOKUP_ISMEMBER
) != 0);
219 int mbr_check_membership_by_id(uuid_t user
, gid_t group
, int* ismember
)
221 struct kauth_identity_extlookup request
;
222 kern_return_t result
;
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
;
228 memcpy(&request
.el_uguid
, user
, sizeof(guid_t
));
229 request
.el_gid
= group
;
230 result
= _mbr_DoMembershipCall(GetServerPort(), &request
);
231 if (result
!= KERN_SUCCESS
)
234 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_MEMBERSHIP
) != 0)
236 *ismember
= ((request
.el_flags
& KAUTH_EXTLOOKUP_ISMEMBER
) != 0);
244 int mbr_reset_cache()
246 kern_return_t result
;
247 result
= _mbr_ClearCache(GetServerPort());
248 if (result
!= KERN_SUCCESS
)
253 int mbr_user_name_to_uuid(const char* name
, uuid_t uu
)
255 kern_return_t result
;
257 if (strlen(name
) > 255)
260 result
= _mbr_MapName(GetServerPort(), 1, (char*)name
, (guid_t
*)uu
);
262 if (result
== KERN_FAILURE
)
264 else if (result
!= KERN_SUCCESS
)
270 int mbr_group_name_to_uuid(const char* name
, uuid_t uu
)
272 kern_return_t result
;
274 if (strlen(name
) > 255)
277 result
= _mbr_MapName(GetServerPort(), 0, (char*)name
, (guid_t
*)uu
);
279 if (result
== KERN_FAILURE
)
281 else if (result
!= KERN_SUCCESS
)
287 int mbr_check_service_membership(const uuid_t user
, const char* servicename
, int* ismember
)
289 char* prefix
= "com.apple.access_";
290 char* all_services
= "com.apple.access_all_services";
295 if (strlen(servicename
) > 255 - strlen(prefix
))
298 // start by checking "all services"
299 result
= mbr_group_name_to_uuid(all_services
, group_uu
);
301 if (result
== ENOENT
)
303 // all_services group didn't exist, check individual group
304 memcpy(groupName
, prefix
, strlen(prefix
));
305 strcpy(groupName
+ strlen(prefix
), servicename
);
306 result
= mbr_group_name_to_uuid(groupName
, group_uu
);
310 result
= mbr_check_membership_refresh(user
, group_uu
, ismember
);
313 // just force cache update with bogus membership check
314 memset(group_uu
, 0, sizeof(group_uu
));
315 mbr_check_membership_refresh(user
, group_uu
, &dummy
);
321 static char* ConvertBytesToDecimal(char* buffer
, unsigned long long value
)
334 *temp
= '0' + (value
% 10);
341 int mbr_sid_to_string(const nt_sid_t
* sid
, char* string
)
343 char* current
= string
;
348 if (sid
->sid_authcount
> NTSID_MAX_AUTHORITIES
)
351 for (i
= 0; i
< 6; i
++)
352 temp
= (temp
<< 8) | sid
->sid_authority
[i
];
357 strcpy(current
, ConvertBytesToDecimal(tempBuffer
, sid
->sid_kind
));
358 current
= current
+ strlen(current
);
361 strcpy(current
, ConvertBytesToDecimal(tempBuffer
, temp
));
363 for(i
=0; i
< sid
->sid_authcount
; i
++)
365 current
= current
+ strlen(current
);
368 strcpy(current
, ConvertBytesToDecimal(tempBuffer
, sid
->sid_authorities
[i
]));
374 int mbr_string_to_sid(const char* string
, nt_sid_t
* sid
)
376 char* current
= string
+2;
380 memset(sid
, 0, sizeof(nt_sid_t
));
381 if (string
[0] != 'S' || string
[1] != '-') return EINVAL
;
383 sid
->sid_kind
= strtol(current
, ¤t
, 10);
384 if (*current
== '\0') return EINVAL
;
386 temp
= strtoll(current
, ¤t
, 10);
387 // convert to BigEndian before copying
388 temp
= OSSwapHostToBigInt64(temp
);
389 memcpy(sid
->sid_authority
, ((char*)&temp
)+2, 6);
390 while (*current
!= '\0' && count
< NTSID_MAX_AUTHORITIES
)
393 sid
->sid_authorities
[count
] = strtol(current
, ¤t
, 10);
397 if (*current
!= '\0')
400 sid
->sid_authcount
= count
;
405 static void ConvertBytesToHex(char** string
, char** data
, int numBytes
)
409 for (i
=0; i
< numBytes
; i
++)
411 unsigned char hi
= ((**data
) >> 4) & 0xf;
412 unsigned char low
= (**data
) & 0xf;
416 **string
= 'A' + hi
- 10;
421 **string
= '0' + low
;
423 **string
= 'A' + low
- 10;
430 int mbr_uuid_to_string(const uuid_t uu
, char* string
)
432 char* guid
= (char*)uu
;
433 char* strPtr
= string
;
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);
448 int mbr_string_to_uuid(const char* string
, uuid_t uu
)
451 int isFirstNibble
= 1;
453 if (strlen(string
) > MBR_UU_STRING_SIZE
)
456 while (*string
!= '\0' && dataIndex
< 16)
460 if (*string
>= '0' && *string
<= '9')
461 nibble
= *string
- '0';
462 else if (*string
>= 'A' && *string
<= 'F')
463 nibble
= *string
- 'A' + 10;
464 else if (*string
>= 'a' && *string
<= 'f')
465 nibble
= *string
- 'a' + 10;
476 uu
[dataIndex
] = nibble
<< 4;
481 uu
[dataIndex
] |= nibble
;