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 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Windows to Solaris Identity Mapping kernel API
29 * This module provides an API to map Windows SIDs to
30 * Solaris UID and GIDs.
34 #include <sys/types.h>
35 #include <sys/ksynch.h>
37 #include <rpc/rpc_msg.h>
40 #include <rpc/rpc_sztypes.h>
42 #include <sys/cmn_err.h>
45 #include <sys/sunddi.h>
46 #include <sys/param.h>
47 #include <sys/atomic.h>
48 #include <sys/sysmacros.h>
50 #include <sys/kidmap.h>
52 #include <rpcsvc/idmap_prot.h>
53 #include "kidmap_priv.h"
62 * This structure holds pointers for the
63 * batch mapping results.
65 typedef struct idmap_get_res
{
71 const char **sid_prefix
;
76 /* Batch mapping handle structure */
77 struct idmap_get_handle
{
78 struct idmap_zone_specific
*zs
;
81 idmap_mapping
*mapping
;
82 idmap_get_res
*result
;
86 /* Zone specific data */
87 typedef struct idmap_zone_specific
{
91 door_handle_t door_handle
;
95 } idmap_zone_specific_t
;
103 static kmutex_t idmap_zone_mutex
;
104 static zone_key_t idmap_zone_key
;
108 * Local function definitions
113 kidmap_rpc_call(idmap_zone_specific_t
*zs
, uint32_t op
,
114 xdrproc_t xdr_args
, caddr_t args
,
115 xdrproc_t xdr_res
, caddr_t res
);
118 kidmap_call_door(idmap_zone_specific_t
*zs
, door_arg_t
*arg
);
120 static idmap_zone_specific_t
*
121 idmap_get_zone_specific(zone_t
*zone
);
126 idmap_reg_dh(zone_t
*zone
, door_handle_t dh
)
128 idmap_zone_specific_t
*zs
;
130 zs
= idmap_get_zone_specific(zone
);
132 mutex_enter(&zs
->zone_mutex
);
135 door_ki_rele(zs
->door_handle
);
137 zs
->door_handle
= dh
;
140 mutex_exit(&zs
->zone_mutex
);
148 * This routine is called by system call idmap_unreg().
149 * idmap_unreg() calls door_ki_rele() on the supplied
150 * door handle after this routine returns. We only
151 * need to perform one door release on zs->door_handle
154 idmap_unreg_dh(zone_t
*zone
, door_handle_t dh
)
156 idmap_zone_specific_t
*zs
;
158 zs
= idmap_get_zone_specific(zone
);
160 kidmap_cache_purge(&zs
->cache
);
162 mutex_enter(&zs
->zone_mutex
);
164 if (!zs
->door_valid
|| zs
->door_handle
!= dh
) {
165 mutex_exit(&zs
->zone_mutex
);
169 door_ki_rele(zs
->door_handle
);
172 zs
->door_retried
= 0;
173 mutex_exit(&zs
->zone_mutex
);
180 * IMPORTANT. This function idmap_get_cache_data() is project
181 * private and is for use of the test system only and should
182 * not be used for other purposes.
185 idmap_get_cache_data(zone_t
*zone
, size_t *uidbysid
, size_t *gidbysid
,
186 size_t *pidbysid
, size_t *sidbyuid
, size_t *sidbygid
)
188 idmap_zone_specific_t
*zs
;
190 zs
= idmap_get_zone_specific(zone
);
192 kidmap_cache_get_data(&zs
->cache
, uidbysid
, gidbysid
,
193 pidbysid
, sidbyuid
, sidbygid
);
197 kidmap_call_door(idmap_zone_specific_t
*zs
, door_arg_t
*arg
)
206 mutex_enter(&zs
->zone_mutex
);
207 if (zs
->door_valid
) {
208 dh
= zs
->door_handle
;
212 door_retried
= zs
->door_retried
;
214 mutex_exit(&zs
->zone_mutex
);
217 /* The door has been retried before so dont wait */
222 * There is no door handle yet. Give
223 * smf a chance to restart idmapd
225 if (num_retries
-- > 0) {
231 zcmn_err(zs
->zone_id
, CE_WARN
,
232 "idmap: Error no registered door to call the "
235 mutex_enter(&zs
->zone_mutex
);
237 zs
->door_retried
= 1;
238 mutex_exit(&zs
->zone_mutex
);
243 status
= door_ki_upcall_limited(dh
, arg
, NULL
, SIZE_MAX
, 0);
246 case 0: /* Success */
251 /* If we took an interrupt we have to bail out. */
252 if (ttolwp(curthread
) && ISSIG(curthread
, JUSTLOOKING
)) {
255 zcmn_err(zs
->zone_id
, CE_WARN
,
256 "idmap: Interrupted\n");
261 * Just retry and see what happens.
266 /* A resouce problem */
268 /* Back off before retrying */
270 zcmn_err(zs
->zone_id
, CE_WARN
,
271 "idmap: Door call returned error %d. Retrying\n", status
);
277 /* Stale door handle. See if smf restarts the daemon. */
279 mutex_enter(&zs
->zone_mutex
);
280 if (zs
->door_valid
&& dh
== zs
->door_handle
) {
282 zs
->door_retried
= 0;
283 door_ki_rele(zs
->door_handle
);
285 mutex_exit(&zs
->zone_mutex
);
286 /* Back off before retrying */
288 zcmn_err(zs
->zone_id
, CE_WARN
,
289 "idmap: Door call returned error %d. Retrying\n", status
);
297 zcmn_err(zs
->zone_id
, CE_WARN
,
298 "idmap: Door call returned error %d.\n", status
);
306 static idmap_zone_specific_t
*
307 idmap_get_zone_specific(zone_t
*zone
)
309 idmap_zone_specific_t
*zs
;
311 ASSERT(zone
!= NULL
);
313 zs
= zone_getspecific(idmap_zone_key
, zone
);
317 mutex_enter(&idmap_zone_mutex
);
318 zs
= zone_getspecific(idmap_zone_key
, zone
);
320 zs
= kmem_zalloc(sizeof (idmap_zone_specific_t
), KM_SLEEP
);
321 mutex_init(&zs
->zone_mutex
, NULL
, MUTEX_DEFAULT
, NULL
);
322 kidmap_cache_create(&zs
->cache
);
323 zs
->zone_id
= zone
->zone_id
;
324 (void) zone_setspecific(idmap_zone_key
, zone
, zs
);
325 mutex_exit(&idmap_zone_mutex
);
328 mutex_exit(&idmap_zone_mutex
);
336 idmap_zone_destroy(zoneid_t zone_id
, void *arg
)
338 idmap_zone_specific_t
*zs
= arg
;
340 kidmap_cache_delete(&zs
->cache
);
341 if (zs
->door_valid
) {
342 door_ki_rele(zs
->door_handle
);
344 mutex_destroy(&zs
->zone_mutex
);
345 kmem_free(zs
, sizeof (idmap_zone_specific_t
));
353 mutex_init(&idmap_zone_mutex
, NULL
, MUTEX_DEFAULT
, NULL
);
354 zone_key_create(&idmap_zone_key
, NULL
, NULL
, idmap_zone_destroy
);
355 kidmap_sid_prefix_store_init();
371 * This is called by the system call allocids() to get the door for the
375 idmap_get_door(zone_t
*zone
)
377 door_handle_t dh
= NULL
;
378 idmap_zone_specific_t
*zs
;
380 zs
= idmap_get_zone_specific(zone
);
382 mutex_enter(&zs
->zone_mutex
);
383 if (zs
->door_valid
) {
384 dh
= zs
->door_handle
;
387 mutex_exit(&zs
->zone_mutex
);
395 * This is called by the system call allocids() to purge the cache for the
399 idmap_purge_cache(zone_t
*zone
)
401 idmap_zone_specific_t
*zs
;
403 zs
= idmap_get_zone_specific(zone
);
405 kidmap_cache_purge(&zs
->cache
);
412 * Given Domain SID and RID, get UID
415 * sid_prefix - Domain SID in canonical form
419 * uid - POSIX UID if return == IDMAP_SUCCESS
422 * Success return IDMAP_SUCCESS else IDMAP error
425 kidmap_getuidbysid(zone_t
*zone
, const char *sid_prefix
, uint32_t rid
,
428 idmap_zone_specific_t
*zs
;
429 idmap_mapping_batch args
;
430 idmap_mapping mapping
;
431 idmap_ids_res results
;
432 uint32_t op
= IDMAP_GET_MAPPED_IDS
;
433 const char *new_sid_prefix
;
436 if (sid_prefix
== NULL
|| uid
== NULL
)
437 return (IDMAP_ERR_ARG
);
439 zs
= idmap_get_zone_specific(zone
);
441 if (kidmap_cache_lookup_uidbysid(&zs
->cache
, sid_prefix
, rid
, uid
)
443 return (IDMAP_SUCCESS
);
445 bzero(&mapping
, sizeof (idmap_mapping
));
446 mapping
.id1
.idtype
= IDMAP_SID
;
447 mapping
.id1
.idmap_id_u
.sid
.prefix
= (char *)sid_prefix
;
448 mapping
.id1
.idmap_id_u
.sid
.rid
= rid
;
449 mapping
.id2
.idtype
= IDMAP_UID
;
451 bzero(&results
, sizeof (idmap_ids_res
));
453 args
.idmap_mapping_batch_len
= 1;
454 args
.idmap_mapping_batch_val
= &mapping
;
456 if (kidmap_rpc_call(zs
, op
, xdr_idmap_mapping_batch
,
457 (caddr_t
)&args
, xdr_idmap_ids_res
,
458 (caddr_t
)&results
) == 0) {
459 /* Door call succeded */
460 if (results
.retcode
!= IDMAP_SUCCESS
) {
461 status
= results
.retcode
;
463 } else if (results
.ids
.ids_len
>= 1 &&
464 results
.ids
.ids_val
[0].id
.idtype
== IDMAP_UID
) {
465 status
= results
.ids
.ids_val
[0].retcode
;
466 *uid
= results
.ids
.ids_val
[0].id
.idmap_id_u
.uid
;
467 if (status
== IDMAP_SUCCESS
) {
468 new_sid_prefix
= kidmap_find_sid_prefix(
470 kidmap_cache_add_sid2uid(&zs
->cache
,
471 new_sid_prefix
, rid
, *uid
,
472 results
.ids
.ids_val
[0].direction
);
475 status
= IDMAP_ERR_NOMAPPING
;
478 xdr_free(xdr_idmap_ids_res
, (char *)&results
);
480 /* Door call failed */
481 status
= IDMAP_ERR_NOMAPPING
;
489 * Given Domain SID and RID, get GID
492 * sid_prefix - Domain SID in canonical form
496 * gid - POSIX UID if return == IDMAP_SUCCESS
499 * Success return IDMAP_SUCCESS else IDMAP error
502 kidmap_getgidbysid(zone_t
*zone
, const char *sid_prefix
, uint32_t rid
,
505 idmap_zone_specific_t
*zs
;
506 idmap_mapping_batch args
;
507 idmap_mapping mapping
;
508 idmap_ids_res results
;
509 uint32_t op
= IDMAP_GET_MAPPED_IDS
;
510 const char *new_sid_prefix
;
513 if (sid_prefix
== NULL
|| gid
== NULL
)
514 return (IDMAP_ERR_ARG
);
516 zs
= idmap_get_zone_specific(zone
);
518 if (kidmap_cache_lookup_gidbysid(&zs
->cache
, sid_prefix
, rid
, gid
)
520 return (IDMAP_SUCCESS
);
522 bzero(&mapping
, sizeof (idmap_mapping
));
523 mapping
.id1
.idtype
= IDMAP_SID
;
524 mapping
.id1
.idmap_id_u
.sid
.prefix
= (char *)sid_prefix
;
525 mapping
.id1
.idmap_id_u
.sid
.rid
= rid
;
526 mapping
.id2
.idtype
= IDMAP_GID
;
528 bzero(&results
, sizeof (idmap_ids_res
));
530 args
.idmap_mapping_batch_len
= 1;
531 args
.idmap_mapping_batch_val
= &mapping
;
533 if (kidmap_rpc_call(zs
, op
, xdr_idmap_mapping_batch
,
534 (caddr_t
)&args
, xdr_idmap_ids_res
,
535 (caddr_t
)&results
) == 0) {
536 /* Door call succeded */
537 if (results
.retcode
!= IDMAP_SUCCESS
) {
538 status
= results
.retcode
;
540 } else if (results
.ids
.ids_len
>= 1 &&
541 results
.ids
.ids_val
[0].id
.idtype
== IDMAP_GID
) {
542 status
= results
.ids
.ids_val
[0].retcode
;
543 *gid
= results
.ids
.ids_val
[0].id
.idmap_id_u
.gid
;
544 if (status
== IDMAP_SUCCESS
) {
545 new_sid_prefix
= kidmap_find_sid_prefix(
547 kidmap_cache_add_sid2gid(&zs
->cache
,
548 new_sid_prefix
, rid
, *gid
,
549 results
.ids
.ids_val
[0].direction
);
552 status
= IDMAP_ERR_NOMAPPING
;
555 xdr_free(xdr_idmap_ids_res
, (char *)&results
);
557 /* Door call failed */
558 status
= IDMAP_ERR_NOMAPPING
;
565 * Given Domain SID and RID, get Posix ID
568 * sid_prefix - Domain SID in canonical form
572 * pid - POSIX ID if return == IDMAP_SUCCESS
573 * is_user - 1 == UID, 0 == GID if return == IDMAP_SUCCESS
576 * Success return IDMAP_SUCCESS else IDMAP error
579 kidmap_getpidbysid(zone_t
*zone
, const char *sid_prefix
, uint32_t rid
,
580 uid_t
*pid
, int *is_user
)
582 idmap_zone_specific_t
*zs
;
583 idmap_mapping_batch args
;
584 idmap_mapping mapping
;
585 idmap_ids_res results
;
586 uint32_t op
= IDMAP_GET_MAPPED_IDS
;
587 const char *new_sid_prefix
;
590 if (sid_prefix
== NULL
|| pid
== NULL
|| is_user
== NULL
)
591 return (IDMAP_ERR_ARG
);
593 zs
= idmap_get_zone_specific(zone
);
595 if (kidmap_cache_lookup_pidbysid(&zs
->cache
, sid_prefix
, rid
, pid
,
596 is_user
) == IDMAP_SUCCESS
)
597 return (IDMAP_SUCCESS
);
599 bzero(&mapping
, sizeof (idmap_mapping
));
600 mapping
.id1
.idtype
= IDMAP_SID
;
601 mapping
.id1
.idmap_id_u
.sid
.prefix
= (char *)sid_prefix
;
602 mapping
.id1
.idmap_id_u
.sid
.rid
= rid
;
603 mapping
.id2
.idtype
= IDMAP_POSIXID
;
605 bzero(&results
, sizeof (idmap_ids_res
));
607 args
.idmap_mapping_batch_len
= 1;
608 args
.idmap_mapping_batch_val
= &mapping
;
610 if (kidmap_rpc_call(zs
, op
, xdr_idmap_mapping_batch
,
611 (caddr_t
)&args
, xdr_idmap_ids_res
,
612 (caddr_t
)&results
) == 0) {
613 /* Door call succeded */
614 if (results
.retcode
!= IDMAP_SUCCESS
) {
615 status
= results
.retcode
;
618 } else if (results
.ids
.ids_len
>= 1 && (
619 results
.ids
.ids_val
[0].id
.idtype
== IDMAP_UID
||
620 results
.ids
.ids_val
[0].id
.idtype
== IDMAP_GID
)) {
621 status
= results
.ids
.ids_val
[0].retcode
;
622 if (results
.ids
.ids_val
[0].id
.idtype
== IDMAP_UID
) {
624 *pid
= results
.ids
.ids_val
[0].id
.idmap_id_u
.uid
;
627 *pid
= results
.ids
.ids_val
[0].id
.idmap_id_u
.gid
;
629 if (status
== IDMAP_SUCCESS
) {
630 new_sid_prefix
= kidmap_find_sid_prefix(
632 kidmap_cache_add_sid2pid(&zs
->cache
,
633 new_sid_prefix
, rid
, *pid
,
635 results
.ids
.ids_val
[0].direction
);
638 status
= IDMAP_ERR_NOMAPPING
;
642 xdr_free(xdr_idmap_ids_res
, (char *)&results
);
644 /* Door call failed */
645 status
= IDMAP_ERR_NOMAPPING
;
654 * Given UID, get Domain SID and RID
660 * sid_prefix - Domain SID if return == IDMAP_SUCCESS
661 * rid - RID if return == IDMAP_SUCCESS
664 * Success return IDMAP_SUCCESS else IDMAP error
667 kidmap_getsidbyuid(zone_t
*zone
, uid_t uid
, const char **sid_prefix
,
670 idmap_zone_specific_t
*zs
;
671 idmap_mapping_batch args
;
672 idmap_mapping mapping
;
673 idmap_ids_res results
;
674 uint32_t op
= IDMAP_GET_MAPPED_IDS
;
679 if (sid_prefix
== NULL
|| rid
== NULL
)
680 return (IDMAP_ERR_ARG
);
682 zs
= idmap_get_zone_specific(zone
);
684 if (kidmap_cache_lookup_sidbyuid(&zs
->cache
, sid_prefix
, rid
, uid
)
686 return (IDMAP_SUCCESS
);
689 bzero(&mapping
, sizeof (idmap_mapping
));
690 mapping
.id1
.idtype
= IDMAP_UID
;
691 mapping
.id1
.idmap_id_u
.uid
= uid
;
692 mapping
.id2
.idtype
= IDMAP_SID
;
694 bzero(&results
, sizeof (idmap_ids_res
));
696 args
.idmap_mapping_batch_len
= 1;
697 args
.idmap_mapping_batch_val
= &mapping
;
699 if (kidmap_rpc_call(zs
, op
, xdr_idmap_mapping_batch
,
700 (caddr_t
)&args
, xdr_idmap_ids_res
,
701 (caddr_t
)&results
) == 0) {
702 /* Door call succeded */
703 if (results
.retcode
!= IDMAP_SUCCESS
) {
704 status
= results
.retcode
;
707 } else if (results
.ids
.ids_len
>= 1 &&
708 (results
.ids
.ids_val
[0].id
.idtype
== IDMAP_SID
||
709 results
.ids
.ids_val
[0].id
.idtype
== IDMAP_USID
||
710 results
.ids
.ids_val
[0].id
.idtype
== IDMAP_GSID
)) {
711 status
= results
.ids
.ids_val
[0].retcode
;
712 id
= &results
.ids
.ids_val
[0].id
;
713 *sid_prefix
= kidmap_find_sid_prefix(
714 id
->idmap_id_u
.sid
.prefix
);
715 *rid
= id
->idmap_id_u
.sid
.rid
;
716 if (status
== IDMAP_SUCCESS
) {
717 kidmap_cache_add_sid2uid(&zs
->cache
,
718 *sid_prefix
, *rid
, uid
,
719 results
.ids
.ids_val
[0].direction
);
722 status
= IDMAP_ERR_NOMAPPING
;
726 xdr_free(xdr_idmap_ids_res
, (char *)&results
);
728 /* Door call failed */
729 status
= IDMAP_ERR_NOMAPPING
;
738 * Given GID, get Domain SID and RID
744 * sid_prefix - Domain SID if return == IDMAP_SUCCESS
745 * rid - RID if return == IDMAP_SUCCESS
748 * Success return IDMAP_SUCCESS else IDMAP error
751 kidmap_getsidbygid(zone_t
*zone
, gid_t gid
, const char **sid_prefix
,
754 idmap_zone_specific_t
*zs
;
755 idmap_mapping_batch args
;
756 idmap_mapping mapping
;
757 idmap_ids_res results
;
758 uint32_t op
= IDMAP_GET_MAPPED_IDS
;
762 if (sid_prefix
== NULL
|| rid
== NULL
)
763 return (IDMAP_ERR_ARG
);
765 zs
= idmap_get_zone_specific(zone
);
767 if (kidmap_cache_lookup_sidbygid(&zs
->cache
, sid_prefix
, rid
, gid
)
769 return (IDMAP_SUCCESS
);
772 bzero(&mapping
, sizeof (idmap_mapping
));
773 mapping
.id1
.idtype
= IDMAP_GID
;
774 mapping
.id1
.idmap_id_u
.uid
= gid
;
775 mapping
.id2
.idtype
= IDMAP_SID
;
777 bzero(&results
, sizeof (idmap_ids_res
));
779 args
.idmap_mapping_batch_len
= 1;
780 args
.idmap_mapping_batch_val
= &mapping
;
782 if (kidmap_rpc_call(zs
, op
, xdr_idmap_mapping_batch
,
783 (caddr_t
)&args
, xdr_idmap_ids_res
,
784 (caddr_t
)&results
) == 0) {
785 /* Door call succeded */
786 if (results
.retcode
!= IDMAP_SUCCESS
) {
787 status
= results
.retcode
;
790 } else if (results
.ids
.ids_len
>= 1 &&
791 (results
.ids
.ids_val
[0].id
.idtype
== IDMAP_SID
||
792 results
.ids
.ids_val
[0].id
.idtype
== IDMAP_USID
||
793 results
.ids
.ids_val
[0].id
.idtype
== IDMAP_GSID
)) {
794 status
= results
.ids
.ids_val
[0].retcode
;
795 id
= &results
.ids
.ids_val
[0].id
;
796 *sid_prefix
= kidmap_find_sid_prefix(
797 id
->idmap_id_u
.sid
.prefix
);
798 *rid
= id
->idmap_id_u
.sid
.rid
;
799 if (status
== IDMAP_SUCCESS
) {
800 kidmap_cache_add_sid2gid(&zs
->cache
,
801 *sid_prefix
, *rid
, gid
,
802 results
.ids
.ids_val
[0].direction
);
805 status
= IDMAP_ERR_NOMAPPING
;
809 xdr_free(xdr_idmap_ids_res
, (char *)&results
);
811 /* Door call failed */
812 status
= IDMAP_ERR_NOMAPPING
;
820 * Create handle to get SID to UID/GID mapping entries
829 kidmap_get_create(zone_t
*zone
)
831 idmap_zone_specific_t
*zs
;
832 idmap_get_handle_t
*handle
;
833 #define INIT_MAPPING_SIZE 32
835 zs
= idmap_get_zone_specific(zone
);
837 handle
= kmem_zalloc(sizeof (idmap_get_handle_t
), KM_SLEEP
);
839 handle
->mapping
= kmem_zalloc((sizeof (idmap_mapping
)) *
840 INIT_MAPPING_SIZE
, KM_SLEEP
);
842 handle
->result
= kmem_zalloc((sizeof (idmap_get_res
)) *
843 INIT_MAPPING_SIZE
, KM_SLEEP
);
844 handle
->mapping_size
= INIT_MAPPING_SIZE
;
851 * Internal routine to extend a "get_handle"
854 kidmap_get_extend(idmap_get_handle_t
*get_handle
)
856 idmap_mapping
*mapping
;
857 idmap_get_res
*result
;
858 int new_size
= get_handle
->mapping_size
+ INIT_MAPPING_SIZE
;
860 mapping
= kmem_zalloc((sizeof (idmap_mapping
)) *
862 (void) memcpy(mapping
, get_handle
->mapping
,
863 (sizeof (idmap_mapping
)) * get_handle
->mapping_size
);
865 result
= kmem_zalloc((sizeof (idmap_get_res
)) *
867 (void) memcpy(result
, get_handle
->result
,
868 (sizeof (idmap_get_res
)) * get_handle
->mapping_size
);
870 kmem_free(get_handle
->mapping
,
871 (sizeof (idmap_mapping
)) * get_handle
->mapping_size
);
872 get_handle
->mapping
= mapping
;
874 kmem_free(get_handle
->result
,
875 (sizeof (idmap_get_res
)) * get_handle
->mapping_size
);
876 get_handle
->result
= result
;
878 get_handle
->mapping_size
= new_size
;
883 * Given Domain SID and RID, get UID
886 * sid_prefix - Domain SID in canonical form
890 * stat - status of the get request
891 * uid - POSIX UID if stat == IDMAP_SUCCESS
894 * The output parameters will be set by idmap_get_mappings()
895 * The sid_prefix is copied.
898 kidmap_batch_getuidbysid(idmap_get_handle_t
*get_handle
, const char *sid_prefix
,
899 uint32_t rid
, uid_t
*uid
, idmap_stat
*stat
)
901 idmap_mapping
*mapping
;
902 idmap_get_res
*result
;
904 if (get_handle
== NULL
|| sid_prefix
== NULL
||
905 uid
== NULL
|| stat
== NULL
)
906 return (IDMAP_ERR_ARG
);
908 if (kidmap_cache_lookup_uidbysid(&get_handle
->zs
->cache
, sid_prefix
,
909 rid
, uid
) == IDMAP_SUCCESS
) {
910 *stat
= IDMAP_SUCCESS
;
911 return (IDMAP_SUCCESS
);
914 /* Get a copy of sid_prefix */
915 sid_prefix
= kidmap_find_sid_prefix(sid_prefix
);
917 if (get_handle
->mapping_num
>= get_handle
->mapping_size
)
918 kidmap_get_extend(get_handle
);
920 mapping
= &get_handle
->mapping
[get_handle
->mapping_num
];
922 mapping
->id1
.idtype
= IDMAP_SID
;
923 mapping
->id1
.idmap_id_u
.sid
.prefix
= (char *)sid_prefix
;
924 mapping
->id1
.idmap_id_u
.sid
.rid
= rid
;
925 mapping
->id2
.idtype
= IDMAP_UID
;
927 result
= &get_handle
->result
[get_handle
->mapping_num
];
928 result
->idtype
= IDMAP_UID
;
932 result
->sid_prefix
= NULL
;
934 result
->is_user
= NULL
;
937 get_handle
->mapping_num
++;
939 return (IDMAP_SUCCESS
);
944 * Given Domain SID and RID, get GID
947 * sid_prefix - Domain SID in canonical form
951 * stat - status of the get request
952 * gid - POSIX GID if stat == IDMAP_SUCCESS
955 * The output parameters will be set by idmap_get_mappings()
956 * The sid_prefix is copied.
959 kidmap_batch_getgidbysid(idmap_get_handle_t
*get_handle
, const char *sid_prefix
,
960 uint32_t rid
, uid_t
*gid
, idmap_stat
*stat
)
962 idmap_mapping
*mapping
;
963 idmap_get_res
*result
;
965 if (get_handle
== NULL
|| sid_prefix
== NULL
||
966 gid
== NULL
|| stat
== NULL
)
967 return (IDMAP_ERR_ARG
);
969 if (kidmap_cache_lookup_gidbysid(&get_handle
->zs
->cache
, sid_prefix
,
970 rid
, gid
) == IDMAP_SUCCESS
) {
971 *stat
= IDMAP_SUCCESS
;
972 return (IDMAP_SUCCESS
);
975 /* Get a copy of sid_prefix */
976 sid_prefix
= kidmap_find_sid_prefix(sid_prefix
);
978 if (get_handle
->mapping_num
>= get_handle
->mapping_size
)
979 kidmap_get_extend(get_handle
);
981 mapping
= &get_handle
->mapping
[get_handle
->mapping_num
];
983 mapping
->id1
.idtype
= IDMAP_SID
;
984 mapping
->id1
.idmap_id_u
.sid
.prefix
= (char *)sid_prefix
;
985 mapping
->id1
.idmap_id_u
.sid
.rid
= rid
;
986 mapping
->id2
.idtype
= IDMAP_GID
;
988 result
= &get_handle
->result
[get_handle
->mapping_num
];
989 result
->idtype
= IDMAP_GID
;
993 result
->sid_prefix
= NULL
;
995 result
->is_user
= NULL
;
998 get_handle
->mapping_num
++;
1000 return (IDMAP_SUCCESS
);
1005 * Given Domain SID and RID, get Posix ID
1008 * sid_prefix - Domain SID in canonical form
1012 * stat - status of the get request
1013 * is_user - user or group
1014 * pid - POSIX UID if stat == IDMAP_SUCCESS and is_user == 1
1015 * POSIX GID if stat == IDMAP_SUCCESS and is_user == 0
1018 * The output parameters will be set by idmap_get_mappings()
1019 * The sid_prefix is copied.
1022 kidmap_batch_getpidbysid(idmap_get_handle_t
*get_handle
, const char *sid_prefix
,
1023 uint32_t rid
, uid_t
*pid
, int *is_user
, idmap_stat
*stat
)
1025 idmap_mapping
*mapping
;
1026 idmap_get_res
*result
;
1028 if (get_handle
== NULL
|| sid_prefix
== NULL
|| pid
== NULL
||
1029 is_user
== NULL
|| stat
== NULL
)
1030 return (IDMAP_ERR_ARG
);
1032 if (kidmap_cache_lookup_pidbysid(&get_handle
->zs
->cache
, sid_prefix
,
1033 rid
, pid
, is_user
) == IDMAP_SUCCESS
) {
1034 *stat
= IDMAP_SUCCESS
;
1035 return (IDMAP_SUCCESS
);
1038 /* Get a copy of sid_prefix */
1039 sid_prefix
= kidmap_find_sid_prefix(sid_prefix
);
1041 if (get_handle
->mapping_num
>= get_handle
->mapping_size
)
1042 kidmap_get_extend(get_handle
);
1044 mapping
= &get_handle
->mapping
[get_handle
->mapping_num
];
1046 mapping
->id1
.idtype
= IDMAP_SID
;
1047 mapping
->id1
.idmap_id_u
.sid
.prefix
= (char *)sid_prefix
;
1048 mapping
->id1
.idmap_id_u
.sid
.rid
= rid
;
1049 mapping
->id2
.idtype
= IDMAP_POSIXID
;
1051 result
= &get_handle
->result
[get_handle
->mapping_num
];
1052 result
->idtype
= IDMAP_POSIXID
;
1056 result
->sid_prefix
= NULL
;
1058 result
->is_user
= is_user
;
1059 result
->stat
= stat
;
1061 get_handle
->mapping_num
++;
1063 return (IDMAP_SUCCESS
);
1068 * Given UID, get SID and RID
1074 * stat - status of the get request
1075 * sid - SID in canonical form (if stat == IDMAP_SUCCESS)
1076 * rid - RID (if stat == IDMAP_SUCCESS)
1078 * Note: The output parameters will be set by idmap_get_mappings()
1081 kidmap_batch_getsidbyuid(idmap_get_handle_t
*get_handle
, uid_t uid
,
1082 const char **sid_prefix
, uint32_t *rid
, idmap_stat
*stat
)
1084 idmap_mapping
*mapping
;
1085 idmap_get_res
*result
;
1087 if (get_handle
== NULL
|| sid_prefix
== NULL
||
1088 rid
== NULL
|| stat
== NULL
)
1089 return (IDMAP_ERR_ARG
);
1091 if (kidmap_cache_lookup_sidbyuid(&get_handle
->zs
->cache
,
1092 sid_prefix
, rid
, uid
) == IDMAP_SUCCESS
) {
1093 *stat
= IDMAP_SUCCESS
;
1094 return (IDMAP_SUCCESS
);
1097 if (get_handle
->mapping_num
>= get_handle
->mapping_size
)
1098 kidmap_get_extend(get_handle
);
1100 mapping
= &get_handle
->mapping
[get_handle
->mapping_num
];
1102 mapping
->id1
.idtype
= IDMAP_UID
;
1103 mapping
->id1
.idmap_id_u
.uid
= uid
;
1104 mapping
->id2
.idtype
= IDMAP_SID
;
1106 result
= &get_handle
->result
[get_handle
->mapping_num
];
1107 result
->idtype
= IDMAP_SID
;
1111 result
->sid_prefix
= sid_prefix
;
1113 result
->is_user
= NULL
;
1114 result
->stat
= stat
;
1116 get_handle
->mapping_num
++;
1118 return (IDMAP_SUCCESS
);
1123 * Given GID, get SID and RID
1129 * stat - status of the get request
1130 * sid - SID in canonical form (if stat == IDMAP_SUCCESS)
1131 * rid - RID (if stat == IDMAP_SUCCESS)
1133 * Note: The output parameters will be set by idmap_get_mappings()
1136 kidmap_batch_getsidbygid(idmap_get_handle_t
*get_handle
, gid_t gid
,
1137 const char **sid_prefix
, uint32_t *rid
, idmap_stat
*stat
)
1139 idmap_mapping
*mapping
;
1140 idmap_get_res
*result
;
1142 if (get_handle
== NULL
|| sid_prefix
== NULL
||
1143 rid
== NULL
|| stat
== NULL
)
1144 return (IDMAP_ERR_ARG
);
1146 if (kidmap_cache_lookup_sidbygid(&get_handle
->zs
->cache
,
1147 sid_prefix
, rid
, gid
) == IDMAP_SUCCESS
) {
1148 *stat
= IDMAP_SUCCESS
;
1149 return (IDMAP_SUCCESS
);
1152 if (get_handle
->mapping_num
>= get_handle
->mapping_size
)
1153 kidmap_get_extend(get_handle
);
1155 mapping
= &get_handle
->mapping
[get_handle
->mapping_num
];
1157 mapping
->id1
.idtype
= IDMAP_GID
;
1158 mapping
->id1
.idmap_id_u
.gid
= gid
;
1159 mapping
->id2
.idtype
= IDMAP_SID
;
1161 result
= &get_handle
->result
[get_handle
->mapping_num
];
1162 result
->idtype
= IDMAP_SID
;
1166 result
->sid_prefix
= sid_prefix
;
1168 result
->is_user
= NULL
;
1169 result
->stat
= stat
;
1171 get_handle
->mapping_num
++;
1173 return (IDMAP_SUCCESS
);
1178 * Process the batched "get mapping" requests. The results (i.e.
1179 * status and identity) will be available in the data areas
1180 * provided by individual requests.
1182 * If the door call fails the status IDMAP_ERR_NOMAPPING is
1183 * return and the UID or UID result is set to "nobody"
1187 kidmap_get_mappings(idmap_get_handle_t
*get_handle
)
1189 idmap_mapping_batch rpc_args
;
1190 idmap_ids_res rpc_res
;
1191 uint32_t op
= IDMAP_GET_MAPPED_IDS
;
1192 idmap_mapping
*request
;
1193 idmap_get_res
*result
;
1197 const char *sid_prefix
;
1199 idmap_cache_t
*cache
;
1202 if (get_handle
== NULL
)
1203 return (IDMAP_ERR_ARG
);
1205 if (get_handle
->mapping_num
== 0)
1206 return (IDMAP_SUCCESS
);
1207 cache
= &get_handle
->zs
->cache
;
1209 bzero(&rpc_res
, sizeof (idmap_ids_res
));
1211 rpc_args
.idmap_mapping_batch_len
= get_handle
->mapping_num
;
1212 rpc_args
.idmap_mapping_batch_val
= get_handle
->mapping
;
1214 if (kidmap_rpc_call(get_handle
->zs
, op
, xdr_idmap_mapping_batch
,
1215 (caddr_t
)&rpc_args
, xdr_idmap_ids_res
,
1216 (caddr_t
)&rpc_res
) != 0) {
1217 /* Door call failed */
1218 status
= IDMAP_ERR_NOMAPPING
;
1222 status
= rpc_res
.retcode
;
1223 if (status
!= IDMAP_SUCCESS
) {
1224 /* RPC returned idmap error code */
1225 xdr_free(xdr_idmap_ids_res
, (char *)&rpc_res
);
1229 for (i
= 0; i
< get_handle
->mapping_num
; i
++) {
1230 request
= &get_handle
->mapping
[i
];
1231 result
= &get_handle
->result
[i
];
1233 if (i
>= rpc_res
.ids
.ids_len
) {
1234 *result
->stat
= IDMAP_ERR_NOMAPPING
;
1236 *result
->uid
= UID_NOBODY
;
1238 *result
->gid
= GID_NOBODY
;
1240 *result
->pid
= UID_NOBODY
;
1241 if (result
->is_user
)
1242 *result
->is_user
= 1;
1243 if (result
->sid_prefix
)
1244 *result
->sid_prefix
= NULL
;
1250 *result
->stat
= rpc_res
.ids
.ids_val
[i
].retcode
;
1252 id
= &rpc_res
.ids
.ids_val
[i
].id
;
1253 direction
= rpc_res
.ids
.ids_val
[i
].direction
;
1255 switch (id
->idtype
) {
1258 *result
->uid
= id
->idmap_id_u
.uid
;
1260 *result
->pid
= id
->idmap_id_u
.uid
;
1261 if (result
->is_user
)
1262 *result
->is_user
= 1;
1263 sid_prefix
= kidmap_find_sid_prefix(
1264 request
->id1
.idmap_id_u
.sid
.prefix
);
1265 if (*result
->stat
== IDMAP_SUCCESS
&& result
->uid
)
1266 kidmap_cache_add_sid2uid(
1268 request
->id1
.idmap_id_u
.sid
.rid
,
1271 else if (*result
->stat
== IDMAP_SUCCESS
&& result
->pid
)
1272 kidmap_cache_add_sid2pid(
1274 request
->id1
.idmap_id_u
.sid
.rid
,
1275 id
->idmap_id_u
.uid
, 1,
1281 *result
->gid
= id
->idmap_id_u
.gid
;
1283 *result
->pid
= id
->idmap_id_u
.gid
;
1284 if (result
->is_user
)
1285 *result
->is_user
= 0;
1286 sid_prefix
= kidmap_find_sid_prefix(
1287 request
->id1
.idmap_id_u
.sid
.prefix
);
1288 if (*result
->stat
== IDMAP_SUCCESS
&& result
->gid
)
1289 kidmap_cache_add_sid2gid(
1291 request
->id1
.idmap_id_u
.sid
.rid
,
1294 else if (*result
->stat
== IDMAP_SUCCESS
&& result
->pid
)
1295 kidmap_cache_add_sid2pid(
1297 request
->id1
.idmap_id_u
.sid
.rid
,
1298 id
->idmap_id_u
.gid
, 0,
1305 sid_prefix
= kidmap_find_sid_prefix(
1306 id
->idmap_id_u
.sid
.prefix
);
1307 if (result
->sid_prefix
&& result
->rid
) {
1308 *result
->sid_prefix
= sid_prefix
;
1309 *result
->rid
= id
->idmap_id_u
.sid
.rid
;
1311 if (*result
->stat
== IDMAP_SUCCESS
&&
1312 request
->id1
.idtype
== IDMAP_UID
)
1313 kidmap_cache_add_sid2uid(
1315 id
->idmap_id_u
.sid
.rid
,
1316 request
->id1
.idmap_id_u
.uid
,
1318 else if (*result
->stat
== IDMAP_SUCCESS
&&
1319 request
->id1
.idtype
== IDMAP_GID
)
1320 kidmap_cache_add_sid2gid(
1322 id
->idmap_id_u
.sid
.rid
,
1323 request
->id1
.idmap_id_u
.gid
,
1328 *result
->stat
= IDMAP_ERR_NORESULT
;
1330 *result
->uid
= UID_NOBODY
;
1332 *result
->gid
= GID_NOBODY
;
1334 *result
->pid
= UID_NOBODY
;
1335 if (result
->is_user
)
1336 *result
->is_user
= 1;
1337 if (result
->sid_prefix
)
1338 *result
->sid_prefix
= NULL
;
1344 xdr_free(xdr_idmap_ids_res
, (char *)&rpc_res
);
1346 /* Reset get_handle for new resquests */
1347 get_handle
->mapping_num
= 0;
1351 for (i
= 0; i
< get_handle
->mapping_num
; i
++) {
1352 result
= &get_handle
->result
[i
];
1354 *result
->stat
= status
;
1356 *result
->uid
= UID_NOBODY
;
1358 *result
->gid
= GID_NOBODY
;
1360 *result
->pid
= UID_NOBODY
;
1361 if (result
->is_user
)
1362 *result
->is_user
= 1;
1363 if (result
->sid_prefix
)
1364 *result
->sid_prefix
= NULL
;
1369 /* Reset get_handle for new resquests */
1370 get_handle
->mapping_num
= 0;
1376 * Destroy the "get mapping" handle
1379 kidmap_get_destroy(idmap_get_handle_t
*get_handle
)
1381 if (get_handle
== NULL
)
1384 kmem_free(get_handle
->mapping
,
1385 (sizeof (idmap_mapping
)) * get_handle
->mapping_size
);
1386 get_handle
->mapping
= NULL
;
1388 kmem_free(get_handle
->result
,
1389 (sizeof (idmap_get_res
)) * get_handle
->mapping_size
);
1390 get_handle
->result
= NULL
;
1392 kmem_free(get_handle
, sizeof (idmap_get_handle_t
));
1397 kidmap_rpc_call(idmap_zone_specific_t
*zs
, uint32_t op
, xdrproc_t xdr_args
,
1398 caddr_t args
, xdrproc_t xdr_res
, caddr_t res
)
1401 struct rpc_msg reply_msg
;
1402 char *inbuf_ptr
= NULL
;
1403 size_t inbuf_size
= 4096;
1404 char *outbuf_ptr
= NULL
;
1405 size_t outbuf_size
= 4096;
1410 struct rpc_msg call_msg
;
1416 inbuf_ptr
= kmem_alloc(inbuf_size
, KM_SLEEP
);
1417 outbuf_ptr
= kmem_alloc(outbuf_size
, KM_SLEEP
);
1419 xdrmem_create(&xdr_ctx
, inbuf_ptr
, inbuf_size
, XDR_ENCODE
);
1421 call_msg
.rm_call
.cb_prog
= IDMAP_PROG
;
1422 call_msg
.rm_call
.cb_vers
= IDMAP_V1
;
1423 call_msg
.rm_xid
= atomic_inc_32_nv(&zs
->message_id
);
1425 if (!xdr_callhdr(&xdr_ctx
, &call_msg
)) {
1427 zcmn_err(zs
->zone_id
, CE_WARN
,
1428 "idmap: xdr encoding header error");
1434 if (!xdr_uint32(&xdr_ctx
, &op
) ||
1436 !xdr_opaque_auth(&xdr_ctx
, &_null_auth
) ||
1437 !xdr_opaque_auth(&xdr_ctx
, &_null_auth
) ||
1439 !xdr_args(&xdr_ctx
, args
)) {
1441 zcmn_err(zs
->zone_id
, CE_WARN
, "idmap: xdr encoding error");
1449 kmem_free(inbuf_ptr
, inbuf_size
);
1453 kmem_free(outbuf_ptr
, outbuf_size
);
1456 if ((size
= xdr_sizeof(xdr_args
, args
)) == 0) {
1458 zcmn_err(zs
->zone_id
, CE_WARN
,
1459 "idmap: xdr_sizeof error");
1464 inbuf_size
= size
+ 1024;
1465 outbuf_size
= size
+ 1024;
1469 params
.data_ptr
= inbuf_ptr
;
1470 params
.data_size
= XDR_GETPOS(&xdr_ctx
);
1471 params
.desc_ptr
= NULL
;
1472 params
.desc_num
= 0;
1473 params
.rbuf
= outbuf_ptr
;
1474 params
.rsize
= outbuf_size
;
1476 if (kidmap_call_door(zs
, ¶ms
) != 0) {
1481 reply_msg
.acpted_rply
.ar_verf
= _null_auth
;
1482 reply_msg
.acpted_rply
.ar_results
.where
= res
;
1483 reply_msg
.acpted_rply
.ar_results
.proc
= xdr_res
;
1484 xdrmem_create(&xdr_ctx
, params
.data_ptr
, params
.data_size
, XDR_DECODE
);
1485 if (xdr_replymsg(&xdr_ctx
, &reply_msg
)) {
1486 if (reply_msg
.rm_reply
.rp_stat
!= MSG_ACCEPTED
||
1487 reply_msg
.rm_reply
.rp_acpt
.ar_stat
!= SUCCESS
) {
1493 zcmn_err(zs
->zone_id
, CE_WARN
,
1494 "idmap: xdr decoding reply message error");
1500 if (outbuf_ptr
!= params
.rbuf
&& params
.rbuf
!= NULL
)
1501 kmem_free(params
.rbuf
, params
.rsize
);
1503 kmem_free(inbuf_ptr
, inbuf_size
);
1505 kmem_free(outbuf_ptr
, outbuf_size
);