xref: /illumos-gate/usr/src/lib/libidmap/common/idmap_api.c (revision 148c5f43199ca0b43fc8e3b643aab11cd66ea327)
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 /*
22c5866007SKeyur Desai  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23c5c4113dSnw  */
24c5c4113dSnw 
25c5c4113dSnw 
26c5c4113dSnw /*
27c5c4113dSnw  * libidmap API
28c5c4113dSnw  */
29c5c4113dSnw 
30c5c4113dSnw #include <stdlib.h>
31479ac375Sdm #include <sys/varargs.h>
32c5c4113dSnw #include <inttypes.h>
33c5c4113dSnw #include <errno.h>
34c5c4113dSnw #include <strings.h>
35c5c4113dSnw #include <ctype.h>
36c5c4113dSnw #include <sys/param.h>
37c5c4113dSnw #include <sys/types.h>
38c5c4113dSnw #include <sys/stat.h>
39c5c4113dSnw #include <dlfcn.h>
40c5c4113dSnw #include <libintl.h>
41d3a612caSnw #include <ucontext.h>
42c5866007SKeyur Desai #include <syslog.h>
43*148c5f43SAlan Wright #include <assert.h>
44c5c4113dSnw #include "idmap_impl.h"
453ee87bcaSJulian Pullen #include "idmap_cache.h"
46c5c4113dSnw 
47c5c4113dSnw static struct timeval TIMEOUT = { 25, 0 };
48c5c4113dSnw 
49c5c4113dSnw static int idmap_stat2errno(idmap_stat);
50479ac375Sdm static idmap_stat	idmap_strdupnull(char **, const char *);
51c5c4113dSnw 
52c5c4113dSnw #define	__ITER_CREATE(itera, argu, handl, ityp)\
53c5c4113dSnw 	if (handl == NULL) {\
54c5c4113dSnw 		errno = EINVAL;\
55c5c4113dSnw 		return (IDMAP_ERR_ARG);\
56c5c4113dSnw 	}\
57c5c4113dSnw 	itera = calloc(1, sizeof (*itera));\
58c5c4113dSnw 	if (itera == NULL) {\
59c5c4113dSnw 		errno = ENOMEM;\
60c5c4113dSnw 		return (IDMAP_ERR_MEMORY);\
61c5c4113dSnw 	}\
62c5c4113dSnw 	argu = calloc(1, sizeof (*argu));\
63c5c4113dSnw 	if (argu == NULL) {\
64c5c4113dSnw 		free(itera);\
65c5c4113dSnw 		errno = ENOMEM;\
66c5c4113dSnw 		return (IDMAP_ERR_MEMORY);\
67c5c4113dSnw 	}\
68c5c4113dSnw 	itera->ih = handl;\
69c5c4113dSnw 	itera->type = ityp;\
70c5c4113dSnw 	itera->retcode = IDMAP_NEXT;\
71c5c4113dSnw 	itera->limit = 1024;\
72c5c4113dSnw 	itera->arg = argu;
73c5c4113dSnw 
74c5c4113dSnw 
75c5c4113dSnw #define	__ITER_ERR_RETURN(itera, argu, xdr_argu, iretcod)\
76c5c4113dSnw 	if (argu) {\
77c5c4113dSnw 		xdr_free(xdr_argu, (caddr_t)argu);\
78c5c4113dSnw 		free(argu);\
79c5c4113dSnw 	}\
80c5c4113dSnw 	if (itera)\
81c5c4113dSnw 		free(itera);\
82c5c4113dSnw 	return (iretcod);
83c5c4113dSnw 
84c5c4113dSnw 
85c5c4113dSnw #define	__ITER_CHECK(itera, ityp)\
86c5c4113dSnw 	if (itera == NULL) {\
87c5c4113dSnw 		errno = EINVAL;\
88c5c4113dSnw 		return (IDMAP_ERR_ARG);\
89c5c4113dSnw 	}\
90c5c4113dSnw 	if (itera->type != ityp) {\
91c5c4113dSnw 		errno = EINVAL;\
92c5c4113dSnw 		return (IDMAP_ERR_ARG);\
93c5c4113dSnw 	}
94c5c4113dSnw 
95c5c4113dSnw /*
96c5c4113dSnw  * Free memory allocated by libidmap API
97c5c4113dSnw  *
98c5c4113dSnw  * Input:
99c5c4113dSnw  * ptr - memory to be freed
100c5c4113dSnw  */
101c5c4113dSnw void
102cd37da74Snw idmap_free(void *ptr)
103cd37da74Snw {
104c5c4113dSnw 	free(ptr);
105c5c4113dSnw }
106c5c4113dSnw 
107c5c4113dSnw 
1082b4a7802SBaban Kenkre #define	MIN_STACK_NEEDS	65536
109d3a612caSnw 
110c5c4113dSnw /*
111c5c4113dSnw  * Create and Initialize idmap client handle for rpc/doors
112c5c4113dSnw  *
113c5c4113dSnw  * Output:
114c5c4113dSnw  * handle - idmap handle
115c5c4113dSnw  */
116c5c4113dSnw idmap_stat
117cd37da74Snw idmap_init(idmap_handle_t **handle)
118cd37da74Snw {
119c5c4113dSnw 	CLIENT			*clnt = NULL;
120c5c4113dSnw 	struct idmap_handle	*hptr;
121d3a612caSnw 	uint_t			sendsz = 0;
122d3a612caSnw 	stack_t			st;
123c5c4113dSnw 
124c5c4113dSnw 	*handle = NULL;
125c5c4113dSnw 	hptr = (struct idmap_handle *)calloc(1, sizeof (*hptr));
126c5c4113dSnw 	if (hptr == NULL)
127c5c4113dSnw 		return (IDMAP_ERR_MEMORY);
128c5c4113dSnw 
129d3a612caSnw 	/*
130d3a612caSnw 	 * clnt_door_call() alloca()s sendsz bytes (twice too, once for
131d3a612caSnw 	 * the call args buffer and once for the call result buffer), so
132d3a612caSnw 	 * we want to pick a sendsz that will be large enough, but not
133d3a612caSnw 	 * too large.
134d3a612caSnw 	 */
135d3a612caSnw 	if (stack_getbounds(&st) == 0) {
136d3a612caSnw 		/*
137d3a612caSnw 		 * Estimate how much stack space is left;
138d3a612caSnw 		 * st.ss_sp is the top of stack.
139d3a612caSnw 		 */
140d3a612caSnw 		if ((char *)&sendsz < (char *)st.ss_sp)
141d3a612caSnw 			/* stack grows up */
142d3a612caSnw 			sendsz = ((char *)st.ss_sp - (char *)&sendsz);
143d3a612caSnw 		else
144d3a612caSnw 			/* stack grows down */
145d3a612caSnw 			sendsz = ((char *)&sendsz - (char *)st.ss_sp);
146d3a612caSnw 
1472b4a7802SBaban Kenkre 		if (sendsz <= MIN_STACK_NEEDS) {
148d3a612caSnw 			sendsz = 0;	/* RPC call may fail */
1492b4a7802SBaban Kenkre 		} else {
1502b4a7802SBaban Kenkre 			/* Leave 64Kb (just a guess) for our needs */
1512b4a7802SBaban Kenkre 			sendsz -= MIN_STACK_NEEDS;
1522b4a7802SBaban Kenkre 
1532b4a7802SBaban Kenkre 			/* Divide the stack space left by two */
1542b4a7802SBaban Kenkre 			sendsz = RNDUP(sendsz / 2);
1552b4a7802SBaban Kenkre 
1562b4a7802SBaban Kenkre 			/* Limit sendsz to 256KB */
1572b4a7802SBaban Kenkre 			if (sendsz > IDMAP_MAX_DOOR_RPC)
1582b4a7802SBaban Kenkre 				sendsz = IDMAP_MAX_DOOR_RPC;
1592b4a7802SBaban Kenkre 		}
160d3a612caSnw 	}
161d3a612caSnw 
162d3a612caSnw 	clnt = clnt_door_create(IDMAP_PROG, IDMAP_V1, sendsz);
163c5c4113dSnw 	if (clnt == NULL) {
164c5c4113dSnw 		free(hptr);
165c5c4113dSnw 		return (IDMAP_ERR_RPC);
166c5c4113dSnw 	}
167c5c4113dSnw 	hptr->type = _IDMAP_HANDLE_RPC_DOORS;
168c5c4113dSnw 	hptr->privhandle = clnt;
169c5c4113dSnw 	*handle = hptr;
170c5c4113dSnw 	return (IDMAP_SUCCESS);
171c5c4113dSnw }
172c5c4113dSnw 
173c5c4113dSnw 
174c5c4113dSnw /*
175c5c4113dSnw  * Finalize idmap handle
176c5c4113dSnw  *
177c5c4113dSnw  * Input:
178c5c4113dSnw  * handle - idmap handle
179c5c4113dSnw  */
180c5c4113dSnw idmap_stat
181cd37da74Snw idmap_fini(idmap_handle_t *handle)
182cd37da74Snw {
183c5c4113dSnw 	CLIENT			*clnt;
184c5c4113dSnw 	struct idmap_handle	*hptr;
185c5c4113dSnw 
186c5c4113dSnw 	if (handle == NULL)
187c5c4113dSnw 		return (IDMAP_SUCCESS);
188c5c4113dSnw 
189c5c4113dSnw 	hptr = (struct idmap_handle *)handle;
190c5c4113dSnw 
191c5c4113dSnw 	switch (hptr->type) {
192c5c4113dSnw 	case _IDMAP_HANDLE_RPC_DOORS:
193c5c4113dSnw 		clnt = (CLIENT *)hptr->privhandle;
194c5c4113dSnw 		if (clnt) {
195c5c4113dSnw 			if (clnt->cl_auth)
196c5c4113dSnw 				auth_destroy(clnt->cl_auth);
197c5c4113dSnw 			clnt_destroy(clnt);
198c5c4113dSnw 		}
199c5c4113dSnw 		break;
200c5c4113dSnw 	default:
201c5c4113dSnw 		break;
202c5c4113dSnw 	}
203c5c4113dSnw 	free(hptr);
204c5c4113dSnw 	return (IDMAP_SUCCESS);
205c5c4113dSnw }
206c5c4113dSnw 
207c5c4113dSnw 
2084d61c878SJulian Pullen static idmap_stat
209479ac375Sdm idmap_get_prop(idmap_handle_t *handle, idmap_prop_type pr, idmap_prop_res *res)
210479ac375Sdm {
211479ac375Sdm 	CLIENT			*clnt;
212479ac375Sdm 	enum clnt_stat		clntstat;
213479ac375Sdm 
214479ac375Sdm 
215479ac375Sdm 	(void) memset(res, 0, sizeof (*res));
216479ac375Sdm 	_IDMAP_GET_CLIENT_HANDLE(handle, clnt);
217479ac375Sdm 
218479ac375Sdm 	clntstat = clnt_call(clnt, IDMAP_GET_PROP,
219479ac375Sdm 	    (xdrproc_t)xdr_idmap_prop_type, (caddr_t)&pr,
220479ac375Sdm 	    (xdrproc_t)xdr_idmap_prop_res, (caddr_t)res, TIMEOUT);
221479ac375Sdm 
222479ac375Sdm 	if (clntstat != RPC_SUCCESS) {
223479ac375Sdm 		return (_idmap_rpc2stat(clnt));
224479ac375Sdm 	}
225479ac375Sdm 
226479ac375Sdm 	return (res->retcode); /* This might not be IDMAP_SUCCESS! */
227479ac375Sdm }
228479ac375Sdm 
2294d61c878SJulian Pullen 
230479ac375Sdm idmap_stat
231479ac375Sdm idmap_get_prop_ds(idmap_handle_t *handle, idmap_prop_type pr,
232479ac375Sdm     idmap_ad_disc_ds_t *dc)
233479ac375Sdm {
234479ac375Sdm 	idmap_prop_res res;
235479ac375Sdm 	idmap_stat rc = IDMAP_SUCCESS;
236479ac375Sdm 
237479ac375Sdm 	rc = idmap_get_prop(handle, pr, &res);
238479ac375Sdm 	if (rc < 0)
239479ac375Sdm 		return (rc);
240479ac375Sdm 
241479ac375Sdm 	dc->port = res.value.idmap_prop_val_u.dsval.port;
242479ac375Sdm 	(void) strlcpy(dc->host, res.value.idmap_prop_val_u.dsval.host,
243479ac375Sdm 	    AD_DISC_MAXHOSTNAME);
244479ac375Sdm 
245479ac375Sdm 	/* xdr doesn't guarantee 0-termination of char[]: */
246479ac375Sdm 	dc->host[AD_DISC_MAXHOSTNAME - 1] = '\0';
247479ac375Sdm 
248479ac375Sdm 	return (rc);
249479ac375Sdm }
250479ac375Sdm 
251479ac375Sdm 
252479ac375Sdm /*
253479ac375Sdm  * Sometimes the property is not set. In that case, str is set to NULL but
254479ac375Sdm  * otherwise IDMAP_SUCCESS is returned.
255479ac375Sdm  */
256479ac375Sdm idmap_stat
257479ac375Sdm idmap_get_prop_str(idmap_handle_t *handle, idmap_prop_type pr, char **str)
258479ac375Sdm {
259479ac375Sdm 	idmap_prop_res res;
260479ac375Sdm 	idmap_stat rc = IDMAP_SUCCESS;
261479ac375Sdm 
262479ac375Sdm 	rc = idmap_get_prop(handle, pr, &res);
263479ac375Sdm 	if (rc < 0)
264479ac375Sdm 		return (rc);
265479ac375Sdm 
266479ac375Sdm 	rc = idmap_strdupnull(str, res.value.idmap_prop_val_u.utf8val);
267479ac375Sdm 	return (rc);
268479ac375Sdm }
269c5c4113dSnw 
270c5c4113dSnw /*
271c5c4113dSnw  * Create/Initialize handle for updates
272c5c4113dSnw  *
273c5c4113dSnw  * Output:
274c5c4113dSnw  * udthandle - update handle
275c5c4113dSnw  */
276c5c4113dSnw idmap_stat
277cd37da74Snw idmap_udt_create(idmap_handle_t *handle, idmap_udt_handle_t **udthandle)
278cd37da74Snw {
279c5c4113dSnw 	idmap_udt_handle_t	*tmp;
280c5c4113dSnw 
281c5c4113dSnw 	if (handle == NULL || udthandle == NULL) {
282c5c4113dSnw 		errno = EINVAL;
283c5c4113dSnw 		return (IDMAP_ERR_ARG);
284c5c4113dSnw 	}
285c5c4113dSnw 	if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
286c5c4113dSnw 		errno = ENOMEM;
287c5c4113dSnw 		return (IDMAP_ERR_MEMORY);
288c5c4113dSnw 	}
289c5c4113dSnw 
290c5c4113dSnw 	tmp->ih = handle;
291c5c4113dSnw 	*udthandle = tmp;
292c5c4113dSnw 	return (IDMAP_SUCCESS);
293c5c4113dSnw }
294c5c4113dSnw 
295c5c4113dSnw 
296c5c4113dSnw /*
297c5c4113dSnw  * All the updates specified by the update handle are committed
298c5c4113dSnw  * in a single transaction. i.e either all succeed or none.
299c5c4113dSnw  *
300c5c4113dSnw  * Input:
301c5c4113dSnw  * udthandle - update handle with the update requests
302c5c4113dSnw  *
303c5c4113dSnw  * Return value:
304c5c4113dSnw  * Status of the commit
305c5c4113dSnw  */
306c5c4113dSnw idmap_stat
307cd37da74Snw idmap_udt_commit(idmap_udt_handle_t *udthandle)
308cd37da74Snw {
309c5c4113dSnw 	CLIENT			*clnt;
310c5c4113dSnw 	enum clnt_stat		clntstat;
3118e228215Sdm 	idmap_update_res	res;
3128e228215Sdm 	idmap_stat		retcode;
313c5c4113dSnw 
314c5c4113dSnw 	if (udthandle == NULL) {
315c5c4113dSnw 		errno = EINVAL;
316c5c4113dSnw 		return (IDMAP_ERR_ARG);
317c5c4113dSnw 	}
3188e228215Sdm 
3198e228215Sdm 	(void) memset(&res, 0, sizeof (res));
3208e228215Sdm 
321c5c4113dSnw 	_IDMAP_GET_CLIENT_HANDLE(udthandle->ih, clnt);
322c5c4113dSnw 	clntstat = clnt_call(clnt, IDMAP_UPDATE,
323cd37da74Snw 	    (xdrproc_t)xdr_idmap_update_batch, (caddr_t)&udthandle->batch,
324cd37da74Snw 	    (xdrproc_t)xdr_idmap_update_res, (caddr_t)&res,
325cd37da74Snw 	    TIMEOUT);
326651c0131Sbaban 
3278e228215Sdm 	if (clntstat != RPC_SUCCESS) {
3288e228215Sdm 		retcode = _idmap_rpc2stat(clnt);
3298e228215Sdm 		goto out;
3308e228215Sdm 	}
3318e228215Sdm 
3328e228215Sdm 	retcode = udthandle->commit_stat = res.retcode;
3338e228215Sdm 	udthandle->error_index = res.error_index;
3348e228215Sdm 
3358e228215Sdm 	if (retcode != IDMAP_SUCCESS) {
3368e228215Sdm 
3378e228215Sdm 		if (udthandle->error_index < 0)
3388e228215Sdm 			goto out;
3398e228215Sdm 
3408e228215Sdm 		retcode = idmap_namerule_cpy(&udthandle->error_rule,
3418e228215Sdm 		    &res.error_rule);
3428e228215Sdm 		if (retcode != IDMAP_SUCCESS) {
3438e228215Sdm 			udthandle->error_index = -2;
3448e228215Sdm 			goto out;
3458e228215Sdm 		}
3468e228215Sdm 
3478e228215Sdm 		retcode = idmap_namerule_cpy(&udthandle->conflict_rule,
3488e228215Sdm 		    &res.conflict_rule);
3498e228215Sdm 		if (retcode != IDMAP_SUCCESS) {
3508e228215Sdm 			udthandle->error_index = -2;
3518e228215Sdm 			goto out;
3528e228215Sdm 		}
3538e228215Sdm 	}
3548e228215Sdm 
3558e228215Sdm 	retcode = res.retcode;
3568e228215Sdm 
3578e228215Sdm 
3588e228215Sdm out:
359651c0131Sbaban 	/* reset handle so that it can be used again */
3608e228215Sdm 	if (retcode == IDMAP_SUCCESS) {
3618e228215Sdm 		_IDMAP_RESET_UDT_HANDLE(udthandle);
3628e228215Sdm 	}
363651c0131Sbaban 
3648e228215Sdm 	(void) xdr_free(xdr_idmap_update_res, (caddr_t)&res);
3658e228215Sdm 	errno = idmap_stat2errno(retcode);
3668e228215Sdm 	return (retcode);
3678e228215Sdm }
3688e228215Sdm 
3698e228215Sdm 
3708e228215Sdm static void
3718e228215Sdm idmap_namerule_parts_clear(char **windomain, char **winname,
372cd37da74Snw     char **unixname, boolean_t *is_user, boolean_t *is_wuser,
373cd37da74Snw     boolean_t *is_nt4, int *direction)
374cd37da74Snw {
3758e228215Sdm 	if (windomain)
3768e228215Sdm 		*windomain = NULL;
3778e228215Sdm 	if (winname)
3788e228215Sdm 		*winname = NULL;
3798e228215Sdm 	if (unixname)
3808e228215Sdm 		*unixname = NULL;
3818e228215Sdm 
3828e228215Sdm 	if (is_nt4)
3838e228215Sdm 		*is_nt4 = 0;
3848e228215Sdm 	if (is_user)
3858e228215Sdm 		*is_user = -1;
386cd37da74Snw 	if (is_wuser)
387cd37da74Snw 		*is_wuser = -1;
3888e228215Sdm 	if (direction)
3898e228215Sdm 		*direction = IDMAP_DIRECTION_UNDEF;
3908e228215Sdm }
3918e228215Sdm 
3928e228215Sdm static idmap_stat
393cd37da74Snw idmap_namerule2parts(idmap_namerule *rule,
3948e228215Sdm     char **windomain, char **winname,
395cd37da74Snw     char **unixname, boolean_t *is_user, boolean_t *is_wuser,
396cd37da74Snw     boolean_t *is_nt4, int *direction)
397cd37da74Snw {
3988e228215Sdm 	idmap_stat retcode;
3998e228215Sdm 
4008e228215Sdm 	if (EMPTY_STRING(rule->winname) && EMPTY_STRING(rule->unixname))
4018e228215Sdm 		return (IDMAP_ERR_NORESULT);
4028e228215Sdm 
4038e228215Sdm 
4048e228215Sdm 	retcode = idmap_strdupnull(windomain, rule->windomain);
405c5c4113dSnw 	if (retcode != IDMAP_SUCCESS)
4068e228215Sdm 		goto errout;
4078e228215Sdm 
4088e228215Sdm 	retcode = idmap_strdupnull(winname, rule->winname);
4098e228215Sdm 	if (retcode != IDMAP_SUCCESS)
4108e228215Sdm 		goto errout;
4118e228215Sdm 
4128e228215Sdm 	retcode = idmap_strdupnull(unixname, rule->unixname);
4138e228215Sdm 	if (retcode != IDMAP_SUCCESS)
4148e228215Sdm 		goto errout;
4158e228215Sdm 
4168e228215Sdm 
4178e228215Sdm 	if (is_user)
4188e228215Sdm 		*is_user = rule->is_user;
419cd37da74Snw 	if (is_wuser)
420cd37da74Snw 		*is_wuser = rule->is_wuser;
4218e228215Sdm 	if (is_nt4)
4228e228215Sdm 		*is_nt4 = rule->is_nt4;
4238e228215Sdm 	if (direction)
4248e228215Sdm 		*direction = rule->direction;
4258e228215Sdm 
4268e228215Sdm 
4278e228215Sdm 	return (IDMAP_SUCCESS);
4288e228215Sdm 
4298e228215Sdm errout:
4308e228215Sdm 	if (windomain && *windomain)
4318e228215Sdm 		free(*windomain);
4328e228215Sdm 	if (winname && *winname)
4338e228215Sdm 		free(*winname);
4348e228215Sdm 	if (unixname && *unixname)
4358e228215Sdm 		free(*unixname);
4368e228215Sdm 
4378e228215Sdm 	idmap_namerule_parts_clear(windomain, winname,
438cd37da74Snw 	    unixname, is_user, is_wuser, is_nt4, direction);
4398e228215Sdm 
440c5c4113dSnw 	return (retcode);
4418e228215Sdm 
4428e228215Sdm }
4438e228215Sdm 
4448e228215Sdm /*
4458e228215Sdm  * Retrieve the index of the failed batch element. error_index == -1
4468e228215Sdm  * indicates failure at the beginning, -2 at the end.
4478e228215Sdm  *
4488e228215Sdm  * If idmap_udt_commit didn't return error, the returned value is undefined.
4498e228215Sdm  *
4508e228215Sdm  * Return value:
4518e228215Sdm  * IDMAP_SUCCESS
4528e228215Sdm  */
4538e228215Sdm 
4548e228215Sdm idmap_stat
4558e228215Sdm idmap_udt_get_error_index(idmap_udt_handle_t *udthandle,
456cd37da74Snw     int64_t *error_index)
457cd37da74Snw {
4588e228215Sdm 	if (error_index)
4598e228215Sdm 		*error_index = udthandle->error_index;
4608e228215Sdm 
4618e228215Sdm 	return (IDMAP_SUCCESS);
4628e228215Sdm }
4638e228215Sdm 
4648e228215Sdm 
4658e228215Sdm /*
4668e228215Sdm  * Retrieve the rule which caused the batch to fail. If
4678e228215Sdm  * idmap_udt_commit didn't return error or if error_index is < 0, the
4688e228215Sdm  * retrieved rule is undefined.
4698e228215Sdm  *
4708e228215Sdm  * Return value:
4718e228215Sdm  * IDMAP_ERR_NORESULT if there is no error rule.
4728e228215Sdm  * IDMAP_SUCCESS if the rule was obtained OK.
4738e228215Sdm  * other error code (IDMAP_ERR_NOMEMORY etc)
4748e228215Sdm  */
4758e228215Sdm 
4768e228215Sdm idmap_stat
4778e228215Sdm idmap_udt_get_error_rule(idmap_udt_handle_t *udthandle,
4788e228215Sdm     char **windomain, char **winname,
479cd37da74Snw     char **unixname, boolean_t *is_user, boolean_t *is_wuser,
480cd37da74Snw     boolean_t *is_nt4, int *direction)
481cd37da74Snw {
4828e228215Sdm 	idmap_namerule_parts_clear(windomain, winname,
483cd37da74Snw 	    unixname, is_user, is_wuser, is_nt4, direction);
4848e228215Sdm 
4858e228215Sdm 	if (udthandle->commit_stat == IDMAP_SUCCESS ||
4868e228215Sdm 	    udthandle->error_index < 0)
4878e228215Sdm 		return (IDMAP_ERR_NORESULT);
4888e228215Sdm 
4898e228215Sdm 	return (idmap_namerule2parts(
490cd37da74Snw 	    &udthandle->error_rule,
491cd37da74Snw 	    windomain,
492cd37da74Snw 	    winname,
493cd37da74Snw 	    unixname,
494cd37da74Snw 	    is_user,
495cd37da74Snw 	    is_wuser,
496cd37da74Snw 	    is_nt4,
497cd37da74Snw 	    direction));
4988e228215Sdm }
4998e228215Sdm 
5008e228215Sdm /*
5018e228215Sdm  * Retrieve the rule with which there was a conflict. TODO: retrieve
5028e228215Sdm  * the value.
5038e228215Sdm  *
5048e228215Sdm  * Return value:
5058e228215Sdm  * IDMAP_ERR_NORESULT if there is no error rule.
5068e228215Sdm  * IDMAP_SUCCESS if the rule was obtained OK.
5078e228215Sdm  * other error code (IDMAP_ERR_NOMEMORY etc)
5088e228215Sdm  */
5098e228215Sdm 
5108e228215Sdm idmap_stat
5118e228215Sdm idmap_udt_get_conflict_rule(idmap_udt_handle_t *udthandle,
5128e228215Sdm     char **windomain, char **winname,
513cd37da74Snw     char **unixname, boolean_t *is_user, boolean_t *is_wuser,
514cd37da74Snw     boolean_t *is_nt4, int *direction)
515cd37da74Snw {
5168e228215Sdm 	idmap_namerule_parts_clear(windomain, winname,
517cd37da74Snw 	    unixname, is_user, is_wuser, is_nt4, direction);
5188e228215Sdm 
5198e228215Sdm 	if (udthandle->commit_stat != IDMAP_ERR_W2U_NAMERULE_CONFLICT &&
5208e228215Sdm 	    udthandle->commit_stat != IDMAP_ERR_U2W_NAMERULE_CONFLICT) {
521cd37da74Snw 		return (IDMAP_ERR_NORESULT);
5228e228215Sdm 	}
5238e228215Sdm 
5248e228215Sdm 	return (idmap_namerule2parts(
525cd37da74Snw 	    &udthandle->conflict_rule,
526cd37da74Snw 	    windomain,
527cd37da74Snw 	    winname,
528cd37da74Snw 	    unixname,
529cd37da74Snw 	    is_user,
530cd37da74Snw 	    is_wuser,
531cd37da74Snw 	    is_nt4,
532cd37da74Snw 	    direction));
533c5c4113dSnw }
534c5c4113dSnw 
535c5c4113dSnw 
536c5c4113dSnw /*
537c5c4113dSnw  * Destroy the update handle
538c5c4113dSnw  */
539c5c4113dSnw void
540cd37da74Snw idmap_udt_destroy(idmap_udt_handle_t *udthandle)
541cd37da74Snw {
542c5c4113dSnw 	if (udthandle == NULL)
543c5c4113dSnw 		return;
544c5c4113dSnw 	(void) xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch);
5458e228215Sdm 	(void) xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->error_rule);
5468e228215Sdm 	(void) xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->conflict_rule);
547c5c4113dSnw 	free(udthandle);
548c5c4113dSnw }
549c5c4113dSnw 
550c5c4113dSnw 
551c5c4113dSnw idmap_stat
552c5c4113dSnw idmap_udt_add_namerule(idmap_udt_handle_t *udthandle, const char *windomain,
553cd37da74Snw     boolean_t is_user, boolean_t is_wuser, const char *winname,
554cd37da74Snw     const char *unixname, boolean_t is_nt4, int direction)
555cd37da74Snw {
556c5c4113dSnw 	idmap_retcode	retcode;
557651c0131Sbaban 	idmap_namerule	*rule = NULL;
558c5c4113dSnw 
559651c0131Sbaban 	retcode = _udt_extend_batch(udthandle);
560c5c4113dSnw 	if (retcode != IDMAP_SUCCESS)
561c5c4113dSnw 		goto errout;
562c5c4113dSnw 
563c5c4113dSnw 	rule = &udthandle->batch.
564cd37da74Snw 	    idmap_update_batch_val[udthandle->next].
565cd37da74Snw 	    idmap_update_op_u.rule;
566c5c4113dSnw 	rule->is_user = is_user;
567cd37da74Snw 	rule->is_wuser = is_wuser;
568c5c4113dSnw 	rule->direction = direction;
569c5c4113dSnw 	rule->is_nt4 = is_nt4;
5708e228215Sdm 
5718e228215Sdm 	retcode = idmap_strdupnull(&rule->windomain, windomain);
5728e228215Sdm 	if (retcode != IDMAP_SUCCESS)
5738e228215Sdm 		goto errout;
5748e228215Sdm 
5758e228215Sdm 	retcode = idmap_strdupnull(&rule->winname, winname);
5768e228215Sdm 	if (retcode != IDMAP_SUCCESS)
5778e228215Sdm 		goto errout;
5788e228215Sdm 
5798e228215Sdm 	retcode = idmap_strdupnull(&rule->unixname, unixname);
5808e228215Sdm 	if (retcode != IDMAP_SUCCESS)
5818e228215Sdm 		goto errout;
582651c0131Sbaban 
583651c0131Sbaban 	udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
584651c0131Sbaban 	    OP_ADD_NAMERULE;
585c5c4113dSnw 	udthandle->next++;
586c5c4113dSnw 	return (IDMAP_SUCCESS);
587c5c4113dSnw 
588c5c4113dSnw errout:
589651c0131Sbaban 	/* The batch should still be usable */
590651c0131Sbaban 	if (rule)
591651c0131Sbaban 		(void) xdr_free(xdr_idmap_namerule, (caddr_t)rule);
592c5c4113dSnw 	errno = idmap_stat2errno(retcode);
593c5c4113dSnw 	return (retcode);
594c5c4113dSnw }
595c5c4113dSnw 
596c5c4113dSnw 
597c5c4113dSnw /* ARGSUSED */
598c5c4113dSnw idmap_stat
599c5c4113dSnw idmap_udt_rm_namerule(idmap_udt_handle_t *udthandle, boolean_t is_user,
600cd37da74Snw     boolean_t is_wuser,	const char *windomain, const char *winname,
601cd37da74Snw     const char *unixname, int direction)
602cd37da74Snw {
603c5c4113dSnw 	idmap_retcode	retcode;
604651c0131Sbaban 	idmap_namerule	*rule = NULL;
605c5c4113dSnw 
606651c0131Sbaban 	retcode = _udt_extend_batch(udthandle);
607c5c4113dSnw 	if (retcode != IDMAP_SUCCESS)
608c5c4113dSnw 		goto errout;
609c5c4113dSnw 
610c5c4113dSnw 	rule = &udthandle->batch.
611cd37da74Snw 	    idmap_update_batch_val[udthandle->next].
612cd37da74Snw 	    idmap_update_op_u.rule;
613c5c4113dSnw 	rule->is_user = is_user;
614cd37da74Snw 	rule->is_wuser = is_wuser;
615c5c4113dSnw 	rule->direction = direction;
6168e228215Sdm 
6178e228215Sdm 	retcode = idmap_strdupnull(&rule->windomain, windomain);
6188e228215Sdm 	if (retcode != IDMAP_SUCCESS)
6198e228215Sdm 		goto errout;
6208e228215Sdm 
6218e228215Sdm 	retcode = idmap_strdupnull(&rule->winname, winname);
6228e228215Sdm 	if (retcode != IDMAP_SUCCESS)
6238e228215Sdm 		goto errout;
6248e228215Sdm 
6258e228215Sdm 	retcode = idmap_strdupnull(&rule->unixname, unixname);
6268e228215Sdm 	if (retcode != IDMAP_SUCCESS)
6278e228215Sdm 		goto errout;
6288e228215Sdm 
629651c0131Sbaban 	udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
630651c0131Sbaban 	    OP_RM_NAMERULE;
631c5c4113dSnw 	udthandle->next++;
632c5c4113dSnw 	return (IDMAP_SUCCESS);
633c5c4113dSnw 
634c5c4113dSnw errout:
635651c0131Sbaban 	if (rule)
636651c0131Sbaban 		(void) xdr_free(xdr_idmap_namerule, (caddr_t)rule);
637c5c4113dSnw 	errno = idmap_stat2errno(retcode);
638c5c4113dSnw 	return (retcode);
639c5c4113dSnw }
640c5c4113dSnw 
641c5c4113dSnw 
642c5c4113dSnw /* ARGSUSED */
643c5c4113dSnw idmap_stat
644cd37da74Snw idmap_udt_flush_namerules(idmap_udt_handle_t *udthandle)
645cd37da74Snw {
646c5c4113dSnw 	idmap_retcode	retcode;
647c5c4113dSnw 
648651c0131Sbaban 	retcode = _udt_extend_batch(udthandle);
649c5c4113dSnw 	if (retcode != IDMAP_SUCCESS)
650c5c4113dSnw 		goto errout;
651c5c4113dSnw 
652651c0131Sbaban 	udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
653651c0131Sbaban 	    OP_FLUSH_NAMERULES;
654c5c4113dSnw 	udthandle->next++;
655c5c4113dSnw 	return (IDMAP_SUCCESS);
656c5c4113dSnw 
657c5c4113dSnw errout:
658c5c4113dSnw 	errno = idmap_stat2errno(retcode);
659c5c4113dSnw 	return (retcode);
660c5c4113dSnw }
661c5c4113dSnw 
662c5c4113dSnw 
663c5c4113dSnw /*
664c5c4113dSnw  * Set the number of entries requested per batch by the iterator
665c5c4113dSnw  *
666c5c4113dSnw  * Input:
667c5c4113dSnw  * iter  - iterator
668c5c4113dSnw  * limit - number of entries requested per batch
669c5c4113dSnw  */
670c5c4113dSnw idmap_stat
671cd37da74Snw idmap_iter_set_limit(idmap_iter_t *iter, uint64_t limit)
672cd37da74Snw {
673c5c4113dSnw 	if (iter == NULL) {
674c5c4113dSnw 		errno = EINVAL;
675c5c4113dSnw 		return (IDMAP_ERR_ARG);
676c5c4113dSnw 	}
677c5c4113dSnw 	iter->limit = limit;
678c5c4113dSnw 	return (IDMAP_SUCCESS);
679c5c4113dSnw }
680c5c4113dSnw 
681c5c4113dSnw 
682c5c4113dSnw /*
683c5c4113dSnw  * Create iterator to get name-based mapping rules
684c5c4113dSnw  *
685c5c4113dSnw  * Input:
686c5c4113dSnw  * windomain - Windows domain
687c5c4113dSnw  * is_user   - user or group rules
688c5c4113dSnw  * winname   - Windows user or group name
689c5c4113dSnw  * unixname  - Unix user or group name
690c5c4113dSnw  *
691c5c4113dSnw  * Output:
692c5c4113dSnw  * iter - iterator
693c5c4113dSnw  */
694c5c4113dSnw idmap_stat
695c5c4113dSnw idmap_iter_namerules(idmap_handle_t *handle, const char *windomain,
696cd37da74Snw 		boolean_t is_user, boolean_t is_wuser, const char *winname,
697cd37da74Snw 		const char *unixname, idmap_iter_t **iter)
698cd37da74Snw {
699c5c4113dSnw 
700c5c4113dSnw 	idmap_iter_t			*tmpiter;
701c5c4113dSnw 	idmap_list_namerules_1_argument	*arg = NULL;
702c5c4113dSnw 	idmap_namerule			*rule;
703c5c4113dSnw 	idmap_retcode			retcode;
704c5c4113dSnw 
705c5c4113dSnw 	__ITER_CREATE(tmpiter, arg, handle, IDMAP_LIST_NAMERULES);
706c5c4113dSnw 
707c5c4113dSnw 	rule = &arg->rule;
708c5c4113dSnw 	rule->is_user = is_user;
709cd37da74Snw 	rule->is_wuser = is_wuser;
710651c0131Sbaban 	rule->direction = IDMAP_DIRECTION_UNDEF;
7118e228215Sdm 
7128e228215Sdm 	retcode = idmap_strdupnull(&rule->windomain, windomain);
7138e228215Sdm 	if (retcode != IDMAP_SUCCESS)
7148e228215Sdm 		goto errout;
7158e228215Sdm 
7168e228215Sdm 	retcode = idmap_strdupnull(&rule->winname, winname);
7178e228215Sdm 	if (retcode != IDMAP_SUCCESS)
7188e228215Sdm 		goto errout;
7198e228215Sdm 
7208e228215Sdm 	retcode = idmap_strdupnull(&rule->unixname, unixname);
7218e228215Sdm 	if (retcode != IDMAP_SUCCESS)
7228e228215Sdm 		goto errout;
723c5c4113dSnw 
724c5c4113dSnw 	*iter = tmpiter;
725c5c4113dSnw 	return (IDMAP_SUCCESS);
726c5c4113dSnw 
727c5c4113dSnw errout:
728c5c4113dSnw 	__ITER_ERR_RETURN(tmpiter, arg,
729cd37da74Snw 	    xdr_idmap_list_namerules_1_argument, retcode);
730c5c4113dSnw }
731c5c4113dSnw 
732c5c4113dSnw 
733c5c4113dSnw /*
734c5c4113dSnw  * Iterate through the name-based mapping rules
735c5c4113dSnw  *
736c5c4113dSnw  * Input:
737c5c4113dSnw  * iter - iterator
738c5c4113dSnw  *
739c5c4113dSnw  * Output:
740c5c4113dSnw  * windomain - Windows domain
741c5c4113dSnw  * winname   - Windows user or group name
742c5c4113dSnw  * unixname  - Unix user or group name
743c5c4113dSnw  * is_nt4    - NT4 or AD
744c5c4113dSnw  * direction - bi(0), win2unix(1), unix2win(2)
745c5c4113dSnw  *
746c5c4113dSnw  * Return value:
747c5c4113dSnw  * 0   - done
748c5c4113dSnw  * 1   - more results available
749c5c4113dSnw  * < 0 - error
750c5c4113dSnw  */
751c5c4113dSnw idmap_stat
752c5c4113dSnw idmap_iter_next_namerule(idmap_iter_t *iter, char **windomain,
753cd37da74Snw     char **winname, char **unixname,  boolean_t *is_user,
754cd37da74Snw     boolean_t *is_wuser, boolean_t *is_nt4, int *direction)
755cd37da74Snw {
756c5c4113dSnw 	idmap_namerules_res		*namerules;
757c5c4113dSnw 	idmap_list_namerules_1_argument	*arg;
758c5c4113dSnw 	idmap_retcode			retcode;
759c5c4113dSnw 
760cd37da74Snw 	idmap_namerule_parts_clear(windomain, winname,
761cd37da74Snw 	    unixname, is_user, is_wuser, is_nt4, direction);
762cd37da74Snw 
763c5c4113dSnw 
764c5c4113dSnw 	__ITER_CHECK(iter, IDMAP_LIST_NAMERULES);
765c5c4113dSnw 
766c5c4113dSnw 	namerules = (idmap_namerules_res *)iter->retlist;
767c5c4113dSnw 	if (iter->retcode == IDMAP_NEXT && (namerules == NULL ||
768cd37da74Snw 	    iter->next >= namerules->rules.rules_len)) {
769c5c4113dSnw 
770c5c4113dSnw 		if ((arg = iter->arg) == NULL) {
771c5c4113dSnw 			errno = EINVAL;
772c5c4113dSnw 			return (IDMAP_ERR_ARG);
773c5c4113dSnw 		}
774c5c4113dSnw 		arg->limit = iter->limit;
775c5c4113dSnw 
776c5c4113dSnw 		retcode = _iter_get_next_list(IDMAP_LIST_NAMERULES,
777cd37da74Snw 		    iter, arg,
778cd37da74Snw 		    (uchar_t **)&namerules, sizeof (*namerules),
779cd37da74Snw 		    (xdrproc_t)xdr_idmap_list_namerules_1_argument,
780cd37da74Snw 		    (xdrproc_t)xdr_idmap_namerules_res);
781c5c4113dSnw 		if (retcode != IDMAP_SUCCESS)
782c5c4113dSnw 			return (retcode);
783c5c4113dSnw 
784c5c4113dSnw 		if (IDMAP_ERROR(namerules->retcode)) {
785c5c4113dSnw 			retcode  = namerules->retcode;
786c5c4113dSnw 			xdr_free(xdr_idmap_namerules_res, (caddr_t)namerules);
787c5c4113dSnw 			free(namerules);
788c5c4113dSnw 			iter->retlist = NULL;
789c5c4113dSnw 			return (retcode);
790c5c4113dSnw 		}
791c5c4113dSnw 		iter->retcode = namerules->retcode;
792c5c4113dSnw 		arg->lastrowid = namerules->lastrowid;
793c5c4113dSnw 	}
794c5c4113dSnw 
795c5c4113dSnw 	if (namerules == NULL || namerules->rules.rules_len == 0)
796c5c4113dSnw 		return (IDMAP_SUCCESS);
797c5c4113dSnw 
798c5c4113dSnw 	if (iter->next >= namerules->rules.rules_len) {
799c5c4113dSnw 		return (IDMAP_ERR_ARG);
800c5c4113dSnw 	}
801c5c4113dSnw 
8028e228215Sdm 	retcode = idmap_strdupnull(windomain,
8038e228215Sdm 	    namerules->rules.rules_val[iter->next].windomain);
8048e228215Sdm 	if (retcode != IDMAP_SUCCESS)
8058e228215Sdm 		goto errout;
8068e228215Sdm 
8078e228215Sdm 	retcode = idmap_strdupnull(winname,
8088e228215Sdm 	    namerules->rules.rules_val[iter->next].winname);
8098e228215Sdm 	if (retcode != IDMAP_SUCCESS)
8108e228215Sdm 		goto errout;
8118e228215Sdm 
8128e228215Sdm 	retcode = idmap_strdupnull(unixname,
8138e228215Sdm 	    namerules->rules.rules_val[iter->next].unixname);
8148e228215Sdm 	if (retcode != IDMAP_SUCCESS)
8158e228215Sdm 		goto errout;
8168e228215Sdm 
817c5c4113dSnw 	if (is_nt4)
818c5c4113dSnw 		*is_nt4 = namerules->rules.rules_val[iter->next].is_nt4;
819cd37da74Snw 	if (is_user)
820cd37da74Snw 		*is_user = namerules->rules.rules_val[iter->next].is_user;
821cd37da74Snw 	if (is_wuser)
822cd37da74Snw 		*is_wuser = namerules->rules.rules_val[iter->next].is_wuser;
823c5c4113dSnw 	if (direction)
824c5c4113dSnw 		*direction = namerules->rules.rules_val[iter->next].direction;
825c5c4113dSnw 	iter->next++;
826c5c4113dSnw 
827c5c4113dSnw 	if (iter->next == namerules->rules.rules_len)
828c5c4113dSnw 		return (iter->retcode);
829c5c4113dSnw 	else
830c5c4113dSnw 		return (IDMAP_NEXT);
831c5c4113dSnw 
832c5c4113dSnw errout:
833c5c4113dSnw 	if (windomain && *windomain)
834c5c4113dSnw 		free(*windomain);
835c5c4113dSnw 	if (winname && *winname)
836c5c4113dSnw 		free(*winname);
837c5c4113dSnw 	if (unixname && *unixname)
838c5c4113dSnw 		free(*unixname);
839c5c4113dSnw 	return (retcode);
840c5c4113dSnw }
841c5c4113dSnw 
842c5c4113dSnw 
843c5c4113dSnw /*
844c5c4113dSnw  * Create iterator to get SID to UID/GID mappings
845c5c4113dSnw  *
846c5c4113dSnw  * Output:
847c5c4113dSnw  * iter - iterator
848c5c4113dSnw  */
849c5c4113dSnw idmap_stat
85048258c6bSjp idmap_iter_mappings(idmap_handle_t *handle, idmap_iter_t **iter, int flag)
851cd37da74Snw {
852c5c4113dSnw 	idmap_iter_t			*tmpiter;
853c5c4113dSnw 	idmap_list_mappings_1_argument	*arg = NULL;
854c5c4113dSnw 
855c5c4113dSnw 	__ITER_CREATE(tmpiter, arg, handle, IDMAP_LIST_MAPPINGS);
856c5c4113dSnw 
85748258c6bSjp 	arg->flag = flag;
858c5c4113dSnw 	*iter = tmpiter;
859c5c4113dSnw 	return (IDMAP_SUCCESS);
860c5c4113dSnw }
861c5c4113dSnw 
862c5c4113dSnw 
863c5c4113dSnw /*
864c5c4113dSnw  * Iterate through the SID to UID/GID mappings
865c5c4113dSnw  *
866c5c4113dSnw  * Input:
867c5c4113dSnw  * iter - iterator
868c5c4113dSnw  *
869c5c4113dSnw  * Output:
870c5c4113dSnw  * sid - SID in canonical form
871c5c4113dSnw  * pid - UID or GID
872c5c4113dSnw  *
873c5c4113dSnw  * Return value:
874c5c4113dSnw  * 0   - done
875c5c4113dSnw  * 1   - more results available
876c5c4113dSnw  * < 0 - error
877c5c4113dSnw  */
878c5c4113dSnw idmap_stat
879c5c4113dSnw idmap_iter_next_mapping(idmap_iter_t *iter, char **sidprefix,
880cd37da74Snw     idmap_rid_t *rid, uid_t *pid, char **winname,
881cd37da74Snw     char **windomain, char **unixname, boolean_t *is_user,
88248258c6bSjp     boolean_t *is_wuser, int *direction, idmap_info *info)
883cd37da74Snw {
884c5c4113dSnw 	idmap_mappings_res		*mappings;
885c5c4113dSnw 	idmap_list_mappings_1_argument	*arg;
886c5c4113dSnw 	idmap_retcode			retcode;
887c5c4113dSnw 	char				*str;
888c5c4113dSnw 
889c5c4113dSnw 	if (sidprefix)
890c5c4113dSnw 		*sidprefix = NULL;
891c5c4113dSnw 	if (rid)
892c5c4113dSnw 		*rid = UINT32_MAX;
893c5c4113dSnw 	if (winname)
894c5c4113dSnw 		*winname = NULL;
895c5c4113dSnw 	if (windomain)
896c5c4113dSnw 		*windomain = NULL;
897c5c4113dSnw 	if (unixname)
898c5c4113dSnw 		*unixname = NULL;
899c5c4113dSnw 	if (pid)
900c5c4113dSnw 		*pid = UINT32_MAX;
901cd37da74Snw 	if (is_user)
902cd37da74Snw 		*is_user = -1;
903cd37da74Snw 	if (is_wuser)
904cd37da74Snw 		*is_wuser = -1;
905c5c4113dSnw 	if (direction)
906651c0131Sbaban 		*direction = IDMAP_DIRECTION_UNDEF;
907c5c4113dSnw 
908c5c4113dSnw 	__ITER_CHECK(iter, IDMAP_LIST_MAPPINGS);
909c5c4113dSnw 
910c5c4113dSnw 	mappings = (idmap_mappings_res *)iter->retlist;
911c5c4113dSnw 	if (iter->retcode == IDMAP_NEXT && (mappings == NULL ||
912cd37da74Snw 	    iter->next >= mappings->mappings.mappings_len)) {
913c5c4113dSnw 
914c5c4113dSnw 		if ((arg = iter->arg) == NULL) {
915c5c4113dSnw 			errno = EINVAL;
916c5c4113dSnw 			return (IDMAP_ERR_ARG);
917c5c4113dSnw 		}
918c5c4113dSnw 		arg->limit = iter->limit;
919c5c4113dSnw 
920c5c4113dSnw 		retcode = _iter_get_next_list(IDMAP_LIST_MAPPINGS,
921cd37da74Snw 		    iter, arg,
922cd37da74Snw 		    (uchar_t **)&mappings, sizeof (*mappings),
923cd37da74Snw 		    (xdrproc_t)xdr_idmap_list_mappings_1_argument,
924cd37da74Snw 		    (xdrproc_t)xdr_idmap_mappings_res);
925c5c4113dSnw 		if (retcode != IDMAP_SUCCESS)
926c5c4113dSnw 			return (retcode);
927c5c4113dSnw 
928c5c4113dSnw 		if (IDMAP_ERROR(mappings->retcode)) {
929c5c4113dSnw 			retcode  = mappings->retcode;
930c5c4113dSnw 			xdr_free(xdr_idmap_mappings_res, (caddr_t)mappings);
931c5c4113dSnw 			free(mappings);
932c5c4113dSnw 			iter->retlist = NULL;
933c5c4113dSnw 			return (retcode);
934c5c4113dSnw 		}
935c5c4113dSnw 		iter->retcode = mappings->retcode;
936c5c4113dSnw 		arg->lastrowid = mappings->lastrowid;
937c5c4113dSnw 	}
938c5c4113dSnw 
939c5c4113dSnw 	if (mappings == NULL || mappings->mappings.mappings_len == 0)
940c5c4113dSnw 		return (IDMAP_SUCCESS);
941c5c4113dSnw 
942c5c4113dSnw 	if (iter->next >= mappings->mappings.mappings_len) {
943c5c4113dSnw 		return (IDMAP_ERR_ARG);
944c5c4113dSnw 	}
945c5c4113dSnw 
946c5c4113dSnw 	if (sidprefix) {
947c5c4113dSnw 		str = mappings->mappings.mappings_val[iter->next].id1.
948cd37da74Snw 		    idmap_id_u.sid.prefix;
9498edda628Sbaban 		if (str && *str != '\0') {
950c5c4113dSnw 			*sidprefix = strdup(str);
9519581d9f4Sbaban 			if (*sidprefix == NULL) {
9529581d9f4Sbaban 				retcode = IDMAP_ERR_MEMORY;
9539581d9f4Sbaban 				goto errout;
9549581d9f4Sbaban 			}
955c5c4113dSnw 		}
956c5c4113dSnw 	}
957c5c4113dSnw 	if (rid)
958c5c4113dSnw 		*rid = mappings->mappings.mappings_val[iter->next].id1.
959cd37da74Snw 		    idmap_id_u.sid.rid;
9608e228215Sdm 
9618e228215Sdm 	retcode = idmap_strdupnull(windomain,
9628e228215Sdm 	    mappings->mappings.mappings_val[iter->next].id1domain);
9638e228215Sdm 	if (retcode != IDMAP_SUCCESS)
9648e228215Sdm 		goto errout;
9658e228215Sdm 
9668e228215Sdm 	retcode = idmap_strdupnull(winname,
9678e228215Sdm 	    mappings->mappings.mappings_val[iter->next].id1name);
9688e228215Sdm 	if (retcode != IDMAP_SUCCESS)
9698e228215Sdm 		goto errout;
9708e228215Sdm 
9718e228215Sdm 	retcode = idmap_strdupnull(unixname,
9728e228215Sdm 	    mappings->mappings.mappings_val[iter->next].id2name);
9738e228215Sdm 	if (retcode != IDMAP_SUCCESS)
9748e228215Sdm 		goto errout;
9758e228215Sdm 
9768e228215Sdm 
977c5c4113dSnw 	if (pid)
978c5c4113dSnw 		*pid = mappings->mappings.mappings_val[iter->next].id2.
979cd37da74Snw 		    idmap_id_u.uid;
980c5c4113dSnw 	if (direction)
981c5c4113dSnw 		*direction = mappings->mappings.mappings_val[iter->next].
982cd37da74Snw 		    direction;
983cd37da74Snw 	if (is_user)
984cd37da74Snw 		*is_user = (mappings->mappings.mappings_val[iter->next].id2
985cd37da74Snw 		    .idtype == IDMAP_UID)?1:0;
986cd37da74Snw 	if (is_wuser)
987cd37da74Snw 		*is_wuser = (mappings->mappings.mappings_val[iter->next].id1
988cd37da74Snw 		    .idtype == IDMAP_USID)?1:0;
989cd37da74Snw 
99048258c6bSjp 	if (info) {
991*148c5f43SAlan Wright 		idmap_info_mov(info,
99248258c6bSjp 		    &mappings->mappings.mappings_val[iter->next].info);
99348258c6bSjp 	}
994c5c4113dSnw 	iter->next++;
995c5c4113dSnw 
996c5c4113dSnw 	if (iter->next == mappings->mappings.mappings_len)
997c5c4113dSnw 		return (iter->retcode);
998c5c4113dSnw 	else
999c5c4113dSnw 		return (IDMAP_NEXT);
1000c5c4113dSnw 
1001c5c4113dSnw errout:
1002c5c4113dSnw 	if (sidprefix && *sidprefix)
1003c5c4113dSnw 		free(*sidprefix);
1004c5c4113dSnw 	if (winname && *winname)
1005c5c4113dSnw 		free(*winname);
1006c5c4113dSnw 	if (windomain && *windomain)
1007c5c4113dSnw 		free(*windomain);
1008c5c4113dSnw 	if (unixname && *unixname)
1009c5c4113dSnw 		free(*unixname);
1010c5c4113dSnw 	return (retcode);
1011c5c4113dSnw }
1012c5c4113dSnw 
1013c5c4113dSnw 
1014c5c4113dSnw /*
1015c5c4113dSnw  * Destroy the iterator
1016c5c4113dSnw  */
1017c5c4113dSnw void
1018cd37da74Snw idmap_iter_destroy(idmap_iter_t *iter)
1019cd37da74Snw {
1020c5c4113dSnw 	xdrproc_t _xdr_argument, _xdr_result;
1021c5c4113dSnw 
1022c5c4113dSnw 	if (iter == NULL)
1023c5c4113dSnw 		return;
1024c5c4113dSnw 
1025c5c4113dSnw 	switch (iter->type) {
1026c5c4113dSnw 	case IDMAP_LIST_NAMERULES:
1027c5c4113dSnw 		_xdr_argument = (xdrproc_t)xdr_idmap_list_namerules_1_argument;
1028c5c4113dSnw 		_xdr_result = (xdrproc_t)xdr_idmap_namerules_res;
1029c5c4113dSnw 		break;
1030c5c4113dSnw 	case IDMAP_LIST_MAPPINGS:
1031c5c4113dSnw 		_xdr_argument = (xdrproc_t)xdr_idmap_list_mappings_1_argument;
1032c5c4113dSnw 		_xdr_result = (xdrproc_t)xdr_idmap_mappings_res;
1033c5c4113dSnw 		break;
1034c5c4113dSnw 	default:
1035c5c4113dSnw 		free(iter);
1036c5c4113dSnw 		return;
1037c5c4113dSnw 	};
1038c5c4113dSnw 
1039c5c4113dSnw 	if (iter->arg) {
1040c5c4113dSnw 		xdr_free(_xdr_argument, (caddr_t)iter->arg);
1041c5c4113dSnw 		free(iter->arg);
1042c5c4113dSnw 	}
1043c5c4113dSnw 	if (iter->retlist) {
1044c5c4113dSnw 		xdr_free(_xdr_result, (caddr_t)iter->retlist);
1045c5c4113dSnw 		free(iter->retlist);
1046c5c4113dSnw 	}
1047c5c4113dSnw 	free(iter);
1048c5c4113dSnw }
1049c5c4113dSnw 
1050c5c4113dSnw 
1051c5c4113dSnw /*
1052c5c4113dSnw  * Create handle to get SID to UID/GID mapping entries
1053c5c4113dSnw  *
1054c5c4113dSnw  * Input:
1055c5c4113dSnw  * gh - "get mapping" handle
1056c5c4113dSnw  */
1057c5c4113dSnw idmap_stat
1058cd37da74Snw idmap_get_create(idmap_handle_t *handle, idmap_get_handle_t **gh)
1059cd37da74Snw {
1060c5c4113dSnw 	idmap_get_handle_t	*tmp;
1061c5c4113dSnw 
1062c5c4113dSnw 	/* sanity checks */
1063c5c4113dSnw 	if (handle == NULL || gh == NULL) {
1064c5c4113dSnw 		errno = EINVAL;
1065c5c4113dSnw 		return (IDMAP_ERR_ARG);
1066c5c4113dSnw 	}
1067c5c4113dSnw 
1068c5c4113dSnw 	/* allocate the handle */
1069c5c4113dSnw 	if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
1070c5c4113dSnw 		errno = ENOMEM;
1071c5c4113dSnw 		return (IDMAP_ERR_MEMORY);
1072c5c4113dSnw 	}
1073c5c4113dSnw 
1074c5c4113dSnw 	tmp->ih = handle;
1075c5c4113dSnw 	*gh = tmp;
1076c5c4113dSnw 	return (IDMAP_SUCCESS);
1077c5c4113dSnw }
1078c5c4113dSnw 
1079c5c4113dSnw 
1080c5c4113dSnw /*
1081c5c4113dSnw  * Given SID, get UID
1082c5c4113dSnw  *
1083c5c4113dSnw  * Input:
1084c5c4113dSnw  * sidprefix  - SID prefix
1085c5c4113dSnw  * rid        - RID
1086c5c4113dSnw  * flag       - flag
1087c5c4113dSnw  *
1088c5c4113dSnw  * Output:
1089c5c4113dSnw  * stat - status of the get request
1090c5c4113dSnw  * uid  - POSIX UID if stat = 0
1091c5c4113dSnw  *
1092c5c4113dSnw  * Note: The output parameters will be set by idmap_get_mappings()
1093c5c4113dSnw  */
1094c5c4113dSnw idmap_stat
1095c5c4113dSnw idmap_get_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
1096cd37da74Snw 		int flag, uid_t *uid, idmap_stat *stat)
1097cd37da74Snw {
109848258c6bSjp 	return (idmap_getext_uidbysid(gh, sidprefix, rid, flag, uid,
109948258c6bSjp 	    NULL, stat));
110048258c6bSjp }
110148258c6bSjp 
110248258c6bSjp /*
110348258c6bSjp  * Given SID, get UID
110448258c6bSjp  *
110548258c6bSjp  * Input:
110648258c6bSjp  * sidprefix  - SID prefix
110748258c6bSjp  * rid        - RID
110848258c6bSjp  * flag       - flag
110948258c6bSjp  *
111048258c6bSjp  * Output:
111148258c6bSjp  * stat - status of the get request
111248258c6bSjp  * uid  - POSIX UID if stat = 0
111348258c6bSjp  * how  - mapping type if stat = 0
111448258c6bSjp  *
111548258c6bSjp  * Note: The output parameters will be set by idmap_get_mappings()
111648258c6bSjp  */
1117c5c4113dSnw 
111848258c6bSjp idmap_stat
111948258c6bSjp idmap_getext_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
112048258c6bSjp 		int flag, uid_t *uid, idmap_info *info, idmap_stat *stat)
112148258c6bSjp {
1122c5c4113dSnw 	idmap_retcode	retcode;
1123651c0131Sbaban 	idmap_mapping	*mapping = NULL;
1124c5c4113dSnw 
1125c5c4113dSnw 	/* sanity checks */
1126c5c4113dSnw 	if (gh == NULL)
1127c5c4113dSnw 		return (IDMAP_ERR_ARG);
1128c5c4113dSnw 	if (uid == NULL || sidprefix == NULL)
1129c5c4113dSnw 		return (IDMAP_ERR_ARG);
1130c5c4113dSnw 
11313ee87bcaSJulian Pullen 	if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
11323ee87bcaSJulian Pullen 	    !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
11333ee87bcaSJulian Pullen 		retcode = idmap_cache_lookup_uidbysid(sidprefix, rid, uid);
11343ee87bcaSJulian Pullen 		if (retcode  == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
11353ee87bcaSJulian Pullen 			*stat = retcode;
11363ee87bcaSJulian Pullen 			return (retcode);
11373ee87bcaSJulian Pullen 		}
11383ee87bcaSJulian Pullen 	}
11393ee87bcaSJulian Pullen 
1140c5c4113dSnw 	/* Extend the request array and the return list */
1141c5c4113dSnw 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1142c5c4113dSnw 		goto errout;
1143c5c4113dSnw 
1144c5c4113dSnw 	/* Setup the request */
1145c5c4113dSnw 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1146c5c4113dSnw 	mapping->flag = flag;
1147c5c4113dSnw 	mapping->id1.idtype = IDMAP_SID;
1148c5c4113dSnw 	mapping->id1.idmap_id_u.sid.rid = rid;
1149c5c4113dSnw 	if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
1150c5c4113dSnw 		retcode = IDMAP_ERR_MEMORY;
1151c5c4113dSnw 		goto errout;
1152c5c4113dSnw 	}
1153c5c4113dSnw 	mapping->id2.idtype = IDMAP_UID;
1154c5c4113dSnw 
1155c5c4113dSnw 	/* Setup pointers for the result */
1156c5c4113dSnw 	gh->retlist[gh->next].idtype = IDMAP_UID;
1157c5c4113dSnw 	gh->retlist[gh->next].uid = uid;
1158c5c4113dSnw 	gh->retlist[gh->next].stat = stat;
115948258c6bSjp 	gh->retlist[gh->next].info = info;
11603ee87bcaSJulian Pullen 	gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1161c5c4113dSnw 
1162c5c4113dSnw 	gh->next++;
1163c5c4113dSnw 	return (IDMAP_SUCCESS);
1164c5c4113dSnw 
1165c5c4113dSnw errout:
1166651c0131Sbaban 	/* Batch created so far should still be usable */
1167651c0131Sbaban 	if (mapping)
1168651c0131Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
1169c5c4113dSnw 	errno = idmap_stat2errno(retcode);
1170c5c4113dSnw 	return (retcode);
1171c5c4113dSnw }
1172c5c4113dSnw 
1173c5c4113dSnw 
1174c5c4113dSnw /*
1175c5c4113dSnw  * Given SID, get GID
1176c5c4113dSnw  *
1177c5c4113dSnw  * Input:
1178c5c4113dSnw  * sidprefix  - SID prefix
1179c5c4113dSnw  * rid        - rid
1180c5c4113dSnw  * flag       - flag
1181c5c4113dSnw  *
1182c5c4113dSnw  * Output:
1183c5c4113dSnw  * stat - status of the get request
1184c5c4113dSnw  * gid  - POSIX GID if stat = 0
1185c5c4113dSnw  *
1186c5c4113dSnw  * Note: The output parameters will be set by idmap_get_mappings()
1187c5c4113dSnw  */
1188c5c4113dSnw idmap_stat
1189c5c4113dSnw idmap_get_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
1190cd37da74Snw 		int flag, gid_t *gid, idmap_stat *stat)
1191cd37da74Snw {
119248258c6bSjp 	return (idmap_getext_gidbysid(gh, sidprefix, rid, flag, gid,
119348258c6bSjp 	    NULL, stat));
119448258c6bSjp }
119548258c6bSjp 
119648258c6bSjp 
119748258c6bSjp /*
119848258c6bSjp  * Given SID, get GID
119948258c6bSjp  *
120048258c6bSjp  * Input:
120148258c6bSjp  * sidprefix  - SID prefix
120248258c6bSjp  * rid        - rid
120348258c6bSjp  * flag       - flag
120448258c6bSjp  *
120548258c6bSjp  * Output:
120648258c6bSjp  * stat - status of the get request
120748258c6bSjp  * gid  - POSIX GID if stat = 0
120848258c6bSjp  * how  - mapping type if stat = 0
120948258c6bSjp  *
121048258c6bSjp  * Note: The output parameters will be set by idmap_get_mappings()
121148258c6bSjp  */
121248258c6bSjp idmap_stat
121348258c6bSjp idmap_getext_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
121448258c6bSjp 		int flag, gid_t *gid, idmap_info *info, idmap_stat *stat)
121548258c6bSjp {
1216c5c4113dSnw 
1217c5c4113dSnw 	idmap_retcode	retcode;
1218651c0131Sbaban 	idmap_mapping	*mapping = NULL;
1219c5c4113dSnw 
1220c5c4113dSnw 	/* sanity checks */
1221c5c4113dSnw 	if (gh == NULL)
1222c5c4113dSnw 		return (IDMAP_ERR_ARG);
1223c5c4113dSnw 	if (gid == NULL || sidprefix == NULL)
1224c5c4113dSnw 		return (IDMAP_ERR_ARG);
1225c5c4113dSnw 
12263ee87bcaSJulian Pullen 	if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
12273ee87bcaSJulian Pullen 	    !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
12283ee87bcaSJulian Pullen 		retcode = idmap_cache_lookup_gidbysid(sidprefix, rid, gid);
12293ee87bcaSJulian Pullen 		if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
12303ee87bcaSJulian Pullen 			*stat = retcode;
12313ee87bcaSJulian Pullen 			return (retcode);
12323ee87bcaSJulian Pullen 		}
12333ee87bcaSJulian Pullen 	}
12343ee87bcaSJulian Pullen 
1235c5c4113dSnw 	/* Extend the request array and the return list */
1236c5c4113dSnw 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1237c5c4113dSnw 		goto errout;
1238c5c4113dSnw 
1239c5c4113dSnw 	/* Setup the request */
1240c5c4113dSnw 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1241c5c4113dSnw 	mapping->flag = flag;
1242c5c4113dSnw 	mapping->id1.idtype = IDMAP_SID;
1243c5c4113dSnw 	mapping->id1.idmap_id_u.sid.rid = rid;
1244c5c4113dSnw 	if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
1245c5c4113dSnw 		retcode = IDMAP_ERR_MEMORY;
1246c5c4113dSnw 		goto errout;
1247c5c4113dSnw 	}
1248c5c4113dSnw 	mapping->id2.idtype = IDMAP_GID;
1249c5c4113dSnw 
1250c5c4113dSnw 	/* Setup pointers for the result */
1251c5c4113dSnw 	gh->retlist[gh->next].idtype = IDMAP_GID;
1252c5c4113dSnw 	gh->retlist[gh->next].gid = gid;
1253c5c4113dSnw 	gh->retlist[gh->next].stat = stat;
125448258c6bSjp 	gh->retlist[gh->next].info = info;
12553ee87bcaSJulian Pullen 	gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1256c5c4113dSnw 
1257c5c4113dSnw 	gh->next++;
1258c5c4113dSnw 	return (IDMAP_SUCCESS);
1259c5c4113dSnw 
1260c5c4113dSnw errout:
1261651c0131Sbaban 	if (mapping)
1262651c0131Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
1263c5c4113dSnw 	errno = idmap_stat2errno(retcode);
1264c5c4113dSnw 	return (retcode);
1265c5c4113dSnw }
1266c5c4113dSnw 
1267c5c4113dSnw 
126848258c6bSjp 
1269c5c4113dSnw /*
1270c5c4113dSnw  * Given SID, get POSIX ID i.e. UID/GID
1271c5c4113dSnw  *
1272c5c4113dSnw  * Input:
1273c5c4113dSnw  * sidprefix  - SID prefix
1274c5c4113dSnw  * rid        - rid
1275c5c4113dSnw  * flag       - flag
1276c5c4113dSnw  *
1277c5c4113dSnw  * Output:
1278c5c4113dSnw  * stat    - status of the get request
1279c5c4113dSnw  * is_user - user or group
1280c5c4113dSnw  * pid     - POSIX UID if stat = 0 and is_user = 1
1281c5c4113dSnw  *           POSIX GID if stat = 0 and is_user = 0
1282c5c4113dSnw  *
1283c5c4113dSnw  * Note: The output parameters will be set by idmap_get_mappings()
1284c5c4113dSnw  */
1285c5c4113dSnw idmap_stat
1286c5c4113dSnw idmap_get_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
1287cd37da74Snw 		int flag, uid_t *pid, int *is_user, idmap_stat *stat)
128848258c6bSjp {
128948258c6bSjp 	return (idmap_getext_pidbysid(gh, sidprefix, rid, flag, pid, is_user,
129048258c6bSjp 	    NULL, stat));
129148258c6bSjp }
129248258c6bSjp 
129348258c6bSjp 
129448258c6bSjp 
129548258c6bSjp /*
129648258c6bSjp  * Given SID, get POSIX ID i.e. UID/GID
129748258c6bSjp  *
129848258c6bSjp  * Input:
129948258c6bSjp  * sidprefix  - SID prefix
130048258c6bSjp  * rid        - rid
130148258c6bSjp  * flag       - flag
130248258c6bSjp  *
130348258c6bSjp  * Output:
130448258c6bSjp  * stat    - status of the get request
130548258c6bSjp  * is_user - user or group
130648258c6bSjp  * pid     - POSIX UID if stat = 0 and is_user = 1
130748258c6bSjp  *           POSIX GID if stat = 0 and is_user = 0
130848258c6bSjp  * how     - mapping type if stat = 0
130948258c6bSjp  *
131048258c6bSjp  * Note: The output parameters will be set by idmap_get_mappings()
131148258c6bSjp  */
131248258c6bSjp idmap_stat
131348258c6bSjp idmap_getext_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
131448258c6bSjp 	int flag, uid_t *pid, int *is_user, idmap_info *info, idmap_stat *stat)
1315cd37da74Snw {
1316c5c4113dSnw 	idmap_retcode	retcode;
1317651c0131Sbaban 	idmap_mapping	*mapping = NULL;
1318c5c4113dSnw 
1319c5c4113dSnw 	/* sanity checks */
1320c5c4113dSnw 	if (gh == NULL)
1321c5c4113dSnw 		return (IDMAP_ERR_ARG);
1322c5c4113dSnw 	if (pid == NULL || sidprefix == NULL || is_user == NULL)
1323c5c4113dSnw 		return (IDMAP_ERR_ARG);
1324c5c4113dSnw 
13253ee87bcaSJulian Pullen 	if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
13263ee87bcaSJulian Pullen 	    !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
13273ee87bcaSJulian Pullen 		retcode = idmap_cache_lookup_pidbysid(sidprefix, rid, pid,
13283ee87bcaSJulian Pullen 		    is_user);
13293ee87bcaSJulian Pullen 		if (retcode  == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
13303ee87bcaSJulian Pullen 			*stat = retcode;
13313ee87bcaSJulian Pullen 			return (retcode);
13323ee87bcaSJulian Pullen 		}
13333ee87bcaSJulian Pullen 	}
13343ee87bcaSJulian Pullen 
1335c5c4113dSnw 	/* Extend the request array and the return list */
1336c5c4113dSnw 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1337c5c4113dSnw 		goto errout;
1338c5c4113dSnw 
1339c5c4113dSnw 	/* Setup the request */
1340c5c4113dSnw 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1341c5c4113dSnw 	mapping->flag = flag;
1342c5c4113dSnw 	mapping->id1.idtype = IDMAP_SID;
1343c5c4113dSnw 	mapping->id1.idmap_id_u.sid.rid = rid;
1344c5c4113dSnw 	if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
1345c5c4113dSnw 		retcode = IDMAP_ERR_MEMORY;
1346c5c4113dSnw 		goto errout;
1347c5c4113dSnw 	}
1348c5c4113dSnw 	mapping->id2.idtype = IDMAP_POSIXID;
1349c5c4113dSnw 
1350c5c4113dSnw 	/* Setup pointers for the result */
1351c5c4113dSnw 	gh->retlist[gh->next].idtype = IDMAP_POSIXID;
1352c5c4113dSnw 	gh->retlist[gh->next].uid = pid;
1353c5c4113dSnw 	gh->retlist[gh->next].gid = pid;
1354c5c4113dSnw 	gh->retlist[gh->next].is_user = is_user;
1355c5c4113dSnw 	gh->retlist[gh->next].stat = stat;
135648258c6bSjp 	gh->retlist[gh->next].info = info;
13573ee87bcaSJulian Pullen 	gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1358c5c4113dSnw 
1359c5c4113dSnw 	gh->next++;
1360c5c4113dSnw 	return (IDMAP_SUCCESS);
1361c5c4113dSnw 
1362c5c4113dSnw errout:
1363651c0131Sbaban 	if (mapping)
1364651c0131Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
1365c5c4113dSnw 	errno = idmap_stat2errno(retcode);
1366c5c4113dSnw 	return (retcode);
1367c5c4113dSnw }
1368c5c4113dSnw 
1369c5c4113dSnw 
1370c5c4113dSnw /*
1371c5c4113dSnw  * Given UID, get SID
1372c5c4113dSnw  *
1373c5c4113dSnw  * Input:
1374c5c4113dSnw  * uid  - POSIX UID
1375c5c4113dSnw  * flag - flag
1376c5c4113dSnw  *
1377c5c4113dSnw  * Output:
1378c5c4113dSnw  * stat - status of the get request
1379c5c4113dSnw  * sid  - SID prefix (if stat == 0)
1380c5c4113dSnw  * rid  - rid
1381c5c4113dSnw  *
1382c5c4113dSnw  * Note: The output parameters will be set by idmap_get_mappings()
1383c5c4113dSnw  */
1384c5c4113dSnw idmap_stat
1385c5c4113dSnw idmap_get_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag,
1386cd37da74Snw 		char **sidprefix, idmap_rid_t *rid, idmap_stat *stat)
1387cd37da74Snw {
138848258c6bSjp 	return (idmap_getext_sidbyuid(gh, uid, flag, sidprefix, rid,
138948258c6bSjp 	    NULL, stat));
139048258c6bSjp }
139148258c6bSjp 
139248258c6bSjp 
139348258c6bSjp /*
139448258c6bSjp  * Given UID, get SID
139548258c6bSjp  *
139648258c6bSjp  * Input:
139748258c6bSjp  * uid  - POSIX UID
139848258c6bSjp  * flag - flag
139948258c6bSjp  *
140048258c6bSjp  * Output:
140148258c6bSjp  * stat - status of the get request
140248258c6bSjp  * sid  - SID prefix (if stat == 0)
140348258c6bSjp  * rid  - rid
140448258c6bSjp  * how  - mapping type if stat = 0
140548258c6bSjp  *
140648258c6bSjp  * Note: The output parameters will be set by idmap_get_mappings()
140748258c6bSjp  */
140848258c6bSjp idmap_stat
140948258c6bSjp idmap_getext_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag,
141048258c6bSjp 	char **sidprefix, idmap_rid_t *rid, idmap_info *info, idmap_stat *stat)
141148258c6bSjp {
1412c5c4113dSnw 
1413c5c4113dSnw 	idmap_retcode	retcode;
1414651c0131Sbaban 	idmap_mapping	*mapping = NULL;
1415c5c4113dSnw 
1416c5c4113dSnw 	/* sanity checks */
1417c5c4113dSnw 	if (gh == NULL)
1418c5c4113dSnw 		return (IDMAP_ERR_ARG);
1419c5c4113dSnw 	if (sidprefix == NULL)
1420c5c4113dSnw 		return (IDMAP_ERR_ARG);
1421c5c4113dSnw 
14223ee87bcaSJulian Pullen 	if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
14233ee87bcaSJulian Pullen 	    !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
14243ee87bcaSJulian Pullen 		retcode = idmap_cache_lookup_sidbyuid(sidprefix, rid, uid);
14253ee87bcaSJulian Pullen 		if (retcode  == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
14263ee87bcaSJulian Pullen 			*stat = retcode;
14273ee87bcaSJulian Pullen 			return (retcode);
14283ee87bcaSJulian Pullen 		}
14293ee87bcaSJulian Pullen 	}
14303ee87bcaSJulian Pullen 
1431c5c4113dSnw 	/* Extend the request array and the return list */
1432c5c4113dSnw 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1433c5c4113dSnw 		goto errout;
1434c5c4113dSnw 
1435c5c4113dSnw 	/* Setup the request */
1436c5c4113dSnw 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1437c5c4113dSnw 	mapping->flag = flag;
1438c5c4113dSnw 	mapping->id1.idtype = IDMAP_UID;
1439c5c4113dSnw 	mapping->id1.idmap_id_u.uid = uid;
1440c5c4113dSnw 	mapping->id2.idtype = IDMAP_SID;
1441c5c4113dSnw 
1442c5c4113dSnw 	/* Setup pointers for the result */
1443c5c4113dSnw 	gh->retlist[gh->next].idtype = IDMAP_SID;
1444c5c4113dSnw 	gh->retlist[gh->next].sidprefix = sidprefix;
1445c5c4113dSnw 	gh->retlist[gh->next].rid = rid;
1446c5c4113dSnw 	gh->retlist[gh->next].stat = stat;
144748258c6bSjp 	gh->retlist[gh->next].info = info;
14483ee87bcaSJulian Pullen 	gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1449c5c4113dSnw 
1450c5c4113dSnw 	gh->next++;
1451c5c4113dSnw 	return (IDMAP_SUCCESS);
1452c5c4113dSnw 
1453c5c4113dSnw errout:
1454651c0131Sbaban 	if (mapping)
1455651c0131Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
1456c5c4113dSnw 	errno = idmap_stat2errno(retcode);
1457c5c4113dSnw 	return (retcode);
1458c5c4113dSnw }
1459c5c4113dSnw 
1460c5c4113dSnw 
1461c5c4113dSnw /*
1462c5c4113dSnw  * Given GID, get SID
1463c5c4113dSnw  *
1464c5c4113dSnw  * Input:
1465c5c4113dSnw  * gid  - POSIX GID
1466c5c4113dSnw  * flag - flag
1467c5c4113dSnw  *
1468c5c4113dSnw  * Output:
1469c5c4113dSnw  * stat       - status of the get request
1470c5c4113dSnw  * sidprefix  - SID prefix (if stat == 0)
1471c5c4113dSnw  * rid        - rid
1472c5c4113dSnw  *
1473c5c4113dSnw  * Note: The output parameters will be set by idmap_get_mappings()
1474c5c4113dSnw  */
1475c5c4113dSnw idmap_stat
1476c5c4113dSnw idmap_get_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag,
1477cd37da74Snw 		char **sidprefix, idmap_rid_t *rid, idmap_stat *stat)
1478cd37da74Snw {
147948258c6bSjp 	return (idmap_getext_sidbygid(gh, gid, flag, sidprefix, rid,
148048258c6bSjp 	    NULL, stat));
148148258c6bSjp }
148248258c6bSjp 
148348258c6bSjp 
148448258c6bSjp /*
148548258c6bSjp  * Given GID, get SID
148648258c6bSjp  *
148748258c6bSjp  * Input:
148848258c6bSjp  * gid  - POSIX GID
148948258c6bSjp  * flag - flag
149048258c6bSjp  *
149148258c6bSjp  * Output:
149248258c6bSjp  * stat       - status of the get request
149348258c6bSjp  * sidprefix  - SID prefix (if stat == 0)
149448258c6bSjp  * rid        - rid
149548258c6bSjp  * how        - mapping type if stat = 0
149648258c6bSjp  *
149748258c6bSjp  * Note: The output parameters will be set by idmap_get_mappings()
149848258c6bSjp  */
149948258c6bSjp idmap_stat
150048258c6bSjp idmap_getext_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag,
150148258c6bSjp 	char **sidprefix, idmap_rid_t *rid, idmap_info *info, idmap_stat *stat)
150248258c6bSjp {
1503c5c4113dSnw 
1504c5c4113dSnw 	idmap_retcode	retcode;
1505651c0131Sbaban 	idmap_mapping	*mapping = NULL;
1506c5c4113dSnw 
1507c5c4113dSnw 	/* sanity checks */
1508c5c4113dSnw 	if (gh == NULL)
1509c5c4113dSnw 		return (IDMAP_ERR_ARG);
1510c5c4113dSnw 	if (sidprefix == NULL)
1511c5c4113dSnw 		return (IDMAP_ERR_ARG);
1512c5c4113dSnw 
15133ee87bcaSJulian Pullen 	if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
15143ee87bcaSJulian Pullen 	    !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
15153ee87bcaSJulian Pullen 		retcode = idmap_cache_lookup_sidbygid(sidprefix, rid, gid);
15163ee87bcaSJulian Pullen 		if (retcode  == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
15173ee87bcaSJulian Pullen 			*stat = retcode;
15183ee87bcaSJulian Pullen 			return (retcode);
15193ee87bcaSJulian Pullen 		}
15203ee87bcaSJulian Pullen 	}
15213ee87bcaSJulian Pullen 
1522c5c4113dSnw 	/* Extend the request array and the return list */
1523c5c4113dSnw 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
1524c5c4113dSnw 		goto errout;
1525c5c4113dSnw 
1526c5c4113dSnw 	/* Setup the request */
1527c5c4113dSnw 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
1528c5c4113dSnw 	mapping->flag = flag;
1529c5c4113dSnw 	mapping->id1.idtype = IDMAP_GID;
1530c5c4113dSnw 	mapping->id1.idmap_id_u.gid = gid;
1531c5c4113dSnw 	mapping->id2.idtype = IDMAP_SID;
1532c5c4113dSnw 
1533c5c4113dSnw 	/* Setup pointers for the result */
1534c5c4113dSnw 	gh->retlist[gh->next].idtype = IDMAP_SID;
1535c5c4113dSnw 	gh->retlist[gh->next].sidprefix = sidprefix;
1536c5c4113dSnw 	gh->retlist[gh->next].rid = rid;
1537c5c4113dSnw 	gh->retlist[gh->next].stat = stat;
153848258c6bSjp 	gh->retlist[gh->next].info = info;
15393ee87bcaSJulian Pullen 	gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
1540c5c4113dSnw 
1541c5c4113dSnw 	gh->next++;
1542c5c4113dSnw 	return (IDMAP_SUCCESS);
1543c5c4113dSnw 
1544c5c4113dSnw errout:
1545651c0131Sbaban 	if (mapping)
1546651c0131Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
1547c5c4113dSnw 	errno = idmap_stat2errno(retcode);
1548c5c4113dSnw 	return (retcode);
1549c5c4113dSnw }
1550c5c4113dSnw 
1551c5c4113dSnw 
1552c5c4113dSnw /*
1553c5c4113dSnw  * Process the batched "get mapping" requests. The results (i.e.
1554c5c4113dSnw  * status and identity) will be available in the data areas
1555c5c4113dSnw  * provided by individual requests.
1556c5c4113dSnw  */
1557c5c4113dSnw idmap_stat
1558cd37da74Snw idmap_get_mappings(idmap_get_handle_t *gh)
1559cd37da74Snw {
1560c5c4113dSnw 	CLIENT		*clnt;
1561c5c4113dSnw 	enum clnt_stat	clntstat;
1562c5c4113dSnw 	idmap_retcode	retcode;
1563c5c4113dSnw 	idmap_ids_res	res;
15643ee87bcaSJulian Pullen 	idmap_id	*res_id;
1565c5c4113dSnw 	int		i;
15663ee87bcaSJulian Pullen 	idmap_id	*req_id;
15673ee87bcaSJulian Pullen 	int		direction;
1568c5c4113dSnw 
1569c5c4113dSnw 	if (gh == NULL) {
1570c5c4113dSnw 		errno = EINVAL;
1571c5c4113dSnw 		return (IDMAP_ERR_ARG);
1572c5c4113dSnw 	}
1573c5c4113dSnw 	_IDMAP_GET_CLIENT_HANDLE(gh->ih, clnt);
1574c5c4113dSnw 
1575c5c4113dSnw 	(void) memset(&res, 0, sizeof (idmap_ids_res));
1576c5c4113dSnw 	clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_IDS,
1577cd37da74Snw 	    (xdrproc_t)xdr_idmap_mapping_batch,
1578cd37da74Snw 	    (caddr_t)&gh->batch,
1579cd37da74Snw 	    (xdrproc_t)xdr_idmap_ids_res,
1580cd37da74Snw 	    (caddr_t)&res,
1581cd37da74Snw 	    TIMEOUT);
1582c5c4113dSnw 	if (clntstat != RPC_SUCCESS) {
1583651c0131Sbaban 		retcode = _idmap_rpc2stat(clnt);
1584c5c4113dSnw 		goto out;
1585c5c4113dSnw 	}
1586c5c4113dSnw 	if (res.retcode != IDMAP_SUCCESS) {
1587c5c4113dSnw 		retcode = res.retcode;
1588c5c4113dSnw 		goto out;
1589c5c4113dSnw 	}
1590c5c4113dSnw 	for (i = 0; i < gh->next; i++) {
1591c5c4113dSnw 		if (i >= res.ids.ids_len) {
1592c5c4113dSnw 			*gh->retlist[i].stat = IDMAP_ERR_NORESULT;
1593c5c4113dSnw 			continue;
1594c5c4113dSnw 		}
1595c5c4113dSnw 		*gh->retlist[i].stat = res.ids.ids_val[i].retcode;
15963ee87bcaSJulian Pullen 		res_id = &res.ids.ids_val[i].id;
15973ee87bcaSJulian Pullen 		direction = res.ids.ids_val[i].direction;
15983ee87bcaSJulian Pullen 		req_id = &gh->batch.idmap_mapping_batch_val[i].id1;
15993ee87bcaSJulian Pullen 		switch (res_id->idtype) {
1600c5c4113dSnw 		case IDMAP_UID:
1601c5c4113dSnw 			if (gh->retlist[i].uid)
16023ee87bcaSJulian Pullen 				*gh->retlist[i].uid = res_id->idmap_id_u.uid;
1603c5c4113dSnw 			if (gh->retlist[i].is_user)
1604c5c4113dSnw 				*gh->retlist[i].is_user = 1;
16053ee87bcaSJulian Pullen 
16063ee87bcaSJulian Pullen 			if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS &&
16073ee87bcaSJulian Pullen 			    gh->retlist[i].cache_res) {
16083ee87bcaSJulian Pullen 				if (gh->retlist[i].is_user != NULL)
16093ee87bcaSJulian Pullen 					idmap_cache_add_sid2pid(
16103ee87bcaSJulian Pullen 					    req_id->idmap_id_u.sid.prefix,
16113ee87bcaSJulian Pullen 					    req_id->idmap_id_u.sid.rid,
16123ee87bcaSJulian Pullen 					    res_id->idmap_id_u.uid, 1,
16133ee87bcaSJulian Pullen 					    direction);
16143ee87bcaSJulian Pullen 				else
16153ee87bcaSJulian Pullen 					idmap_cache_add_sid2uid(
16163ee87bcaSJulian Pullen 					    req_id->idmap_id_u.sid.prefix,
16173ee87bcaSJulian Pullen 					    req_id->idmap_id_u.sid.rid,
16183ee87bcaSJulian Pullen 					    res_id->idmap_id_u.uid,
16193ee87bcaSJulian Pullen 					    direction);
16203ee87bcaSJulian Pullen 			}
1621c5c4113dSnw 			break;
16223ee87bcaSJulian Pullen 
1623c5c4113dSnw 		case IDMAP_GID:
1624c5c4113dSnw 			if (gh->retlist[i].gid)
16253ee87bcaSJulian Pullen 				*gh->retlist[i].gid = res_id->idmap_id_u.gid;
1626c5c4113dSnw 			if (gh->retlist[i].is_user)
1627c5c4113dSnw 				*gh->retlist[i].is_user = 0;
16283ee87bcaSJulian Pullen 
16293ee87bcaSJulian Pullen 			if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS &&
16303ee87bcaSJulian Pullen 			    gh->retlist[i].cache_res) {
16313ee87bcaSJulian Pullen 				if (gh->retlist[i].is_user != NULL)
16323ee87bcaSJulian Pullen 					idmap_cache_add_sid2pid(
16333ee87bcaSJulian Pullen 					    req_id->idmap_id_u.sid.prefix,
16343ee87bcaSJulian Pullen 					    req_id->idmap_id_u.sid.rid,
16353ee87bcaSJulian Pullen 					    res_id->idmap_id_u.gid, 0,
16363ee87bcaSJulian Pullen 					    direction);
16373ee87bcaSJulian Pullen 				else
16383ee87bcaSJulian Pullen 					idmap_cache_add_sid2gid(
16393ee87bcaSJulian Pullen 					    req_id->idmap_id_u.sid.prefix,
16403ee87bcaSJulian Pullen 					    req_id->idmap_id_u.sid.rid,
16413ee87bcaSJulian Pullen 					    res_id->idmap_id_u.gid,
16423ee87bcaSJulian Pullen 					    direction);
16433ee87bcaSJulian Pullen 			}
1644c5c4113dSnw 			break;
16453ee87bcaSJulian Pullen 
164662c60062Sbaban 		case IDMAP_POSIXID:
164762c60062Sbaban 			if (gh->retlist[i].uid)
164862c60062Sbaban 				*gh->retlist[i].uid = 60001;
164962c60062Sbaban 			if (gh->retlist[i].is_user)
165062c60062Sbaban 				*gh->retlist[i].is_user = -1;
165162c60062Sbaban 			break;
16523ee87bcaSJulian Pullen 
1653c5c4113dSnw 		case IDMAP_SID:
1654cd37da74Snw 		case IDMAP_USID:
1655cd37da74Snw 		case IDMAP_GSID:
1656c5c4113dSnw 			if (gh->retlist[i].rid)
16573ee87bcaSJulian Pullen 				*gh->retlist[i].rid =
16583ee87bcaSJulian Pullen 				    res_id->idmap_id_u.sid.rid;
1659c5c4113dSnw 			if (gh->retlist[i].sidprefix) {
16603ee87bcaSJulian Pullen 				if (res_id->idmap_id_u.sid.prefix == NULL ||
16613ee87bcaSJulian Pullen 				    *res_id->idmap_id_u.sid.prefix == '\0') {
1662c5c4113dSnw 					*gh->retlist[i].sidprefix = NULL;
1663c5c4113dSnw 					break;
1664c5c4113dSnw 				}
1665c5c4113dSnw 				*gh->retlist[i].sidprefix =
16663ee87bcaSJulian Pullen 				    strdup(res_id->idmap_id_u.sid.prefix);
1667c5c4113dSnw 				if (*gh->retlist[i].sidprefix == NULL)
1668c5c4113dSnw 					*gh->retlist[i].stat =
1669cd37da74Snw 					    IDMAP_ERR_MEMORY;
1670c5c4113dSnw 			}
16713ee87bcaSJulian Pullen 			if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS &&
16723ee87bcaSJulian Pullen 			    gh->retlist[i].cache_res) {
16733ee87bcaSJulian Pullen 				if (req_id->idtype == IDMAP_UID)
16743ee87bcaSJulian Pullen 					idmap_cache_add_sid2uid(
16753ee87bcaSJulian Pullen 					    res_id->idmap_id_u.sid.prefix,
16763ee87bcaSJulian Pullen 					    res_id->idmap_id_u.sid.rid,
16773ee87bcaSJulian Pullen 					    req_id->idmap_id_u.uid,
16783ee87bcaSJulian Pullen 					    direction);
16793ee87bcaSJulian Pullen 				else /* req_id->idtype == IDMAP_GID */
16803ee87bcaSJulian Pullen 					idmap_cache_add_sid2gid(
16813ee87bcaSJulian Pullen 					    res_id->idmap_id_u.sid.prefix,
16823ee87bcaSJulian Pullen 					    res_id->idmap_id_u.sid.rid,
16833ee87bcaSJulian Pullen 					    req_id->idmap_id_u.gid,
16843ee87bcaSJulian Pullen 					    direction);
16853ee87bcaSJulian Pullen 			}
1686c5c4113dSnw 			break;
16873ee87bcaSJulian Pullen 
1688c5c4113dSnw 		case IDMAP_NONE:
1689c5c4113dSnw 			break;
16903ee87bcaSJulian Pullen 
1691c5c4113dSnw 		default:
1692c5c4113dSnw 			*gh->retlist[i].stat = IDMAP_ERR_NORESULT;
1693c5c4113dSnw 			break;
1694c5c4113dSnw 		}
1695*148c5f43SAlan Wright 		if (gh->retlist[i].info != NULL) {
1696*148c5f43SAlan Wright 			idmap_info_mov(gh->retlist[i].info,
169748258c6bSjp 			    &res.ids.ids_val[i].info);
1698*148c5f43SAlan Wright 		}
1699c5c4113dSnw 	}
1700c5c4113dSnw 	retcode = IDMAP_SUCCESS;
1701c5c4113dSnw 
1702c5c4113dSnw out:
1703651c0131Sbaban 	_IDMAP_RESET_GET_HANDLE(gh);
1704c5c4113dSnw 	(void) xdr_free(xdr_idmap_ids_res, (caddr_t)&res);
1705c5c4113dSnw 	errno = idmap_stat2errno(retcode);
1706c5c4113dSnw 	return (retcode);
1707c5c4113dSnw }
1708c5c4113dSnw 
1709c5c4113dSnw 
1710c5c4113dSnw /*
1711c5c4113dSnw  * Destroy the "get mapping" handle
1712c5c4113dSnw  */
1713c5c4113dSnw void
1714cd37da74Snw idmap_get_destroy(idmap_get_handle_t *gh)
1715cd37da74Snw {
1716c5c4113dSnw 	if (gh == NULL)
1717c5c4113dSnw 		return;
1718c5c4113dSnw 	(void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch);
1719c5c4113dSnw 	if (gh->retlist)
1720c5c4113dSnw 		free(gh->retlist);
1721c5c4113dSnw 	free(gh);
1722c5c4113dSnw }
1723c5c4113dSnw 
1724c5c4113dSnw 
1725c5c4113dSnw /*
1726c5c4113dSnw  * Get windows to unix mapping
1727c5c4113dSnw  */
1728c5c4113dSnw idmap_stat
1729c5c4113dSnw idmap_get_w2u_mapping(idmap_handle_t *handle,
1730c5c4113dSnw 		const char *sidprefix, idmap_rid_t *rid,
1731c5c4113dSnw 		const char *winname, const char *windomain,
1732cd37da74Snw 		int flag, int *is_user, int *is_wuser,
173348258c6bSjp 		uid_t *pid, char **unixname, int *direction, idmap_info *info)
1734cd37da74Snw {
1735c5c4113dSnw 	CLIENT			*clnt;
1736c5c4113dSnw 	enum clnt_stat		clntstat;
1737c5c4113dSnw 	idmap_mapping		request, *mapping;
1738c5c4113dSnw 	idmap_mappings_res	result;
1739c5c4113dSnw 	idmap_retcode		retcode, rc;
1740c5c4113dSnw 
1741c5c4113dSnw 	if (handle == NULL) {
1742c5c4113dSnw 		errno = EINVAL;
1743c5c4113dSnw 		return (IDMAP_ERR_ARG);
1744c5c4113dSnw 	}
1745c5c4113dSnw 
1746c5c4113dSnw 	_IDMAP_GET_CLIENT_HANDLE(handle, clnt);
1747c5c4113dSnw 
1748c5c4113dSnw 	(void) memset(&request, 0, sizeof (request));
1749c5c4113dSnw 	(void) memset(&result, 0, sizeof (result));
1750c5c4113dSnw 
1751c5c4113dSnw 	if (pid)
1752c5c4113dSnw 		*pid = UINT32_MAX;
1753c5c4113dSnw 	if (unixname)
1754c5c4113dSnw 		*unixname = NULL;
1755c5c4113dSnw 	if (direction)
1756651c0131Sbaban 		*direction = IDMAP_DIRECTION_UNDEF;
1757c5c4113dSnw 
1758c5c4113dSnw 	request.flag = flag;
1759c5c4113dSnw 	request.id1.idtype = IDMAP_SID;
1760c5c4113dSnw 	if (sidprefix && rid) {
1761c5c4113dSnw 		request.id1.idmap_id_u.sid.prefix = (char *)sidprefix;
1762c5c4113dSnw 		request.id1.idmap_id_u.sid.rid = *rid;
1763c5c4113dSnw 	} else if (winname) {
17648e228215Sdm 		retcode = idmap_strdupnull(&request.id1name, winname);
1765c5a946baSbaban 		if (retcode != IDMAP_SUCCESS)
1766c5c4113dSnw 			goto out;
17678e228215Sdm 
17688e228215Sdm 		retcode = idmap_strdupnull(&request.id1domain, windomain);
1769c5a946baSbaban 		if (retcode != IDMAP_SUCCESS)
17708e228215Sdm 			goto out;
17718e228215Sdm 
1772c5c4113dSnw 		request.id1.idmap_id_u.sid.prefix = NULL;
1773c5c4113dSnw 	} else {
1774c5c4113dSnw 		errno = EINVAL;
1775c5c4113dSnw 		return (IDMAP_ERR_ARG);
1776c5c4113dSnw 	}
1777c5c4113dSnw 
1778cd37da74Snw 	if (*is_user == 1)
1779c5c4113dSnw 		request.id2.idtype = IDMAP_UID;
1780c5c4113dSnw 	else if (*is_user == 0)
1781c5c4113dSnw 		request.id2.idtype = IDMAP_GID;
1782c5c4113dSnw 	else
1783c5c4113dSnw 		request.id2.idtype = IDMAP_POSIXID;
1784c5c4113dSnw 
1785cd37da74Snw 	if (*is_wuser == 1)
1786cd37da74Snw 		request.id1.idtype = IDMAP_USID;
1787cd37da74Snw 	else if (*is_wuser == 0)
1788cd37da74Snw 		request.id1.idtype = IDMAP_GSID;
1789cd37da74Snw 	else
1790cd37da74Snw 		request.id1.idtype = IDMAP_SID;
1791cd37da74Snw 
1792c5c4113dSnw 	clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_ID_BY_NAME,
1793cd37da74Snw 	    (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request,
1794cd37da74Snw 	    (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result,
1795cd37da74Snw 	    TIMEOUT);
1796c5c4113dSnw 
1797651c0131Sbaban 	if (clntstat != RPC_SUCCESS)
1798651c0131Sbaban 		return (_idmap_rpc2stat(clnt));
1799c5c4113dSnw 
1800c5c4113dSnw 	retcode = result.retcode;
1801c5c4113dSnw 
1802c5c4113dSnw 	if ((mapping = result.mappings.mappings_val) == NULL) {
1803c5c4113dSnw 		if (retcode == IDMAP_SUCCESS)
1804c5c4113dSnw 			retcode = IDMAP_ERR_NORESULT;
1805c5c4113dSnw 		goto out;
1806c5c4113dSnw 	}
1807c5c4113dSnw 
1808*148c5f43SAlan Wright 	if (info != NULL)
1809*148c5f43SAlan Wright 		idmap_info_mov(info, &mapping->info);
1810*148c5f43SAlan Wright 
181162c60062Sbaban 	if (mapping->id2.idtype == IDMAP_UID) {
1812cd37da74Snw 		*is_user = 1;
181362c60062Sbaban 	} else if (mapping->id2.idtype == IDMAP_GID) {
1814cd37da74Snw 		*is_user = 0;
181562c60062Sbaban 	} else {
181662c60062Sbaban 		goto out;
181762c60062Sbaban 	}
1818cd37da74Snw 
1819cd37da74Snw 	if (mapping->id1.idtype == IDMAP_USID) {
1820cd37da74Snw 		*is_wuser = 1;
1821cd37da74Snw 	} else if (mapping->id1.idtype == IDMAP_GSID) {
1822cd37da74Snw 		*is_wuser = 0;
1823cd37da74Snw 	} else {
1824cd37da74Snw 		goto out;
1825cd37da74Snw 	}
1826cd37da74Snw 
1827c5c4113dSnw 	if (direction)
1828c5c4113dSnw 		*direction = mapping->direction;
1829c5c4113dSnw 	if (pid)
1830c5c4113dSnw 		*pid = mapping->id2.idmap_id_u.uid;
18318e228215Sdm 
18328e228215Sdm 	rc = idmap_strdupnull(unixname, mapping->id2name);
18338e228215Sdm 	if (rc != IDMAP_SUCCESS)
18348e228215Sdm 		retcode = rc;
1835c5c4113dSnw 
1836c5c4113dSnw out:
1837f7b4b2feSjp 	if (request.id1name != NULL)
1838f7b4b2feSjp 		free(request.id1name);
1839f7b4b2feSjp 	if (request.id1domain != NULL)
1840f7b4b2feSjp 		free(request.id1domain);
1841c5c4113dSnw 	xdr_free(xdr_idmap_mappings_res, (caddr_t)&result);
1842c5c4113dSnw 	if (retcode != IDMAP_SUCCESS)
1843c5c4113dSnw 		errno = idmap_stat2errno(retcode);
1844c5c4113dSnw 	return (retcode);
1845c5c4113dSnw }
1846c5c4113dSnw 
1847c5c4113dSnw 
1848c5c4113dSnw /*
1849c5c4113dSnw  * Get unix to windows mapping
1850c5c4113dSnw  */
1851c5c4113dSnw idmap_stat
1852c5c4113dSnw idmap_get_u2w_mapping(idmap_handle_t *handle,
1853c5c4113dSnw 		uid_t *pid, const char *unixname,
1854cd37da74Snw 		int flag, int is_user, int *is_wuser,
1855c5c4113dSnw 		char **sidprefix, idmap_rid_t *rid,
1856c5c4113dSnw 		char **winname, char **windomain,
185748258c6bSjp 		int *direction, idmap_info *info)
1858cd37da74Snw {
1859c5c4113dSnw 	CLIENT			*clnt;
1860c5c4113dSnw 	enum clnt_stat		clntstat;
1861c5c4113dSnw 	idmap_mapping		request, *mapping;
1862c5c4113dSnw 	idmap_mappings_res	result;
1863c5c4113dSnw 	idmap_retcode		retcode, rc;
1864c5c4113dSnw 
1865c5c4113dSnw 	if (handle == NULL) {
1866c5c4113dSnw 		errno = EINVAL;
1867c5c4113dSnw 		return (IDMAP_ERR_ARG);
1868c5c4113dSnw 	}
1869c5c4113dSnw 
1870c5c4113dSnw 	_IDMAP_GET_CLIENT_HANDLE(handle, clnt);
1871c5c4113dSnw 
1872c5c4113dSnw 	if (sidprefix)
1873c5c4113dSnw 		*sidprefix = NULL;
1874c5c4113dSnw 	if (winname)
1875c5c4113dSnw 		*winname = NULL;
1876c5c4113dSnw 	if (windomain)
1877c5c4113dSnw 		*windomain = NULL;
1878c5c4113dSnw 	if (rid)
1879c5c4113dSnw 		*rid = UINT32_MAX;
1880c5c4113dSnw 	if (direction)
1881651c0131Sbaban 		*direction = IDMAP_DIRECTION_UNDEF;
1882c5c4113dSnw 
1883c5c4113dSnw 	(void) memset(&request, 0, sizeof (request));
1884c5c4113dSnw 	(void) memset(&result, 0, sizeof (result));
1885c5c4113dSnw 
1886c5c4113dSnw 	request.flag = flag;
1887c5c4113dSnw 	request.id1.idtype = is_user?IDMAP_UID:IDMAP_GID;
1888c5c4113dSnw 
1889c5c4113dSnw 	if (pid && *pid != UINT32_MAX) {
1890c5c4113dSnw 		request.id1.idmap_id_u.uid = *pid;
1891c5c4113dSnw 	} else if (unixname) {
18928e228215Sdm 		request.id1name = (char *)unixname;
1893c5c4113dSnw 		request.id1.idmap_id_u.uid = UINT32_MAX;
1894c5c4113dSnw 	} else {
1895c5c4113dSnw 		errno = EINVAL;
1896c5c4113dSnw 		return (IDMAP_ERR_ARG);
1897c5c4113dSnw 	}
1898c5c4113dSnw 
1899cd37da74Snw 	if (is_wuser == NULL)
1900cd37da74Snw 		request.id2.idtype = IDMAP_SID;
1901cd37da74Snw 	else if (*is_wuser == -1)
1902cd37da74Snw 		request.id2.idtype = IDMAP_SID;
1903cd37da74Snw 	else if (*is_wuser == 0)
1904cd37da74Snw 		request.id2.idtype = IDMAP_GSID;
1905cd37da74Snw 	else if (*is_wuser == 1)
1906cd37da74Snw 		request.id2.idtype = IDMAP_USID;
1907c5c4113dSnw 
1908c5c4113dSnw 	clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_ID_BY_NAME,
1909cd37da74Snw 	    (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request,
1910cd37da74Snw 	    (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result,
1911cd37da74Snw 	    TIMEOUT);
1912c5c4113dSnw 
1913651c0131Sbaban 	if (clntstat != RPC_SUCCESS)
1914651c0131Sbaban 		return (_idmap_rpc2stat(clnt));
1915c5c4113dSnw 
1916c5c4113dSnw 	retcode = result.retcode;
1917c5c4113dSnw 
1918c5c4113dSnw 	if ((mapping = result.mappings.mappings_val) == NULL) {
1919c5c4113dSnw 		if (retcode == IDMAP_SUCCESS)
1920c5c4113dSnw 			retcode = IDMAP_ERR_NORESULT;
1921c5c4113dSnw 		goto out;
1922c5c4113dSnw 	}
1923c5c4113dSnw 
1924*148c5f43SAlan Wright 	if (info != NULL)
1925*148c5f43SAlan Wright 		idmap_info_mov(info, &mapping->info);
1926*148c5f43SAlan Wright 
1927cd37da74Snw 	if (direction != NULL)
1928c5c4113dSnw 		*direction = mapping->direction;
1929cd37da74Snw 
193048258c6bSjp 	if (is_wuser != NULL) {
193148258c6bSjp 		if (mapping->id2.idtype == IDMAP_USID)
193248258c6bSjp 			*is_wuser = 1;
193348258c6bSjp 		else if (mapping->id2.idtype == IDMAP_GSID)
193448258c6bSjp 			*is_wuser = 0;
193548258c6bSjp 		else
193648258c6bSjp 			*is_wuser = -1;
193748258c6bSjp 	}
1938cd37da74Snw 
19398edda628Sbaban 	if (sidprefix && mapping->id2.idmap_id_u.sid.prefix &&
19408edda628Sbaban 	    *mapping->id2.idmap_id_u.sid.prefix != '\0') {
1941c5c4113dSnw 		*sidprefix = strdup(mapping->id2.idmap_id_u.sid.prefix);
1942c5c4113dSnw 		if (*sidprefix == NULL) {
1943c5c4113dSnw 			retcode = IDMAP_ERR_MEMORY;
1944c5c4113dSnw 			goto errout;
1945c5c4113dSnw 		}
1946c5c4113dSnw 	}
1947c5c4113dSnw 	if (rid)
1948c5c4113dSnw 		*rid = mapping->id2.idmap_id_u.sid.rid;
19498e228215Sdm 
19508e228215Sdm 	rc = idmap_strdupnull(winname, mapping->id2name);
19518e228215Sdm 	if (rc != IDMAP_SUCCESS)
19528e228215Sdm 		retcode = rc;
19538e228215Sdm 
19548e228215Sdm 	rc = idmap_strdupnull(windomain, mapping->id2domain);
19558e228215Sdm 	if (rc != IDMAP_SUCCESS)
19568e228215Sdm 		retcode = rc;
1957c5c4113dSnw 
1958c5c4113dSnw 	goto out;
1959c5c4113dSnw 
1960c5c4113dSnw errout:
1961c5c4113dSnw 	if (sidprefix && *sidprefix) {
1962c5c4113dSnw 		free(*sidprefix);
1963c5c4113dSnw 		*sidprefix = NULL;
1964c5c4113dSnw 	}
1965c5c4113dSnw 	if (winname && *winname) {
1966c5c4113dSnw 		free(*winname);
1967c5c4113dSnw 		*winname = NULL;
1968c5c4113dSnw 	}
1969c5c4113dSnw 	if (windomain && *windomain) {
1970c5c4113dSnw 		free(*windomain);
1971c5c4113dSnw 		*windomain = NULL;
1972c5c4113dSnw 	}
1973c5c4113dSnw 
1974c5c4113dSnw out:
1975c5c4113dSnw 	xdr_free(xdr_idmap_mappings_res, (caddr_t)&result);
1976c5c4113dSnw 	if (retcode != IDMAP_SUCCESS)
1977c5c4113dSnw 		errno = idmap_stat2errno(retcode);
1978c5c4113dSnw 	return (retcode);
1979c5c4113dSnw }
1980c5c4113dSnw 
1981c5c4113dSnw 
1982c5c4113dSnw 
1983c5c4113dSnw #define	gettext(s)	s
1984c5c4113dSnw static stat_table_t stattable[] = {
1985c5c4113dSnw 	{IDMAP_SUCCESS, gettext("Success"), 0},
1986c5c4113dSnw 	{IDMAP_NEXT, gettext("More results available"), 0},
1987c5c4113dSnw 	{IDMAP_ERR_OTHER, gettext("Undefined error"), EINVAL},
1988c5c4113dSnw 	{IDMAP_ERR_INTERNAL, gettext("Internal error"), EINVAL},
1989c5c4113dSnw 	{IDMAP_ERR_MEMORY, gettext("Out of memory"), ENOMEM},
1990c5c4113dSnw 	{IDMAP_ERR_NORESULT, gettext("No results available"), EINVAL},
1991c5c4113dSnw 	{IDMAP_ERR_NOTUSER, gettext("Not a user"), EINVAL},
1992c5c4113dSnw 	{IDMAP_ERR_NOTGROUP, gettext("Not a group"), EINVAL},
1993651c0131Sbaban 	{IDMAP_ERR_NOTSUPPORTED, gettext("Operation not supported"), ENOTSUP},
1994c5c4113dSnw 	{IDMAP_ERR_W2U_NAMERULE,
1995c5c4113dSnw 		gettext("Invalid Windows to UNIX name-based rule"), EINVAL},
1996c5c4113dSnw 	{IDMAP_ERR_U2W_NAMERULE,
1997c5c4113dSnw 		gettext("Invalid UNIX to Windows name-based rule"), EINVAL},
1998c5c4113dSnw 	{IDMAP_ERR_CACHE, gettext("Invalid cache"), EINVAL},
1999c5c4113dSnw 	{IDMAP_ERR_DB, gettext("Invalid database"), EINVAL},
2000c5c4113dSnw 	{IDMAP_ERR_ARG, gettext("Invalid argument"), EINVAL},
2001c5c4113dSnw 	{IDMAP_ERR_SID, gettext("Invalid SID"), EINVAL},
2002c5c4113dSnw 	{IDMAP_ERR_IDTYPE, gettext("Invalid identity type"), EINVAL},
2003651c0131Sbaban 	{IDMAP_ERR_RPC_HANDLE, gettext("Bad RPC handle"), EBADF},
2004c5c4113dSnw 	{IDMAP_ERR_RPC, gettext("RPC error"), EINVAL},
2005c5c4113dSnw 	{IDMAP_ERR_CLIENT_HANDLE, gettext("Bad client handle"), EINVAL},
2006651c0131Sbaban 	{IDMAP_ERR_BUSY, gettext("Server is busy"), EBUSY},
20078edda628Sbaban 	{IDMAP_ERR_PERMISSION_DENIED, gettext("Permission denied"), EACCES},
2008c5c4113dSnw 	{IDMAP_ERR_NOMAPPING,
2009c5c4113dSnw 		gettext("Mapping not found or inhibited"), EINVAL},
2010c5c4113dSnw 	{IDMAP_ERR_NEW_ID_ALLOC_REQD,
2011c5c4113dSnw 		gettext("New mapping needs to be created"), EINVAL},
2012c5c4113dSnw 	{IDMAP_ERR_DOMAIN, gettext("Invalid domain"), EINVAL},
2013c5c4113dSnw 	{IDMAP_ERR_SECURITY, gettext("Security issue"), EINVAL},
2014c5c4113dSnw 	{IDMAP_ERR_NOTFOUND, gettext("Not found"), EINVAL},
2015c5c4113dSnw 	{IDMAP_ERR_DOMAIN_NOTFOUND, gettext("Domain not found"), EINVAL},
2016c5c4113dSnw 	{IDMAP_ERR_UPDATE_NOTALLOWED, gettext("Update not allowed"), EINVAL},
2017c5c4113dSnw 	{IDMAP_ERR_CFG, gettext("Configuration error"), EINVAL},
2018c5c4113dSnw 	{IDMAP_ERR_CFG_CHANGE, gettext("Invalid configuration change"), EINVAL},
2019c5c4113dSnw 	{IDMAP_ERR_NOTMAPPED_WELLKNOWN,
2020c5c4113dSnw 		gettext("No mapping for well-known SID"), EINVAL},
2021c5c4113dSnw 	{IDMAP_ERR_RETRIABLE_NET_ERR,
202262c60062Sbaban 		gettext("Windows lookup failed"), EINVAL},
202362c60062Sbaban 	{IDMAP_ERR_W2U_NAMERULE_CONFLICT,
202462c60062Sbaban 		gettext("Duplicate rule or conflicts with an existing "
202562c60062Sbaban 		"Windows to UNIX name-based rule"), EINVAL},
202662c60062Sbaban 	{IDMAP_ERR_U2W_NAMERULE_CONFLICT,
202762c60062Sbaban 		gettext("Duplicate rule or conflicts with an existing "
202862c60062Sbaban 		"Unix to Windows name-based rule"), EINVAL},
20290dcc7149Snw 	{IDMAP_ERR_BAD_UTF8,
20300dcc7149Snw 		gettext("Invalid or illegal UTF-8 sequence found in "
20310dcc7149Snw 		"a given Windows entity name or domain name"), EINVAL},
20324d61c878SJulian Pullen 	{IDMAP_ERR_NONE_GENERATED,
203348258c6bSjp 		gettext("Mapping not found and none created (see -c option)"),
203448258c6bSjp 		EINVAL},
2035479ac375Sdm 	{IDMAP_ERR_PROP_UNKNOWN,
2036479ac375Sdm 		gettext("Undefined property"),
2037479ac375Sdm 		EINVAL},
2038479ac375Sdm 	{IDMAP_ERR_NS_LDAP_CFG,
2039479ac375Sdm 		gettext("Native LDAP configuration error"), EINVAL},
2040479ac375Sdm 	{IDMAP_ERR_NS_LDAP_PARTIAL,
2041479ac375Sdm 		gettext("Partial result from Native LDAP"), EINVAL},
2042479ac375Sdm 	{IDMAP_ERR_NS_LDAP_OP_FAILED,
2043479ac375Sdm 		gettext("Native LDAP operation failed"), EINVAL},
2044479ac375Sdm 	{IDMAP_ERR_NS_LDAP_BAD_WINNAME,
2045479ac375Sdm 		gettext("Improper winname form found in Native LDAP"), EINVAL},
20464d61c878SJulian Pullen 	{IDMAP_ERR_NO_ACTIVEDIRECTORY,
20474d61c878SJulian Pullen 		gettext("No AD servers"),
20484d61c878SJulian Pullen 		EINVAL},
2049c5c4113dSnw 	{-1, NULL, 0}
2050c5c4113dSnw };
2051c5c4113dSnw #undef	gettext
2052c5c4113dSnw 
2053c5c4113dSnw 
2054c5c4113dSnw /*
2055c5c4113dSnw  * Get description of status code
2056c5c4113dSnw  *
2057c5c4113dSnw  * Input:
2058c5c4113dSnw  * status - Status code returned by libidmap API call
2059c5c4113dSnw  *
2060c5c4113dSnw  * Return Value:
2061c5c4113dSnw  * human-readable localized description of idmap_stat
2062c5c4113dSnw  */
2063c5c4113dSnw /* ARGSUSED */
2064c5c4113dSnw const char *
2065cd37da74Snw idmap_stat2string(idmap_handle_t *handle, idmap_stat status)
2066cd37da74Snw {
2067c5c4113dSnw 	int i;
2068c5c4113dSnw 
2069c5c4113dSnw 	for (i = 0; stattable[i].msg; i++) {
2070c5c4113dSnw 		if (stattable[i].retcode == status)
20711fcced4cSJordan Brown 			return (dgettext(TEXT_DOMAIN, stattable[i].msg));
2072c5c4113dSnw 	}
20731fcced4cSJordan Brown 	return (dgettext(TEXT_DOMAIN, "Unknown error"));
2074c5c4113dSnw }
2075c5c4113dSnw 
2076c5c4113dSnw 
2077c5c4113dSnw static int
2078cd37da74Snw idmap_stat2errno(idmap_stat stat)
2079cd37da74Snw {
2080c5c4113dSnw 	int i;
2081c5c4113dSnw 	for (i = 0; stattable[i].msg; i++) {
2082c5c4113dSnw 		if (stattable[i].retcode == stat)
2083c5c4113dSnw 			return (stattable[i].errnum);
2084c5c4113dSnw 	}
2085c5c4113dSnw 	return (EINVAL);
2086c5c4113dSnw }
2087c5c4113dSnw 
2088c5c4113dSnw 
2089c5c4113dSnw /*
2090c5c4113dSnw  * Get status code from string
2091c5c4113dSnw  */
2092c5c4113dSnw idmap_stat
2093cd37da74Snw idmap_string2stat(const char *str)
2094cd37da74Snw {
2095c5c4113dSnw 	if (str == NULL)
2096c5c4113dSnw 		return (IDMAP_ERR_INTERNAL);
2097c5c4113dSnw 
2098c5c4113dSnw #define	return_cmp(a) \
2099c5c4113dSnw 	if (0 == strcmp(str, "IDMAP_ERR_" #a)) \
2100c5c4113dSnw 		return (IDMAP_ERR_ ## a);
2101c5c4113dSnw 
2102c5c4113dSnw 	return_cmp(OTHER);
2103c5c4113dSnw 	return_cmp(INTERNAL);
2104c5c4113dSnw 	return_cmp(MEMORY);
2105c5c4113dSnw 	return_cmp(NORESULT);
2106c5c4113dSnw 	return_cmp(NOTUSER);
2107c5c4113dSnw 	return_cmp(NOTGROUP);
2108c5c4113dSnw 	return_cmp(NOTSUPPORTED);
2109c5c4113dSnw 	return_cmp(W2U_NAMERULE);
2110c5c4113dSnw 	return_cmp(U2W_NAMERULE);
2111c5c4113dSnw 	return_cmp(CACHE);
2112c5c4113dSnw 	return_cmp(DB);
2113c5c4113dSnw 	return_cmp(ARG);
2114c5c4113dSnw 	return_cmp(SID);
2115c5c4113dSnw 	return_cmp(IDTYPE);
2116c5c4113dSnw 	return_cmp(RPC_HANDLE);
2117c5c4113dSnw 	return_cmp(RPC);
2118c5c4113dSnw 	return_cmp(CLIENT_HANDLE);
2119c5c4113dSnw 	return_cmp(BUSY);
2120c5c4113dSnw 	return_cmp(PERMISSION_DENIED);
2121c5c4113dSnw 	return_cmp(NOMAPPING);
2122c5c4113dSnw 	return_cmp(NEW_ID_ALLOC_REQD);
2123c5c4113dSnw 	return_cmp(DOMAIN);
2124c5c4113dSnw 	return_cmp(SECURITY);
2125c5c4113dSnw 	return_cmp(NOTFOUND);
2126c5c4113dSnw 	return_cmp(DOMAIN_NOTFOUND);
2127c5c4113dSnw 	return_cmp(MEMORY);
2128c5c4113dSnw 	return_cmp(UPDATE_NOTALLOWED);
2129c5c4113dSnw 	return_cmp(CFG);
2130c5c4113dSnw 	return_cmp(CFG_CHANGE);
2131c5c4113dSnw 	return_cmp(NOTMAPPED_WELLKNOWN);
2132c5c4113dSnw 	return_cmp(RETRIABLE_NET_ERR);
213362c60062Sbaban 	return_cmp(W2U_NAMERULE_CONFLICT);
213462c60062Sbaban 	return_cmp(U2W_NAMERULE_CONFLICT);
2135479ac375Sdm 	return_cmp(BAD_UTF8);
21364d61c878SJulian Pullen 	return_cmp(NONE_GENERATED);
2137479ac375Sdm 	return_cmp(PROP_UNKNOWN);
2138479ac375Sdm 	return_cmp(NS_LDAP_CFG);
2139479ac375Sdm 	return_cmp(NS_LDAP_PARTIAL);
2140479ac375Sdm 	return_cmp(NS_LDAP_OP_FAILED);
2141479ac375Sdm 	return_cmp(NS_LDAP_BAD_WINNAME);
21424d61c878SJulian Pullen 	return_cmp(NO_ACTIVEDIRECTORY);
2143c5c4113dSnw #undef return_cmp
2144c5c4113dSnw 
2145c5c4113dSnw 	return (IDMAP_ERR_OTHER);
2146c5c4113dSnw }
2147c5c4113dSnw 
2148c5c4113dSnw 
2149c5c4113dSnw /*
2150c5c4113dSnw  * Map the given status to one that can be returned by the protocol
2151c5c4113dSnw  */
2152c5c4113dSnw idmap_stat
2153cd37da74Snw idmap_stat4prot(idmap_stat status)
2154cd37da74Snw {
2155c5c4113dSnw 	switch (status) {
2156c5c4113dSnw 	case IDMAP_ERR_MEMORY:
2157c5c4113dSnw 	case IDMAP_ERR_CACHE:
2158c5c4113dSnw 		return (IDMAP_ERR_INTERNAL);
2159c5c4113dSnw 	}
2160c5c4113dSnw 	return (status);
2161c5c4113dSnw }
2162dd5829d1Sbaban 
2163dd5829d1Sbaban 
21648e228215Sdm /*
2165c5a946baSbaban  * This is a convenience routine which duplicates a string after
2166c5a946baSbaban  * checking for NULL pointers. This function will return success if
2167c5a946baSbaban  * either the 'to' OR 'from' pointers are NULL.
21688e228215Sdm  */
21698e228215Sdm static idmap_stat
2170cd37da74Snw idmap_strdupnull(char **to, const char *from)
2171cd37da74Snw {
2172c5a946baSbaban 	if (to == NULL)
2173c5a946baSbaban 		return (IDMAP_SUCCESS);
2174c5a946baSbaban 
21758e228215Sdm 	if (from == NULL || *from == '\0') {
21768e228215Sdm 		*to = NULL;
21778e228215Sdm 		return (IDMAP_SUCCESS);
21788e228215Sdm 	}
21798e228215Sdm 
21808e228215Sdm 	*to = strdup(from);
21818e228215Sdm 	if (*to == NULL)
21828e228215Sdm 		return (IDMAP_ERR_MEMORY);
21838e228215Sdm 	return (IDMAP_SUCCESS);
21848e228215Sdm }
21858e228215Sdm 
218648258c6bSjp 
21878e228215Sdm idmap_stat
2188cd37da74Snw idmap_namerule_cpy(idmap_namerule *to, idmap_namerule *from)
2189cd37da74Snw {
21908e228215Sdm 	idmap_stat retval;
21918e228215Sdm 
219248258c6bSjp 	if (to == NULL)
219348258c6bSjp 		return (IDMAP_SUCCESS);
219448258c6bSjp 
21958e228215Sdm 	(void) memcpy(to, from, sizeof (idmap_namerule));
219648258c6bSjp 	to->windomain = NULL;
219748258c6bSjp 	to->winname = NULL;
219848258c6bSjp 	to->unixname = NULL;
21998e228215Sdm 
22008e228215Sdm 	retval = idmap_strdupnull(&to->windomain, from->windomain);
22018e228215Sdm 	if (retval != IDMAP_SUCCESS)
22028e228215Sdm 		return (retval);
22038e228215Sdm 
22048e228215Sdm 	retval = idmap_strdupnull(&to->winname, from->winname);
220548258c6bSjp 	if (retval != IDMAP_SUCCESS) {
220648258c6bSjp 		free(to->windomain);
220748258c6bSjp 		to->windomain = NULL;
22088e228215Sdm 		return (retval);
220948258c6bSjp 	}
22108e228215Sdm 
22118e228215Sdm 	retval = idmap_strdupnull(&to->unixname, from->unixname);
221248258c6bSjp 	if (retval != IDMAP_SUCCESS) {
221348258c6bSjp 		free(to->windomain);
221448258c6bSjp 		to->windomain = NULL;
221548258c6bSjp 		free(to->winname);
221648258c6bSjp 		to->winname = NULL;
221748258c6bSjp 		return (retval);
221848258c6bSjp 	}
221948258c6bSjp 
222048258c6bSjp 	return (retval);
222148258c6bSjp }
222248258c6bSjp 
222348258c6bSjp 
222448258c6bSjp /*
2225*148c5f43SAlan Wright  * Move the contents of the "info" structure from "from" to "to".
222648258c6bSjp  */
2227*148c5f43SAlan Wright void
222848258c6bSjp idmap_info_mov(idmap_info *to, idmap_info *from)
222948258c6bSjp {
223048258c6bSjp 	(void) memcpy(to, from, sizeof (idmap_info));
223148258c6bSjp 	(void) memset(from, 0, sizeof (idmap_info));
22328e228215Sdm }
22338e228215Sdm 
22348e228215Sdm 
223548258c6bSjp void
223648258c6bSjp idmap_info_free(idmap_info *info)
223748258c6bSjp {
223848258c6bSjp 	if (info == NULL)
223948258c6bSjp 		return;
224048258c6bSjp 
2241*148c5f43SAlan Wright 	xdr_free(xdr_idmap_info, (caddr_t)info);
2242*148c5f43SAlan Wright 	(void) memset(info, 0, sizeof (idmap_info));
2243*148c5f43SAlan Wright }
224448258c6bSjp 
224548258c6bSjp 
2246*148c5f43SAlan Wright void
2247*148c5f43SAlan Wright idmap_how_clear(idmap_how *how)
2248*148c5f43SAlan Wright {
2249*148c5f43SAlan Wright 	xdr_free(xdr_idmap_how, (caddr_t)how);
2250*148c5f43SAlan Wright 	(void) memset(how, 0, sizeof (*how));
225148258c6bSjp }
225248258c6bSjp 
225348258c6bSjp 
2254dd5829d1Sbaban /*
2255dd5829d1Sbaban  * Get uid given Windows name
2256dd5829d1Sbaban  */
2257dd5829d1Sbaban idmap_stat
22583ee87bcaSJulian Pullen idmap_getuidbywinname(const char *name, const char *domain, int flag,
22593ee87bcaSJulian Pullen 	uid_t *uid)
2260cd37da74Snw {
2261dd5829d1Sbaban 	idmap_handle_t	*ih;
2262dd5829d1Sbaban 	idmap_retcode	rc;
2263cd37da74Snw 	int		is_user = 1;
2264cd37da74Snw 	int		is_wuser = -1;
22653ee87bcaSJulian Pullen 	int 		direction;
2266dd5829d1Sbaban 
2267dd5829d1Sbaban 	if (uid == NULL)
2268dd5829d1Sbaban 		return (IDMAP_ERR_ARG);
2269dd5829d1Sbaban 
22703ee87bcaSJulian Pullen 	if (flag & IDMAP_REQ_FLG_USE_CACHE) {
22713ee87bcaSJulian Pullen 		rc = idmap_cache_lookup_uidbywinname(name, domain, uid);
22723ee87bcaSJulian Pullen 		if (rc == IDMAP_SUCCESS || rc == IDMAP_ERR_MEMORY)
22733ee87bcaSJulian Pullen 			return (rc);
22743ee87bcaSJulian Pullen 	}
2275dd5829d1Sbaban 	/* Get mapping */
2276dd5829d1Sbaban 	if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS)
2277dd5829d1Sbaban 		return (rc);
22783ee87bcaSJulian Pullen 	rc = idmap_get_w2u_mapping(ih, NULL, NULL, name, domain, flag,
22793ee87bcaSJulian Pullen 	    &is_user, &is_wuser, uid, NULL, &direction, NULL);
2280dd5829d1Sbaban 	(void) idmap_fini(ih);
2281dd5829d1Sbaban 
22823ee87bcaSJulian Pullen 	if (rc == IDMAP_SUCCESS && (flag & IDMAP_REQ_FLG_USE_CACHE)) {
22833ee87bcaSJulian Pullen 		/* If we have not got the domain don't store UID to winname */
22843ee87bcaSJulian Pullen 		if (domain == NULL)
22853ee87bcaSJulian Pullen 			direction = IDMAP_DIRECTION_W2U;
22863ee87bcaSJulian Pullen 		idmap_cache_add_winname2uid(name, domain, *uid, direction);
22873ee87bcaSJulian Pullen 	}
22883ee87bcaSJulian Pullen 
2289dd5829d1Sbaban 	return (rc);
2290dd5829d1Sbaban }
2291dd5829d1Sbaban 
2292dd5829d1Sbaban 
2293dd5829d1Sbaban /*
2294dd5829d1Sbaban  * Get gid given Windows name
2295dd5829d1Sbaban  */
2296dd5829d1Sbaban idmap_stat
22973ee87bcaSJulian Pullen idmap_getgidbywinname(const char *name, const char *domain, int flag,
22983ee87bcaSJulian Pullen 	gid_t *gid)
2299cd37da74Snw {
2300dd5829d1Sbaban 	idmap_handle_t	*ih;
2301dd5829d1Sbaban 	idmap_retcode	rc;
2302cd37da74Snw 	int		is_user = 0;
2303cd37da74Snw 	int		is_wuser = -1;
23043ee87bcaSJulian Pullen 	int		direction;
2305dd5829d1Sbaban 
2306dd5829d1Sbaban 	if (gid == NULL)
2307dd5829d1Sbaban 		return (IDMAP_ERR_ARG);
2308dd5829d1Sbaban 
23093ee87bcaSJulian Pullen 	if (flag & IDMAP_REQ_FLG_USE_CACHE) {
23103ee87bcaSJulian Pullen 		rc = idmap_cache_lookup_gidbywinname(name, domain, gid);
23113ee87bcaSJulian Pullen 		if (rc == IDMAP_SUCCESS || rc == IDMAP_ERR_MEMORY)
23123ee87bcaSJulian Pullen 			return (rc);
23133ee87bcaSJulian Pullen 	}
23143ee87bcaSJulian Pullen 
2315dd5829d1Sbaban 	/* Get mapping */
2316dd5829d1Sbaban 	if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS)
2317dd5829d1Sbaban 		return (rc);
23183ee87bcaSJulian Pullen 	rc = idmap_get_w2u_mapping(ih, NULL, NULL, name, domain, flag,
23193ee87bcaSJulian Pullen 	    &is_user, &is_wuser, gid, NULL, &direction, NULL);
2320dd5829d1Sbaban 	(void) idmap_fini(ih);
2321dd5829d1Sbaban 
23223ee87bcaSJulian Pullen 	if (rc == IDMAP_SUCCESS && (flag & IDMAP_REQ_FLG_USE_CACHE)) {
23233ee87bcaSJulian Pullen 		/* If we have not got the domain don't store GID to winname */
23243ee87bcaSJulian Pullen 		if (domain == NULL)
23253ee87bcaSJulian Pullen 			direction = IDMAP_DIRECTION_W2U;
23263ee87bcaSJulian Pullen 		idmap_cache_add_winname2gid(name, domain, *gid, direction);
23273ee87bcaSJulian Pullen 	}
23283ee87bcaSJulian Pullen 
2329dd5829d1Sbaban 	return (rc);
2330dd5829d1Sbaban }
2331dd5829d1Sbaban 
2332dd5829d1Sbaban 
2333dd5829d1Sbaban /*
2334dd5829d1Sbaban  * Get winname given pid
2335dd5829d1Sbaban  */
2336dd5829d1Sbaban static idmap_retcode
23373ee87bcaSJulian Pullen idmap_getwinnamebypid(uid_t pid, int is_user, int flag, char **name,
23383ee87bcaSJulian Pullen 	char **domain)
2339cd37da74Snw {
2340dd5829d1Sbaban 	idmap_handle_t	*ih;
2341dd5829d1Sbaban 	idmap_retcode	rc;
2342dd5829d1Sbaban 	int		len;
2343dd5829d1Sbaban 	char		*winname, *windomain;
23443ee87bcaSJulian Pullen 	int		direction;
2345dd5829d1Sbaban 
2346dd5829d1Sbaban 	if (name == NULL)
2347dd5829d1Sbaban 		return (IDMAP_ERR_ARG);
2348dd5829d1Sbaban 
23493ee87bcaSJulian Pullen 	if (flag & IDMAP_REQ_FLG_USE_CACHE) {
23503ee87bcaSJulian Pullen 		if (is_user)
23513ee87bcaSJulian Pullen 			rc = idmap_cache_lookup_winnamebyuid(&winname,
23523ee87bcaSJulian Pullen 			    &windomain, pid);
23533ee87bcaSJulian Pullen 		else
23543ee87bcaSJulian Pullen 			rc = idmap_cache_lookup_winnamebygid(&winname,
23553ee87bcaSJulian Pullen 			    &windomain, pid);
23563ee87bcaSJulian Pullen 		if (rc == IDMAP_SUCCESS)
23573ee87bcaSJulian Pullen 			goto out;
23583ee87bcaSJulian Pullen 		if (rc == IDMAP_ERR_MEMORY)
23593ee87bcaSJulian Pullen 			return (rc);
23603ee87bcaSJulian Pullen 	}
23613ee87bcaSJulian Pullen 
2362dd5829d1Sbaban 	/* Get mapping */
2363dd5829d1Sbaban 	if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS)
2364dd5829d1Sbaban 		return (rc);
23653ee87bcaSJulian Pullen 	rc = idmap_get_u2w_mapping(ih, &pid, NULL, flag, is_user, NULL,
23663ee87bcaSJulian Pullen 	    NULL, NULL, &winname, &windomain, &direction, NULL);
2367dd5829d1Sbaban 	(void) idmap_fini(ih);
2368dd5829d1Sbaban 
2369dd5829d1Sbaban 	/* Return on error */
2370dd5829d1Sbaban 	if (rc != IDMAP_SUCCESS)
2371dd5829d1Sbaban 		return (rc);
2372dd5829d1Sbaban 
2373dd5829d1Sbaban 	/*
2374dd5829d1Sbaban 	 * The given PID may have been mapped to a locally
2375dd5829d1Sbaban 	 * generated SID in which case there isn't any
2376dd5829d1Sbaban 	 * Windows name
2377dd5829d1Sbaban 	 */
2378dd5829d1Sbaban 	if (winname == NULL || windomain == NULL) {
2379dd5829d1Sbaban 		idmap_free(winname);
2380dd5829d1Sbaban 		idmap_free(windomain);
2381dd5829d1Sbaban 		return (IDMAP_ERR_NORESULT);
2382dd5829d1Sbaban 	}
2383dd5829d1Sbaban 
23843ee87bcaSJulian Pullen 	if (flag & IDMAP_REQ_FLG_USE_CACHE) {
23853ee87bcaSJulian Pullen 		if (is_user)
23863ee87bcaSJulian Pullen 			idmap_cache_add_winname2uid(winname, windomain,
23873ee87bcaSJulian Pullen 			    pid, direction);
23883ee87bcaSJulian Pullen 		else
23893ee87bcaSJulian Pullen 			idmap_cache_add_winname2gid(winname, windomain,
23903ee87bcaSJulian Pullen 			    pid, direction);
23913ee87bcaSJulian Pullen 	}
23923ee87bcaSJulian Pullen 
23933ee87bcaSJulian Pullen out:
2394dd5829d1Sbaban 	if (domain != NULL) {
2395dd5829d1Sbaban 		*name = winname;
2396dd5829d1Sbaban 		*domain = windomain;
2397dd5829d1Sbaban 	} else {
2398dd5829d1Sbaban 		len = strlen(winname) + strlen(windomain) + 2;
2399dd5829d1Sbaban 		if ((*name = malloc(len)) != NULL)
2400dd5829d1Sbaban 			(void) snprintf(*name, len, "%s@%s", winname,
2401dd5829d1Sbaban 			    windomain);
2402dd5829d1Sbaban 		else
2403dd5829d1Sbaban 			rc = IDMAP_ERR_MEMORY;
2404dd5829d1Sbaban 		idmap_free(winname);
2405dd5829d1Sbaban 		idmap_free(windomain);
2406dd5829d1Sbaban 	}
24073ee87bcaSJulian Pullen 
2408dd5829d1Sbaban 	return (rc);
2409dd5829d1Sbaban }
2410dd5829d1Sbaban 
2411dd5829d1Sbaban 
2412dd5829d1Sbaban /*
2413dd5829d1Sbaban  * Get winname given uid
2414dd5829d1Sbaban  */
2415dd5829d1Sbaban idmap_stat
24163ee87bcaSJulian Pullen idmap_getwinnamebyuid(uid_t uid, int flag, char **name, char **domain)
2417cd37da74Snw {
24183ee87bcaSJulian Pullen 	return (idmap_getwinnamebypid(uid, 1, flag, name, domain));
2419dd5829d1Sbaban }
2420dd5829d1Sbaban 
2421dd5829d1Sbaban 
2422dd5829d1Sbaban /*
2423dd5829d1Sbaban  * Get winname given gid
2424dd5829d1Sbaban  */
2425dd5829d1Sbaban idmap_stat
24263ee87bcaSJulian Pullen idmap_getwinnamebygid(gid_t gid, int flag, char **name, char **domain)
2427cd37da74Snw {
24283ee87bcaSJulian Pullen 	return (idmap_getwinnamebypid(gid, 0, flag, name, domain));
2429dd5829d1Sbaban }
24309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
24319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States idmap_stat
24329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States idmap_flush(idmap_handle_t *handle, idmap_flush_op op)
24339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
24349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	CLIENT			*clnt;
24359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	enum clnt_stat		clntstat;
24369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	idmap_retcode		res;
24379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
24389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	res = IDMAP_SUCCESS;
24399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	_IDMAP_GET_CLIENT_HANDLE(handle, clnt);
24409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
24419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	clntstat = clnt_call(clnt, IDMAP_FLUSH,
24429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    (xdrproc_t)xdr_idmap_flush_op, (caddr_t)&op,
24439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    (xdrproc_t)xdr_idmap_retcode, (caddr_t)&res, TIMEOUT);
24449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
24459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (clntstat != RPC_SUCCESS) {
24469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (_idmap_rpc2stat(clnt));
24479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
24489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (res);
24499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
2450c5866007SKeyur Desai 
2451c5866007SKeyur Desai 
2452c5866007SKeyur Desai /*
2453c5866007SKeyur Desai  * syslog is the default logger.
2454c5866007SKeyur Desai  * It can be overwritten by supplying a logger
2455c5866007SKeyur Desai  * with  idmap_set_logger()
2456c5866007SKeyur Desai  */
2457c5866007SKeyur Desai idmap_logger_t logger = syslog;
2458c5866007SKeyur Desai 
2459c5866007SKeyur Desai 
2460c5866007SKeyur Desai void
2461c5866007SKeyur Desai idmap_set_logger(idmap_logger_t funct)
2462c5866007SKeyur Desai {
2463c5866007SKeyur Desai 	logger = funct;
2464c5866007SKeyur Desai }
2465*148c5f43SAlan Wright 
2466*148c5f43SAlan Wright /*
2467*148c5f43SAlan Wright  * Helper functions that concatenate two parts of a name and then
2468*148c5f43SAlan Wright  * look up a value, so that the same set of functions can be used to
2469*148c5f43SAlan Wright  * process both "in" and "out" parameters.
2470*148c5f43SAlan Wright  */
2471*148c5f43SAlan Wright static
2472*148c5f43SAlan Wright boolean_t
2473*148c5f43SAlan Wright idmap_trace_get_str(nvlist_t *entry, char *n1, char *n2, char **ret)
2474*148c5f43SAlan Wright {
2475*148c5f43SAlan Wright 	char name[IDMAP_TRACE_NAME_MAX+1];	/* Max used is about 11 */
2476*148c5f43SAlan Wright 	int err;
2477*148c5f43SAlan Wright 
2478*148c5f43SAlan Wright 	(void) strlcpy(name, n1, sizeof (name));
2479*148c5f43SAlan Wright 	if (n2 != NULL)
2480*148c5f43SAlan Wright 		(void) strlcat(name, n2, sizeof (name));
2481*148c5f43SAlan Wright 
2482*148c5f43SAlan Wright 	err = nvlist_lookup_string(entry, name, ret);
2483*148c5f43SAlan Wright 	return (err == 0);
2484*148c5f43SAlan Wright }
2485*148c5f43SAlan Wright 
2486*148c5f43SAlan Wright static
2487*148c5f43SAlan Wright boolean_t
2488*148c5f43SAlan Wright idmap_trace_get_int(nvlist_t *entry, char *n1, char *n2, int64_t *ret)
2489*148c5f43SAlan Wright {
2490*148c5f43SAlan Wright 	char name[IDMAP_TRACE_NAME_MAX+1];	/* Max used is about 11 */
2491*148c5f43SAlan Wright 	int err;
2492*148c5f43SAlan Wright 
2493*148c5f43SAlan Wright 	(void) strlcpy(name, n1, sizeof (name));
2494*148c5f43SAlan Wright 	if (n2 != NULL)
2495*148c5f43SAlan Wright 		(void) strlcat(name, n2, sizeof (name));
2496*148c5f43SAlan Wright 
2497*148c5f43SAlan Wright 	err = nvlist_lookup_int64(entry, name, ret);
2498*148c5f43SAlan Wright 	return (err == 0);
2499*148c5f43SAlan Wright }
2500*148c5f43SAlan Wright 
2501*148c5f43SAlan Wright static
2502*148c5f43SAlan Wright void
2503*148c5f43SAlan Wright idmap_trace_print_id(FILE *out, nvlist_t *entry, char *fromto)
2504*148c5f43SAlan Wright {
2505*148c5f43SAlan Wright 	char *s;
2506*148c5f43SAlan Wright 	int64_t i64;
2507*148c5f43SAlan Wright 
2508*148c5f43SAlan Wright 	if (idmap_trace_get_int(entry, fromto, IDMAP_TRACE_TYPE, &i64)) {
2509*148c5f43SAlan Wright 		switch (i64) {
2510*148c5f43SAlan Wright 		case IDMAP_POSIXID:
2511*148c5f43SAlan Wright 			(void) fprintf(out, "unixname ");
2512*148c5f43SAlan Wright 			break;
2513*148c5f43SAlan Wright 		case IDMAP_UID:
2514*148c5f43SAlan Wright 			(void) fprintf(out, "unixuser ");
2515*148c5f43SAlan Wright 			break;
2516*148c5f43SAlan Wright 		case IDMAP_GID:
2517*148c5f43SAlan Wright 			(void) fprintf(out, "unixgroup ");
2518*148c5f43SAlan Wright 			break;
2519*148c5f43SAlan Wright 		case IDMAP_SID:
2520*148c5f43SAlan Wright 			(void) fprintf(out, "winname ");
2521*148c5f43SAlan Wright 			break;
2522*148c5f43SAlan Wright 		case IDMAP_USID:
2523*148c5f43SAlan Wright 			(void) fprintf(out, "winuser ");
2524*148c5f43SAlan Wright 			break;
2525*148c5f43SAlan Wright 		case IDMAP_GSID:
2526*148c5f43SAlan Wright 			(void) fprintf(out, "wingroup ");
2527*148c5f43SAlan Wright 			break;
2528*148c5f43SAlan Wright 		case IDMAP_NONE:
2529*148c5f43SAlan Wright 			(void) fprintf(out, gettext("unknown "));
2530*148c5f43SAlan Wright 			break;
2531*148c5f43SAlan Wright 		default:
2532*148c5f43SAlan Wright 			(void) fprintf(out, gettext("bad %d "), (int)i64);
2533*148c5f43SAlan Wright 			break;
2534*148c5f43SAlan Wright 		}
2535*148c5f43SAlan Wright 	}
2536*148c5f43SAlan Wright 
2537*148c5f43SAlan Wright 	if (idmap_trace_get_str(entry, fromto, IDMAP_TRACE_NAME, &s))
2538*148c5f43SAlan Wright 		(void) fprintf(out, "%s ", s);
2539*148c5f43SAlan Wright 
2540*148c5f43SAlan Wright 	if (idmap_trace_get_str(entry, fromto, IDMAP_TRACE_SID, &s))
2541*148c5f43SAlan Wright 		(void) fprintf(out, "%s ", s);
2542*148c5f43SAlan Wright 
2543*148c5f43SAlan Wright 	if (idmap_trace_get_int(entry, fromto, IDMAP_TRACE_UNIXID, &i64))
2544*148c5f43SAlan Wright 		(void) fprintf(out, "%u ", (uid_t)i64);
2545*148c5f43SAlan Wright }
2546*148c5f43SAlan Wright 
2547*148c5f43SAlan Wright void
2548*148c5f43SAlan Wright idmap_trace_print_1(FILE *out, char *prefix, nvlist_t *entry)
2549*148c5f43SAlan Wright {
2550*148c5f43SAlan Wright 	char *s;
2551*148c5f43SAlan Wright 	int64_t i64;
2552*148c5f43SAlan Wright 
2553*148c5f43SAlan Wright 	(void) fprintf(out, "%s", prefix);
2554*148c5f43SAlan Wright 	idmap_trace_print_id(out, entry, "from");
2555*148c5f43SAlan Wright 	(void) fprintf(out, "-> ");
2556*148c5f43SAlan Wright 	idmap_trace_print_id(out, entry, "to");
2557*148c5f43SAlan Wright 	if (idmap_trace_get_int(entry, IDMAP_TRACE_ERROR, NULL, &i64))
2558*148c5f43SAlan Wright 		(void) fprintf(out, gettext("Error %d "), (int)i64);
2559*148c5f43SAlan Wright 	(void) fprintf(out, "-");
2560*148c5f43SAlan Wright 	if (idmap_trace_get_str(entry, IDMAP_TRACE_MESSAGE, NULL, &s))
2561*148c5f43SAlan Wright 		(void) fprintf(out, " %s", s);
2562*148c5f43SAlan Wright 	(void) fprintf(out, "\n");
2563*148c5f43SAlan Wright }
2564*148c5f43SAlan Wright 
2565*148c5f43SAlan Wright void
2566*148c5f43SAlan Wright idmap_trace_print(FILE *out, char *prefix, nvlist_t *trace)
2567*148c5f43SAlan Wright {
2568*148c5f43SAlan Wright 	nvpair_t *nvp;
2569*148c5f43SAlan Wright 
2570*148c5f43SAlan Wright 	for (nvp = nvlist_next_nvpair(trace, NULL);
2571*148c5f43SAlan Wright 	    nvp != NULL;
2572*148c5f43SAlan Wright 	    nvp = nvlist_next_nvpair(trace, nvp)) {
2573*148c5f43SAlan Wright 		nvlist_t *entry;
2574*148c5f43SAlan Wright 		int err;
2575*148c5f43SAlan Wright 
2576*148c5f43SAlan Wright 		err = nvpair_value_nvlist(nvp, &entry);
2577*148c5f43SAlan Wright 		assert(err == 0);
2578*148c5f43SAlan Wright 
2579*148c5f43SAlan Wright 		idmap_trace_print_1(out, prefix, entry);
2580*148c5f43SAlan Wright 	}
2581*148c5f43SAlan Wright }
2582