xref: /titanic_50/usr/src/uts/common/idmap/idmap_kapi.c (revision dea83360607af241eb793e94f19278029f3a8a97)
1c5c4113dSnw141292 /*
2c5c4113dSnw141292  * CDDL HEADER START
3c5c4113dSnw141292  *
4c5c4113dSnw141292  * The contents of this file are subject to the terms of the
5c5c4113dSnw141292  * Common Development and Distribution License (the "License").
6c5c4113dSnw141292  * You may not use this file except in compliance with the License.
7c5c4113dSnw141292  *
8c5c4113dSnw141292  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9c5c4113dSnw141292  * or http://www.opensolaris.org/os/licensing.
10c5c4113dSnw141292  * See the License for the specific language governing permissions
11c5c4113dSnw141292  * and limitations under the License.
12c5c4113dSnw141292  *
13c5c4113dSnw141292  * When distributing Covered Code, include this CDDL HEADER in each
14c5c4113dSnw141292  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15c5c4113dSnw141292  * If applicable, add the following below this CDDL HEADER, with the
16c5c4113dSnw141292  * fields enclosed by brackets "[]" replaced with your own identifying
17c5c4113dSnw141292  * information: Portions Copyright [yyyy] [name of copyright owner]
18c5c4113dSnw141292  *
19c5c4113dSnw141292  * CDDL HEADER END
20c5c4113dSnw141292  */
21c5c4113dSnw141292 
22c5c4113dSnw141292 /*
239b214d32SJordan Brown  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24c5c4113dSnw141292  * Use is subject to license terms.
25c5c4113dSnw141292  */
26c5c4113dSnw141292 
27c5c4113dSnw141292 /*
28c5c4113dSnw141292  * Windows to Solaris Identity Mapping kernel API
29c5c4113dSnw141292  * This module provides an API to map Windows SIDs to
30c5c4113dSnw141292  * Solaris UID and GIDs.
31c5c4113dSnw141292  */
32c5c4113dSnw141292 
33c5c4113dSnw141292 
34c5c4113dSnw141292 #include <sys/types.h>
35c5c4113dSnw141292 #include <sys/ksynch.h>
36c5c4113dSnw141292 #include <sys/door.h>
37c5c4113dSnw141292 #include <rpc/rpc_msg.h>
38c5c4113dSnw141292 #include <rpc/xdr.h>
39c5c4113dSnw141292 #include <rpc/auth.h>
40c5c4113dSnw141292 #include <rpc/rpc_sztypes.h>
41c5c4113dSnw141292 #ifdef	DEBUG
42c5c4113dSnw141292 #include <sys/cmn_err.h>
43c5c4113dSnw141292 #endif	/* DEBUG */
44c5c4113dSnw141292 #include <sys/proc.h>
45c5c4113dSnw141292 #include <sys/sunddi.h>
46c5c4113dSnw141292 #include <sys/param.h>
47c5c4113dSnw141292 #include <sys/atomic.h>
48c5c4113dSnw141292 #include <sys/sysmacros.h>
49c5c4113dSnw141292 #include <sys/disp.h>
50c5c4113dSnw141292 #include <sys/kidmap.h>
51bda89588Sjp151216 #include <sys/zone.h>
529b214d32SJordan Brown #include <rpcsvc/idmap_prot.h>
53c5c4113dSnw141292 #include "kidmap_priv.h"
54c5c4113dSnw141292 
55c5c4113dSnw141292 
56bda89588Sjp151216 /*
57bda89588Sjp151216  * Defined types
58bda89588Sjp151216  */
59bda89588Sjp151216 
60c5c4113dSnw141292 
61c5c4113dSnw141292 /*
62bda89588Sjp151216  * This structure holds pointers for the
63bda89588Sjp151216  * batch mapping results.
64c5c4113dSnw141292  */
65c5c4113dSnw141292 typedef struct idmap_get_res {
66c5c4113dSnw141292 	idmap_id_type	idtype;
67c5c4113dSnw141292 	uid_t		*uid;
68c5c4113dSnw141292 	gid_t		*gid;
690b10de9fSjp151216 	uid_t		*pid;
70c5c4113dSnw141292 	int		*is_user;
71c5c4113dSnw141292 	const char	**sid_prefix;
72c5c4113dSnw141292 	uint32_t	*rid;
73c5c4113dSnw141292 	idmap_stat	*stat;
74c5c4113dSnw141292 } idmap_get_res;
75c5c4113dSnw141292 
76c5c4113dSnw141292 /* Batch mapping handle structure */
77c5c4113dSnw141292 struct idmap_get_handle {
78bda89588Sjp151216 	struct idmap_zone_specific *zs;
79c5c4113dSnw141292 	int 		mapping_num;
80c5c4113dSnw141292 	int 		mapping_size;
81c5c4113dSnw141292 	idmap_mapping	*mapping;
82c5c4113dSnw141292 	idmap_get_res	*result;
83c5c4113dSnw141292 };
84c5c4113dSnw141292 
85c5c4113dSnw141292 
86bda89588Sjp151216 /* Zone specific data */
87bda89588Sjp151216 typedef struct idmap_zone_specific {
88f7b4b2feSjp151216 	zoneid_t	zone_id;
89bda89588Sjp151216 	kmutex_t	zone_mutex;
90bda89588Sjp151216 	idmap_cache_t	cache;
91bda89588Sjp151216 	door_handle_t 	door_handle;
92bda89588Sjp151216 	int		door_valid;
938d059b82SJulian Pullen 	int		door_retried;
94bda89588Sjp151216 	uint32_t	message_id;
95bda89588Sjp151216 } idmap_zone_specific_t;
96c5c4113dSnw141292 
97bda89588Sjp151216 
98bda89588Sjp151216 
99bda89588Sjp151216 /*
100bda89588Sjp151216  * Module global data
101bda89588Sjp151216  */
102bda89588Sjp151216 
103bda89588Sjp151216 static kmutex_t		idmap_zone_mutex;
104bda89588Sjp151216 static zone_key_t	idmap_zone_key;
105bda89588Sjp151216 
106bda89588Sjp151216 
107bda89588Sjp151216 /*
108bda89588Sjp151216  * Local function definitions
109bda89588Sjp151216  */
110c5c4113dSnw141292 
111c5c4113dSnw141292 
112c5c4113dSnw141292 static int
113bda89588Sjp151216 kidmap_rpc_call(idmap_zone_specific_t *zs, uint32_t op,
114bda89588Sjp151216 		xdrproc_t xdr_args, caddr_t args,
115c5c4113dSnw141292 		xdrproc_t xdr_res, caddr_t res);
116c5c4113dSnw141292 
117bda89588Sjp151216 static int
118bda89588Sjp151216 kidmap_call_door(idmap_zone_specific_t *zs, door_arg_t *arg);
119c5c4113dSnw141292 
120bda89588Sjp151216 static idmap_zone_specific_t *
121bda89588Sjp151216 idmap_get_zone_specific(zone_t *zone);
122c5c4113dSnw141292 
123c5c4113dSnw141292 
124c5c4113dSnw141292 
125c5c4113dSnw141292 int
idmap_reg_dh(zone_t * zone,door_handle_t dh)126bda89588Sjp151216 idmap_reg_dh(zone_t *zone, door_handle_t dh)
127c5c4113dSnw141292 {
128bda89588Sjp151216 	idmap_zone_specific_t *zs;
129c5c4113dSnw141292 
130bda89588Sjp151216 	zs = idmap_get_zone_specific(zone);
131c5c4113dSnw141292 
132bda89588Sjp151216 	mutex_enter(&zs->zone_mutex);
133c5c4113dSnw141292 
134bda89588Sjp151216 	if (zs->door_valid)
135bda89588Sjp151216 		door_ki_rele(zs->door_handle);
136c5c4113dSnw141292 
137bda89588Sjp151216 	zs->door_handle = dh;
138bda89588Sjp151216 	zs->door_valid = 1;
139c5c4113dSnw141292 
140bda89588Sjp151216 	mutex_exit(&zs->zone_mutex);
141c5c4113dSnw141292 
142c5c4113dSnw141292 	return (0);
143c5c4113dSnw141292 }
144c5c4113dSnw141292 
145bda89588Sjp151216 /*
146bda89588Sjp151216  * idmap_unreg_dh
147bda89588Sjp151216  *
148bda89588Sjp151216  * This routine is called by system call idmap_unreg().
149bda89588Sjp151216  * idmap_unreg() calls door_ki_rele() on the supplied
150bda89588Sjp151216  * door handle after this routine returns. We only
151bda89588Sjp151216  * need to perform one door release on zs->door_handle
152bda89588Sjp151216  */
153c5c4113dSnw141292 int
idmap_unreg_dh(zone_t * zone,door_handle_t dh)154bda89588Sjp151216 idmap_unreg_dh(zone_t *zone, door_handle_t dh)
155c5c4113dSnw141292 {
156bda89588Sjp151216 	idmap_zone_specific_t *zs;
1570b10de9fSjp151216 
158bda89588Sjp151216 	zs = idmap_get_zone_specific(zone);
159bda89588Sjp151216 
160bda89588Sjp151216 	kidmap_cache_purge(&zs->cache);
161bda89588Sjp151216 
162bda89588Sjp151216 	mutex_enter(&zs->zone_mutex);
163bda89588Sjp151216 
164f7b4b2feSjp151216 	if (!zs->door_valid || zs->door_handle != dh) {
165bda89588Sjp151216 		mutex_exit(&zs->zone_mutex);
166c5c4113dSnw141292 		return (EINVAL);
167c5c4113dSnw141292 	}
168bda89588Sjp151216 
169bda89588Sjp151216 	door_ki_rele(zs->door_handle);
170bda89588Sjp151216 
171bda89588Sjp151216 	zs->door_valid = 0;
1728d059b82SJulian Pullen 	zs->door_retried = 0;
173bda89588Sjp151216 	mutex_exit(&zs->zone_mutex);
174bda89588Sjp151216 
175c5c4113dSnw141292 	return (0);
176c5c4113dSnw141292 }
177c5c4113dSnw141292 
178c5c4113dSnw141292 
179f7b4b2feSjp151216 /*
180f7b4b2feSjp151216  * IMPORTANT. This function idmap_get_cache_data() is project
181f7b4b2feSjp151216  * private and is for use of the test system only and should
182f7b4b2feSjp151216  * not be used for other purposes.
183f7b4b2feSjp151216  */
184f7b4b2feSjp151216 void
idmap_get_cache_data(zone_t * zone,size_t * uidbysid,size_t * gidbysid,size_t * pidbysid,size_t * sidbyuid,size_t * sidbygid)185f7b4b2feSjp151216 idmap_get_cache_data(zone_t *zone, size_t *uidbysid, size_t *gidbysid,
186f7b4b2feSjp151216 	size_t *pidbysid, size_t *sidbyuid, size_t *sidbygid)
187f7b4b2feSjp151216 {
188f7b4b2feSjp151216 	idmap_zone_specific_t *zs;
189f7b4b2feSjp151216 
190f7b4b2feSjp151216 	zs = idmap_get_zone_specific(zone);
191f7b4b2feSjp151216 
192f7b4b2feSjp151216 	kidmap_cache_get_data(&zs->cache, uidbysid, gidbysid,
193f7b4b2feSjp151216 	    pidbysid, sidbyuid, sidbygid);
194f7b4b2feSjp151216 }
195f7b4b2feSjp151216 
196c5c4113dSnw141292 static int
kidmap_call_door(idmap_zone_specific_t * zs,door_arg_t * arg)197bda89588Sjp151216 kidmap_call_door(idmap_zone_specific_t *zs, door_arg_t *arg)
198c5c4113dSnw141292 {
199c5c4113dSnw141292 	door_handle_t 	dh;
200f7b4b2feSjp151216 	door_info_t	di;
201bda89588Sjp151216 	int		status = 0;
2028d059b82SJulian Pullen 	int		num_retries = 5;
2038d059b82SJulian Pullen 	int		door_retried;
204c5c4113dSnw141292 
205f7b4b2feSjp151216 retry:
206bda89588Sjp151216 	mutex_enter(&zs->zone_mutex);
207f7b4b2feSjp151216 	if (zs->door_valid) {
208bda89588Sjp151216 		dh = zs->door_handle;
209bda89588Sjp151216 		door_ki_hold(dh);
2108d059b82SJulian Pullen 	} else {
2118d059b82SJulian Pullen 		dh = NULL;
2128d059b82SJulian Pullen 		door_retried = zs->door_retried;
213f7b4b2feSjp151216 	}
214bda89588Sjp151216 	mutex_exit(&zs->zone_mutex);
215c5c4113dSnw141292 
216f7b4b2feSjp151216 	if (dh == NULL) {
2178d059b82SJulian Pullen 		/* The door has been retried before so dont wait */
2188d059b82SJulian Pullen 		if (door_retried)
2198d059b82SJulian Pullen 			return (-1);
2208d059b82SJulian Pullen 
221f7b4b2feSjp151216 		/*
222f7b4b2feSjp151216 		 * There is no door handle yet. Give
2238d059b82SJulian Pullen 		 * smf a chance to restart idmapd
224f7b4b2feSjp151216 		 */
2258d059b82SJulian Pullen 		if (num_retries-- > 0) {
226f7b4b2feSjp151216 			delay(hz);
227f7b4b2feSjp151216 			goto retry;
228f7b4b2feSjp151216 		}
2298d059b82SJulian Pullen 
230f7b4b2feSjp151216 #ifdef	DEBUG
231f7b4b2feSjp151216 		zcmn_err(zs->zone_id, CE_WARN,
232f7b4b2feSjp151216 		    "idmap: Error no registered door to call the "
233f7b4b2feSjp151216 		    "idmap daemon\n");
234f7b4b2feSjp151216 #endif
2358d059b82SJulian Pullen 		mutex_enter(&zs->zone_mutex);
2368d059b82SJulian Pullen 		if (!zs->door_valid)
2378d059b82SJulian Pullen 			zs->door_retried = 1;
2388d059b82SJulian Pullen 		mutex_exit(&zs->zone_mutex);
2398d059b82SJulian Pullen 
240f7b4b2feSjp151216 		return (-1);
241f7b4b2feSjp151216 	}
242f7b4b2feSjp151216 
243323a81d9Sjwadams 	status = door_ki_upcall_limited(dh, arg, NULL, SIZE_MAX, 0);
244c5c4113dSnw141292 
245f7b4b2feSjp151216 	switch (status) {
246f7b4b2feSjp151216 	case 0:	/* Success */
247bda89588Sjp151216 		door_ki_rele(dh);
248f7b4b2feSjp151216 		return (0);
249bda89588Sjp151216 
250f7b4b2feSjp151216 	case EINTR:
251f7b4b2feSjp151216 		/* If we took an interrupt we have to bail out. */
252f7b4b2feSjp151216 		if (ttolwp(curthread) && ISSIG(curthread, JUSTLOOKING)) {
253f7b4b2feSjp151216 			door_ki_rele(dh);
2548d059b82SJulian Pullen #ifdef	DEBUG
255f7b4b2feSjp151216 			zcmn_err(zs->zone_id, CE_WARN,
256f7b4b2feSjp151216 			    "idmap: Interrupted\n");
2578d059b82SJulian Pullen #endif
258f7b4b2feSjp151216 			return (-1);
259f7b4b2feSjp151216 		}
260bda89588Sjp151216 		/*
261f7b4b2feSjp151216 		 * Just retry and see what happens.
262bda89588Sjp151216 		 */
263f7b4b2feSjp151216 		/* FALLTHROUGH */
264f7b4b2feSjp151216 
265f7b4b2feSjp151216 	case EAGAIN:
266f7b4b2feSjp151216 		/* A resouce problem */
267f7b4b2feSjp151216 		door_ki_rele(dh);
268f7b4b2feSjp151216 		/* Back off before retrying */
269f7b4b2feSjp151216 #ifdef	DEBUG
270f7b4b2feSjp151216 		zcmn_err(zs->zone_id, CE_WARN,
271f7b4b2feSjp151216 		    "idmap: Door call returned error %d. Retrying\n", status);
272f7b4b2feSjp151216 #endif	/* DEBUG */
273f7b4b2feSjp151216 		delay(hz);
274f7b4b2feSjp151216 		goto retry;
275f7b4b2feSjp151216 
276f7b4b2feSjp151216 	case EBADF:
277f7b4b2feSjp151216 		/* Stale door handle. See if smf restarts the daemon. */
278f7b4b2feSjp151216 		door_ki_rele(dh);
279bda89588Sjp151216 		mutex_enter(&zs->zone_mutex);
280f7b4b2feSjp151216 		if (zs->door_valid && dh == zs->door_handle) {
281bda89588Sjp151216 			zs->door_valid = 0;
2828d059b82SJulian Pullen 			zs->door_retried = 0;
283bda89588Sjp151216 			door_ki_rele(zs->door_handle);
284bda89588Sjp151216 		}
285bda89588Sjp151216 		mutex_exit(&zs->zone_mutex);
286f7b4b2feSjp151216 		/* Back off before retrying */
287f7b4b2feSjp151216 #ifdef	DEBUG
288f7b4b2feSjp151216 		zcmn_err(zs->zone_id, CE_WARN,
289f7b4b2feSjp151216 		    "idmap: Door call returned error %d. Retrying\n", status);
290f7b4b2feSjp151216 #endif	/* DEBUG */
291f7b4b2feSjp151216 		delay(hz);
292f7b4b2feSjp151216 		goto retry;
293c5c4113dSnw141292 
294f7b4b2feSjp151216 	default:
295f7b4b2feSjp151216 		/* Unknown error */
296f7b4b2feSjp151216 #ifdef	DEBUG
297f7b4b2feSjp151216 		zcmn_err(zs->zone_id, CE_WARN,
298f7b4b2feSjp151216 		    "idmap: Door call returned error %d.\n", status);
299f7b4b2feSjp151216 #endif	/* DEBUG */
300f7b4b2feSjp151216 		door_ki_rele(dh);
301f7b4b2feSjp151216 		return (-1);
302f7b4b2feSjp151216 	}
303c5c4113dSnw141292 }
304c5c4113dSnw141292 
305c5c4113dSnw141292 
306bda89588Sjp151216 static idmap_zone_specific_t *
idmap_get_zone_specific(zone_t * zone)307bda89588Sjp151216 idmap_get_zone_specific(zone_t *zone)
308bda89588Sjp151216 {
309bda89588Sjp151216 	idmap_zone_specific_t *zs;
310bda89588Sjp151216 
311bda89588Sjp151216 	ASSERT(zone != NULL);
312bda89588Sjp151216 
313bda89588Sjp151216 	zs = zone_getspecific(idmap_zone_key, zone);
314bda89588Sjp151216 	if (zs != NULL)
315bda89588Sjp151216 		return (zs);
316bda89588Sjp151216 
317bda89588Sjp151216 	mutex_enter(&idmap_zone_mutex);
318bda89588Sjp151216 	zs = zone_getspecific(idmap_zone_key, zone);
319bda89588Sjp151216 	if (zs == NULL) {
320bda89588Sjp151216 		zs = kmem_zalloc(sizeof (idmap_zone_specific_t), KM_SLEEP);
321bda89588Sjp151216 		mutex_init(&zs->zone_mutex, NULL, MUTEX_DEFAULT, NULL);
322bda89588Sjp151216 		kidmap_cache_create(&zs->cache);
323f7b4b2feSjp151216 		zs->zone_id = zone->zone_id;
324bda89588Sjp151216 		(void) zone_setspecific(idmap_zone_key, zone, zs);
325bda89588Sjp151216 		mutex_exit(&idmap_zone_mutex);
326bda89588Sjp151216 		return (zs);
327bda89588Sjp151216 	}
328bda89588Sjp151216 	mutex_exit(&idmap_zone_mutex);
329bda89588Sjp151216 
330bda89588Sjp151216 	return (zs);
331bda89588Sjp151216 }
332bda89588Sjp151216 
333bda89588Sjp151216 
334bda89588Sjp151216 static void
335bda89588Sjp151216 /* ARGSUSED */
idmap_zone_destroy(zoneid_t zone_id,void * arg)336bda89588Sjp151216 idmap_zone_destroy(zoneid_t zone_id, void *arg)
337bda89588Sjp151216 {
338bda89588Sjp151216 	idmap_zone_specific_t *zs = arg;
339bda89588Sjp151216 	if (zs != NULL) {
340bda89588Sjp151216 		kidmap_cache_delete(&zs->cache);
341bda89588Sjp151216 		if (zs->door_valid) {
342bda89588Sjp151216 			door_ki_rele(zs->door_handle);
343bda89588Sjp151216 		}
344bda89588Sjp151216 		mutex_destroy(&zs->zone_mutex);
345bda89588Sjp151216 		kmem_free(zs, sizeof (idmap_zone_specific_t));
346bda89588Sjp151216 	}
347bda89588Sjp151216 }
348bda89588Sjp151216 
349bda89588Sjp151216 
350c5c4113dSnw141292 int
kidmap_start(void)351c5c4113dSnw141292 kidmap_start(void)
352c5c4113dSnw141292 {
353bda89588Sjp151216 	mutex_init(&idmap_zone_mutex, NULL, MUTEX_DEFAULT, NULL);
354bda89588Sjp151216 	zone_key_create(&idmap_zone_key, NULL, NULL, idmap_zone_destroy);
355c5c4113dSnw141292 	kidmap_sid_prefix_store_init();
356c5c4113dSnw141292 
357c5c4113dSnw141292 	return (0);
358c5c4113dSnw141292 }
359c5c4113dSnw141292 
360c5c4113dSnw141292 
361c5c4113dSnw141292 int
kidmap_stop(void)362c5c4113dSnw141292 kidmap_stop(void)
363c5c4113dSnw141292 {
364c5c4113dSnw141292 	return (EBUSY);
365c5c4113dSnw141292 }
366c5c4113dSnw141292 
367c5c4113dSnw141292 
368bda89588Sjp151216 /*
369bda89588Sjp151216  * idmap_get_door
370bda89588Sjp151216  *
371bda89588Sjp151216  * This is called by the system call allocids() to get the door for the
372bda89588Sjp151216  * given zone.
373bda89588Sjp151216  */
374bda89588Sjp151216 door_handle_t
idmap_get_door(zone_t * zone)375bda89588Sjp151216 idmap_get_door(zone_t *zone)
376bda89588Sjp151216 {
377bda89588Sjp151216 	door_handle_t dh = NULL;
378bda89588Sjp151216 	idmap_zone_specific_t *zs;
379c5c4113dSnw141292 
380bda89588Sjp151216 	zs = idmap_get_zone_specific(zone);
381c5c4113dSnw141292 
382bda89588Sjp151216 	mutex_enter(&zs->zone_mutex);
383bda89588Sjp151216 	if (zs->door_valid) {
384bda89588Sjp151216 		dh = zs->door_handle;
385bda89588Sjp151216 		door_ki_hold(dh);
386c5c4113dSnw141292 	}
387bda89588Sjp151216 	mutex_exit(&zs->zone_mutex);
388bda89588Sjp151216 	return (dh);
389bda89588Sjp151216 }
390bda89588Sjp151216 
391bda89588Sjp151216 
392bda89588Sjp151216 /*
393bda89588Sjp151216  * idmap_purge_cache
394bda89588Sjp151216  *
395bda89588Sjp151216  * This is called by the system call allocids() to purge the cache for the
396bda89588Sjp151216  * given zone.
397bda89588Sjp151216  */
398bda89588Sjp151216 void
idmap_purge_cache(zone_t * zone)399bda89588Sjp151216 idmap_purge_cache(zone_t *zone)
400bda89588Sjp151216 {
401bda89588Sjp151216 	idmap_zone_specific_t *zs;
402bda89588Sjp151216 
403bda89588Sjp151216 	zs = idmap_get_zone_specific(zone);
404bda89588Sjp151216 
405bda89588Sjp151216 	kidmap_cache_purge(&zs->cache);
406bda89588Sjp151216 }
407bda89588Sjp151216 
408bda89588Sjp151216 
409c5c4113dSnw141292 
410c5c4113dSnw141292 
411c5c4113dSnw141292 /*
412c5c4113dSnw141292  * Given Domain SID and RID, get UID
413c5c4113dSnw141292  *
414c5c4113dSnw141292  * Input:
415c5c4113dSnw141292  * sid_prefix	- Domain SID in canonical form
416c5c4113dSnw141292  * rid	- RID
417c5c4113dSnw141292  *
418c5c4113dSnw141292  * Output:
419c5c4113dSnw141292  * uid  - POSIX UID if return == IDMAP_SUCCESS
420c5c4113dSnw141292  *
421c5c4113dSnw141292  * Return:
422c5c4113dSnw141292  * Success return IDMAP_SUCCESS else IDMAP error
423c5c4113dSnw141292  */
424c5c4113dSnw141292 idmap_stat
kidmap_getuidbysid(zone_t * zone,const char * sid_prefix,uint32_t rid,uid_t * uid)425bda89588Sjp151216 kidmap_getuidbysid(zone_t *zone, const char *sid_prefix, uint32_t rid,
426bda89588Sjp151216 		uid_t *uid)
427c5c4113dSnw141292 {
428bda89588Sjp151216 	idmap_zone_specific_t	*zs;
429c5c4113dSnw141292 	idmap_mapping_batch	args;
430c5c4113dSnw141292 	idmap_mapping		mapping;
431c5c4113dSnw141292 	idmap_ids_res		results;
432c5c4113dSnw141292 	uint32_t		op = IDMAP_GET_MAPPED_IDS;
433c5c4113dSnw141292 	const char		*new_sid_prefix;
434c5c4113dSnw141292 	idmap_stat		status;
435c5c4113dSnw141292 
436c5c4113dSnw141292 	if (sid_prefix == NULL || uid == NULL)
437c5c4113dSnw141292 		return (IDMAP_ERR_ARG);
438c5c4113dSnw141292 
439bda89588Sjp151216 	zs = idmap_get_zone_specific(zone);
440bda89588Sjp151216 
441bda89588Sjp151216 	if (kidmap_cache_lookup_uidbysid(&zs->cache, sid_prefix, rid, uid)
4420b10de9fSjp151216 	    == IDMAP_SUCCESS)
443c5c4113dSnw141292 		return (IDMAP_SUCCESS);
444c5c4113dSnw141292 
445c5c4113dSnw141292 	bzero(&mapping, sizeof (idmap_mapping));
446c5c4113dSnw141292 	mapping.id1.idtype = IDMAP_SID;
447c5c4113dSnw141292 	mapping.id1.idmap_id_u.sid.prefix = (char *)sid_prefix;
448c5c4113dSnw141292 	mapping.id1.idmap_id_u.sid.rid = rid;
449c5c4113dSnw141292 	mapping.id2.idtype = IDMAP_UID;
450c5c4113dSnw141292 
451c5c4113dSnw141292 	bzero(&results, sizeof (idmap_ids_res));
452c5c4113dSnw141292 
453c5c4113dSnw141292 	args.idmap_mapping_batch_len = 1;
454c5c4113dSnw141292 	args.idmap_mapping_batch_val = &mapping;
455c5c4113dSnw141292 
456bda89588Sjp151216 	if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch,
457c5c4113dSnw141292 	    (caddr_t)&args, xdr_idmap_ids_res,
458c5c4113dSnw141292 	    (caddr_t)&results) == 0) {
459c5c4113dSnw141292 		/* Door call succeded */
4609d0aba92Sjp151216 		if (results.retcode != IDMAP_SUCCESS) {
4619d0aba92Sjp151216 			status = results.retcode;
4629d0aba92Sjp151216 			*uid = UID_NOBODY;
4639d0aba92Sjp151216 		} else if (results.ids.ids_len >= 1 &&
464c5c4113dSnw141292 		    results.ids.ids_val[0].id.idtype == IDMAP_UID) {
465c5c4113dSnw141292 			status = results.ids.ids_val[0].retcode;
466c5c4113dSnw141292 			*uid = results.ids.ids_val[0].id.idmap_id_u.uid;
467c5c4113dSnw141292 			if (status == IDMAP_SUCCESS) {
468c5c4113dSnw141292 				new_sid_prefix = kidmap_find_sid_prefix(
469c5c4113dSnw141292 				    sid_prefix);
470d15447b6Sjp151216 				kidmap_cache_add_sid2uid(&zs->cache,
471d15447b6Sjp151216 				    new_sid_prefix, rid, *uid,
472d15447b6Sjp151216 				    results.ids.ids_val[0].direction);
473c5c4113dSnw141292 			}
474c5c4113dSnw141292 		} else {
475c5c4113dSnw141292 			status = IDMAP_ERR_NOMAPPING;
476c5c4113dSnw141292 			*uid = UID_NOBODY;
477c5c4113dSnw141292 		}
478c5c4113dSnw141292 		xdr_free(xdr_idmap_ids_res, (char *)&results);
479c5c4113dSnw141292 	} else {
480c5c4113dSnw141292 		/* Door call failed */
481c5c4113dSnw141292 		status = IDMAP_ERR_NOMAPPING;
482c5c4113dSnw141292 		*uid = UID_NOBODY;
483c5c4113dSnw141292 	}
484c5c4113dSnw141292 	return (status);
485c5c4113dSnw141292 }
486c5c4113dSnw141292 
487c5c4113dSnw141292 
488c5c4113dSnw141292 /*
489c5c4113dSnw141292  * Given Domain SID and RID, get GID
490c5c4113dSnw141292  *
491c5c4113dSnw141292  * Input:
492c5c4113dSnw141292  * sid_prefix	- Domain SID in canonical form
493c5c4113dSnw141292  * rid	- RID
494c5c4113dSnw141292  *
495c5c4113dSnw141292  * Output:
496c5c4113dSnw141292  * gid  - POSIX UID if return == IDMAP_SUCCESS
497c5c4113dSnw141292  *
498c5c4113dSnw141292  * Return:
499c5c4113dSnw141292  * Success return IDMAP_SUCCESS else IDMAP error
500c5c4113dSnw141292  */
501c5c4113dSnw141292 idmap_stat
kidmap_getgidbysid(zone_t * zone,const char * sid_prefix,uint32_t rid,gid_t * gid)502bda89588Sjp151216 kidmap_getgidbysid(zone_t *zone, const char *sid_prefix, uint32_t rid,
503bda89588Sjp151216 		gid_t *gid)
504c5c4113dSnw141292 {
505bda89588Sjp151216 	idmap_zone_specific_t	*zs;
506c5c4113dSnw141292 	idmap_mapping_batch	args;
507c5c4113dSnw141292 	idmap_mapping		mapping;
508c5c4113dSnw141292 	idmap_ids_res		results;
509c5c4113dSnw141292 	uint32_t		op = IDMAP_GET_MAPPED_IDS;
510c5c4113dSnw141292 	const char		*new_sid_prefix;
511c5c4113dSnw141292 	idmap_stat		status;
512c5c4113dSnw141292 
513c5c4113dSnw141292 	if (sid_prefix == NULL || gid == NULL)
514c5c4113dSnw141292 		return (IDMAP_ERR_ARG);
515c5c4113dSnw141292 
516bda89588Sjp151216 	zs = idmap_get_zone_specific(zone);
517bda89588Sjp151216 
518bda89588Sjp151216 	if (kidmap_cache_lookup_gidbysid(&zs->cache, sid_prefix, rid, gid)
519bda89588Sjp151216 	    == IDMAP_SUCCESS)
520c5c4113dSnw141292 		return (IDMAP_SUCCESS);
521c5c4113dSnw141292 
522c5c4113dSnw141292 	bzero(&mapping, sizeof (idmap_mapping));
523c5c4113dSnw141292 	mapping.id1.idtype = IDMAP_SID;
524c5c4113dSnw141292 	mapping.id1.idmap_id_u.sid.prefix = (char *)sid_prefix;
525c5c4113dSnw141292 	mapping.id1.idmap_id_u.sid.rid = rid;
526c5c4113dSnw141292 	mapping.id2.idtype = IDMAP_GID;
527c5c4113dSnw141292 
528c5c4113dSnw141292 	bzero(&results, sizeof (idmap_ids_res));
529c5c4113dSnw141292 
530c5c4113dSnw141292 	args.idmap_mapping_batch_len = 1;
531c5c4113dSnw141292 	args.idmap_mapping_batch_val = &mapping;
532c5c4113dSnw141292 
533bda89588Sjp151216 	if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch,
534c5c4113dSnw141292 	    (caddr_t)&args, xdr_idmap_ids_res,
535c5c4113dSnw141292 	    (caddr_t)&results) == 0) {
536c5c4113dSnw141292 		/* Door call succeded */
5379d0aba92Sjp151216 		if (results.retcode != IDMAP_SUCCESS) {
5389d0aba92Sjp151216 			status = results.retcode;
5399d0aba92Sjp151216 			*gid = GID_NOBODY;
5409d0aba92Sjp151216 		} else if (results.ids.ids_len >= 1 &&
541c5c4113dSnw141292 		    results.ids.ids_val[0].id.idtype == IDMAP_GID) {
542c5c4113dSnw141292 			status = results.ids.ids_val[0].retcode;
543c5c4113dSnw141292 			*gid = results.ids.ids_val[0].id.idmap_id_u.gid;
544c5c4113dSnw141292 			if (status == IDMAP_SUCCESS) {
545c5c4113dSnw141292 				new_sid_prefix = kidmap_find_sid_prefix(
546c5c4113dSnw141292 				    sid_prefix);
547d15447b6Sjp151216 				kidmap_cache_add_sid2gid(&zs->cache,
548d15447b6Sjp151216 				    new_sid_prefix, rid, *gid,
549d15447b6Sjp151216 				    results.ids.ids_val[0].direction);
550c5c4113dSnw141292 			}
551c5c4113dSnw141292 		} else {
552c5c4113dSnw141292 			status = IDMAP_ERR_NOMAPPING;
553c5c4113dSnw141292 			*gid = GID_NOBODY;
554c5c4113dSnw141292 		}
555c5c4113dSnw141292 		xdr_free(xdr_idmap_ids_res, (char *)&results);
556c5c4113dSnw141292 	} else {
557c5c4113dSnw141292 		/* Door call failed */
558c5c4113dSnw141292 		status = IDMAP_ERR_NOMAPPING;
559c5c4113dSnw141292 		*gid = GID_NOBODY;
560c5c4113dSnw141292 	}
561c5c4113dSnw141292 	return (status);
562c5c4113dSnw141292 }
563c5c4113dSnw141292 
564c5c4113dSnw141292 /*
565c5c4113dSnw141292  * Given Domain SID and RID, get Posix ID
566c5c4113dSnw141292  *
567c5c4113dSnw141292  * Input:
568c5c4113dSnw141292  * sid_prefix	- Domain SID in canonical form
569c5c4113dSnw141292  * rid	- RID
570c5c4113dSnw141292  *
571c5c4113dSnw141292  * Output:
572c5c4113dSnw141292  * pid  - POSIX ID if return == IDMAP_SUCCESS
573c5c4113dSnw141292  * is_user - 1 == UID, 0 == GID  if return == IDMAP_SUCCESS
574c5c4113dSnw141292  *
575c5c4113dSnw141292  * Return:
576c5c4113dSnw141292  * Success return IDMAP_SUCCESS else IDMAP error
577c5c4113dSnw141292  */
578c5c4113dSnw141292 idmap_stat
kidmap_getpidbysid(zone_t * zone,const char * sid_prefix,uint32_t rid,uid_t * pid,int * is_user)579bda89588Sjp151216 kidmap_getpidbysid(zone_t *zone, const char *sid_prefix, uint32_t rid,
580bda89588Sjp151216 		uid_t *pid, int *is_user)
581c5c4113dSnw141292 {
582bda89588Sjp151216 	idmap_zone_specific_t	*zs;
583c5c4113dSnw141292 	idmap_mapping_batch	args;
584c5c4113dSnw141292 	idmap_mapping		mapping;
585c5c4113dSnw141292 	idmap_ids_res		results;
586c5c4113dSnw141292 	uint32_t		op = IDMAP_GET_MAPPED_IDS;
587c5c4113dSnw141292 	const char		*new_sid_prefix;
588c5c4113dSnw141292 	idmap_stat		status;
589c5c4113dSnw141292 
590c5c4113dSnw141292 	if (sid_prefix == NULL || pid == NULL || is_user == NULL)
591c5c4113dSnw141292 		return (IDMAP_ERR_ARG);
592c5c4113dSnw141292 
593bda89588Sjp151216 	zs = idmap_get_zone_specific(zone);
594bda89588Sjp151216 
595bda89588Sjp151216 	if (kidmap_cache_lookup_pidbysid(&zs->cache, sid_prefix, rid, pid,
596bda89588Sjp151216 	    is_user) == IDMAP_SUCCESS)
597c5c4113dSnw141292 		return (IDMAP_SUCCESS);
598c5c4113dSnw141292 
599c5c4113dSnw141292 	bzero(&mapping, sizeof (idmap_mapping));
600c5c4113dSnw141292 	mapping.id1.idtype = IDMAP_SID;
601c5c4113dSnw141292 	mapping.id1.idmap_id_u.sid.prefix = (char *)sid_prefix;
602c5c4113dSnw141292 	mapping.id1.idmap_id_u.sid.rid = rid;
603c5c4113dSnw141292 	mapping.id2.idtype = IDMAP_POSIXID;
604c5c4113dSnw141292 
605c5c4113dSnw141292 	bzero(&results, sizeof (idmap_ids_res));
606c5c4113dSnw141292 
607c5c4113dSnw141292 	args.idmap_mapping_batch_len = 1;
608c5c4113dSnw141292 	args.idmap_mapping_batch_val = &mapping;
609c5c4113dSnw141292 
610bda89588Sjp151216 	if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch,
611c5c4113dSnw141292 	    (caddr_t)&args, xdr_idmap_ids_res,
612c5c4113dSnw141292 	    (caddr_t)&results) == 0) {
613c5c4113dSnw141292 		/* Door call succeded */
6149d0aba92Sjp151216 		if (results.retcode != IDMAP_SUCCESS) {
6159d0aba92Sjp151216 			status = results.retcode;
6169d0aba92Sjp151216 			*is_user = 1;
6179d0aba92Sjp151216 			*pid = UID_NOBODY;
6189d0aba92Sjp151216 		} else if (results.ids.ids_len >= 1 && (
619c5c4113dSnw141292 		    results.ids.ids_val[0].id.idtype == IDMAP_UID ||
620c5c4113dSnw141292 		    results.ids.ids_val[0].id.idtype == IDMAP_GID)) {
621c5c4113dSnw141292 			status = results.ids.ids_val[0].retcode;
622c5c4113dSnw141292 			if (results.ids.ids_val[0].id.idtype == IDMAP_UID) {
623c5c4113dSnw141292 				*is_user = 1;
624c5c4113dSnw141292 				*pid = results.ids.ids_val[0].id.idmap_id_u.uid;
625c5c4113dSnw141292 			} else {
626c5c4113dSnw141292 				*is_user = 0;
627c5c4113dSnw141292 				*pid = results.ids.ids_val[0].id.idmap_id_u.gid;
628c5c4113dSnw141292 			}
629c5c4113dSnw141292 			if (status == IDMAP_SUCCESS) {
630c5c4113dSnw141292 				new_sid_prefix = kidmap_find_sid_prefix(
631c5c4113dSnw141292 				    sid_prefix);
632d15447b6Sjp151216 				kidmap_cache_add_sid2pid(&zs->cache,
633c5c4113dSnw141292 				    new_sid_prefix, rid, *pid,
634d15447b6Sjp151216 				    *is_user,
635d15447b6Sjp151216 				    results.ids.ids_val[0].direction);
636c5c4113dSnw141292 			}
637c5c4113dSnw141292 		} else {
638c5c4113dSnw141292 			status = IDMAP_ERR_NOMAPPING;
639c5c4113dSnw141292 			*is_user = 1;
640c5c4113dSnw141292 			*pid = UID_NOBODY;
641c5c4113dSnw141292 		}
642c5c4113dSnw141292 		xdr_free(xdr_idmap_ids_res, (char *)&results);
643c5c4113dSnw141292 	} else {
644c5c4113dSnw141292 		/* Door call failed */
645c5c4113dSnw141292 		status = IDMAP_ERR_NOMAPPING;
646c5c4113dSnw141292 		*is_user = 1;
647c5c4113dSnw141292 		*pid = UID_NOBODY;
648c5c4113dSnw141292 	}
649c5c4113dSnw141292 	return (status);
650c5c4113dSnw141292 }
651c5c4113dSnw141292 
652c5c4113dSnw141292 
653c5c4113dSnw141292 /*
654c5c4113dSnw141292  * Given UID, get Domain SID and RID
655c5c4113dSnw141292  *
656c5c4113dSnw141292  * Input:
657c5c4113dSnw141292  * uid - Posix UID
658c5c4113dSnw141292  *
659c5c4113dSnw141292  * Output:
660c5c4113dSnw141292  * sid_prefix	- Domain SID if return == IDMAP_SUCCESS
661c5c4113dSnw141292  * rid	- RID if return == IDMAP_SUCCESS
662c5c4113dSnw141292  *
663c5c4113dSnw141292  * Return:
664c5c4113dSnw141292  * Success return IDMAP_SUCCESS else IDMAP error
665c5c4113dSnw141292  */
666c5c4113dSnw141292 idmap_stat
kidmap_getsidbyuid(zone_t * zone,uid_t uid,const char ** sid_prefix,uint32_t * rid)667bda89588Sjp151216 kidmap_getsidbyuid(zone_t *zone, uid_t uid, const char **sid_prefix,
668bda89588Sjp151216 		uint32_t *rid)
669c5c4113dSnw141292 {
670bda89588Sjp151216 	idmap_zone_specific_t	*zs;
671c5c4113dSnw141292 	idmap_mapping_batch	args;
672c5c4113dSnw141292 	idmap_mapping		mapping;
673c5c4113dSnw141292 	idmap_ids_res		results;
674c5c4113dSnw141292 	uint32_t		op = IDMAP_GET_MAPPED_IDS;
675c5c4113dSnw141292 	idmap_stat		status;
676c5c4113dSnw141292 	time_t			entry_ttl;
677c5c4113dSnw141292 	idmap_id		*id;
678c5c4113dSnw141292 
679c5c4113dSnw141292 	if (sid_prefix == NULL || rid == NULL)
680c5c4113dSnw141292 		return (IDMAP_ERR_ARG);
681c5c4113dSnw141292 
682bda89588Sjp151216 	zs = idmap_get_zone_specific(zone);
683bda89588Sjp151216 
684bda89588Sjp151216 	if (kidmap_cache_lookup_sidbyuid(&zs->cache, sid_prefix, rid, uid)
685c5c4113dSnw141292 	    == IDMAP_SUCCESS) {
686c5c4113dSnw141292 		return (IDMAP_SUCCESS);
687c5c4113dSnw141292 	}
688c5c4113dSnw141292 
689c5c4113dSnw141292 	bzero(&mapping, sizeof (idmap_mapping));
690c5c4113dSnw141292 	mapping.id1.idtype = IDMAP_UID;
691c5c4113dSnw141292 	mapping.id1.idmap_id_u.uid = uid;
692c5c4113dSnw141292 	mapping.id2.idtype = IDMAP_SID;
693c5c4113dSnw141292 
694c5c4113dSnw141292 	bzero(&results, sizeof (idmap_ids_res));
695c5c4113dSnw141292 
696c5c4113dSnw141292 	args.idmap_mapping_batch_len = 1;
697c5c4113dSnw141292 	args.idmap_mapping_batch_val = &mapping;
698c5c4113dSnw141292 
699bda89588Sjp151216 	if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch,
700c5c4113dSnw141292 	    (caddr_t)&args, xdr_idmap_ids_res,
701c5c4113dSnw141292 	    (caddr_t)&results) == 0) {
702c5c4113dSnw141292 		/* Door call succeded */
7039d0aba92Sjp151216 		if (results.retcode != IDMAP_SUCCESS) {
7049d0aba92Sjp151216 			status = results.retcode;
7059d0aba92Sjp151216 			*rid = 0;
7069d0aba92Sjp151216 			*sid_prefix = NULL;
7079d0aba92Sjp151216 		} else if (results.ids.ids_len >= 1 &&
708cd37da74Snw141292 		    (results.ids.ids_val[0].id.idtype == IDMAP_SID ||
709cd37da74Snw141292 		    results.ids.ids_val[0].id.idtype == IDMAP_USID ||
710cd37da74Snw141292 		    results.ids.ids_val[0].id.idtype == IDMAP_GSID)) {
711c5c4113dSnw141292 			status = results.ids.ids_val[0].retcode;
712c5c4113dSnw141292 			id = &results.ids.ids_val[0].id;
713c5c4113dSnw141292 			*sid_prefix = kidmap_find_sid_prefix(
714c5c4113dSnw141292 			    id->idmap_id_u.sid.prefix);
715c5c4113dSnw141292 			*rid = id->idmap_id_u.sid.rid;
716c5c4113dSnw141292 			if (status == IDMAP_SUCCESS) {
717d15447b6Sjp151216 				kidmap_cache_add_sid2uid(&zs->cache,
718d15447b6Sjp151216 				    *sid_prefix, *rid, uid,
719d15447b6Sjp151216 				    results.ids.ids_val[0].direction);
720c5c4113dSnw141292 			}
721c5c4113dSnw141292 		} else {
722c5c4113dSnw141292 			status = IDMAP_ERR_NOMAPPING;
723c5c4113dSnw141292 			*rid = 0;
724c5c4113dSnw141292 			*sid_prefix = NULL;
725c5c4113dSnw141292 		}
726c5c4113dSnw141292 		xdr_free(xdr_idmap_ids_res, (char *)&results);
727c5c4113dSnw141292 	} else {
728c5c4113dSnw141292 		/* Door call failed */
729c5c4113dSnw141292 		status = IDMAP_ERR_NOMAPPING;
730c5c4113dSnw141292 		*rid = 0;
731c5c4113dSnw141292 		*sid_prefix = NULL;
732c5c4113dSnw141292 	}
733c5c4113dSnw141292 	return (status);
734c5c4113dSnw141292 }
735c5c4113dSnw141292 
736c5c4113dSnw141292 
737c5c4113dSnw141292 /*
738c5c4113dSnw141292  * Given GID, get Domain SID and RID
739c5c4113dSnw141292  *
740c5c4113dSnw141292  * Input:
741c5c4113dSnw141292  * gid - Posix GID
742c5c4113dSnw141292  *
743c5c4113dSnw141292  * Output:
744c5c4113dSnw141292  * sid_prefix	- Domain SID if return == IDMAP_SUCCESS
745c5c4113dSnw141292  * rid	- RID if return == IDMAP_SUCCESS
746c5c4113dSnw141292  *
747c5c4113dSnw141292  * Return:
748c5c4113dSnw141292  * Success return IDMAP_SUCCESS else IDMAP error
749c5c4113dSnw141292  */
750c5c4113dSnw141292 idmap_stat
kidmap_getsidbygid(zone_t * zone,gid_t gid,const char ** sid_prefix,uint32_t * rid)751bda89588Sjp151216 kidmap_getsidbygid(zone_t *zone, gid_t gid, const char **sid_prefix,
752bda89588Sjp151216 		uint32_t *rid)
753c5c4113dSnw141292 {
754bda89588Sjp151216 	idmap_zone_specific_t	*zs;
755c5c4113dSnw141292 	idmap_mapping_batch	args;
756c5c4113dSnw141292 	idmap_mapping		mapping;
757c5c4113dSnw141292 	idmap_ids_res		results;
758c5c4113dSnw141292 	uint32_t		op = IDMAP_GET_MAPPED_IDS;
759c5c4113dSnw141292 	idmap_stat		status;
760c5c4113dSnw141292 	idmap_id		*id;
761c5c4113dSnw141292 
762c5c4113dSnw141292 	if (sid_prefix == NULL || rid == NULL)
763c5c4113dSnw141292 		return (IDMAP_ERR_ARG);
764c5c4113dSnw141292 
765bda89588Sjp151216 	zs = idmap_get_zone_specific(zone);
766bda89588Sjp151216 
767bda89588Sjp151216 	if (kidmap_cache_lookup_sidbygid(&zs->cache, sid_prefix, rid, gid)
768c5c4113dSnw141292 	    == IDMAP_SUCCESS) {
769c5c4113dSnw141292 		return (IDMAP_SUCCESS);
770c5c4113dSnw141292 	}
771c5c4113dSnw141292 
772c5c4113dSnw141292 	bzero(&mapping, sizeof (idmap_mapping));
773c5c4113dSnw141292 	mapping.id1.idtype = IDMAP_GID;
774c5c4113dSnw141292 	mapping.id1.idmap_id_u.uid = gid;
775c5c4113dSnw141292 	mapping.id2.idtype = IDMAP_SID;
776c5c4113dSnw141292 
777c5c4113dSnw141292 	bzero(&results, sizeof (idmap_ids_res));
778c5c4113dSnw141292 
779c5c4113dSnw141292 	args.idmap_mapping_batch_len = 1;
780c5c4113dSnw141292 	args.idmap_mapping_batch_val = &mapping;
781c5c4113dSnw141292 
782bda89588Sjp151216 	if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch,
783c5c4113dSnw141292 	    (caddr_t)&args, xdr_idmap_ids_res,
784c5c4113dSnw141292 	    (caddr_t)&results) == 0) {
785c5c4113dSnw141292 		/* Door call succeded */
7869d0aba92Sjp151216 		if (results.retcode != IDMAP_SUCCESS) {
7879d0aba92Sjp151216 			status = results.retcode;
7889d0aba92Sjp151216 			*rid = 0;
7899d0aba92Sjp151216 			*sid_prefix = NULL;
7909d0aba92Sjp151216 		} else if (results.ids.ids_len >= 1 &&
791cd37da74Snw141292 		    (results.ids.ids_val[0].id.idtype == IDMAP_SID ||
792cd37da74Snw141292 		    results.ids.ids_val[0].id.idtype == IDMAP_USID ||
793cd37da74Snw141292 		    results.ids.ids_val[0].id.idtype == IDMAP_GSID)) {
794c5c4113dSnw141292 			status = results.ids.ids_val[0].retcode;
795c5c4113dSnw141292 			id = &results.ids.ids_val[0].id;
796c5c4113dSnw141292 			*sid_prefix = kidmap_find_sid_prefix(
797c5c4113dSnw141292 			    id->idmap_id_u.sid.prefix);
798c5c4113dSnw141292 			*rid = id->idmap_id_u.sid.rid;
799c5c4113dSnw141292 			if (status == IDMAP_SUCCESS) {
800d15447b6Sjp151216 				kidmap_cache_add_sid2gid(&zs->cache,
801d15447b6Sjp151216 				    *sid_prefix, *rid, gid,
802d15447b6Sjp151216 				    results.ids.ids_val[0].direction);
803c5c4113dSnw141292 			}
804c5c4113dSnw141292 		} else {
805c5c4113dSnw141292 			status = IDMAP_ERR_NOMAPPING;
806c5c4113dSnw141292 			*rid = 0;
807c5c4113dSnw141292 			*sid_prefix = NULL;
808c5c4113dSnw141292 		}
809c5c4113dSnw141292 		xdr_free(xdr_idmap_ids_res, (char *)&results);
810c5c4113dSnw141292 	} else {
811c5c4113dSnw141292 		/* Door call failed */
812c5c4113dSnw141292 		status = IDMAP_ERR_NOMAPPING;
813c5c4113dSnw141292 		*rid = 0;
814c5c4113dSnw141292 		*sid_prefix = NULL;
815c5c4113dSnw141292 	}
816c5c4113dSnw141292 	return (status);
817c5c4113dSnw141292 }
818c5c4113dSnw141292 
819c5c4113dSnw141292 /*
820c5c4113dSnw141292  * Create handle to get SID to UID/GID mapping entries
821c5c4113dSnw141292  *
822c5c4113dSnw141292  * Input:
823c5c4113dSnw141292  * 	none
824c5c4113dSnw141292  * Return:
825c5c4113dSnw141292  *	get_handle
826c5c4113dSnw141292  *
827c5c4113dSnw141292  */
828c5c4113dSnw141292 idmap_get_handle_t *
kidmap_get_create(zone_t * zone)829bda89588Sjp151216 kidmap_get_create(zone_t *zone)
830c5c4113dSnw141292 {
831bda89588Sjp151216 	idmap_zone_specific_t	*zs;
832c5c4113dSnw141292 	idmap_get_handle_t	*handle;
833bda89588Sjp151216 #define	INIT_MAPPING_SIZE	32
834bda89588Sjp151216 
835bda89588Sjp151216 	zs = idmap_get_zone_specific(zone);
836c5c4113dSnw141292 
837c5c4113dSnw141292 	handle = kmem_zalloc(sizeof (idmap_get_handle_t), KM_SLEEP);
838c5c4113dSnw141292 
839c5c4113dSnw141292 	handle->mapping = kmem_zalloc((sizeof (idmap_mapping)) *
840c5c4113dSnw141292 	    INIT_MAPPING_SIZE, KM_SLEEP);
841c5c4113dSnw141292 
842c5c4113dSnw141292 	handle->result = kmem_zalloc((sizeof (idmap_get_res)) *
843c5c4113dSnw141292 	    INIT_MAPPING_SIZE, KM_SLEEP);
844c5c4113dSnw141292 	handle->mapping_size = INIT_MAPPING_SIZE;
845bda89588Sjp151216 	handle->zs = zs;
846c5c4113dSnw141292 
847c5c4113dSnw141292 	return (handle);
848c5c4113dSnw141292 }
849c5c4113dSnw141292 
850c5c4113dSnw141292 /*
851c5c4113dSnw141292  * Internal routine to extend a "get_handle"
852c5c4113dSnw141292  */
853c5c4113dSnw141292 static void
kidmap_get_extend(idmap_get_handle_t * get_handle)854c5c4113dSnw141292 kidmap_get_extend(idmap_get_handle_t *get_handle)
855c5c4113dSnw141292 {
856c5c4113dSnw141292 	idmap_mapping *mapping;
857c5c4113dSnw141292 	idmap_get_res *result;
858c5c4113dSnw141292 	int new_size = get_handle->mapping_size + INIT_MAPPING_SIZE;
859c5c4113dSnw141292 
860c5c4113dSnw141292 	mapping = kmem_zalloc((sizeof (idmap_mapping)) *
861c5c4113dSnw141292 	    new_size, KM_SLEEP);
862c5c4113dSnw141292 	(void) memcpy(mapping, get_handle->mapping,
863c5c4113dSnw141292 	    (sizeof (idmap_mapping)) * get_handle->mapping_size);
864c5c4113dSnw141292 
865c5c4113dSnw141292 	result = kmem_zalloc((sizeof (idmap_get_res)) *
866c5c4113dSnw141292 	    new_size, KM_SLEEP);
867c5c4113dSnw141292 	(void) memcpy(result, get_handle->result,
868c5c4113dSnw141292 	    (sizeof (idmap_get_res)) * get_handle->mapping_size);
869c5c4113dSnw141292 
870c5c4113dSnw141292 	kmem_free(get_handle->mapping,
871c5c4113dSnw141292 	    (sizeof (idmap_mapping)) * get_handle->mapping_size);
872c5c4113dSnw141292 	get_handle->mapping = mapping;
873c5c4113dSnw141292 
874c5c4113dSnw141292 	kmem_free(get_handle->result,
875c5c4113dSnw141292 	    (sizeof (idmap_get_res)) * get_handle->mapping_size);
876c5c4113dSnw141292 	get_handle->result = result;
877c5c4113dSnw141292 
878c5c4113dSnw141292 	get_handle->mapping_size = new_size;
879c5c4113dSnw141292 }
880c5c4113dSnw141292 
881c5c4113dSnw141292 
882c5c4113dSnw141292 /*
883c5c4113dSnw141292  * Given Domain SID and RID, get UID
884c5c4113dSnw141292  *
885c5c4113dSnw141292  * Input:
886c5c4113dSnw141292  * sid_prefix	- Domain SID in canonical form
887c5c4113dSnw141292  * rid	- RID
888c5c4113dSnw141292  *
889c5c4113dSnw141292  * Output:
890c5c4113dSnw141292  * stat - status of the get request
891c5c4113dSnw141292  * uid  - POSIX UID if stat == IDMAP_SUCCESS
892c5c4113dSnw141292  *
893*dea83360SGordon Ross  * Notes:
894*dea83360SGordon Ross  * The output parameters will be set by idmap_get_mappings()
895*dea83360SGordon Ross  * The sid_prefix is copied.
896c5c4113dSnw141292  */
897c5c4113dSnw141292 idmap_stat
kidmap_batch_getuidbysid(idmap_get_handle_t * get_handle,const char * sid_prefix,uint32_t rid,uid_t * uid,idmap_stat * stat)898c5c4113dSnw141292 kidmap_batch_getuidbysid(idmap_get_handle_t *get_handle, const char *sid_prefix,
899c5c4113dSnw141292 			uint32_t rid, uid_t *uid, idmap_stat *stat)
900c5c4113dSnw141292 {
901c5c4113dSnw141292 	idmap_mapping	*mapping;
902c5c4113dSnw141292 	idmap_get_res 	*result;
903c5c4113dSnw141292 
904c5c4113dSnw141292 	if (get_handle == NULL || sid_prefix == NULL ||
905c5c4113dSnw141292 	    uid == NULL || stat == NULL)
906c5c4113dSnw141292 		return (IDMAP_ERR_ARG);
907c5c4113dSnw141292 
908bda89588Sjp151216 	if (kidmap_cache_lookup_uidbysid(&get_handle->zs->cache, sid_prefix,
9090b10de9fSjp151216 	    rid, uid) == IDMAP_SUCCESS) {
910c5c4113dSnw141292 		*stat = IDMAP_SUCCESS;
911c5c4113dSnw141292 		return (IDMAP_SUCCESS);
912c5c4113dSnw141292 	}
913c5c4113dSnw141292 
914*dea83360SGordon Ross 	/* Get a copy of sid_prefix */
915*dea83360SGordon Ross 	sid_prefix = kidmap_find_sid_prefix(sid_prefix);
916*dea83360SGordon Ross 
917c5c4113dSnw141292 	if (get_handle->mapping_num >= get_handle->mapping_size)
918c5c4113dSnw141292 		kidmap_get_extend(get_handle);
919c5c4113dSnw141292 
920c5c4113dSnw141292 	mapping = &get_handle->mapping[get_handle->mapping_num];
921c5c4113dSnw141292 	mapping->flag = 0;
922c5c4113dSnw141292 	mapping->id1.idtype = IDMAP_SID;
923c5c4113dSnw141292 	mapping->id1.idmap_id_u.sid.prefix = (char *)sid_prefix;
924c5c4113dSnw141292 	mapping->id1.idmap_id_u.sid.rid = rid;
925c5c4113dSnw141292 	mapping->id2.idtype = IDMAP_UID;
926c5c4113dSnw141292 
927c5c4113dSnw141292 	result = &get_handle->result[get_handle->mapping_num];
928c5c4113dSnw141292 	result->idtype = IDMAP_UID;
929c5c4113dSnw141292 	result->uid = uid;
930c5c4113dSnw141292 	result->gid = NULL;
9310b10de9fSjp151216 	result->pid = NULL;
932c5c4113dSnw141292 	result->sid_prefix = NULL;
933c5c4113dSnw141292 	result->rid = NULL;
934c5c4113dSnw141292 	result->is_user = NULL;
935c5c4113dSnw141292 	result->stat = stat;
936c5c4113dSnw141292 
937c5c4113dSnw141292 	get_handle->mapping_num++;
938c5c4113dSnw141292 
939c5c4113dSnw141292 	return (IDMAP_SUCCESS);
940c5c4113dSnw141292 }
941c5c4113dSnw141292 
942c5c4113dSnw141292 
943c5c4113dSnw141292 /*
944c5c4113dSnw141292  * Given Domain SID and RID, get GID
945c5c4113dSnw141292  *
946c5c4113dSnw141292  * Input:
947c5c4113dSnw141292  * sid_prefix	- Domain SID in canonical form
948c5c4113dSnw141292  * rid	- RID
949c5c4113dSnw141292  *
950c5c4113dSnw141292  * Output:
951c5c4113dSnw141292  * stat - status of the get request
952c5c4113dSnw141292  * gid  - POSIX GID if stat == IDMAP_SUCCESS
953c5c4113dSnw141292  *
954*dea83360SGordon Ross  * Notes:
955*dea83360SGordon Ross  * The output parameters will be set by idmap_get_mappings()
956*dea83360SGordon Ross  * The sid_prefix is copied.
957c5c4113dSnw141292  */
958c5c4113dSnw141292 idmap_stat
kidmap_batch_getgidbysid(idmap_get_handle_t * get_handle,const char * sid_prefix,uint32_t rid,uid_t * gid,idmap_stat * stat)959c5c4113dSnw141292 kidmap_batch_getgidbysid(idmap_get_handle_t *get_handle, const char *sid_prefix,
960c5c4113dSnw141292 			uint32_t rid, uid_t *gid, idmap_stat *stat)
961c5c4113dSnw141292 {
962c5c4113dSnw141292 	idmap_mapping	*mapping;
963c5c4113dSnw141292 	idmap_get_res 	*result;
964c5c4113dSnw141292 
965c5c4113dSnw141292 	if (get_handle == NULL || sid_prefix == NULL ||
966c5c4113dSnw141292 	    gid == NULL || stat == NULL)
967c5c4113dSnw141292 		return (IDMAP_ERR_ARG);
968c5c4113dSnw141292 
969bda89588Sjp151216 	if (kidmap_cache_lookup_gidbysid(&get_handle->zs->cache, sid_prefix,
9700b10de9fSjp151216 	    rid, gid) == IDMAP_SUCCESS) {
971c5c4113dSnw141292 		*stat = IDMAP_SUCCESS;
972c5c4113dSnw141292 		return (IDMAP_SUCCESS);
973c5c4113dSnw141292 	}
974c5c4113dSnw141292 
975*dea83360SGordon Ross 	/* Get a copy of sid_prefix */
976*dea83360SGordon Ross 	sid_prefix = kidmap_find_sid_prefix(sid_prefix);
977*dea83360SGordon Ross 
978c5c4113dSnw141292 	if (get_handle->mapping_num >= get_handle->mapping_size)
979c5c4113dSnw141292 		kidmap_get_extend(get_handle);
980c5c4113dSnw141292 
981c5c4113dSnw141292 	mapping = &get_handle->mapping[get_handle->mapping_num];
982c5c4113dSnw141292 	mapping->flag = 0;
983c5c4113dSnw141292 	mapping->id1.idtype = IDMAP_SID;
984c5c4113dSnw141292 	mapping->id1.idmap_id_u.sid.prefix = (char *)sid_prefix;
985c5c4113dSnw141292 	mapping->id1.idmap_id_u.sid.rid = rid;
986c5c4113dSnw141292 	mapping->id2.idtype = IDMAP_GID;
987c5c4113dSnw141292 
988c5c4113dSnw141292 	result = &get_handle->result[get_handle->mapping_num];
989c5c4113dSnw141292 	result->idtype = IDMAP_GID;
990c5c4113dSnw141292 	result->uid = NULL;
991c5c4113dSnw141292 	result->gid = gid;
9920b10de9fSjp151216 	result->pid = NULL;
993c5c4113dSnw141292 	result->sid_prefix = NULL;
994c5c4113dSnw141292 	result->rid = NULL;
995c5c4113dSnw141292 	result->is_user = NULL;
996c5c4113dSnw141292 	result->stat = stat;
997c5c4113dSnw141292 
998c5c4113dSnw141292 	get_handle->mapping_num++;
999c5c4113dSnw141292 
1000c5c4113dSnw141292 	return (IDMAP_SUCCESS);
1001c5c4113dSnw141292 }
1002c5c4113dSnw141292 
1003c5c4113dSnw141292 
1004c5c4113dSnw141292 /*
1005c5c4113dSnw141292  * Given Domain SID and RID, get Posix ID
1006c5c4113dSnw141292  *
1007c5c4113dSnw141292  * Input:
1008c5c4113dSnw141292  * sid_prefix	- Domain SID in canonical form
1009c5c4113dSnw141292  * rid	- RID
1010c5c4113dSnw141292  *
1011c5c4113dSnw141292  * Output:
1012c5c4113dSnw141292  * stat    - status of the get request
1013c5c4113dSnw141292  * is_user - user or group
1014c5c4113dSnw141292  * pid     - POSIX UID if stat == IDMAP_SUCCESS and is_user == 1
1015c5c4113dSnw141292  *           POSIX GID if stat == IDMAP_SUCCESS and is_user == 0
1016c5c4113dSnw141292  *
1017*dea83360SGordon Ross  * Notes:
1018*dea83360SGordon Ross  * The output parameters will be set by idmap_get_mappings()
1019*dea83360SGordon Ross  * The sid_prefix is copied.
1020c5c4113dSnw141292  */
1021c5c4113dSnw141292 idmap_stat
kidmap_batch_getpidbysid(idmap_get_handle_t * get_handle,const char * sid_prefix,uint32_t rid,uid_t * pid,int * is_user,idmap_stat * stat)1022c5c4113dSnw141292 kidmap_batch_getpidbysid(idmap_get_handle_t *get_handle, const char *sid_prefix,
1023c5c4113dSnw141292 		uint32_t rid, uid_t *pid, int *is_user, idmap_stat *stat)
1024c5c4113dSnw141292 {
1025c5c4113dSnw141292 	idmap_mapping	*mapping;
1026c5c4113dSnw141292 	idmap_get_res 	*result;
1027c5c4113dSnw141292 
1028c5c4113dSnw141292 	if (get_handle == NULL || sid_prefix == NULL || pid == NULL ||
1029c5c4113dSnw141292 	    is_user == NULL || stat == NULL)
1030c5c4113dSnw141292 		return (IDMAP_ERR_ARG);
1031c5c4113dSnw141292 
1032bda89588Sjp151216 	if (kidmap_cache_lookup_pidbysid(&get_handle->zs->cache, sid_prefix,
1033c5c4113dSnw141292 	    rid, pid, is_user) == IDMAP_SUCCESS) {
1034c5c4113dSnw141292 		*stat = IDMAP_SUCCESS;
1035c5c4113dSnw141292 		return (IDMAP_SUCCESS);
1036c5c4113dSnw141292 	}
1037c5c4113dSnw141292 
1038*dea83360SGordon Ross 	/* Get a copy of sid_prefix */
1039*dea83360SGordon Ross 	sid_prefix = kidmap_find_sid_prefix(sid_prefix);
1040c5c4113dSnw141292 
1041c5c4113dSnw141292 	if (get_handle->mapping_num >= get_handle->mapping_size)
1042c5c4113dSnw141292 		kidmap_get_extend(get_handle);
1043c5c4113dSnw141292 
1044c5c4113dSnw141292 	mapping = &get_handle->mapping[get_handle->mapping_num];
1045c5c4113dSnw141292 	mapping->flag = 0;
1046c5c4113dSnw141292 	mapping->id1.idtype = IDMAP_SID;
1047c5c4113dSnw141292 	mapping->id1.idmap_id_u.sid.prefix = (char *)sid_prefix;
1048c5c4113dSnw141292 	mapping->id1.idmap_id_u.sid.rid = rid;
1049c5c4113dSnw141292 	mapping->id2.idtype = IDMAP_POSIXID;
1050c5c4113dSnw141292 
1051c5c4113dSnw141292 	result = &get_handle->result[get_handle->mapping_num];
1052c5c4113dSnw141292 	result->idtype = IDMAP_POSIXID;
10530b10de9fSjp151216 	result->uid = NULL;
10540b10de9fSjp151216 	result->gid = NULL;
10550b10de9fSjp151216 	result->pid = pid;
1056c5c4113dSnw141292 	result->sid_prefix = NULL;
1057c5c4113dSnw141292 	result->rid = NULL;
1058c5c4113dSnw141292 	result->is_user = is_user;
1059c5c4113dSnw141292 	result->stat = stat;
1060c5c4113dSnw141292 
1061c5c4113dSnw141292 	get_handle->mapping_num++;
1062c5c4113dSnw141292 
1063c5c4113dSnw141292 	return (IDMAP_SUCCESS);
1064c5c4113dSnw141292 }
1065c5c4113dSnw141292 
1066c5c4113dSnw141292 
1067c5c4113dSnw141292 /*
1068c5c4113dSnw141292  * Given UID, get SID and RID
1069c5c4113dSnw141292  *
1070c5c4113dSnw141292  * Input:
1071c5c4113dSnw141292  * uid  - POSIX UID
1072c5c4113dSnw141292  *
1073c5c4113dSnw141292  * Output:
1074c5c4113dSnw141292  * stat - status of the get request
1075c5c4113dSnw141292  * sid  - SID in canonical form (if stat == IDMAP_SUCCESS)
1076c5c4113dSnw141292  * rid	- RID (if stat == IDMAP_SUCCESS)
1077c5c4113dSnw141292  *
1078c5c4113dSnw141292  * Note: The output parameters will be set by idmap_get_mappings()
1079c5c4113dSnw141292  */
1080c5c4113dSnw141292 idmap_stat
kidmap_batch_getsidbyuid(idmap_get_handle_t * get_handle,uid_t uid,const char ** sid_prefix,uint32_t * rid,idmap_stat * stat)1081c5c4113dSnw141292 kidmap_batch_getsidbyuid(idmap_get_handle_t *get_handle, uid_t uid,
1082c5c4113dSnw141292 		const char **sid_prefix, uint32_t *rid, idmap_stat *stat)
1083c5c4113dSnw141292 {
1084c5c4113dSnw141292 	idmap_mapping	*mapping;
1085c5c4113dSnw141292 	idmap_get_res 	*result;
1086c5c4113dSnw141292 
1087c5c4113dSnw141292 	if (get_handle == NULL || sid_prefix == NULL ||
1088c5c4113dSnw141292 	    rid == NULL || stat == NULL)
1089c5c4113dSnw141292 		return (IDMAP_ERR_ARG);
1090c5c4113dSnw141292 
1091bda89588Sjp151216 	if (kidmap_cache_lookup_sidbyuid(&get_handle->zs->cache,
1092bda89588Sjp151216 	    sid_prefix, rid, uid) == IDMAP_SUCCESS) {
1093c5c4113dSnw141292 		*stat = IDMAP_SUCCESS;
1094c5c4113dSnw141292 		return (IDMAP_SUCCESS);
1095c5c4113dSnw141292 	}
1096c5c4113dSnw141292 
1097c5c4113dSnw141292 	if (get_handle->mapping_num >= get_handle->mapping_size)
1098c5c4113dSnw141292 		kidmap_get_extend(get_handle);
1099c5c4113dSnw141292 
1100c5c4113dSnw141292 	mapping = &get_handle->mapping[get_handle->mapping_num];
1101c5c4113dSnw141292 	mapping->flag = 0;
1102c5c4113dSnw141292 	mapping->id1.idtype = IDMAP_UID;
1103c5c4113dSnw141292 	mapping->id1.idmap_id_u.uid = uid;
1104c5c4113dSnw141292 	mapping->id2.idtype = IDMAP_SID;
1105c5c4113dSnw141292 
1106c5c4113dSnw141292 	result = &get_handle->result[get_handle->mapping_num];
1107c5c4113dSnw141292 	result->idtype = IDMAP_SID;
1108c5c4113dSnw141292 	result->uid = NULL;
1109c5c4113dSnw141292 	result->gid = NULL;
11100b10de9fSjp151216 	result->pid = NULL;
1111c5c4113dSnw141292 	result->sid_prefix = sid_prefix;
1112c5c4113dSnw141292 	result->rid = rid;
1113c5c4113dSnw141292 	result->is_user = NULL;
1114c5c4113dSnw141292 	result->stat = stat;
1115c5c4113dSnw141292 
1116c5c4113dSnw141292 	get_handle->mapping_num++;
1117c5c4113dSnw141292 
1118c5c4113dSnw141292 	return (IDMAP_SUCCESS);
1119c5c4113dSnw141292 }
1120c5c4113dSnw141292 
1121c5c4113dSnw141292 
1122c5c4113dSnw141292 /*
1123c5c4113dSnw141292  * Given GID, get SID and RID
1124c5c4113dSnw141292  *
1125c5c4113dSnw141292  * Input:
1126c5c4113dSnw141292  * gid  - POSIX GID
1127c5c4113dSnw141292  *
1128c5c4113dSnw141292  * Output:
1129c5c4113dSnw141292  * stat - status of the get request
1130c5c4113dSnw141292  * sid  - SID in canonical form (if stat == IDMAP_SUCCESS)
1131c5c4113dSnw141292  * rid	- RID (if stat == IDMAP_SUCCESS)
1132c5c4113dSnw141292  *
1133c5c4113dSnw141292  * Note: The output parameters will be set by idmap_get_mappings()
1134c5c4113dSnw141292  */
1135c5c4113dSnw141292 idmap_stat
kidmap_batch_getsidbygid(idmap_get_handle_t * get_handle,gid_t gid,const char ** sid_prefix,uint32_t * rid,idmap_stat * stat)1136c5c4113dSnw141292 kidmap_batch_getsidbygid(idmap_get_handle_t *get_handle, gid_t gid,
1137c5c4113dSnw141292 		const char **sid_prefix, uint32_t *rid, idmap_stat *stat)
1138c5c4113dSnw141292 {
1139c5c4113dSnw141292 	idmap_mapping	*mapping;
1140c5c4113dSnw141292 	idmap_get_res 	*result;
1141c5c4113dSnw141292 
1142c5c4113dSnw141292 	if (get_handle == NULL || sid_prefix == NULL ||
1143c5c4113dSnw141292 	    rid == NULL || stat == NULL)
1144c5c4113dSnw141292 		return (IDMAP_ERR_ARG);
1145c5c4113dSnw141292 
1146bda89588Sjp151216 	if (kidmap_cache_lookup_sidbygid(&get_handle->zs->cache,
1147bda89588Sjp151216 	    sid_prefix, rid, gid) == IDMAP_SUCCESS) {
1148c5c4113dSnw141292 		*stat = IDMAP_SUCCESS;
1149c5c4113dSnw141292 		return (IDMAP_SUCCESS);
1150c5c4113dSnw141292 	}
1151c5c4113dSnw141292 
1152c5c4113dSnw141292 	if (get_handle->mapping_num >= get_handle->mapping_size)
1153c5c4113dSnw141292 		kidmap_get_extend(get_handle);
1154c5c4113dSnw141292 
1155c5c4113dSnw141292 	mapping = &get_handle->mapping[get_handle->mapping_num];
1156c5c4113dSnw141292 	mapping->flag = 0;
1157c5c4113dSnw141292 	mapping->id1.idtype = IDMAP_GID;
1158c5c4113dSnw141292 	mapping->id1.idmap_id_u.gid = gid;
1159c5c4113dSnw141292 	mapping->id2.idtype = IDMAP_SID;
1160c5c4113dSnw141292 
1161c5c4113dSnw141292 	result = &get_handle->result[get_handle->mapping_num];
1162c5c4113dSnw141292 	result->idtype = IDMAP_SID;
1163c5c4113dSnw141292 	result->uid = NULL;
1164c5c4113dSnw141292 	result->gid = NULL;
11650b10de9fSjp151216 	result->pid = NULL;
1166c5c4113dSnw141292 	result->sid_prefix = sid_prefix;
1167c5c4113dSnw141292 	result->rid = rid;
1168c5c4113dSnw141292 	result->is_user = NULL;
1169c5c4113dSnw141292 	result->stat = stat;
1170c5c4113dSnw141292 
1171c5c4113dSnw141292 	get_handle->mapping_num++;
1172c5c4113dSnw141292 
1173c5c4113dSnw141292 	return (IDMAP_SUCCESS);
1174c5c4113dSnw141292 }
1175c5c4113dSnw141292 
1176c5c4113dSnw141292 
1177c5c4113dSnw141292 /*
1178c5c4113dSnw141292  * Process the batched "get mapping" requests. The results (i.e.
1179c5c4113dSnw141292  * status and identity) will be available in the data areas
1180c5c4113dSnw141292  * provided by individual requests.
1181c5c4113dSnw141292  *
1182c5c4113dSnw141292  * If the door call fails the status IDMAP_ERR_NOMAPPING is
1183c5c4113dSnw141292  * return and the UID or UID result is set to "nobody"
1184c5c4113dSnw141292  */
1185c5c4113dSnw141292 
1186c5c4113dSnw141292 idmap_stat
kidmap_get_mappings(idmap_get_handle_t * get_handle)1187c5c4113dSnw141292 kidmap_get_mappings(idmap_get_handle_t *get_handle)
1188c5c4113dSnw141292 {
11899d0aba92Sjp151216 	idmap_mapping_batch	rpc_args;
11909d0aba92Sjp151216 	idmap_ids_res		rpc_res;
1191c5c4113dSnw141292 	uint32_t		op = IDMAP_GET_MAPPED_IDS;
1192d15447b6Sjp151216 	idmap_mapping		*request;
1193c5c4113dSnw141292 	idmap_get_res		*result;
1194c5c4113dSnw141292 	idmap_id		*id;
1195c5c4113dSnw141292 	int			status;
1196c5c4113dSnw141292 	int			i;
1197c5c4113dSnw141292 	const char		*sid_prefix;
1198c5c4113dSnw141292 	int			is_user;
1199bda89588Sjp151216 	idmap_cache_t		*cache;
1200d15447b6Sjp151216 	int			direction;
1201c5c4113dSnw141292 
1202c5c4113dSnw141292 	if (get_handle == NULL)
1203c5c4113dSnw141292 		return (IDMAP_ERR_ARG);
1204c5c4113dSnw141292 
1205c5c4113dSnw141292 	if (get_handle->mapping_num == 0)
1206c5c4113dSnw141292 		return (IDMAP_SUCCESS);
1207bda89588Sjp151216 	cache = &get_handle->zs->cache;
1208c5c4113dSnw141292 
12099d0aba92Sjp151216 	bzero(&rpc_res, sizeof (idmap_ids_res));
1210c5c4113dSnw141292 
12119d0aba92Sjp151216 	rpc_args.idmap_mapping_batch_len = get_handle->mapping_num;
12129d0aba92Sjp151216 	rpc_args.idmap_mapping_batch_val = get_handle->mapping;
1213c5c4113dSnw141292 
1214bda89588Sjp151216 	if (kidmap_rpc_call(get_handle->zs, op, xdr_idmap_mapping_batch,
12159d0aba92Sjp151216 	    (caddr_t)&rpc_args, xdr_idmap_ids_res,
12169d0aba92Sjp151216 	    (caddr_t)&rpc_res) != 0) {
12179d0aba92Sjp151216 		/* Door call failed */
12189d0aba92Sjp151216 		status = IDMAP_ERR_NOMAPPING;
12199d0aba92Sjp151216 		goto error;
12209d0aba92Sjp151216 	}
12219d0aba92Sjp151216 
12229d0aba92Sjp151216 	status = rpc_res.retcode;
12239d0aba92Sjp151216 	if (status != IDMAP_SUCCESS) {
12249d0aba92Sjp151216 		/* RPC returned idmap error code */
12259d0aba92Sjp151216 		xdr_free(xdr_idmap_ids_res, (char *)&rpc_res);
12269d0aba92Sjp151216 		goto error;
12279d0aba92Sjp151216 	}
12289d0aba92Sjp151216 
1229c5c4113dSnw141292 	for (i = 0; i < get_handle->mapping_num; i++) {
1230d15447b6Sjp151216 		request = &get_handle->mapping[i];
1231c5c4113dSnw141292 		result =  &get_handle->result[i];
1232c5c4113dSnw141292 
12339d0aba92Sjp151216 		if (i >= rpc_res.ids.ids_len) {
1234c5c4113dSnw141292 			*result->stat =	IDMAP_ERR_NOMAPPING;
1235c5c4113dSnw141292 			if (result->uid)
1236c5c4113dSnw141292 				*result->uid = UID_NOBODY;
12370b10de9fSjp151216 			if (result->gid)
12380b10de9fSjp151216 				*result->gid = GID_NOBODY;
12390b10de9fSjp151216 			if (result->pid)
12400b10de9fSjp151216 				*result->pid = UID_NOBODY;
1241c5c4113dSnw141292 			if (result->is_user)
1242c5c4113dSnw141292 				*result->is_user = 1;
1243c5c4113dSnw141292 			if (result->sid_prefix)
1244c5c4113dSnw141292 				*result->sid_prefix = NULL;
1245c5c4113dSnw141292 			if (result->rid)
1246c5c4113dSnw141292 				*result->rid = 0;
1247c5c4113dSnw141292 			continue;
1248c5c4113dSnw141292 		}
1249c5c4113dSnw141292 
12509d0aba92Sjp151216 		*result->stat = rpc_res.ids.ids_val[i].retcode;
12519d0aba92Sjp151216 
12529d0aba92Sjp151216 		id = &rpc_res.ids.ids_val[i].id;
1253d15447b6Sjp151216 		direction = rpc_res.ids.ids_val[i].direction;
1254d15447b6Sjp151216 
1255c5c4113dSnw141292 		switch (id->idtype) {
1256c5c4113dSnw141292 		case IDMAP_UID:
1257c5c4113dSnw141292 			if (result->uid)
1258c5c4113dSnw141292 				*result->uid = id->idmap_id_u.uid;
12590b10de9fSjp151216 			if (result->pid)
12600b10de9fSjp151216 				*result->pid = id->idmap_id_u.uid;
1261c5c4113dSnw141292 			if (result->is_user)
1262c5c4113dSnw141292 				*result->is_user = 1;
1263c5c4113dSnw141292 			sid_prefix = kidmap_find_sid_prefix(
1264d15447b6Sjp151216 			    request->id1.idmap_id_u.sid.prefix);
12659d0aba92Sjp151216 			if (*result->stat == IDMAP_SUCCESS && result->uid)
1266d15447b6Sjp151216 				kidmap_cache_add_sid2uid(
12679d0aba92Sjp151216 				    cache, sid_prefix,
1268d15447b6Sjp151216 				    request->id1.idmap_id_u.sid.rid,
1269d15447b6Sjp151216 				    id->idmap_id_u.uid,
1270d15447b6Sjp151216 				    direction);
12719d0aba92Sjp151216 			else if (*result->stat == IDMAP_SUCCESS && result->pid)
1272d15447b6Sjp151216 				kidmap_cache_add_sid2pid(
12739d0aba92Sjp151216 				    cache, sid_prefix,
1274d15447b6Sjp151216 				    request->id1.idmap_id_u.sid.rid,
1275d15447b6Sjp151216 				    id->idmap_id_u.uid, 1,
1276d15447b6Sjp151216 				    direction);
1277c5c4113dSnw141292 			break;
1278c5c4113dSnw141292 
1279c5c4113dSnw141292 		case IDMAP_GID:
1280c5c4113dSnw141292 			if (result->gid)
1281c5c4113dSnw141292 				*result->gid = id->idmap_id_u.gid;
12820b10de9fSjp151216 			if (result->pid)
12830b10de9fSjp151216 				*result->pid = id->idmap_id_u.gid;
1284c5c4113dSnw141292 			if (result->is_user)
1285c5c4113dSnw141292 				*result->is_user = 0;
1286c5c4113dSnw141292 			sid_prefix = kidmap_find_sid_prefix(
1287d15447b6Sjp151216 			    request->id1.idmap_id_u.sid.prefix);
12889d0aba92Sjp151216 			if (*result->stat == IDMAP_SUCCESS && result->gid)
1289d15447b6Sjp151216 				kidmap_cache_add_sid2gid(
12909d0aba92Sjp151216 				    cache, sid_prefix,
1291d15447b6Sjp151216 				    request->id1.idmap_id_u.sid.rid,
1292d15447b6Sjp151216 				    id->idmap_id_u.gid,
1293d15447b6Sjp151216 				    direction);
12949d0aba92Sjp151216 			else if (*result->stat == IDMAP_SUCCESS && result->pid)
1295d15447b6Sjp151216 				kidmap_cache_add_sid2pid(
12969d0aba92Sjp151216 				    cache, sid_prefix,
1297d15447b6Sjp151216 				    request->id1.idmap_id_u.sid.rid,
1298d15447b6Sjp151216 				    id->idmap_id_u.gid, 0,
1299d15447b6Sjp151216 				    direction);
1300c5c4113dSnw141292 			break;
1301c5c4113dSnw141292 
1302c5c4113dSnw141292 		case IDMAP_SID:
1303cd37da74Snw141292 		case IDMAP_USID:
1304cd37da74Snw141292 		case IDMAP_GSID:
1305c5c4113dSnw141292 			sid_prefix = kidmap_find_sid_prefix(
1306c5c4113dSnw141292 			    id->idmap_id_u.sid.prefix);
1307c5c4113dSnw141292 			if (result->sid_prefix && result->rid) {
1308c5c4113dSnw141292 				*result->sid_prefix = sid_prefix;
1309c5c4113dSnw141292 				*result->rid = id->idmap_id_u.sid.rid;
1310c5c4113dSnw141292 			}
13110b10de9fSjp151216 			if (*result->stat == IDMAP_SUCCESS &&
1312d15447b6Sjp151216 			    request->id1.idtype == IDMAP_UID)
1313d15447b6Sjp151216 				kidmap_cache_add_sid2uid(
13149d0aba92Sjp151216 				    cache, sid_prefix,
1315c5c4113dSnw141292 				    id->idmap_id_u.sid.rid,
1316d15447b6Sjp151216 				    request->id1.idmap_id_u.uid,
1317d15447b6Sjp151216 				    direction);
13180b10de9fSjp151216 			else if (*result->stat == IDMAP_SUCCESS &&
1319d15447b6Sjp151216 			    request->id1.idtype == IDMAP_GID)
1320d15447b6Sjp151216 				kidmap_cache_add_sid2gid(
13219d0aba92Sjp151216 				    cache, sid_prefix,
13220b10de9fSjp151216 				    id->idmap_id_u.sid.rid,
1323d15447b6Sjp151216 				    request->id1.idmap_id_u.gid,
1324d15447b6Sjp151216 				    direction);
1325c5c4113dSnw141292 			break;
1326c5c4113dSnw141292 
1327c5c4113dSnw141292 		default:
1328c5c4113dSnw141292 			*result->stat = IDMAP_ERR_NORESULT;
1329c5c4113dSnw141292 			if (result->uid)
1330c5c4113dSnw141292 				*result->uid = UID_NOBODY;
13310b10de9fSjp151216 			if (result->gid)
13320b10de9fSjp151216 				*result->gid = GID_NOBODY;
13330b10de9fSjp151216 			if (result->pid)
13340b10de9fSjp151216 				*result->pid = UID_NOBODY;
1335c5c4113dSnw141292 			if (result->is_user)
1336c5c4113dSnw141292 				*result->is_user = 1;
1337c5c4113dSnw141292 			if (result->sid_prefix)
1338c5c4113dSnw141292 				*result->sid_prefix = NULL;
1339c5c4113dSnw141292 			if (result->rid)
1340c5c4113dSnw141292 				*result->rid = 0;
1341c5c4113dSnw141292 			break;
1342c5c4113dSnw141292 		}
1343c5c4113dSnw141292 	}
13449d0aba92Sjp151216 	xdr_free(xdr_idmap_ids_res, (char *)&rpc_res);
13459d0aba92Sjp151216 
13469d0aba92Sjp151216 	/* Reset get_handle for new resquests */
13479d0aba92Sjp151216 	get_handle->mapping_num = 0;
13489d0aba92Sjp151216 	return (status);
13499d0aba92Sjp151216 
13509d0aba92Sjp151216 error:
1351c5c4113dSnw141292 	for (i = 0; i < get_handle->mapping_num; i++) {
1352c5c4113dSnw141292 		result =  &get_handle->result[i];
1353c5c4113dSnw141292 
13549d0aba92Sjp151216 		*result->stat = status;
1355c5c4113dSnw141292 		if (result->uid)
1356c5c4113dSnw141292 			*result->uid = UID_NOBODY;
13570b10de9fSjp151216 		if (result->gid)
13580b10de9fSjp151216 			*result->gid = GID_NOBODY;
13590b10de9fSjp151216 		if (result->pid)
13600b10de9fSjp151216 			*result->pid = UID_NOBODY;
1361c5c4113dSnw141292 		if (result->is_user)
1362c5c4113dSnw141292 			*result->is_user = 1;
1363c5c4113dSnw141292 		if (result->sid_prefix)
1364c5c4113dSnw141292 			*result->sid_prefix = NULL;
1365c5c4113dSnw141292 		if (result->rid)
1366c5c4113dSnw141292 			*result->rid = 0;
1367c5c4113dSnw141292 	}
1368c5c4113dSnw141292 
1369c5c4113dSnw141292 	/* Reset get_handle for new resquests */
1370c5c4113dSnw141292 	get_handle->mapping_num = 0;
1371c5c4113dSnw141292 	return (status);
1372c5c4113dSnw141292 }
1373c5c4113dSnw141292 
1374c5c4113dSnw141292 
1375c5c4113dSnw141292 /*
1376c5c4113dSnw141292  * Destroy the "get mapping" handle
1377c5c4113dSnw141292  */
1378c5c4113dSnw141292 void
kidmap_get_destroy(idmap_get_handle_t * get_handle)1379c5c4113dSnw141292 kidmap_get_destroy(idmap_get_handle_t *get_handle)
1380c5c4113dSnw141292 {
1381c5c4113dSnw141292 	if (get_handle == NULL)
1382c5c4113dSnw141292 		return;
1383c5c4113dSnw141292 
1384c5c4113dSnw141292 	kmem_free(get_handle->mapping,
1385c5c4113dSnw141292 	    (sizeof (idmap_mapping)) * get_handle->mapping_size);
1386c5c4113dSnw141292 	get_handle->mapping = NULL;
1387c5c4113dSnw141292 
1388c5c4113dSnw141292 	kmem_free(get_handle->result,
1389c5c4113dSnw141292 	    (sizeof (idmap_get_res)) * get_handle->mapping_size);
1390c5c4113dSnw141292 	get_handle->result = NULL;
1391c5c4113dSnw141292 
1392c5c4113dSnw141292 	kmem_free(get_handle, sizeof (idmap_get_handle_t));
1393c5c4113dSnw141292 }
1394c5c4113dSnw141292 
1395c5c4113dSnw141292 
1396c5c4113dSnw141292 static int
kidmap_rpc_call(idmap_zone_specific_t * zs,uint32_t op,xdrproc_t xdr_args,caddr_t args,xdrproc_t xdr_res,caddr_t res)1397bda89588Sjp151216 kidmap_rpc_call(idmap_zone_specific_t *zs, uint32_t op, xdrproc_t xdr_args,
1398bda89588Sjp151216 		caddr_t args, xdrproc_t xdr_res, caddr_t res)
1399c5c4113dSnw141292 {
1400c5c4113dSnw141292 	XDR		xdr_ctx;
1401c5c4113dSnw141292 	struct	rpc_msg reply_msg;
1402c5c4113dSnw141292 	char		*inbuf_ptr = NULL;
1403c5c4113dSnw141292 	size_t		inbuf_size = 4096;
1404c5c4113dSnw141292 	char		*outbuf_ptr = NULL;
1405c5c4113dSnw141292 	size_t 		outbuf_size = 4096;
1406c5c4113dSnw141292 	size_t		size;
1407c5c4113dSnw141292 	int		status = 0;
1408c5c4113dSnw141292 	door_arg_t	params;
1409c5c4113dSnw141292 	int 		retry = 0;
1410bda89588Sjp151216 	struct rpc_msg	call_msg;
1411c5c4113dSnw141292 
1412c5c4113dSnw141292 	params.rbuf = NULL;
1413c5c4113dSnw141292 	params.rsize = 0;
1414c5c4113dSnw141292 
1415c5c4113dSnw141292 retry:
1416c5c4113dSnw141292 	inbuf_ptr = kmem_alloc(inbuf_size, KM_SLEEP);
1417c5c4113dSnw141292 	outbuf_ptr = kmem_alloc(outbuf_size, KM_SLEEP);
1418c5c4113dSnw141292 
1419c5c4113dSnw141292 	xdrmem_create(&xdr_ctx, inbuf_ptr, inbuf_size, XDR_ENCODE);
1420bda89588Sjp151216 
1421bda89588Sjp151216 	call_msg.rm_call.cb_prog = IDMAP_PROG;
1422bda89588Sjp151216 	call_msg.rm_call.cb_vers = IDMAP_V1;
1423bda89588Sjp151216 	call_msg.rm_xid = atomic_inc_32_nv(&zs->message_id);
1424bda89588Sjp151216 
1425c5c4113dSnw141292 	if (!xdr_callhdr(&xdr_ctx, &call_msg)) {
1426c5c4113dSnw141292 #ifdef	DEBUG
1427f7b4b2feSjp151216 		zcmn_err(zs->zone_id, CE_WARN,
1428f7b4b2feSjp151216 		    "idmap: xdr encoding header error");
1429c5c4113dSnw141292 #endif	/* DEBUG */
1430c5c4113dSnw141292 		status = -1;
1431c5c4113dSnw141292 		goto exit;
1432c5c4113dSnw141292 	}
1433c5c4113dSnw141292 
1434c5c4113dSnw141292 	if (!xdr_uint32(&xdr_ctx, &op) ||
1435c5c4113dSnw141292 	    /* Auth none */
1436c5c4113dSnw141292 	    !xdr_opaque_auth(&xdr_ctx, &_null_auth) ||
1437c5c4113dSnw141292 	    !xdr_opaque_auth(&xdr_ctx, &_null_auth) ||
1438c5c4113dSnw141292 	    /* RPC args */
1439c5c4113dSnw141292 	    !xdr_args(&xdr_ctx, args)) {
1440c5c4113dSnw141292 #ifdef	DEBUG
1441f7b4b2feSjp151216 		zcmn_err(zs->zone_id, CE_WARN, "idmap: xdr encoding error");
1442c5c4113dSnw141292 #endif	/* DEBUG */
1443c5c4113dSnw141292 		if (retry > 2) {
1444c5c4113dSnw141292 			status = -1;
1445c5c4113dSnw141292 			goto exit;
1446c5c4113dSnw141292 		}
1447c5c4113dSnw141292 		retry++;
1448c5c4113dSnw141292 		if (inbuf_ptr) {
1449c5c4113dSnw141292 			kmem_free(inbuf_ptr, inbuf_size);
1450c5c4113dSnw141292 			inbuf_ptr = NULL;
1451c5c4113dSnw141292 		}
1452c5c4113dSnw141292 		if (outbuf_ptr) {
1453c5c4113dSnw141292 			kmem_free(outbuf_ptr, outbuf_size);
1454c5c4113dSnw141292 			outbuf_ptr = NULL;
1455c5c4113dSnw141292 		}
1456c5c4113dSnw141292 		if ((size = xdr_sizeof(xdr_args, args)) == 0) {
1457c5c4113dSnw141292 #ifdef	DEBUG
1458f7b4b2feSjp151216 			zcmn_err(zs->zone_id, CE_WARN,
1459f7b4b2feSjp151216 			    "idmap: xdr_sizeof error");
1460c5c4113dSnw141292 #endif	/* DEBUG */
1461c5c4113dSnw141292 			status = -1;
1462c5c4113dSnw141292 			goto exit;
1463c5c4113dSnw141292 		}
1464c5c4113dSnw141292 		inbuf_size = size + 1024;
1465c5c4113dSnw141292 		outbuf_size = size + 1024;
1466c5c4113dSnw141292 		goto retry;
1467c5c4113dSnw141292 	}
1468c5c4113dSnw141292 
1469c5c4113dSnw141292 	params.data_ptr = inbuf_ptr;
1470c5c4113dSnw141292 	params.data_size = XDR_GETPOS(&xdr_ctx);
1471c5c4113dSnw141292 	params.desc_ptr = NULL;
1472c5c4113dSnw141292 	params.desc_num = 0;
1473c5c4113dSnw141292 	params.rbuf = outbuf_ptr;
1474c5c4113dSnw141292 	params.rsize = outbuf_size;
1475c5c4113dSnw141292 
1476bda89588Sjp151216 	if (kidmap_call_door(zs, &params) != 0) {
1477c5c4113dSnw141292 		status = -1;
1478c5c4113dSnw141292 		goto exit;
1479c5c4113dSnw141292 	}
1480c5c4113dSnw141292 
1481c5c4113dSnw141292 	reply_msg.acpted_rply.ar_verf = _null_auth;
1482c5c4113dSnw141292 	reply_msg.acpted_rply.ar_results.where = res;
1483c5c4113dSnw141292 	reply_msg.acpted_rply.ar_results.proc = xdr_res;
1484c5c4113dSnw141292 	xdrmem_create(&xdr_ctx, params.data_ptr, params.data_size, XDR_DECODE);
1485c5c4113dSnw141292 	if (xdr_replymsg(&xdr_ctx, &reply_msg)) {
1486c5c4113dSnw141292 		if (reply_msg.rm_reply.rp_stat != MSG_ACCEPTED ||
1487c5c4113dSnw141292 		    reply_msg.rm_reply.rp_acpt.ar_stat != SUCCESS) {
1488c5c4113dSnw141292 			status = -1;
1489c5c4113dSnw141292 			goto exit;
1490c5c4113dSnw141292 		}
1491c5c4113dSnw141292 	} else {
1492c5c4113dSnw141292 #ifdef	DEBUG
1493f7b4b2feSjp151216 		zcmn_err(zs->zone_id, CE_WARN,
1494f7b4b2feSjp151216 		    "idmap: xdr decoding reply message error");
1495c5c4113dSnw141292 #endif	/* DEBUG */
1496c5c4113dSnw141292 		status = -1;
1497c5c4113dSnw141292 	}
1498c5c4113dSnw141292 
1499c5c4113dSnw141292 exit:
1500c5c4113dSnw141292 	if (outbuf_ptr != params.rbuf && params.rbuf != NULL)
1501c5c4113dSnw141292 		kmem_free(params.rbuf, params.rsize);
1502c5c4113dSnw141292 	if (inbuf_ptr)
1503c5c4113dSnw141292 		kmem_free(inbuf_ptr, inbuf_size);
1504c5c4113dSnw141292 	if (outbuf_ptr)
1505c5c4113dSnw141292 		kmem_free(outbuf_ptr, outbuf_size);
1506c5c4113dSnw141292 	return (status);
1507c5c4113dSnw141292 }
1508