4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
27 * Some helper routines for directory lookup. These offer functions that
28 * you could implement yourself on top of the generic routines, but since
29 * they're a common request we implement them here. (Well, OK, we cheat a bit
30 * and call an internal routine to do the dirty work to reduce code
31 * duplication, but you could still implement them using the generic routines.)
37 #include <rpcsvc/idmap_prot.h>
38 #include "directory.h"
39 #include "directory_private.h"
40 #include "directory_library_impl.h"
44 * Given a username, return a text-form SID.
46 * The SID must be free()ed by the caller.
48 * d, if non-NULL, specifies an existing directory-search context.
49 * If NULL, a temporary one will be created.
52 directory_sid_from_name_common(
59 directory_t d1
= NULL
;
60 static char *attrs
[] = {
65 directory_entry_t
*ret_list
= NULL
;
72 /* Prep for error cases. */
78 de
= directory_open(&d1
);
85 de
= directory_get_v(d1
, &ret_list
, &name
, 1, type
, attrs
);
88 if (ret_list
[0].err
!= NULL
) {
90 ret_list
[0].err
= NULL
;
94 ret_sid
= (struct ret_sid
*)ret_list
[0].attrs
;
98 if (ret_sid
->objectSid
!= NULL
&&
99 ret_sid
->objectSid
[0] != NULL
) {
100 char text_sid
[SID_STRSZ
+1];
101 sid_from_le(ret_sid
->objectSid
[0]);
102 sid_tostr(ret_sid
->objectSid
[0], text_sid
);
103 *sid
= strdup(text_sid
);
108 if (ret_sid
->objectClass
!= NULL
&&
110 *classes
= class_bitmap(ret_sid
->objectClass
);
115 de
= directory_error("ENOMEM.directory_sid_from_name_common",
116 "Insufficient memory retrieving data about SID", NULL
);
119 directory_free(ret_list
);
126 directory_sid_from_name(
132 return (directory_sid_from_name_common(d
, name
, DIRECTORY_ID_NAME
, sid
,
137 directory_sid_from_user_name(directory_t d
, char *name
, char **sid
)
139 return (directory_sid_from_name_common(d
, name
, DIRECTORY_ID_USER
, sid
,
144 directory_sid_from_group_name(directory_t d
, char *name
, char **sid
)
146 return (directory_sid_from_name_common(d
, name
, DIRECTORY_ID_GROUP
, sid
,
151 * Given a name or text-format SID, return a user@domain.
153 * The user@domain returned must be free()ed by the caller.
155 * Returns NULL and sets *name to NULL if no error occurred but the specified
156 * entity does not exist.
158 * d, if non-NULL, specifies an existing directory-search context.
159 * If NULL, a temporary one will be created.
163 directory_canon_common(
170 directory_t d1
= NULL
;
171 directory_entry_t
*ret_list
= NULL
;
172 directory_error_t de
;
174 * Attributes required to generate a canonical name, in named-list and
177 static char *attrs
[] = {
178 "x-sun-canonicalName",
183 struct canon_name_ret
{
184 char **x_sun_canonicalName
;
188 /* Prep for error cases. */
194 de
= directory_open(&d1
);
201 de
= directory_get_v(d1
, &ret_list
, &id
, 1, id_type
, attrs
);
204 if (ret_list
[0].err
!= NULL
) {
205 de
= ret_list
[0].err
;
206 ret_list
[0].err
= NULL
;
210 ret_name
= (struct canon_name_ret
*)ret_list
[0].attrs
;
211 if (ret_name
== NULL
)
214 if (ret_name
->x_sun_canonicalName
!= NULL
&&
215 ret_name
->x_sun_canonicalName
[0] != NULL
) {
216 *canon
= strdup(ret_name
->x_sun_canonicalName
[0]);
221 if (ret_name
->objectClass
!= NULL
&&
223 *classes
= class_bitmap(ret_name
->objectClass
);
228 de
= directory_error("ENOMEM.directory_canon_common",
229 "Insufficient memory retrieving data about name", NULL
);
232 directory_free(ret_list
);
239 directory_name_from_sid(
245 return (directory_canon_common(d
, sid
, DIRECTORY_ID_SID
, canon
,
250 directory_canon_from_name(
256 return (directory_canon_common(d
, name
, DIRECTORY_ID_NAME
, canon
,
261 directory_canon_from_user_name(directory_t d
, char *name
, char **canon
)
264 directory_canon_common(d
, name
, DIRECTORY_ID_USER
, canon
, NULL
));
268 directory_canon_from_group_name(directory_t d
, char *name
, char **canon
)
271 directory_canon_common(d
, name
, DIRECTORY_ID_GROUP
, canon
, NULL
));
275 is_in_list(char **list
, char *val
)
277 for (; *list
!= NULL
; list
++) {
278 if (uu_strcaseeq(*list
, val
))
285 class_bitmap(char **objectClass
)
289 for (; *objectClass
!= NULL
; objectClass
++) {
290 if (uu_strcaseeq(*objectClass
, "user") ||
291 uu_strcaseeq(*objectClass
, "posixAccount"))
292 ret
|= DIRECTORY_CLASS_USER
;
294 if (uu_strcaseeq(*objectClass
, "group") ||
295 uu_strcaseeq(*objectClass
, "posixGroup"))
296 ret
|= DIRECTORY_CLASS_GROUP
;