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]
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright Milan Jurik 2012. All rights reserved.
24 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
25 * Copyright 2015 Joyent, Inc.
34 #include <sys/varargs.h>
39 #include <sys/param.h>
40 #include <sys/types.h>
46 #include "idmap_impl.h"
47 #include "idmap_cache.h"
49 static struct timeval TIMEOUT
= { 25, 0 };
51 static int idmap_stat2errno(idmap_stat
);
52 static idmap_stat
idmap_strdupnull(char **, const char *);
54 #define __ITER_CREATE(itera, argu, ityp)\
55 itera = calloc(1, sizeof (*itera));\
58 return (IDMAP_ERR_MEMORY);\
60 argu = calloc(1, sizeof (*argu));\
64 return (IDMAP_ERR_MEMORY);\
67 itera->retcode = IDMAP_NEXT;\
71 #define __ITER_CHECK(itera, ityp)\
74 return (IDMAP_ERR_ARG);\
76 if (itera->type != ityp) {\
78 return (IDMAP_ERR_ARG);\
82 * Free memory allocated by libidmap API
85 * ptr - memory to be freed
95 idmap_get_prop(idmap_prop_type pr
, idmap_prop_res
*res
)
99 (void) memset(res
, 0, sizeof (*res
));
101 retcode
= _idmap_clnt_call(IDMAP_GET_PROP
,
102 (xdrproc_t
)xdr_idmap_prop_type
, (caddr_t
)&pr
,
103 (xdrproc_t
)xdr_idmap_prop_res
, (caddr_t
)res
, TIMEOUT
);
104 if (retcode
!= IDMAP_SUCCESS
)
107 return (res
->retcode
); /* This might not be IDMAP_SUCCESS! */
112 idmap_get_prop_ds(idmap_prop_type pr
, idmap_ad_disc_ds_t
*dc
)
115 idmap_stat rc
= IDMAP_SUCCESS
;
117 rc
= idmap_get_prop(pr
, &res
);
121 dc
->port
= res
.value
.idmap_prop_val_u
.dsval
.port
;
122 (void) strlcpy(dc
->host
, res
.value
.idmap_prop_val_u
.dsval
.host
,
123 AD_DISC_MAXHOSTNAME
);
125 /* xdr doesn't guarantee 0-termination of char[]: */
126 dc
->host
[AD_DISC_MAXHOSTNAME
- 1] = '\0';
133 * Sometimes the property is not set. In that case, str is set to NULL but
134 * otherwise IDMAP_SUCCESS is returned.
137 idmap_get_prop_str(idmap_prop_type pr
, char **str
)
140 idmap_stat rc
= IDMAP_SUCCESS
;
142 rc
= idmap_get_prop(pr
, &res
);
146 rc
= idmap_strdupnull(str
, res
.value
.idmap_prop_val_u
.utf8val
);
151 * Create/Initialize handle for updates
154 * udthandle - update handle
157 idmap_udt_create(idmap_udt_handle_t
**udthandle
)
159 idmap_udt_handle_t
*tmp
;
161 if (udthandle
== NULL
) {
163 return (IDMAP_ERR_ARG
);
165 if ((tmp
= calloc(1, sizeof (*tmp
))) == NULL
) {
167 return (IDMAP_ERR_MEMORY
);
171 return (IDMAP_SUCCESS
);
176 * All the updates specified by the update handle are committed
177 * in a single transaction. i.e either all succeed or none.
180 * udthandle - update handle with the update requests
183 * Status of the commit
186 idmap_udt_commit(idmap_udt_handle_t
*udthandle
)
188 idmap_update_res res
;
191 if (udthandle
== NULL
) {
193 return (IDMAP_ERR_ARG
);
196 (void) memset(&res
, 0, sizeof (res
));
198 retcode
= _idmap_clnt_call(IDMAP_UPDATE
,
199 (xdrproc_t
)xdr_idmap_update_batch
, (caddr_t
)&udthandle
->batch
,
200 (xdrproc_t
)xdr_idmap_update_res
, (caddr_t
)&res
,
202 if (retcode
!= IDMAP_SUCCESS
)
205 retcode
= udthandle
->commit_stat
= res
.retcode
;
206 udthandle
->error_index
= res
.error_index
;
208 if (retcode
!= IDMAP_SUCCESS
) {
210 if (udthandle
->error_index
< 0)
213 retcode
= idmap_namerule_cpy(&udthandle
->error_rule
,
215 if (retcode
!= IDMAP_SUCCESS
) {
216 udthandle
->error_index
= -2;
220 retcode
= idmap_namerule_cpy(&udthandle
->conflict_rule
,
222 if (retcode
!= IDMAP_SUCCESS
) {
223 udthandle
->error_index
= -2;
228 retcode
= res
.retcode
;
232 /* reset handle so that it can be used again */
233 if (retcode
== IDMAP_SUCCESS
) {
234 _IDMAP_RESET_UDT_HANDLE(udthandle
);
237 xdr_free(xdr_idmap_update_res
, (caddr_t
)&res
);
238 errno
= idmap_stat2errno(retcode
);
244 idmap_namerule_parts_clear(char **windomain
, char **winname
,
245 char **unixname
, boolean_t
*is_user
, boolean_t
*is_wuser
,
246 boolean_t
*is_nt4
, int *direction
)
262 *direction
= IDMAP_DIRECTION_UNDEF
;
266 idmap_namerule2parts(idmap_namerule
*rule
,
267 char **windomain
, char **winname
,
268 char **unixname
, boolean_t
*is_user
, boolean_t
*is_wuser
,
269 boolean_t
*is_nt4
, int *direction
)
273 if (EMPTY_STRING(rule
->winname
) && EMPTY_STRING(rule
->unixname
))
274 return (IDMAP_ERR_NORESULT
);
277 retcode
= idmap_strdupnull(windomain
, rule
->windomain
);
278 if (retcode
!= IDMAP_SUCCESS
)
281 retcode
= idmap_strdupnull(winname
, rule
->winname
);
282 if (retcode
!= IDMAP_SUCCESS
)
285 retcode
= idmap_strdupnull(unixname
, rule
->unixname
);
286 if (retcode
!= IDMAP_SUCCESS
)
291 *is_user
= rule
->is_user
;
293 *is_wuser
= rule
->is_wuser
;
295 *is_nt4
= rule
->is_nt4
;
297 *direction
= rule
->direction
;
300 return (IDMAP_SUCCESS
);
310 idmap_namerule_parts_clear(windomain
, winname
,
311 unixname
, is_user
, is_wuser
, is_nt4
, direction
);
318 * Retrieve the index of the failed batch element. error_index == -1
319 * indicates failure at the beginning, -2 at the end.
321 * If idmap_udt_commit didn't return error, the returned value is undefined.
328 idmap_udt_get_error_index(idmap_udt_handle_t
*udthandle
,
329 int64_t *error_index
)
332 *error_index
= udthandle
->error_index
;
334 return (IDMAP_SUCCESS
);
339 * Retrieve the rule which caused the batch to fail. If
340 * idmap_udt_commit didn't return error or if error_index is < 0, the
341 * retrieved rule is undefined.
344 * IDMAP_ERR_NORESULT if there is no error rule.
345 * IDMAP_SUCCESS if the rule was obtained OK.
346 * other error code (IDMAP_ERR_NOMEMORY etc)
350 idmap_udt_get_error_rule(idmap_udt_handle_t
*udthandle
,
351 char **windomain
, char **winname
,
352 char **unixname
, boolean_t
*is_user
, boolean_t
*is_wuser
,
353 boolean_t
*is_nt4
, int *direction
)
355 idmap_namerule_parts_clear(windomain
, winname
,
356 unixname
, is_user
, is_wuser
, is_nt4
, direction
);
358 if (udthandle
->commit_stat
== IDMAP_SUCCESS
||
359 udthandle
->error_index
< 0)
360 return (IDMAP_ERR_NORESULT
);
362 return (idmap_namerule2parts(
363 &udthandle
->error_rule
,
374 * Retrieve the rule with which there was a conflict. TODO: retrieve
378 * IDMAP_ERR_NORESULT if there is no error rule.
379 * IDMAP_SUCCESS if the rule was obtained OK.
380 * other error code (IDMAP_ERR_NOMEMORY etc)
384 idmap_udt_get_conflict_rule(idmap_udt_handle_t
*udthandle
,
385 char **windomain
, char **winname
,
386 char **unixname
, boolean_t
*is_user
, boolean_t
*is_wuser
,
387 boolean_t
*is_nt4
, int *direction
)
389 idmap_namerule_parts_clear(windomain
, winname
,
390 unixname
, is_user
, is_wuser
, is_nt4
, direction
);
392 if (udthandle
->commit_stat
!= IDMAP_ERR_W2U_NAMERULE_CONFLICT
&&
393 udthandle
->commit_stat
!= IDMAP_ERR_U2W_NAMERULE_CONFLICT
) {
394 return (IDMAP_ERR_NORESULT
);
397 return (idmap_namerule2parts(
398 &udthandle
->conflict_rule
,
410 * Destroy the update handle
413 idmap_udt_destroy(idmap_udt_handle_t
*udthandle
)
415 if (udthandle
== NULL
)
417 xdr_free(xdr_idmap_update_batch
, (caddr_t
)&udthandle
->batch
);
418 xdr_free(xdr_idmap_namerule
, (caddr_t
)&udthandle
->error_rule
);
419 xdr_free(xdr_idmap_namerule
, (caddr_t
)&udthandle
->conflict_rule
);
425 idmap_udt_add_namerule(idmap_udt_handle_t
*udthandle
, const char *windomain
,
426 boolean_t is_user
, boolean_t is_wuser
, const char *winname
,
427 const char *unixname
, boolean_t is_nt4
, int direction
)
429 idmap_retcode retcode
;
430 idmap_namerule
*rule
= NULL
;
432 retcode
= _udt_extend_batch(udthandle
);
433 if (retcode
!= IDMAP_SUCCESS
)
436 rule
= &udthandle
->batch
.
437 idmap_update_batch_val
[udthandle
->next
].
438 idmap_update_op_u
.rule
;
439 rule
->is_user
= is_user
;
440 rule
->is_wuser
= is_wuser
;
441 rule
->direction
= direction
;
442 rule
->is_nt4
= is_nt4
;
444 retcode
= idmap_strdupnull(&rule
->windomain
, windomain
);
445 if (retcode
!= IDMAP_SUCCESS
)
448 retcode
= idmap_strdupnull(&rule
->winname
, winname
);
449 if (retcode
!= IDMAP_SUCCESS
)
452 retcode
= idmap_strdupnull(&rule
->unixname
, unixname
);
453 if (retcode
!= IDMAP_SUCCESS
)
456 udthandle
->batch
.idmap_update_batch_val
[udthandle
->next
].opnum
=
459 return (IDMAP_SUCCESS
);
462 /* The batch should still be usable */
464 xdr_free(xdr_idmap_namerule
, (caddr_t
)rule
);
465 errno
= idmap_stat2errno(retcode
);
472 idmap_udt_rm_namerule(idmap_udt_handle_t
*udthandle
, boolean_t is_user
,
473 boolean_t is_wuser
, const char *windomain
, const char *winname
,
474 const char *unixname
, int direction
)
476 idmap_retcode retcode
;
477 idmap_namerule
*rule
= NULL
;
479 retcode
= _udt_extend_batch(udthandle
);
480 if (retcode
!= IDMAP_SUCCESS
)
483 rule
= &udthandle
->batch
.
484 idmap_update_batch_val
[udthandle
->next
].
485 idmap_update_op_u
.rule
;
486 rule
->is_user
= is_user
;
487 rule
->is_wuser
= is_wuser
;
488 rule
->direction
= direction
;
490 retcode
= idmap_strdupnull(&rule
->windomain
, windomain
);
491 if (retcode
!= IDMAP_SUCCESS
)
494 retcode
= idmap_strdupnull(&rule
->winname
, winname
);
495 if (retcode
!= IDMAP_SUCCESS
)
498 retcode
= idmap_strdupnull(&rule
->unixname
, unixname
);
499 if (retcode
!= IDMAP_SUCCESS
)
502 udthandle
->batch
.idmap_update_batch_val
[udthandle
->next
].opnum
=
505 return (IDMAP_SUCCESS
);
509 xdr_free(xdr_idmap_namerule
, (caddr_t
)rule
);
510 errno
= idmap_stat2errno(retcode
);
517 idmap_udt_flush_namerules(idmap_udt_handle_t
*udthandle
)
519 idmap_retcode retcode
;
521 retcode
= _udt_extend_batch(udthandle
);
522 if (retcode
!= IDMAP_SUCCESS
)
525 udthandle
->batch
.idmap_update_batch_val
[udthandle
->next
].opnum
=
528 return (IDMAP_SUCCESS
);
531 errno
= idmap_stat2errno(retcode
);
537 * Set the number of entries requested per batch by the iterator
541 * limit - number of entries requested per batch
544 idmap_iter_set_limit(idmap_iter_t
*iter
, uint64_t limit
)
548 return (IDMAP_ERR_ARG
);
551 return (IDMAP_SUCCESS
);
556 * Create iterator to get name-based mapping rules
559 * windomain - Windows domain
560 * is_user - user or group rules
561 * winname - Windows user or group name
562 * unixname - Unix user or group name
568 idmap_iter_namerules(const char *windomain
, boolean_t is_user
,
569 boolean_t is_wuser
, const char *winname
, const char *unixname
,
573 idmap_iter_t
*tmpiter
;
574 idmap_list_namerules_1_argument
*arg
= NULL
;
575 idmap_namerule
*rule
;
576 idmap_retcode retcode
;
578 __ITER_CREATE(tmpiter
, arg
, IDMAP_LIST_NAMERULES
);
581 rule
->is_user
= is_user
;
582 rule
->is_wuser
= is_wuser
;
583 rule
->direction
= IDMAP_DIRECTION_UNDEF
;
585 retcode
= idmap_strdupnull(&rule
->windomain
, windomain
);
586 if (retcode
!= IDMAP_SUCCESS
)
589 retcode
= idmap_strdupnull(&rule
->winname
, winname
);
590 if (retcode
!= IDMAP_SUCCESS
)
593 retcode
= idmap_strdupnull(&rule
->unixname
, unixname
);
594 if (retcode
!= IDMAP_SUCCESS
)
598 return (IDMAP_SUCCESS
);
602 xdr_free(xdr_idmap_list_namerules_1_argument
, (char *)arg
);
612 * Iterate through the name-based mapping rules
618 * windomain - Windows domain
619 * winname - Windows user or group name
620 * unixname - Unix user or group name
622 * direction - bi(0), win2unix(1), unix2win(2)
626 * 1 - more results available
630 idmap_iter_next_namerule(idmap_iter_t
*iter
, char **windomain
,
631 char **winname
, char **unixname
, boolean_t
*is_user
,
632 boolean_t
*is_wuser
, boolean_t
*is_nt4
, int *direction
)
634 idmap_namerules_res
*namerules
;
635 idmap_list_namerules_1_argument
*arg
;
636 idmap_retcode retcode
;
638 idmap_namerule_parts_clear(windomain
, winname
,
639 unixname
, is_user
, is_wuser
, is_nt4
, direction
);
642 __ITER_CHECK(iter
, IDMAP_LIST_NAMERULES
);
644 namerules
= (idmap_namerules_res
*)iter
->retlist
;
645 if (iter
->retcode
== IDMAP_NEXT
&& (namerules
== NULL
||
646 iter
->next
>= namerules
->rules
.rules_len
)) {
648 if ((arg
= iter
->arg
) == NULL
) {
650 return (IDMAP_ERR_ARG
);
652 arg
->limit
= iter
->limit
;
654 retcode
= _iter_get_next_list(IDMAP_LIST_NAMERULES
,
656 (uchar_t
**)&namerules
, sizeof (*namerules
),
657 (xdrproc_t
)xdr_idmap_list_namerules_1_argument
,
658 (xdrproc_t
)xdr_idmap_namerules_res
);
659 if (retcode
!= IDMAP_SUCCESS
)
662 if (IDMAP_ERROR(namerules
->retcode
)) {
663 retcode
= namerules
->retcode
;
664 xdr_free(xdr_idmap_namerules_res
, (caddr_t
)namerules
);
666 iter
->retlist
= NULL
;
669 iter
->retcode
= namerules
->retcode
;
670 arg
->lastrowid
= namerules
->lastrowid
;
673 if (namerules
== NULL
|| namerules
->rules
.rules_len
== 0)
674 return (IDMAP_SUCCESS
);
676 if (iter
->next
>= namerules
->rules
.rules_len
) {
677 return (IDMAP_ERR_ARG
);
680 retcode
= idmap_strdupnull(windomain
,
681 namerules
->rules
.rules_val
[iter
->next
].windomain
);
682 if (retcode
!= IDMAP_SUCCESS
)
685 retcode
= idmap_strdupnull(winname
,
686 namerules
->rules
.rules_val
[iter
->next
].winname
);
687 if (retcode
!= IDMAP_SUCCESS
)
690 retcode
= idmap_strdupnull(unixname
,
691 namerules
->rules
.rules_val
[iter
->next
].unixname
);
692 if (retcode
!= IDMAP_SUCCESS
)
696 *is_nt4
= namerules
->rules
.rules_val
[iter
->next
].is_nt4
;
698 *is_user
= namerules
->rules
.rules_val
[iter
->next
].is_user
;
700 *is_wuser
= namerules
->rules
.rules_val
[iter
->next
].is_wuser
;
702 *direction
= namerules
->rules
.rules_val
[iter
->next
].direction
;
705 if (iter
->next
== namerules
->rules
.rules_len
)
706 return (iter
->retcode
);
722 * Create iterator to get SID to UID/GID mappings
728 idmap_iter_mappings(idmap_iter_t
**iter
, int flag
)
730 idmap_iter_t
*tmpiter
;
731 idmap_list_mappings_1_argument
*arg
= NULL
;
733 __ITER_CREATE(tmpiter
, arg
, IDMAP_LIST_MAPPINGS
);
737 return (IDMAP_SUCCESS
);
742 * Iterate through the SID to UID/GID mappings
748 * sid - SID in canonical form
753 * 1 - more results available
757 idmap_iter_next_mapping(idmap_iter_t
*iter
, char **sidprefix
,
758 idmap_rid_t
*rid
, uid_t
*pid
, char **winname
,
759 char **windomain
, char **unixname
, boolean_t
*is_user
,
760 boolean_t
*is_wuser
, int *direction
, idmap_info
*info
)
762 idmap_mappings_res
*mappings
;
763 idmap_list_mappings_1_argument
*arg
;
764 idmap_retcode retcode
;
784 *direction
= IDMAP_DIRECTION_UNDEF
;
786 __ITER_CHECK(iter
, IDMAP_LIST_MAPPINGS
);
788 mappings
= (idmap_mappings_res
*)iter
->retlist
;
789 if (iter
->retcode
== IDMAP_NEXT
&& (mappings
== NULL
||
790 iter
->next
>= mappings
->mappings
.mappings_len
)) {
792 if ((arg
= iter
->arg
) == NULL
) {
794 return (IDMAP_ERR_ARG
);
796 arg
->limit
= iter
->limit
;
798 retcode
= _iter_get_next_list(IDMAP_LIST_MAPPINGS
,
800 (uchar_t
**)&mappings
, sizeof (*mappings
),
801 (xdrproc_t
)xdr_idmap_list_mappings_1_argument
,
802 (xdrproc_t
)xdr_idmap_mappings_res
);
803 if (retcode
!= IDMAP_SUCCESS
)
806 if (IDMAP_ERROR(mappings
->retcode
)) {
807 retcode
= mappings
->retcode
;
808 xdr_free(xdr_idmap_mappings_res
, (caddr_t
)mappings
);
810 iter
->retlist
= NULL
;
813 iter
->retcode
= mappings
->retcode
;
814 arg
->lastrowid
= mappings
->lastrowid
;
817 if (mappings
== NULL
|| mappings
->mappings
.mappings_len
== 0)
818 return (IDMAP_SUCCESS
);
820 if (iter
->next
>= mappings
->mappings
.mappings_len
) {
821 return (IDMAP_ERR_ARG
);
825 str
= mappings
->mappings
.mappings_val
[iter
->next
].id1
.
826 idmap_id_u
.sid
.prefix
;
827 if (str
&& *str
!= '\0') {
828 *sidprefix
= strdup(str
);
829 if (*sidprefix
== NULL
) {
830 retcode
= IDMAP_ERR_MEMORY
;
836 *rid
= mappings
->mappings
.mappings_val
[iter
->next
].id1
.
839 retcode
= idmap_strdupnull(windomain
,
840 mappings
->mappings
.mappings_val
[iter
->next
].id1domain
);
841 if (retcode
!= IDMAP_SUCCESS
)
844 retcode
= idmap_strdupnull(winname
,
845 mappings
->mappings
.mappings_val
[iter
->next
].id1name
);
846 if (retcode
!= IDMAP_SUCCESS
)
849 retcode
= idmap_strdupnull(unixname
,
850 mappings
->mappings
.mappings_val
[iter
->next
].id2name
);
851 if (retcode
!= IDMAP_SUCCESS
)
856 *pid
= mappings
->mappings
.mappings_val
[iter
->next
].id2
.
859 *direction
= mappings
->mappings
.mappings_val
[iter
->next
].
862 *is_user
= (mappings
->mappings
.mappings_val
[iter
->next
].id2
863 .idtype
== IDMAP_UID
)?1:0;
865 *is_wuser
= (mappings
->mappings
.mappings_val
[iter
->next
].id1
866 .idtype
== IDMAP_USID
)?1:0;
870 &mappings
->mappings
.mappings_val
[iter
->next
].info
);
874 if (iter
->next
== mappings
->mappings
.mappings_len
)
875 return (iter
->retcode
);
893 * Destroy the iterator
896 idmap_iter_destroy(idmap_iter_t
*iter
)
898 xdrproc_t _xdr_argument
, _xdr_result
;
903 switch (iter
->type
) {
904 case IDMAP_LIST_NAMERULES
:
905 _xdr_argument
= (xdrproc_t
)xdr_idmap_list_namerules_1_argument
;
906 _xdr_result
= (xdrproc_t
)xdr_idmap_namerules_res
;
908 case IDMAP_LIST_MAPPINGS
:
909 _xdr_argument
= (xdrproc_t
)xdr_idmap_list_mappings_1_argument
;
910 _xdr_result
= (xdrproc_t
)xdr_idmap_mappings_res
;
918 xdr_free(_xdr_argument
, (caddr_t
)iter
->arg
);
922 xdr_free(_xdr_result
, (caddr_t
)iter
->retlist
);
930 * Create handle to get SID to UID/GID mapping entries
933 * gh - "get mapping" handle
936 idmap_get_create(idmap_get_handle_t
**gh
)
938 idmap_get_handle_t
*tmp
;
940 /* allocate the handle */
941 if ((tmp
= calloc(1, sizeof (*tmp
))) == NULL
) {
943 return (IDMAP_ERR_MEMORY
);
947 return (IDMAP_SUCCESS
);
955 * sidprefix - SID prefix
960 * stat - status of the get request
961 * uid - POSIX UID if stat = 0
963 * Note: The output parameters will be set by idmap_get_mappings()
966 idmap_get_uidbysid(idmap_get_handle_t
*gh
, char *sidprefix
, idmap_rid_t rid
,
967 int flag
, uid_t
*uid
, idmap_stat
*stat
)
969 return (idmap_getext_uidbysid(gh
, sidprefix
, rid
, flag
, uid
,
977 * sidprefix - SID prefix
982 * stat - status of the get request
983 * uid - POSIX UID if stat = 0
984 * how - mapping type if stat = 0
986 * Note: The output parameters will be set by idmap_get_mappings()
990 idmap_getext_uidbysid(idmap_get_handle_t
*gh
, char *sidprefix
, idmap_rid_t rid
,
991 int flag
, uid_t
*uid
, idmap_info
*info
, idmap_stat
*stat
)
993 idmap_retcode retcode
;
994 idmap_mapping
*mapping
= NULL
;
998 return (IDMAP_ERR_ARG
);
999 if (uid
== NULL
|| sidprefix
== NULL
)
1000 return (IDMAP_ERR_ARG
);
1002 if ((flag
& IDMAP_REQ_FLG_USE_CACHE
) &&
1003 !(flag
& IDMAP_REQ_FLG_MAPPING_INFO
)) {
1004 retcode
= idmap_cache_lookup_uidbysid(sidprefix
, rid
, uid
);
1005 if (retcode
== IDMAP_SUCCESS
|| retcode
== IDMAP_ERR_MEMORY
) {
1011 /* Extend the request array and the return list */
1012 if ((retcode
= _get_ids_extend_batch(gh
)) != IDMAP_SUCCESS
)
1015 /* Setup the request */
1016 mapping
= &gh
->batch
.idmap_mapping_batch_val
[gh
->next
];
1017 mapping
->flag
= flag
;
1018 mapping
->id1
.idtype
= IDMAP_SID
;
1019 mapping
->id1
.idmap_id_u
.sid
.rid
= rid
;
1020 if ((mapping
->id1
.idmap_id_u
.sid
.prefix
= strdup(sidprefix
)) == NULL
) {
1021 retcode
= IDMAP_ERR_MEMORY
;
1024 mapping
->id2
.idtype
= IDMAP_UID
;
1026 /* Setup pointers for the result */
1027 gh
->retlist
[gh
->next
].idtype
= IDMAP_UID
;
1028 gh
->retlist
[gh
->next
].uid
= uid
;
1029 gh
->retlist
[gh
->next
].stat
= stat
;
1030 gh
->retlist
[gh
->next
].info
= info
;
1031 gh
->retlist
[gh
->next
].cache_res
= flag
& IDMAP_REQ_FLG_USE_CACHE
;
1034 return (IDMAP_SUCCESS
);
1037 /* Batch created so far should still be usable */
1039 (void) memset(mapping
, 0, sizeof (*mapping
));
1040 errno
= idmap_stat2errno(retcode
);
1046 * Given SID, get GID
1049 * sidprefix - SID prefix
1054 * stat - status of the get request
1055 * gid - POSIX GID if stat = 0
1057 * Note: The output parameters will be set by idmap_get_mappings()
1060 idmap_get_gidbysid(idmap_get_handle_t
*gh
, char *sidprefix
, idmap_rid_t rid
,
1061 int flag
, gid_t
*gid
, idmap_stat
*stat
)
1063 return (idmap_getext_gidbysid(gh
, sidprefix
, rid
, flag
, gid
,
1069 * Given SID, get GID
1072 * sidprefix - SID prefix
1077 * stat - status of the get request
1078 * gid - POSIX GID if stat = 0
1079 * how - mapping type if stat = 0
1081 * Note: The output parameters will be set by idmap_get_mappings()
1084 idmap_getext_gidbysid(idmap_get_handle_t
*gh
, char *sidprefix
, idmap_rid_t rid
,
1085 int flag
, gid_t
*gid
, idmap_info
*info
, idmap_stat
*stat
)
1088 idmap_retcode retcode
;
1089 idmap_mapping
*mapping
= NULL
;
1093 return (IDMAP_ERR_ARG
);
1094 if (gid
== NULL
|| sidprefix
== NULL
)
1095 return (IDMAP_ERR_ARG
);
1097 if ((flag
& IDMAP_REQ_FLG_USE_CACHE
) &&
1098 !(flag
& IDMAP_REQ_FLG_MAPPING_INFO
)) {
1099 retcode
= idmap_cache_lookup_gidbysid(sidprefix
, rid
, gid
);
1100 if (retcode
== IDMAP_SUCCESS
|| retcode
== IDMAP_ERR_MEMORY
) {
1106 /* Extend the request array and the return list */
1107 if ((retcode
= _get_ids_extend_batch(gh
)) != IDMAP_SUCCESS
)
1110 /* Setup the request */
1111 mapping
= &gh
->batch
.idmap_mapping_batch_val
[gh
->next
];
1112 mapping
->flag
= flag
;
1113 mapping
->id1
.idtype
= IDMAP_SID
;
1114 mapping
->id1
.idmap_id_u
.sid
.rid
= rid
;
1115 if ((mapping
->id1
.idmap_id_u
.sid
.prefix
= strdup(sidprefix
)) == NULL
) {
1116 retcode
= IDMAP_ERR_MEMORY
;
1119 mapping
->id2
.idtype
= IDMAP_GID
;
1121 /* Setup pointers for the result */
1122 gh
->retlist
[gh
->next
].idtype
= IDMAP_GID
;
1123 gh
->retlist
[gh
->next
].gid
= gid
;
1124 gh
->retlist
[gh
->next
].stat
= stat
;
1125 gh
->retlist
[gh
->next
].info
= info
;
1126 gh
->retlist
[gh
->next
].cache_res
= flag
& IDMAP_REQ_FLG_USE_CACHE
;
1129 return (IDMAP_SUCCESS
);
1133 (void) memset(mapping
, 0, sizeof (*mapping
));
1134 errno
= idmap_stat2errno(retcode
);
1141 * Given SID, get POSIX ID i.e. UID/GID
1144 * sidprefix - SID prefix
1149 * stat - status of the get request
1150 * is_user - user or group
1151 * pid - POSIX UID if stat = 0 and is_user = 1
1152 * POSIX GID if stat = 0 and is_user = 0
1154 * Note: The output parameters will be set by idmap_get_mappings()
1157 idmap_get_pidbysid(idmap_get_handle_t
*gh
, char *sidprefix
, idmap_rid_t rid
,
1158 int flag
, uid_t
*pid
, int *is_user
, idmap_stat
*stat
)
1160 return (idmap_getext_pidbysid(gh
, sidprefix
, rid
, flag
, pid
, is_user
,
1167 * Given SID, get POSIX ID i.e. UID/GID
1170 * sidprefix - SID prefix
1175 * stat - status of the get request
1176 * is_user - user or group
1177 * pid - POSIX UID if stat = 0 and is_user = 1
1178 * POSIX GID if stat = 0 and is_user = 0
1179 * how - mapping type if stat = 0
1181 * Note: The output parameters will be set by idmap_get_mappings()
1184 idmap_getext_pidbysid(idmap_get_handle_t
*gh
, char *sidprefix
, idmap_rid_t rid
,
1185 int flag
, uid_t
*pid
, int *is_user
, idmap_info
*info
, idmap_stat
*stat
)
1187 idmap_retcode retcode
;
1188 idmap_mapping
*mapping
= NULL
;
1192 return (IDMAP_ERR_ARG
);
1193 if (pid
== NULL
|| sidprefix
== NULL
|| is_user
== NULL
)
1194 return (IDMAP_ERR_ARG
);
1196 if ((flag
& IDMAP_REQ_FLG_USE_CACHE
) &&
1197 !(flag
& IDMAP_REQ_FLG_MAPPING_INFO
)) {
1198 retcode
= idmap_cache_lookup_pidbysid(sidprefix
, rid
, pid
,
1200 if (retcode
== IDMAP_SUCCESS
|| retcode
== IDMAP_ERR_MEMORY
) {
1206 /* Extend the request array and the return list */
1207 if ((retcode
= _get_ids_extend_batch(gh
)) != IDMAP_SUCCESS
)
1210 /* Setup the request */
1211 mapping
= &gh
->batch
.idmap_mapping_batch_val
[gh
->next
];
1212 mapping
->flag
= flag
;
1213 mapping
->id1
.idtype
= IDMAP_SID
;
1214 mapping
->id1
.idmap_id_u
.sid
.rid
= rid
;
1215 if ((mapping
->id1
.idmap_id_u
.sid
.prefix
= strdup(sidprefix
)) == NULL
) {
1216 retcode
= IDMAP_ERR_MEMORY
;
1219 mapping
->id2
.idtype
= IDMAP_POSIXID
;
1221 /* Setup pointers for the result */
1222 gh
->retlist
[gh
->next
].idtype
= IDMAP_POSIXID
;
1223 gh
->retlist
[gh
->next
].uid
= pid
;
1224 gh
->retlist
[gh
->next
].gid
= pid
;
1225 gh
->retlist
[gh
->next
].is_user
= is_user
;
1226 gh
->retlist
[gh
->next
].stat
= stat
;
1227 gh
->retlist
[gh
->next
].info
= info
;
1228 gh
->retlist
[gh
->next
].cache_res
= flag
& IDMAP_REQ_FLG_USE_CACHE
;
1231 return (IDMAP_SUCCESS
);
1235 (void) memset(mapping
, 0, sizeof (*mapping
));
1236 errno
= idmap_stat2errno(retcode
);
1242 * Given UID, get SID
1249 * stat - status of the get request
1250 * sid - SID prefix (if stat == 0)
1253 * Note: The output parameters will be set by idmap_get_mappings()
1256 idmap_get_sidbyuid(idmap_get_handle_t
*gh
, uid_t uid
, int flag
,
1257 char **sidprefix
, idmap_rid_t
*rid
, idmap_stat
*stat
)
1259 return (idmap_getext_sidbyuid(gh
, uid
, flag
, sidprefix
, rid
,
1265 * Given UID, get SID
1272 * stat - status of the get request
1273 * sid - SID prefix (if stat == 0)
1275 * how - mapping type if stat = 0
1277 * Note: The output parameters will be set by idmap_get_mappings()
1280 idmap_getext_sidbyuid(idmap_get_handle_t
*gh
, uid_t uid
, int flag
,
1281 char **sidprefix
, idmap_rid_t
*rid
, idmap_info
*info
, idmap_stat
*stat
)
1284 idmap_retcode retcode
;
1285 idmap_mapping
*mapping
= NULL
;
1289 return (IDMAP_ERR_ARG
);
1290 if (sidprefix
== NULL
)
1291 return (IDMAP_ERR_ARG
);
1293 if ((flag
& IDMAP_REQ_FLG_USE_CACHE
) &&
1294 !(flag
& IDMAP_REQ_FLG_MAPPING_INFO
)) {
1295 retcode
= idmap_cache_lookup_sidbyuid(sidprefix
, rid
, uid
);
1296 if (retcode
== IDMAP_SUCCESS
|| retcode
== IDMAP_ERR_MEMORY
) {
1302 /* Extend the request array and the return list */
1303 if ((retcode
= _get_ids_extend_batch(gh
)) != IDMAP_SUCCESS
)
1306 /* Setup the request */
1307 mapping
= &gh
->batch
.idmap_mapping_batch_val
[gh
->next
];
1308 mapping
->flag
= flag
;
1309 mapping
->id1
.idtype
= IDMAP_UID
;
1310 mapping
->id1
.idmap_id_u
.uid
= uid
;
1311 mapping
->id2
.idtype
= IDMAP_SID
;
1313 /* Setup pointers for the result */
1314 gh
->retlist
[gh
->next
].idtype
= IDMAP_SID
;
1315 gh
->retlist
[gh
->next
].sidprefix
= sidprefix
;
1316 gh
->retlist
[gh
->next
].rid
= rid
;
1317 gh
->retlist
[gh
->next
].stat
= stat
;
1318 gh
->retlist
[gh
->next
].info
= info
;
1319 gh
->retlist
[gh
->next
].cache_res
= flag
& IDMAP_REQ_FLG_USE_CACHE
;
1322 return (IDMAP_SUCCESS
);
1326 (void) memset(mapping
, 0, sizeof (*mapping
));
1327 errno
= idmap_stat2errno(retcode
);
1333 * Given GID, get SID
1340 * stat - status of the get request
1341 * sidprefix - SID prefix (if stat == 0)
1344 * Note: The output parameters will be set by idmap_get_mappings()
1347 idmap_get_sidbygid(idmap_get_handle_t
*gh
, gid_t gid
, int flag
,
1348 char **sidprefix
, idmap_rid_t
*rid
, idmap_stat
*stat
)
1350 return (idmap_getext_sidbygid(gh
, gid
, flag
, sidprefix
, rid
,
1356 * Given GID, get SID
1363 * stat - status of the get request
1364 * sidprefix - SID prefix (if stat == 0)
1366 * how - mapping type if stat = 0
1368 * Note: The output parameters will be set by idmap_get_mappings()
1371 idmap_getext_sidbygid(idmap_get_handle_t
*gh
, gid_t gid
, int flag
,
1372 char **sidprefix
, idmap_rid_t
*rid
, idmap_info
*info
, idmap_stat
*stat
)
1375 idmap_retcode retcode
;
1376 idmap_mapping
*mapping
= NULL
;
1380 return (IDMAP_ERR_ARG
);
1381 if (sidprefix
== NULL
)
1382 return (IDMAP_ERR_ARG
);
1384 if ((flag
& IDMAP_REQ_FLG_USE_CACHE
) &&
1385 !(flag
& IDMAP_REQ_FLG_MAPPING_INFO
)) {
1386 retcode
= idmap_cache_lookup_sidbygid(sidprefix
, rid
, gid
);
1387 if (retcode
== IDMAP_SUCCESS
|| retcode
== IDMAP_ERR_MEMORY
) {
1393 /* Extend the request array and the return list */
1394 if ((retcode
= _get_ids_extend_batch(gh
)) != IDMAP_SUCCESS
)
1397 /* Setup the request */
1398 mapping
= &gh
->batch
.idmap_mapping_batch_val
[gh
->next
];
1399 mapping
->flag
= flag
;
1400 mapping
->id1
.idtype
= IDMAP_GID
;
1401 mapping
->id1
.idmap_id_u
.gid
= gid
;
1402 mapping
->id2
.idtype
= IDMAP_SID
;
1404 /* Setup pointers for the result */
1405 gh
->retlist
[gh
->next
].idtype
= IDMAP_SID
;
1406 gh
->retlist
[gh
->next
].sidprefix
= sidprefix
;
1407 gh
->retlist
[gh
->next
].rid
= rid
;
1408 gh
->retlist
[gh
->next
].stat
= stat
;
1409 gh
->retlist
[gh
->next
].info
= info
;
1410 gh
->retlist
[gh
->next
].cache_res
= flag
& IDMAP_REQ_FLG_USE_CACHE
;
1413 return (IDMAP_SUCCESS
);
1417 (void) memset(mapping
, 0, sizeof (*mapping
));
1418 errno
= idmap_stat2errno(retcode
);
1424 * Process the batched "get mapping" requests. The results (i.e.
1425 * status and identity) will be available in the data areas
1426 * provided by individual requests.
1429 idmap_get_mappings(idmap_get_handle_t
*gh
)
1431 idmap_retcode retcode
;
1440 return (IDMAP_ERR_ARG
);
1443 (void) memset(&res
, 0, sizeof (idmap_ids_res
));
1444 retcode
= _idmap_clnt_call(IDMAP_GET_MAPPED_IDS
,
1445 (xdrproc_t
)xdr_idmap_mapping_batch
,
1446 (caddr_t
)&gh
->batch
,
1447 (xdrproc_t
)xdr_idmap_ids_res
,
1450 if (retcode
!= IDMAP_SUCCESS
) {
1453 if (res
.retcode
!= IDMAP_SUCCESS
) {
1454 retcode
= res
.retcode
;
1457 for (i
= 0; i
< gh
->next
; i
++) {
1458 if (i
>= res
.ids
.ids_len
) {
1459 *gh
->retlist
[i
].stat
= IDMAP_ERR_NORESULT
;
1462 *gh
->retlist
[i
].stat
= res
.ids
.ids_val
[i
].retcode
;
1463 res_id
= &res
.ids
.ids_val
[i
].id
;
1464 direction
= res
.ids
.ids_val
[i
].direction
;
1465 req_id
= &gh
->batch
.idmap_mapping_batch_val
[i
].id1
;
1466 switch (res_id
->idtype
) {
1468 if (gh
->retlist
[i
].uid
)
1469 *gh
->retlist
[i
].uid
= res_id
->idmap_id_u
.uid
;
1470 if (gh
->retlist
[i
].is_user
)
1471 *gh
->retlist
[i
].is_user
= 1;
1473 if (res
.ids
.ids_val
[i
].retcode
== IDMAP_SUCCESS
&&
1474 gh
->retlist
[i
].cache_res
) {
1475 if (gh
->retlist
[i
].is_user
!= NULL
)
1476 idmap_cache_add_sid2pid(
1477 req_id
->idmap_id_u
.sid
.prefix
,
1478 req_id
->idmap_id_u
.sid
.rid
,
1479 res_id
->idmap_id_u
.uid
, 1,
1482 idmap_cache_add_sid2uid(
1483 req_id
->idmap_id_u
.sid
.prefix
,
1484 req_id
->idmap_id_u
.sid
.rid
,
1485 res_id
->idmap_id_u
.uid
,
1491 if (gh
->retlist
[i
].gid
)
1492 *gh
->retlist
[i
].gid
= res_id
->idmap_id_u
.gid
;
1493 if (gh
->retlist
[i
].is_user
)
1494 *gh
->retlist
[i
].is_user
= 0;
1496 if (res
.ids
.ids_val
[i
].retcode
== IDMAP_SUCCESS
&&
1497 gh
->retlist
[i
].cache_res
) {
1498 if (gh
->retlist
[i
].is_user
!= NULL
)
1499 idmap_cache_add_sid2pid(
1500 req_id
->idmap_id_u
.sid
.prefix
,
1501 req_id
->idmap_id_u
.sid
.rid
,
1502 res_id
->idmap_id_u
.gid
, 0,
1505 idmap_cache_add_sid2gid(
1506 req_id
->idmap_id_u
.sid
.prefix
,
1507 req_id
->idmap_id_u
.sid
.rid
,
1508 res_id
->idmap_id_u
.gid
,
1514 if (gh
->retlist
[i
].uid
)
1515 *gh
->retlist
[i
].uid
= 60001;
1516 if (gh
->retlist
[i
].is_user
)
1517 *gh
->retlist
[i
].is_user
= -1;
1523 if (gh
->retlist
[i
].rid
)
1524 *gh
->retlist
[i
].rid
=
1525 res_id
->idmap_id_u
.sid
.rid
;
1526 if (gh
->retlist
[i
].sidprefix
) {
1527 if (res_id
->idmap_id_u
.sid
.prefix
== NULL
||
1528 *res_id
->idmap_id_u
.sid
.prefix
== '\0') {
1529 *gh
->retlist
[i
].sidprefix
= NULL
;
1532 *gh
->retlist
[i
].sidprefix
=
1533 strdup(res_id
->idmap_id_u
.sid
.prefix
);
1534 if (*gh
->retlist
[i
].sidprefix
== NULL
)
1535 *gh
->retlist
[i
].stat
=
1538 if (res
.ids
.ids_val
[i
].retcode
== IDMAP_SUCCESS
&&
1539 gh
->retlist
[i
].cache_res
) {
1540 if (req_id
->idtype
== IDMAP_UID
)
1541 idmap_cache_add_sid2uid(
1542 res_id
->idmap_id_u
.sid
.prefix
,
1543 res_id
->idmap_id_u
.sid
.rid
,
1544 req_id
->idmap_id_u
.uid
,
1546 else /* req_id->idtype == IDMAP_GID */
1547 idmap_cache_add_sid2gid(
1548 res_id
->idmap_id_u
.sid
.prefix
,
1549 res_id
->idmap_id_u
.sid
.rid
,
1550 req_id
->idmap_id_u
.gid
,
1559 *gh
->retlist
[i
].stat
= IDMAP_ERR_NORESULT
;
1562 if (gh
->retlist
[i
].info
!= NULL
) {
1563 idmap_info_mov(gh
->retlist
[i
].info
,
1564 &res
.ids
.ids_val
[i
].info
);
1567 retcode
= IDMAP_SUCCESS
;
1570 _IDMAP_RESET_GET_HANDLE(gh
);
1571 xdr_free(xdr_idmap_ids_res
, (caddr_t
)&res
);
1572 errno
= idmap_stat2errno(retcode
);
1578 * Destroy the "get mapping" handle
1581 idmap_get_destroy(idmap_get_handle_t
*gh
)
1585 xdr_free(xdr_idmap_mapping_batch
, (caddr_t
)&gh
->batch
);
1592 * Get windows to unix mapping
1595 idmap_get_w2u_mapping(
1596 const char *sidprefix
, idmap_rid_t
*rid
,
1597 const char *winname
, const char *windomain
,
1598 int flag
, int *is_user
, int *is_wuser
,
1599 uid_t
*pid
, char **unixname
, int *direction
, idmap_info
*info
)
1601 idmap_mapping request
, *mapping
;
1602 idmap_mappings_res result
;
1603 idmap_retcode retcode
, rc
;
1605 (void) memset(&request
, 0, sizeof (request
));
1606 (void) memset(&result
, 0, sizeof (result
));
1613 *direction
= IDMAP_DIRECTION_UNDEF
;
1615 request
.flag
= flag
;
1616 request
.id1
.idtype
= IDMAP_SID
;
1617 if (sidprefix
&& rid
) {
1618 request
.id1
.idmap_id_u
.sid
.prefix
= (char *)sidprefix
;
1619 request
.id1
.idmap_id_u
.sid
.rid
= *rid
;
1620 } else if (winname
) {
1621 retcode
= idmap_strdupnull(&request
.id1name
, winname
);
1622 if (retcode
!= IDMAP_SUCCESS
)
1625 retcode
= idmap_strdupnull(&request
.id1domain
, windomain
);
1626 if (retcode
!= IDMAP_SUCCESS
)
1629 request
.id1
.idmap_id_u
.sid
.prefix
= NULL
;
1632 return (IDMAP_ERR_ARG
);
1636 request
.id2
.idtype
= IDMAP_UID
;
1637 else if (*is_user
== 0)
1638 request
.id2
.idtype
= IDMAP_GID
;
1640 request
.id2
.idtype
= IDMAP_POSIXID
;
1643 request
.id1
.idtype
= IDMAP_USID
;
1644 else if (*is_wuser
== 0)
1645 request
.id1
.idtype
= IDMAP_GSID
;
1647 request
.id1
.idtype
= IDMAP_SID
;
1649 retcode
= _idmap_clnt_call(IDMAP_GET_MAPPED_ID_BY_NAME
,
1650 (xdrproc_t
)xdr_idmap_mapping
, (caddr_t
)&request
,
1651 (xdrproc_t
)xdr_idmap_mappings_res
, (caddr_t
)&result
,
1654 if (retcode
!= IDMAP_SUCCESS
)
1657 retcode
= result
.retcode
;
1659 if ((mapping
= result
.mappings
.mappings_val
) == NULL
) {
1660 if (retcode
== IDMAP_SUCCESS
)
1661 retcode
= IDMAP_ERR_NORESULT
;
1666 idmap_info_mov(info
, &mapping
->info
);
1668 if (mapping
->id2
.idtype
== IDMAP_UID
) {
1670 } else if (mapping
->id2
.idtype
== IDMAP_GID
) {
1676 if (mapping
->id1
.idtype
== IDMAP_USID
) {
1678 } else if (mapping
->id1
.idtype
== IDMAP_GSID
) {
1685 *direction
= mapping
->direction
;
1687 *pid
= mapping
->id2
.idmap_id_u
.uid
;
1689 rc
= idmap_strdupnull(unixname
, mapping
->id2name
);
1690 if (rc
!= IDMAP_SUCCESS
)
1694 free(request
.id1name
);
1695 free(request
.id1domain
);
1696 xdr_free(xdr_idmap_mappings_res
, (caddr_t
)&result
);
1697 if (retcode
!= IDMAP_SUCCESS
)
1698 errno
= idmap_stat2errno(retcode
);
1704 * Get unix to windows mapping
1707 idmap_get_u2w_mapping(
1708 uid_t
*pid
, const char *unixname
,
1709 int flag
, int is_user
, int *is_wuser
,
1710 char **sidprefix
, idmap_rid_t
*rid
,
1711 char **winname
, char **windomain
,
1712 int *direction
, idmap_info
*info
)
1714 idmap_mapping request
, *mapping
;
1715 idmap_mappings_res result
;
1716 idmap_retcode retcode
, rc
;
1727 *direction
= IDMAP_DIRECTION_UNDEF
;
1729 (void) memset(&request
, 0, sizeof (request
));
1730 (void) memset(&result
, 0, sizeof (result
));
1732 request
.flag
= flag
;
1733 request
.id1
.idtype
= is_user
?IDMAP_UID
:IDMAP_GID
;
1735 if (pid
&& *pid
!= UINT32_MAX
) {
1736 request
.id1
.idmap_id_u
.uid
= *pid
;
1737 } else if (unixname
) {
1738 request
.id1name
= (char *)unixname
;
1739 request
.id1
.idmap_id_u
.uid
= UINT32_MAX
;
1742 return (IDMAP_ERR_ARG
);
1745 if (is_wuser
== NULL
)
1746 request
.id2
.idtype
= IDMAP_SID
;
1747 else if (*is_wuser
== -1)
1748 request
.id2
.idtype
= IDMAP_SID
;
1749 else if (*is_wuser
== 0)
1750 request
.id2
.idtype
= IDMAP_GSID
;
1751 else if (*is_wuser
== 1)
1752 request
.id2
.idtype
= IDMAP_USID
;
1754 retcode
= _idmap_clnt_call(IDMAP_GET_MAPPED_ID_BY_NAME
,
1755 (xdrproc_t
)xdr_idmap_mapping
, (caddr_t
)&request
,
1756 (xdrproc_t
)xdr_idmap_mappings_res
, (caddr_t
)&result
,
1759 if (retcode
!= IDMAP_SUCCESS
)
1762 retcode
= result
.retcode
;
1764 if ((mapping
= result
.mappings
.mappings_val
) == NULL
) {
1765 if (retcode
== IDMAP_SUCCESS
)
1766 retcode
= IDMAP_ERR_NORESULT
;
1771 idmap_info_mov(info
, &mapping
->info
);
1773 if (direction
!= NULL
)
1774 *direction
= mapping
->direction
;
1776 if (is_wuser
!= NULL
) {
1777 if (mapping
->id2
.idtype
== IDMAP_USID
)
1779 else if (mapping
->id2
.idtype
== IDMAP_GSID
)
1785 if (sidprefix
&& mapping
->id2
.idmap_id_u
.sid
.prefix
&&
1786 *mapping
->id2
.idmap_id_u
.sid
.prefix
!= '\0') {
1787 *sidprefix
= strdup(mapping
->id2
.idmap_id_u
.sid
.prefix
);
1788 if (*sidprefix
== NULL
) {
1789 retcode
= IDMAP_ERR_MEMORY
;
1794 *rid
= mapping
->id2
.idmap_id_u
.sid
.rid
;
1796 rc
= idmap_strdupnull(winname
, mapping
->id2name
);
1797 if (rc
!= IDMAP_SUCCESS
)
1800 rc
= idmap_strdupnull(windomain
, mapping
->id2domain
);
1801 if (rc
!= IDMAP_SUCCESS
)
1807 if (sidprefix
&& *sidprefix
) {
1811 if (winname
&& *winname
) {
1815 if (windomain
&& *windomain
) {
1821 xdr_free(xdr_idmap_mappings_res
, (caddr_t
)&result
);
1822 if (retcode
!= IDMAP_SUCCESS
)
1823 errno
= idmap_stat2errno(retcode
);
1829 #define gettext(s) s
1830 static stat_table_t stattable
[] = {
1831 {IDMAP_SUCCESS
, gettext("Success"), 0},
1832 {IDMAP_NEXT
, gettext("More results available"), 0},
1833 {IDMAP_ERR_OTHER
, gettext("Undefined error"), EINVAL
},
1834 {IDMAP_ERR_INTERNAL
, gettext("Internal error"), EINVAL
},
1835 {IDMAP_ERR_MEMORY
, gettext("Out of memory"), ENOMEM
},
1836 {IDMAP_ERR_NORESULT
, gettext("No results available"), EINVAL
},
1837 {IDMAP_ERR_NOTUSER
, gettext("Not a user"), EINVAL
},
1838 {IDMAP_ERR_NOTGROUP
, gettext("Not a group"), EINVAL
},
1839 {IDMAP_ERR_NOTSUPPORTED
, gettext("Operation not supported"), ENOTSUP
},
1840 {IDMAP_ERR_W2U_NAMERULE
,
1841 gettext("Invalid Windows to UNIX name-based rule"), EINVAL
},
1842 {IDMAP_ERR_U2W_NAMERULE
,
1843 gettext("Invalid UNIX to Windows name-based rule"), EINVAL
},
1844 {IDMAP_ERR_CACHE
, gettext("Invalid cache"), EINVAL
},
1845 {IDMAP_ERR_DB
, gettext("Invalid database"), EINVAL
},
1846 {IDMAP_ERR_ARG
, gettext("Invalid argument"), EINVAL
},
1847 {IDMAP_ERR_SID
, gettext("Invalid SID"), EINVAL
},
1848 {IDMAP_ERR_IDTYPE
, gettext("Invalid identity type"), EINVAL
},
1849 {IDMAP_ERR_RPC_HANDLE
, gettext("Bad RPC handle"), EBADF
},
1850 {IDMAP_ERR_RPC
, gettext("RPC error"), EINVAL
},
1851 {IDMAP_ERR_CLIENT_HANDLE
, gettext("Bad client handle"), EINVAL
},
1852 {IDMAP_ERR_BUSY
, gettext("Server is busy"), EBUSY
},
1853 {IDMAP_ERR_PERMISSION_DENIED
, gettext("Permission denied"), EACCES
},
1854 {IDMAP_ERR_NOMAPPING
,
1855 gettext("Mapping not found or inhibited"), EINVAL
},
1856 {IDMAP_ERR_NEW_ID_ALLOC_REQD
,
1857 gettext("New mapping needs to be created"), EINVAL
},
1858 {IDMAP_ERR_DOMAIN
, gettext("Invalid domain"), EINVAL
},
1859 {IDMAP_ERR_SECURITY
, gettext("Security issue"), EINVAL
},
1860 {IDMAP_ERR_NOTFOUND
, gettext("Not found"), EINVAL
},
1861 {IDMAP_ERR_DOMAIN_NOTFOUND
, gettext("Domain not found"), EINVAL
},
1862 {IDMAP_ERR_UPDATE_NOTALLOWED
, gettext("Update not allowed"), EINVAL
},
1863 {IDMAP_ERR_CFG
, gettext("Configuration error"), EINVAL
},
1864 {IDMAP_ERR_CFG_CHANGE
, gettext("Invalid configuration change"), EINVAL
},
1865 {IDMAP_ERR_NOTMAPPED_WELLKNOWN
,
1866 gettext("No mapping for well-known SID"), EINVAL
},
1867 {IDMAP_ERR_RETRIABLE_NET_ERR
,
1868 gettext("Windows lookup failed"), EINVAL
},
1869 {IDMAP_ERR_W2U_NAMERULE_CONFLICT
,
1870 gettext("Duplicate rule or conflicts with an existing "
1871 "Windows to UNIX name-based rule"), EINVAL
},
1872 {IDMAP_ERR_U2W_NAMERULE_CONFLICT
,
1873 gettext("Duplicate rule or conflicts with an existing "
1874 "Unix to Windows name-based rule"), EINVAL
},
1875 {IDMAP_ERR_BAD_UTF8
,
1876 gettext("Invalid or illegal UTF-8 sequence found in "
1877 "a given Windows entity name or domain name"), EINVAL
},
1878 {IDMAP_ERR_NONE_GENERATED
,
1879 gettext("Mapping not found and none created (see -c option)"),
1881 {IDMAP_ERR_PROP_UNKNOWN
,
1882 gettext("Undefined property"),
1884 {IDMAP_ERR_NS_LDAP_CFG
,
1885 gettext("Native LDAP configuration error"), EINVAL
},
1886 {IDMAP_ERR_NS_LDAP_PARTIAL
,
1887 gettext("Partial result from Native LDAP"), EINVAL
},
1888 {IDMAP_ERR_NS_LDAP_OP_FAILED
,
1889 gettext("Native LDAP operation failed"), EINVAL
},
1890 {IDMAP_ERR_NS_LDAP_BAD_WINNAME
,
1891 gettext("Improper winname form found in Native LDAP"), EINVAL
},
1892 {IDMAP_ERR_NO_ACTIVEDIRECTORY
,
1893 gettext("No AD servers"),
1901 * Get description of status code
1904 * status - Status code returned by libidmap API call
1907 * human-readable localized description of idmap_stat
1910 idmap_stat2string(idmap_stat status
)
1914 for (i
= 0; stattable
[i
].msg
; i
++) {
1915 if (stattable
[i
].retcode
== status
)
1916 return (dgettext(TEXT_DOMAIN
, stattable
[i
].msg
));
1918 return (dgettext(TEXT_DOMAIN
, "Unknown error"));
1923 idmap_stat2errno(idmap_stat stat
)
1926 for (i
= 0; stattable
[i
].msg
; i
++) {
1927 if (stattable
[i
].retcode
== stat
)
1928 return (stattable
[i
].errnum
);
1935 * Get status code from string
1938 idmap_string2stat(const char *str
)
1941 return (IDMAP_ERR_INTERNAL
);
1943 #define return_cmp(a) \
1944 if (0 == strcmp(str, "IDMAP_ERR_" #a)) \
1945 return (IDMAP_ERR_ ## a);
1948 return_cmp(INTERNAL
);
1950 return_cmp(NORESULT
);
1951 return_cmp(NOTUSER
);
1952 return_cmp(NOTGROUP
);
1953 return_cmp(NOTSUPPORTED
);
1954 return_cmp(W2U_NAMERULE
);
1955 return_cmp(U2W_NAMERULE
);
1961 return_cmp(RPC_HANDLE
);
1963 return_cmp(CLIENT_HANDLE
);
1965 return_cmp(PERMISSION_DENIED
);
1966 return_cmp(NOMAPPING
);
1967 return_cmp(NEW_ID_ALLOC_REQD
);
1969 return_cmp(SECURITY
);
1970 return_cmp(NOTFOUND
);
1971 return_cmp(DOMAIN_NOTFOUND
);
1973 return_cmp(UPDATE_NOTALLOWED
);
1975 return_cmp(CFG_CHANGE
);
1976 return_cmp(NOTMAPPED_WELLKNOWN
);
1977 return_cmp(RETRIABLE_NET_ERR
);
1978 return_cmp(W2U_NAMERULE_CONFLICT
);
1979 return_cmp(U2W_NAMERULE_CONFLICT
);
1980 return_cmp(BAD_UTF8
);
1981 return_cmp(NONE_GENERATED
);
1982 return_cmp(PROP_UNKNOWN
);
1983 return_cmp(NS_LDAP_CFG
);
1984 return_cmp(NS_LDAP_PARTIAL
);
1985 return_cmp(NS_LDAP_OP_FAILED
);
1986 return_cmp(NS_LDAP_BAD_WINNAME
);
1987 return_cmp(NO_ACTIVEDIRECTORY
);
1990 return (IDMAP_ERR_OTHER
);
1995 * Map the given status to one that can be returned by the protocol
1998 idmap_stat4prot(idmap_stat status
)
2001 case IDMAP_ERR_MEMORY
:
2002 case IDMAP_ERR_CACHE
:
2003 return (IDMAP_ERR_INTERNAL
);
2010 * This is a convenience routine which duplicates a string after
2011 * checking for NULL pointers. This function will return success if
2012 * either the 'to' OR 'from' pointers are NULL.
2015 idmap_strdupnull(char **to
, const char *from
)
2018 return (IDMAP_SUCCESS
);
2020 if (from
== NULL
|| *from
== '\0') {
2022 return (IDMAP_SUCCESS
);
2027 return (IDMAP_ERR_MEMORY
);
2028 return (IDMAP_SUCCESS
);
2033 idmap_namerule_cpy(idmap_namerule
*to
, idmap_namerule
*from
)
2038 return (IDMAP_SUCCESS
);
2040 (void) memcpy(to
, from
, sizeof (idmap_namerule
));
2041 to
->windomain
= NULL
;
2043 to
->unixname
= NULL
;
2045 retval
= idmap_strdupnull(&to
->windomain
, from
->windomain
);
2046 if (retval
!= IDMAP_SUCCESS
)
2049 retval
= idmap_strdupnull(&to
->winname
, from
->winname
);
2050 if (retval
!= IDMAP_SUCCESS
) {
2051 free(to
->windomain
);
2052 to
->windomain
= NULL
;
2056 retval
= idmap_strdupnull(&to
->unixname
, from
->unixname
);
2057 if (retval
!= IDMAP_SUCCESS
) {
2058 free(to
->windomain
);
2059 to
->windomain
= NULL
;
2070 * Move the contents of the "info" structure from "from" to "to".
2073 idmap_info_mov(idmap_info
*to
, idmap_info
*from
)
2075 (void) memcpy(to
, from
, sizeof (idmap_info
));
2076 (void) memset(from
, 0, sizeof (idmap_info
));
2081 idmap_info_free(idmap_info
*info
)
2086 xdr_free(xdr_idmap_info
, (caddr_t
)info
);
2087 (void) memset(info
, 0, sizeof (idmap_info
));
2092 idmap_how_clear(idmap_how
*how
)
2094 xdr_free(xdr_idmap_how
, (caddr_t
)how
);
2095 (void) memset(how
, 0, sizeof (*how
));
2100 * Get uid given Windows name
2103 idmap_getuidbywinname(const char *name
, const char *domain
, int flag
,
2112 return (IDMAP_ERR_ARG
);
2114 if (flag
& IDMAP_REQ_FLG_USE_CACHE
) {
2115 rc
= idmap_cache_lookup_uidbywinname(name
, domain
, uid
);
2116 if (rc
== IDMAP_SUCCESS
|| rc
== IDMAP_ERR_MEMORY
)
2120 rc
= idmap_get_w2u_mapping(NULL
, NULL
, name
, domain
, flag
,
2121 &is_user
, &is_wuser
, uid
, NULL
, &direction
, NULL
);
2123 if (rc
== IDMAP_SUCCESS
&& (flag
& IDMAP_REQ_FLG_USE_CACHE
)) {
2124 /* If we have not got the domain don't store UID to winname */
2126 direction
= IDMAP_DIRECTION_W2U
;
2127 idmap_cache_add_winname2uid(name
, domain
, *uid
, direction
);
2135 * Get gid given Windows name
2138 idmap_getgidbywinname(const char *name
, const char *domain
, int flag
,
2147 return (IDMAP_ERR_ARG
);
2149 if (flag
& IDMAP_REQ_FLG_USE_CACHE
) {
2150 rc
= idmap_cache_lookup_gidbywinname(name
, domain
, gid
);
2151 if (rc
== IDMAP_SUCCESS
|| rc
== IDMAP_ERR_MEMORY
)
2156 rc
= idmap_get_w2u_mapping(NULL
, NULL
, name
, domain
, flag
,
2157 &is_user
, &is_wuser
, gid
, NULL
, &direction
, NULL
);
2159 if (rc
== IDMAP_SUCCESS
&& (flag
& IDMAP_REQ_FLG_USE_CACHE
)) {
2160 /* If we have not got the domain don't store GID to winname */
2162 direction
= IDMAP_DIRECTION_W2U
;
2163 idmap_cache_add_winname2gid(name
, domain
, *gid
, direction
);
2171 * Get winname given pid
2174 idmap_getwinnamebypid(uid_t pid
, int is_user
, int flag
, char **name
,
2179 char *winname
, *windomain
;
2183 return (IDMAP_ERR_ARG
);
2185 if (flag
& IDMAP_REQ_FLG_USE_CACHE
) {
2187 rc
= idmap_cache_lookup_winnamebyuid(&winname
,
2190 rc
= idmap_cache_lookup_winnamebygid(&winname
,
2192 if (rc
== IDMAP_SUCCESS
)
2194 if (rc
== IDMAP_ERR_MEMORY
)
2199 rc
= idmap_get_u2w_mapping(&pid
, NULL
, flag
, is_user
, NULL
,
2200 NULL
, NULL
, &winname
, &windomain
, &direction
, NULL
);
2202 /* Return on error */
2203 if (rc
!= IDMAP_SUCCESS
)
2207 * The given PID may have been mapped to a locally
2208 * generated SID in which case there isn't any
2211 if (winname
== NULL
) {
2212 idmap_free(windomain
);
2213 return (IDMAP_ERR_NORESULT
);
2216 if (flag
& IDMAP_REQ_FLG_USE_CACHE
) {
2218 idmap_cache_add_winname2uid(winname
, windomain
,
2221 idmap_cache_add_winname2gid(winname
, windomain
,
2226 if (domain
!= NULL
) {
2228 *domain
= windomain
;
2230 char *wd
= windomain
!= NULL
? windomain
: "";
2231 len
= snprintf(NULL
, 0, "%s@%s", winname
, wd
) + 1;
2232 if ((*name
= malloc(len
)) != NULL
)
2233 (void) snprintf(*name
, len
, "%s@%s", winname
, wd
);
2235 rc
= IDMAP_ERR_MEMORY
;
2236 idmap_free(winname
);
2237 idmap_free(windomain
);
2245 * Get winname given uid
2248 idmap_getwinnamebyuid(uid_t uid
, int flag
, char **name
, char **domain
)
2250 return (idmap_getwinnamebypid(uid
, 1, flag
, name
, domain
));
2255 * Get winname given gid
2258 idmap_getwinnamebygid(gid_t gid
, int flag
, char **name
, char **domain
)
2260 return (idmap_getwinnamebypid(gid
, 0, flag
, name
, domain
));
2264 idmap_flush(idmap_flush_op op
)
2266 idmap_retcode rc1
, rc2
;
2268 rc1
= _idmap_clnt_call(IDMAP_FLUSH
,
2269 (xdrproc_t
)xdr_idmap_flush_op
, (caddr_t
)&op
,
2270 (xdrproc_t
)xdr_idmap_retcode
, (caddr_t
)&rc2
, TIMEOUT
);
2272 if (rc1
!= IDMAP_SUCCESS
)
2279 * syslog is the default logger.
2280 * It can be overwritten by supplying a logger
2281 * with idmap_set_logger()
2283 idmap_logger_t logger
= syslog
;
2287 idmap_set_logger(idmap_logger_t funct
)
2293 * Helper functions that concatenate two parts of a name and then
2294 * look up a value, so that the same set of functions can be used to
2295 * process both "in" and "out" parameters.
2299 idmap_trace_get_str(nvlist_t
*entry
, char *n1
, char *n2
, char **ret
)
2301 char name
[IDMAP_TRACE_NAME_MAX
+1]; /* Max used is about 11 */
2304 (void) strlcpy(name
, n1
, sizeof (name
));
2306 (void) strlcat(name
, n2
, sizeof (name
));
2308 err
= nvlist_lookup_string(entry
, name
, ret
);
2314 idmap_trace_get_int(nvlist_t
*entry
, char *n1
, char *n2
, int64_t *ret
)
2316 char name
[IDMAP_TRACE_NAME_MAX
+1]; /* Max used is about 11 */
2319 (void) strlcpy(name
, n1
, sizeof (name
));
2321 (void) strlcat(name
, n2
, sizeof (name
));
2323 err
= nvlist_lookup_int64(entry
, name
, ret
);
2329 idmap_trace_print_id(FILE *out
, nvlist_t
*entry
, char *fromto
)
2334 if (idmap_trace_get_int(entry
, fromto
, IDMAP_TRACE_TYPE
, &i64
)) {
2337 (void) fprintf(out
, "unixname ");
2340 (void) fprintf(out
, "unixuser ");
2343 (void) fprintf(out
, "unixgroup ");
2346 (void) fprintf(out
, "winname ");
2349 (void) fprintf(out
, "winuser ");
2352 (void) fprintf(out
, "wingroup ");
2355 (void) fprintf(out
, gettext("unknown "));
2358 (void) fprintf(out
, gettext("bad %d "), (int)i64
);
2363 if (idmap_trace_get_str(entry
, fromto
, IDMAP_TRACE_NAME
, &s
))
2364 (void) fprintf(out
, "%s ", s
);
2366 if (idmap_trace_get_str(entry
, fromto
, IDMAP_TRACE_SID
, &s
))
2367 (void) fprintf(out
, "%s ", s
);
2369 if (idmap_trace_get_int(entry
, fromto
, IDMAP_TRACE_UNIXID
, &i64
))
2370 (void) fprintf(out
, "%u ", (uid_t
)i64
);
2374 idmap_trace_print_1(FILE *out
, char *prefix
, nvlist_t
*entry
)
2379 (void) fprintf(out
, "%s", prefix
);
2380 idmap_trace_print_id(out
, entry
, "from");
2381 (void) fprintf(out
, "-> ");
2382 idmap_trace_print_id(out
, entry
, "to");
2383 if (idmap_trace_get_int(entry
, IDMAP_TRACE_ERROR
, NULL
, &i64
))
2384 (void) fprintf(out
, gettext("Error %d "), (int)i64
);
2385 (void) fprintf(out
, "-");
2386 if (idmap_trace_get_str(entry
, IDMAP_TRACE_MESSAGE
, NULL
, &s
))
2387 (void) fprintf(out
, " %s", s
);
2388 (void) fprintf(out
, "\n");
2392 idmap_trace_print(FILE *out
, char *prefix
, nvlist_t
*trace
)
2396 for (nvp
= nvlist_next_nvpair(trace
, NULL
);
2398 nvp
= nvlist_next_nvpair(trace
, nvp
)) {
2402 err
= nvpair_value_nvlist(nvp
, &entry
);
2405 idmap_trace_print_1(out
, prefix
, entry
);