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