2 * Copyright (c) 2004-2007 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 #include <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
);
48 int mbr_uid_to_uuid(uid_t id
, uuid_t uu
)
50 struct kauth_identity_extlookup request
;
51 security_token_t token
;
57 request
.el_seqno
= 1; /* used as byte order field */
58 request
.el_flags
= KAUTH_EXTLOOKUP_VALID_UID
| KAUTH_EXTLOOKUP_WANT_UGUID
;
60 result
= _mbr_DoMembershipCall(GetServerPort(), &request
, &token
);
61 if (result
!= KERN_SUCCESS
) return EIO
;
62 if (token
.val
[0] != 0) return EAUTH
;
64 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_UGUID
) != 0)
65 memcpy(uu
, &request
.el_uguid
, sizeof(guid_t
));
72 int mbr_gid_to_uuid(gid_t id
, uuid_t uu
)
74 struct kauth_identity_extlookup request
;
75 security_token_t token
;
82 request
.el_seqno
= 1; /* used as byte order field */
83 request
.el_flags
= KAUTH_EXTLOOKUP_VALID_GID
| KAUTH_EXTLOOKUP_WANT_GGUID
;
85 result
= _mbr_DoMembershipCall(GetServerPort(), &request
, &token
);
86 if (result
!= KERN_SUCCESS
) return EIO
;
87 if (token
.val
[0] != 0) return EAUTH
;
89 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_GGUID
) != 0)
90 memcpy(uu
, &request
.el_gguid
, sizeof(guid_t
));
97 int mbr_uuid_to_id(const uuid_t uu
, uid_t
*id
, int *id_type
)
99 struct kauth_identity_extlookup request
;
100 security_token_t token
;
101 kern_return_t result
;
107 request
.el_seqno
= 1; /* used as byte order field */
108 request
.el_flags
= KAUTH_EXTLOOKUP_VALID_UGUID
| KAUTH_EXTLOOKUP_VALID_GGUID
| KAUTH_EXTLOOKUP_WANT_UID
| KAUTH_EXTLOOKUP_WANT_GID
;
109 memcpy(&request
.el_uguid
, uu
, sizeof(guid_t
));
110 memcpy(&request
.el_gguid
, uu
, sizeof(guid_t
));
111 result
= _mbr_DoMembershipCall(GetServerPort(), &request
, &token
);
112 if (result
!= KERN_SUCCESS
) return EIO
;
113 if (token
.val
[0] != 0) return EAUTH
;
115 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_UID
) != 0)
117 *id
= request
.el_uid
;
118 *id_type
= ID_TYPE_UID
;
120 else if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_GID
) != 0)
122 *id
= request
.el_gid
;
123 *id_type
= ID_TYPE_GID
;
133 int mbr_sid_to_uuid(const nt_sid_t
*sid
, uuid_t uu
)
135 struct kauth_identity_extlookup request
;
136 security_token_t token
;
137 kern_return_t result
;
143 request
.el_seqno
= 1; /* used as byte order field */
144 request
.el_flags
= KAUTH_EXTLOOKUP_VALID_GSID
| KAUTH_EXTLOOKUP_WANT_GGUID
;
145 memset(&request
.el_gsid
, 0, sizeof(ntsid_t
));
146 memcpy(&request
.el_gsid
, sid
, KAUTH_NTSID_SIZE(sid
));
147 result
= _mbr_DoMembershipCall(GetServerPort(), &request
, &token
);
148 if (result
!= KERN_SUCCESS
) return EIO
;
149 if (token
.val
[0] != 0) return EAUTH
;
151 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_GGUID
) != 0)
152 memcpy(uu
, &request
.el_gguid
, sizeof(guid_t
));
159 int mbr_uuid_to_sid(const uuid_t uu
, nt_sid_t
*sid
)
161 struct kauth_identity_extlookup request
;
162 security_token_t token
;
163 kern_return_t result
;
169 request
.el_seqno
= 1; /* used as byte order field */
170 request
.el_flags
= KAUTH_EXTLOOKUP_VALID_GGUID
| KAUTH_EXTLOOKUP_WANT_GSID
;
171 memcpy(&request
.el_gguid
, uu
, sizeof(guid_t
));
172 result
= _mbr_DoMembershipCall(GetServerPort(), &request
, &token
);
173 if (result
!= KERN_SUCCESS
) return EIO
;
174 if (token
.val
[0] != 0) return EAUTH
;
176 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_GSID
) != 0)
177 memcpy(sid
, &request
.el_gsid
, sizeof(nt_sid_t
));
184 int mbr_check_membership(uuid_t user
, uuid_t group
, int *ismember
)
186 struct kauth_identity_extlookup request
;
187 security_token_t token
;
188 kern_return_t result
;
194 request
.el_seqno
= 1; /* used as byte order field */
195 request
.el_flags
= KAUTH_EXTLOOKUP_VALID_UGUID
| KAUTH_EXTLOOKUP_VALID_GGUID
| KAUTH_EXTLOOKUP_WANT_MEMBERSHIP
;
196 memcpy(&request
.el_uguid
, user
, sizeof(guid_t
));
197 memcpy(&request
.el_gguid
, group
, sizeof(guid_t
));
198 result
= _mbr_DoMembershipCall(GetServerPort(), &request
, &token
);
199 if (result
!= KERN_SUCCESS
) return EIO
;
200 if (token
.val
[0] != 0) return EAUTH
;
202 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_MEMBERSHIP
) != 0)
203 *ismember
= ((request
.el_flags
& KAUTH_EXTLOOKUP_ISMEMBER
) != 0);
210 int mbr_check_membership_refresh(uuid_t user
, uuid_t group
, int *ismember
)
212 struct kauth_identity_extlookup request
;
213 security_token_t token
;
214 kern_return_t result
;
220 request
.el_seqno
= 1; /* used as byte order field */
221 request
.el_flags
= KAUTH_EXTLOOKUP_VALID_UGUID
| KAUTH_EXTLOOKUP_VALID_GGUID
| KAUTH_EXTLOOKUP_WANT_MEMBERSHIP
| (1 << 15);
222 memcpy(&request
.el_uguid
, user
, sizeof(guid_t
));
223 memcpy(&request
.el_gguid
, group
, sizeof(guid_t
));
224 result
= _mbr_DoMembershipCall(GetServerPort(), &request
, &token
);
225 if (result
!= KERN_SUCCESS
) return EIO
;
226 if (token
.val
[0] != 0) return EAUTH
;
228 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_MEMBERSHIP
) != 0)
229 *ismember
= ((request
.el_flags
& KAUTH_EXTLOOKUP_ISMEMBER
) != 0);
236 int mbr_check_membership_by_id(uuid_t user
, gid_t group
, int *ismember
)
238 struct kauth_identity_extlookup request
;
239 security_token_t token
;
240 kern_return_t result
;
246 request
.el_seqno
= 1; /* used as byte order field */
247 request
.el_flags
= KAUTH_EXTLOOKUP_VALID_UGUID
| KAUTH_EXTLOOKUP_VALID_GID
| KAUTH_EXTLOOKUP_WANT_MEMBERSHIP
;
248 memcpy(&request
.el_uguid
, user
, sizeof(guid_t
));
249 request
.el_gid
= group
;
250 result
= _mbr_DoMembershipCall(GetServerPort(), &request
, &token
);
251 if (result
!= KERN_SUCCESS
) return EIO
;
252 if (token
.val
[0] != 0) return EAUTH
;
254 if ((request
.el_flags
& KAUTH_EXTLOOKUP_VALID_MEMBERSHIP
) != 0)
255 *ismember
= ((request
.el_flags
& KAUTH_EXTLOOKUP_ISMEMBER
) != 0);
262 int mbr_reset_cache()
264 security_token_t token
;
265 kern_return_t result
;
270 result
= _mbr_ClearCache(GetServerPort(), &token
);
271 if (result
!= KERN_SUCCESS
) return EIO
;
272 if (token
.val
[0] != 0) return EAUTH
;
277 int mbr_user_name_to_uuid(const char *name
, uuid_t uu
)
279 security_token_t token
;
280 kern_return_t result
;
282 if (name
== NULL
) return EINVAL
;
283 if (strlen(name
) > 255) return EINVAL
;
288 result
= _mbr_MapName(GetServerPort(), 1, (char *)name
, (guid_t
*)uu
, &token
);
289 if (result
== KERN_FAILURE
) return ENOENT
;
290 else if (result
!= KERN_SUCCESS
) return EIO
;
292 if (token
.val
[0] != 0) return EAUTH
;
297 int mbr_group_name_to_uuid(const char *name
, uuid_t uu
)
299 security_token_t token
;
300 kern_return_t result
;
302 if (name
== NULL
) return EINVAL
;
303 if (strlen(name
) > 255) return EINVAL
;
308 result
= _mbr_MapName(GetServerPort(), 0, (char *)name
, (guid_t
*)uu
, &token
);
309 if (result
== KERN_FAILURE
) return ENOENT
;
310 else if (result
!= KERN_SUCCESS
) return EIO
;
312 if (token
.val
[0] != 0) return EAUTH
;
317 int mbr_check_service_membership(const uuid_t user
, const char *servicename
, int *ismember
)
319 char *prefix
= "com.apple.access_";
320 char *all_services
= "com.apple.access_all_services";
325 if (servicename
== NULL
) return EINVAL
;
326 if (strlen(servicename
) > (255 - strlen(prefix
))) return EINVAL
;
328 /* start by checking "all services" */
329 result
= mbr_group_name_to_uuid(all_services
, group_uu
);
331 if (result
== EAUTH
) return result
;
333 if (result
== ENOENT
)
335 /* all_services group didn't exist, check individual group */
336 memcpy(groupName
, prefix
, strlen(prefix
));
337 strcpy(groupName
+ strlen(prefix
), servicename
);
338 result
= mbr_group_name_to_uuid(groupName
, group_uu
);
343 result
= mbr_check_membership_refresh(user
, group_uu
, ismember
);
345 else if (result
== EAUTH
)
351 /* just force cache update with bogus membership check */
352 memset(group_uu
, 0, sizeof(group_uu
));
353 mbr_check_membership_refresh(user
, group_uu
, &dummy
);
359 static char *ConvertBytesToDecimal(char *buffer
, unsigned long long value
)
365 if (value
== 0) return &buffer
[23];
371 *temp
= '0' + (value
% 10);
378 int mbr_sid_to_string(const nt_sid_t
*sid
, char *string
)
380 char *current
= string
;
385 if (sid
->sid_authcount
> NTSID_MAX_AUTHORITIES
) return EINVAL
;
387 for (i
= 0; i
< 6; i
++)
388 temp
= (temp
<< 8) | sid
->sid_authority
[i
];
393 strcpy(current
, ConvertBytesToDecimal(tempBuffer
, sid
->sid_kind
));
394 current
= current
+ strlen(current
);
397 strcpy(current
, ConvertBytesToDecimal(tempBuffer
, temp
));
399 for (i
= 0; i
< sid
->sid_authcount
; i
++)
401 current
= current
+ strlen(current
);
404 strcpy(current
, ConvertBytesToDecimal(tempBuffer
, sid
->sid_authorities
[i
]));
410 int mbr_string_to_sid(const char *string
, nt_sid_t
*sid
)
412 char *current
= string
+2;
416 memset(sid
, 0, sizeof(nt_sid_t
));
417 if ((string
[0] != 'S') || (string
[1] != '-')) return EINVAL
;
419 sid
->sid_kind
= strtol(current
, ¤t
, 10);
420 if (*current
== '\0') return EINVAL
;
422 temp
= strtoll(current
, ¤t
, 10);
424 /* convert to BigEndian before copying */
425 temp
= OSSwapHostToBigInt64(temp
);
426 memcpy(sid
->sid_authority
, ((char*)&temp
)+2, 6);
427 while ((*current
!= '\0') && (count
< NTSID_MAX_AUTHORITIES
))
430 sid
->sid_authorities
[count
] = strtol(current
, ¤t
, 10);
434 if (*current
!= '\0') return EINVAL
;
436 sid
->sid_authcount
= count
;
441 static void ConvertBytesToHex(char **string
, char **data
, int numBytes
)
445 for (i
= 0; i
< numBytes
; i
++)
447 unsigned char hi
= ((**data
) >> 4) & 0xf;
448 unsigned char low
= (**data
) & 0xf;
452 **string
= 'A' + hi
- 10;
457 **string
= '0' + low
;
459 **string
= 'A' + low
- 10;
466 int mbr_uuid_to_string(const uuid_t uu
, char *string
)
468 char *guid
= (char *)uu
;
469 char *strPtr
= string
;
470 ConvertBytesToHex(&strPtr
, &guid
, 4);
471 *strPtr
= '-'; strPtr
++;
472 ConvertBytesToHex(&strPtr
, &guid
, 2);
473 *strPtr
= '-'; strPtr
++;
474 ConvertBytesToHex(&strPtr
, &guid
, 2);
475 *strPtr
= '-'; strPtr
++;
476 ConvertBytesToHex(&strPtr
, &guid
, 2);
477 *strPtr
= '-'; strPtr
++;
478 ConvertBytesToHex(&strPtr
, &guid
, 6);
484 int mbr_string_to_uuid(const char *string
, uuid_t uu
)
487 int isFirstNibble
= 1;
489 if (strlen(string
) > MBR_UU_STRING_SIZE
)
492 while (*string
!= '\0' && dataIndex
< 16)
496 if ((*string
>= '0') && (*string
<= '9'))
498 nibble
= *string
- '0';
500 else if ((*string
>= 'A') && (*string
<= 'F'))
502 nibble
= *string
- 'A' + 10;
504 else if ((*string
>= 'a') && (*string
<= 'f'))
506 nibble
= *string
- 'a' + 10;
510 if (*string
!= '-') return EINVAL
;
517 uu
[dataIndex
] = nibble
<< 4;
522 uu
[dataIndex
] |= nibble
;
530 if (dataIndex
!= 16) return EINVAL
;