14520Snw141292 /*
24520Snw141292  * CDDL HEADER START
34520Snw141292  *
44520Snw141292  * The contents of this file are subject to the terms of the
54520Snw141292  * Common Development and Distribution License (the "License").
64520Snw141292  * You may not use this file except in compliance with the License.
74520Snw141292  *
84520Snw141292  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94520Snw141292  * or http://www.opensolaris.org/os/licensing.
104520Snw141292  * See the License for the specific language governing permissions
114520Snw141292  * and limitations under the License.
124520Snw141292  *
134520Snw141292  * When distributing Covered Code, include this CDDL HEADER in each
144520Snw141292  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154520Snw141292  * If applicable, add the following below this CDDL HEADER, with the
164520Snw141292  * fields enclosed by brackets "[]" replaced with your own identifying
174520Snw141292  * information: Portions Copyright [yyyy] [name of copyright owner]
184520Snw141292  *
194520Snw141292  * CDDL HEADER END
204520Snw141292  */
214520Snw141292 /*
225968Snw141292  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
234520Snw141292  * Use is subject to license terms.
244520Snw141292  */
254520Snw141292 
264520Snw141292 #pragma ident	"%Z%%M%	%I%	%E% SMI"
274520Snw141292 
284520Snw141292 /*
294520Snw141292  * libidmap API
304520Snw141292  */
314520Snw141292 
324520Snw141292 #include <stdlib.h>
33*6616Sdm199847 #include <sys/varargs.h>
344520Snw141292 #include <inttypes.h>
354520Snw141292 #include <errno.h>
364520Snw141292 #include <strings.h>
374520Snw141292 #include <ctype.h>
384520Snw141292 #include <sys/param.h>
394520Snw141292 #include <sys/types.h>
404520Snw141292 #include <sys/stat.h>
414520Snw141292 #include <dlfcn.h>
424520Snw141292 #include <libintl.h>
435232Snw141292 #include <ucontext.h>
444520Snw141292 #include "idmap_impl.h"
454520Snw141292 
46*6616Sdm199847 /*LINTLIBRARY*/
47*6616Sdm199847 
48*6616Sdm199847 /*
49*6616Sdm199847  * The following structure determines where the log messages from idmapdlog()
50*6616Sdm199847  * go to. It can be stderr (idmap, idmapd -d) and/or syslog (idmapd).
51*6616Sdm199847  *
52*6616Sdm199847  * logstate.max_pri is integer cutoff necessary to silence low-priority
53*6616Sdm199847  * messages to stderr. Syslog has its own means so there a boolean
54*6616Sdm199847  * logstate.write_syslog is enough.
55*6616Sdm199847  *
56*6616Sdm199847  * logstate.degraded is a mode used by idmapd in its degraded state.
57*6616Sdm199847  */
58*6616Sdm199847 
59*6616Sdm199847 static struct {
60*6616Sdm199847 	bool_t write_syslog;
61*6616Sdm199847 	int max_pri; /* Max priority written to stderr */
62*6616Sdm199847 	bool_t degraded;
63*6616Sdm199847 } logstate = {FALSE, LOG_DEBUG, FALSE};
64*6616Sdm199847 
65*6616Sdm199847 
664520Snw141292 static struct timeval TIMEOUT = { 25, 0 };
674520Snw141292 
684520Snw141292 static int idmap_stat2errno(idmap_stat);
69*6616Sdm199847 static idmap_stat	idmap_strdupnull(char **, const char *);
704520Snw141292 
714520Snw141292 #define	__ITER_CREATE(itera, argu, handl, ityp)\
724520Snw141292 	if (handl == NULL) {\
734520Snw141292 		errno = EINVAL;\
744520Snw141292 		return (IDMAP_ERR_ARG);\
754520Snw141292 	}\
764520Snw141292 	itera = calloc(1, sizeof (*itera));\
774520Snw141292 	if (itera == NULL) {\
784520Snw141292 		errno = ENOMEM;\
794520Snw141292 		return (IDMAP_ERR_MEMORY);\
804520Snw141292 	}\
814520Snw141292 	argu = calloc(1, sizeof (*argu));\
824520Snw141292 	if (argu == NULL) {\
834520Snw141292 		free(itera);\
844520Snw141292 		errno = ENOMEM;\
854520Snw141292 		return (IDMAP_ERR_MEMORY);\
864520Snw141292 	}\
874520Snw141292 	itera->ih = handl;\
884520Snw141292 	itera->type = ityp;\
894520Snw141292 	itera->retcode = IDMAP_NEXT;\
904520Snw141292 	itera->limit = 1024;\
914520Snw141292 	itera->arg = argu;
924520Snw141292 
934520Snw141292 
944520Snw141292 #define	__ITER_ERR_RETURN(itera, argu, xdr_argu, iretcod)\
954520Snw141292 	if (argu) {\
964520Snw141292 		xdr_free(xdr_argu, (caddr_t)argu);\
974520Snw141292 		free(argu);\
984520Snw141292 	}\
994520Snw141292 	if (itera)\
1004520Snw141292 		free(itera);\
1014520Snw141292 	return (iretcod);
1024520Snw141292 
1034520Snw141292 
1044520Snw141292 #define	__ITER_CHECK(itera, ityp)\
1054520Snw141292 	if (itera == NULL) {\
1064520Snw141292 		errno = EINVAL;\
1074520Snw141292 		return (IDMAP_ERR_ARG);\
1084520Snw141292 	}\
1094520Snw141292 	if (itera->type != ityp) {\
1104520Snw141292 		errno = EINVAL;\
1114520Snw141292 		return (IDMAP_ERR_ARG);\
1124520Snw141292 	}
1134520Snw141292 
1145064Sdm199847 #define	EMPTY_STRING(str)	(str == NULL || *str == '\0')
1154520Snw141292 
1164520Snw141292 /*
1174520Snw141292  * Free memory allocated by libidmap API
1184520Snw141292  *
1194520Snw141292  * Input:
1204520Snw141292  * ptr - memory to be freed
1214520Snw141292  */
1224520Snw141292 void
1235696Snw141292 idmap_free(void *ptr)
1245696Snw141292 {
1254520Snw141292 	free(ptr);
1264520Snw141292 }
1274520Snw141292 
1284520Snw141292 
1295232Snw141292 #define	MIN_STACK_NEEDS	16384
1305232Snw141292 
1314520Snw141292 /*
1324520Snw141292  * Create and Initialize idmap client handle for rpc/doors
1334520Snw141292  *
1344520Snw141292  * Output:
1354520Snw141292  * handle - idmap handle
1364520Snw141292  */
1374520Snw141292 idmap_stat
1385696Snw141292 idmap_init(idmap_handle_t **handle)
1395696Snw141292 {
1404520Snw141292 	CLIENT			*clnt = NULL;
1414520Snw141292 	struct idmap_handle	*hptr;
1425232Snw141292 	uint_t			sendsz = 0;
1435232Snw141292 	stack_t			st;
1444520Snw141292 
1454520Snw141292 	*handle = NULL;
1464520Snw141292 	hptr = (struct idmap_handle *)calloc(1, sizeof (*hptr));
1474520Snw141292 	if (hptr == NULL)
1484520Snw141292 		return (IDMAP_ERR_MEMORY);
1494520Snw141292 
1505232Snw141292 	/*
1515232Snw141292 	 * clnt_door_call() alloca()s sendsz bytes (twice too, once for
1525232Snw141292 	 * the call args buffer and once for the call result buffer), so
1535232Snw141292 	 * we want to pick a sendsz that will be large enough, but not
1545232Snw141292 	 * too large.
1555232Snw141292 	 */
1565232Snw141292 	if (stack_getbounds(&st) == 0) {
1575232Snw141292 		/*
1585232Snw141292 		 * Estimate how much stack space is left;
1595232Snw141292 		 * st.ss_sp is the top of stack.
1605232Snw141292 		 */
1615232Snw141292 		if ((char *)&sendsz < (char *)st.ss_sp)
1625232Snw141292 			/* stack grows up */
1635232Snw141292 			sendsz = ((char *)st.ss_sp - (char *)&sendsz);
1645232Snw141292 		else
1655232Snw141292 			/* stack grows down */
1665232Snw141292 			sendsz = ((char *)&sendsz - (char *)st.ss_sp);
1675232Snw141292 
1685232Snw141292 		/*
1695232Snw141292 		 * Take much of the stack space left, divided by two,
1705232Snw141292 		 * but leave enough for our needs (just a guess!), and
1715232Snw141292 		 * if we can't, then roll the dice.
1725232Snw141292 		 */
1735232Snw141292 		sendsz = RNDUP(sendsz / 2);
1745232Snw141292 		if (sendsz < MIN_STACK_NEEDS)
1755232Snw141292 			sendsz = 0;	/* RPC call may fail */
1765232Snw141292 		else if (sendsz > IDMAP_MAX_DOOR_RPC)
1775232Snw141292 			sendsz = IDMAP_MAX_DOOR_RPC;
1785232Snw141292 	}
1795232Snw141292 
1805232Snw141292 	clnt = clnt_door_create(IDMAP_PROG, IDMAP_V1, sendsz);
1814520Snw141292 	if (clnt == NULL) {
1824520Snw141292 		free(hptr);
1834520Snw141292 		return (IDMAP_ERR_RPC);
1844520Snw141292 	}
1854520Snw141292 	hptr->type = _IDMAP_HANDLE_RPC_DOORS;
1864520Snw141292 	hptr->privhandle = clnt;
1874520Snw141292 	*handle = hptr;
1884520Snw141292 	return (IDMAP_SUCCESS);
1894520Snw141292 }
1904520Snw141292 
1914520Snw141292 
1924520Snw141292 /*
1934520Snw141292  * Finalize idmap handle
1944520Snw141292  *
1954520Snw141292  * Input:
1964520Snw141292  * handle - idmap handle
1974520Snw141292  */
1984520Snw141292 idmap_stat
1995696Snw141292 idmap_fini(idmap_handle_t *handle)
2005696Snw141292 {
2014520Snw141292 	CLIENT			*clnt;
2024520Snw141292 	struct idmap_handle	*hptr;
2034520Snw141292 
2044520Snw141292 	if (handle == NULL)
2054520Snw141292 		return (IDMAP_SUCCESS);
2064520Snw141292 
2074520Snw141292 	hptr = (struct idmap_handle *)handle;
2084520Snw141292 
2094520Snw141292 	switch (hptr->type) {
2104520Snw141292 	case _IDMAP_HANDLE_RPC_DOORS:
2114520Snw141292 		clnt = (CLIENT *)hptr->privhandle;
2124520Snw141292 		if (clnt) {
2134520Snw141292 			if (clnt->cl_auth)
2144520Snw141292 				auth_destroy(clnt->cl_auth);
2154520Snw141292 			clnt_destroy(clnt);
2164520Snw141292 		}
2174520Snw141292 		break;
2184520Snw141292 	default:
2194520Snw141292 		break;
2204520Snw141292 	}
2214520Snw141292 	free(hptr);
2224520Snw141292 	return (IDMAP_SUCCESS);
2234520Snw141292 }
2244520Snw141292 
2254520Snw141292 
226*6616Sdm199847 idmap_stat
227*6616Sdm199847 idmap_get_prop(idmap_handle_t *handle, idmap_prop_type pr, idmap_prop_res *res)
228*6616Sdm199847 {
229*6616Sdm199847 	CLIENT			*clnt;
230*6616Sdm199847 	enum clnt_stat		clntstat;
231*6616Sdm199847 
232*6616Sdm199847 
233*6616Sdm199847 	(void) memset(res, 0, sizeof (*res));
234*6616Sdm199847 	_IDMAP_GET_CLIENT_HANDLE(handle, clnt);
235*6616Sdm199847 
236*6616Sdm199847 	clntstat = clnt_call(clnt, IDMAP_GET_PROP,
237*6616Sdm199847 	    (xdrproc_t)xdr_idmap_prop_type, (caddr_t)&pr,
238*6616Sdm199847 	    (xdrproc_t)xdr_idmap_prop_res, (caddr_t)res, TIMEOUT);
239*6616Sdm199847 
240*6616Sdm199847 	if (clntstat != RPC_SUCCESS) {
241*6616Sdm199847 		return (_idmap_rpc2stat(clnt));
242*6616Sdm199847 	}
243*6616Sdm199847 
244*6616Sdm199847 	return (res->retcode); /* This might not be IDMAP_SUCCESS! */
245*6616Sdm199847 
246*6616Sdm199847 #if 0
247*6616Sdm199847 	(void) memset(&res, 0, sizeof (res));
248*6616Sdm199847 	pr = PROP_DOMAIN_CONTROLLER;
249*6616Sdm199847 
250*6616Sdm199847 	clntstat = clnt_call(clnt, IDMAP_GET_PROP,
251*6616Sdm199847 	    (xdrproc_t)xdr_idmap_prop_type, (caddr_t)&pr,
252*6616Sdm199847 	    (xdrproc_t)xdr_idmap_prop_res, (caddr_t)&res, TIMEOUT);
253*6616Sdm199847 
254*6616Sdm199847 	if (clntstat != RPC_SUCCESS) {
255*6616Sdm199847 		fprintf(stderr, "clntstat != RPC_SUCCESS\n");
256*6616Sdm199847 		rc = _idmap_rpc2stat(clnt);
257*6616Sdm199847 		goto cleanup;
258*6616Sdm199847 	}
259*6616Sdm199847 #endif
260*6616Sdm199847 
261*6616Sdm199847 }
262*6616Sdm199847 
263*6616Sdm199847 idmap_stat
264*6616Sdm199847 idmap_get_prop_ds(idmap_handle_t *handle, idmap_prop_type pr,
265*6616Sdm199847     idmap_ad_disc_ds_t *dc)
266*6616Sdm199847 {
267*6616Sdm199847 	idmap_prop_res res;
268*6616Sdm199847 	idmap_stat rc = IDMAP_SUCCESS;
269*6616Sdm199847 
270*6616Sdm199847 	rc = idmap_get_prop(handle, pr, &res);
271*6616Sdm199847 	if (rc < 0)
272*6616Sdm199847 		return (rc);
273*6616Sdm199847 
274*6616Sdm199847 	dc->port = res.value.idmap_prop_val_u.dsval.port;
275*6616Sdm199847 	(void) strlcpy(dc->host, res.value.idmap_prop_val_u.dsval.host,
276*6616Sdm199847 	    AD_DISC_MAXHOSTNAME);
277*6616Sdm199847 
278*6616Sdm199847 	/* xdr doesn't guarantee 0-termination of char[]: */
279*6616Sdm199847 	dc->host[AD_DISC_MAXHOSTNAME - 1] = '\0';
280*6616Sdm199847 
281*6616Sdm199847 	return (rc);
282*6616Sdm199847 }
283*6616Sdm199847 
284*6616Sdm199847 
285*6616Sdm199847 /*
286*6616Sdm199847  * Sometimes the property is not set. In that case, str is set to NULL but
287*6616Sdm199847  * otherwise IDMAP_SUCCESS is returned.
288*6616Sdm199847  */
289*6616Sdm199847 idmap_stat
290*6616Sdm199847 idmap_get_prop_str(idmap_handle_t *handle, idmap_prop_type pr, char **str)
291*6616Sdm199847 {
292*6616Sdm199847 	idmap_prop_res res;
293*6616Sdm199847 	idmap_stat rc = IDMAP_SUCCESS;
294*6616Sdm199847 
295*6616Sdm199847 	rc = idmap_get_prop(handle, pr, &res);
296*6616Sdm199847 	if (rc < 0)
297*6616Sdm199847 		return (rc);
298*6616Sdm199847 
299*6616Sdm199847 	rc = idmap_strdupnull(str, res.value.idmap_prop_val_u.utf8val);
300*6616Sdm199847 	return (rc);
301*6616Sdm199847 }
3024520Snw141292 
3034520Snw141292 /*
3044520Snw141292  * Create/Initialize handle for updates
3054520Snw141292  *
3064520Snw141292  * Output:
3074520Snw141292  * udthandle - update handle
3084520Snw141292  */
3094520Snw141292 idmap_stat
3105696Snw141292 idmap_udt_create(idmap_handle_t *handle, idmap_udt_handle_t **udthandle)
3115696Snw141292 {
3124520Snw141292 	idmap_udt_handle_t	*tmp;
3134520Snw141292 
3144520Snw141292 	if (handle == NULL || udthandle == NULL) {
3154520Snw141292 		errno = EINVAL;
3164520Snw141292 		return (IDMAP_ERR_ARG);
3174520Snw141292 	}
3184520Snw141292 	if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
3194520Snw141292 		errno = ENOMEM;
3204520Snw141292 		return (IDMAP_ERR_MEMORY);
3214520Snw141292 	}
3224520Snw141292 
3234520Snw141292 	tmp->ih = handle;
3244520Snw141292 	*udthandle = tmp;
3254520Snw141292 	return (IDMAP_SUCCESS);
3264520Snw141292 }
3274520Snw141292 
3284520Snw141292 
3294520Snw141292 /*
3304520Snw141292  * All the updates specified by the update handle are committed
3314520Snw141292  * in a single transaction. i.e either all succeed or none.
3324520Snw141292  *
3334520Snw141292  * Input:
3344520Snw141292  * udthandle - update handle with the update requests
3354520Snw141292  *
3364520Snw141292  * Return value:
3374520Snw141292  * Status of the commit
3384520Snw141292  */
3394520Snw141292 idmap_stat
3405696Snw141292 idmap_udt_commit(idmap_udt_handle_t *udthandle)
3415696Snw141292 {
3424520Snw141292 	CLIENT			*clnt;
3434520Snw141292 	enum clnt_stat		clntstat;
3445064Sdm199847 	idmap_update_res	res;
3455064Sdm199847 	idmap_stat		retcode;
3464520Snw141292 
3474520Snw141292 	if (udthandle == NULL) {
3484520Snw141292 		errno = EINVAL;
3494520Snw141292 		return (IDMAP_ERR_ARG);
3504520Snw141292 	}
3515064Sdm199847 
3525064Sdm199847 	(void) memset(&res, 0, sizeof (res));
3535064Sdm199847 
3544520Snw141292 	_IDMAP_GET_CLIENT_HANDLE(udthandle->ih, clnt);
3554520Snw141292 	clntstat = clnt_call(clnt, IDMAP_UPDATE,
3565696Snw141292 	    (xdrproc_t)xdr_idmap_update_batch, (caddr_t)&udthandle->batch,
3575696Snw141292 	    (xdrproc_t)xdr_idmap_update_res, (caddr_t)&res,
3585696Snw141292 	    TIMEOUT);
3594644Sbaban 
3605064Sdm199847 	if (clntstat != RPC_SUCCESS) {
3615064Sdm199847 		retcode = _idmap_rpc2stat(clnt);
3625064Sdm199847 		goto out;
3635064Sdm199847 	}
3645064Sdm199847 
3655064Sdm199847 	retcode = udthandle->commit_stat = res.retcode;
3665064Sdm199847 	udthandle->error_index = res.error_index;
3675064Sdm199847 
3685064Sdm199847 	if (retcode != IDMAP_SUCCESS) {
3695064Sdm199847 
3705064Sdm199847 		if (udthandle->error_index < 0)
3715064Sdm199847 			goto out;
3725064Sdm199847 
3735064Sdm199847 		retcode = idmap_namerule_cpy(&udthandle->error_rule,
3745064Sdm199847 		    &res.error_rule);
3755064Sdm199847 		if (retcode != IDMAP_SUCCESS) {
3765064Sdm199847 			udthandle->error_index = -2;
3775064Sdm199847 			goto out;
3785064Sdm199847 		}
3795064Sdm199847 
3805064Sdm199847 		retcode = idmap_namerule_cpy(&udthandle->conflict_rule,
3815064Sdm199847 		    &res.conflict_rule);
3825064Sdm199847 		if (retcode != IDMAP_SUCCESS) {
3835064Sdm199847 			udthandle->error_index = -2;
3845064Sdm199847 			goto out;
3855064Sdm199847 		}
3865064Sdm199847 	}
3875064Sdm199847 
3885064Sdm199847 	retcode = res.retcode;
3895064Sdm199847 
3905064Sdm199847 
3915064Sdm199847 out:
3924644Sbaban 	/* reset handle so that it can be used again */
3935064Sdm199847 	if (retcode == IDMAP_SUCCESS) {
3945064Sdm199847 		_IDMAP_RESET_UDT_HANDLE(udthandle);
3955064Sdm199847 	}
3965064Sdm199847 
3975064Sdm199847 	(void) xdr_free(xdr_idmap_update_res, (caddr_t)&res);
3985064Sdm199847 	errno = idmap_stat2errno(retcode);
3995064Sdm199847 	return (retcode);
4005064Sdm199847 }
4015064Sdm199847 
4025064Sdm199847 
4035064Sdm199847 static void
4045064Sdm199847 idmap_namerule_parts_clear(char **windomain, char **winname,
4055696Snw141292     char **unixname, boolean_t *is_user, boolean_t *is_wuser,
4065696Snw141292     boolean_t *is_nt4, int *direction)
4075696Snw141292 {
4085064Sdm199847 	if (windomain)
4095064Sdm199847 		*windomain = NULL;
4105064Sdm199847 	if (winname)
4115064Sdm199847 		*winname = NULL;
4125064Sdm199847 	if (unixname)
4135064Sdm199847 		*unixname = NULL;
4145064Sdm199847 
4155064Sdm199847 	if (is_nt4)
4165064Sdm199847 		*is_nt4 = 0;
4175064Sdm199847 	if (is_user)
4185064Sdm199847 		*is_user = -1;
4195696Snw141292 	if (is_wuser)
4205696Snw141292 		*is_wuser = -1;
4215064Sdm199847 	if (direction)
4225064Sdm199847 		*direction = IDMAP_DIRECTION_UNDEF;
4235064Sdm199847 }
4245064Sdm199847 
4255064Sdm199847 static idmap_stat
4265696Snw141292 idmap_namerule2parts(idmap_namerule *rule,
4275064Sdm199847     char **windomain, char **winname,
4285696Snw141292     char **unixname, boolean_t *is_user, boolean_t *is_wuser,
4295696Snw141292     boolean_t *is_nt4, int *direction)
4305696Snw141292 {
4315064Sdm199847 	idmap_stat retcode;
4325064Sdm199847 
4335064Sdm199847 	if (EMPTY_STRING(rule->winname) && EMPTY_STRING(rule->unixname))
4345064Sdm199847 		return (IDMAP_ERR_NORESULT);
4355064Sdm199847 
4365064Sdm199847 
4375064Sdm199847 	retcode = idmap_strdupnull(windomain, rule->windomain);
4385064Sdm199847 	if (retcode != IDMAP_SUCCESS)
4395064Sdm199847 		goto errout;
4405064Sdm199847 
4415064Sdm199847 	retcode = idmap_strdupnull(winname, rule->winname);
4425064Sdm199847 	if (retcode != IDMAP_SUCCESS)
4435064Sdm199847 		goto errout;
4445064Sdm199847 
4455064Sdm199847 	retcode = idmap_strdupnull(unixname, rule->unixname);
4465064Sdm199847 	if (retcode != IDMAP_SUCCESS)
4475064Sdm199847 		goto errout;
4485064Sdm199847 
4495064Sdm199847 
4505064Sdm199847 	if (is_user)
4515064Sdm199847 		*is_user = rule->is_user;
4525696Snw141292 	if (is_wuser)
4535696Snw141292 		*is_wuser = rule->is_wuser;
4545064Sdm199847 	if (is_nt4)
4555064Sdm199847 		*is_nt4 = rule->is_nt4;
4565064Sdm199847 	if (direction)
4575064Sdm199847 		*direction = rule->direction;
4585064Sdm199847 
4595064Sdm199847 
4605064Sdm199847 	return (IDMAP_SUCCESS);
4614644Sbaban 
4625064Sdm199847 errout:
4635064Sdm199847 	if (windomain && *windomain)
4645064Sdm199847 		free(*windomain);
4655064Sdm199847 	if (winname && *winname)
4665064Sdm199847 		free(*winname);
4675064Sdm199847 	if (unixname && *unixname)
4685064Sdm199847 		free(*unixname);
4695064Sdm199847 
4705064Sdm199847 	idmap_namerule_parts_clear(windomain, winname,
4715696Snw141292 	    unixname, is_user, is_wuser, is_nt4, direction);
4725064Sdm199847 
4734520Snw141292 	return (retcode);
4745064Sdm199847 
4755064Sdm199847 }
4765064Sdm199847 
4775064Sdm199847 /*
4785064Sdm199847  * Retrieve the index of the failed batch element. error_index == -1
4795064Sdm199847  * indicates failure at the beginning, -2 at the end.
4805064Sdm199847  *
4815064Sdm199847  * If idmap_udt_commit didn't return error, the returned value is undefined.
4825064Sdm199847  *
4835064Sdm199847  * Return value:
4845064Sdm199847  * IDMAP_SUCCESS
4855064Sdm199847  */
4865064Sdm199847 
4875064Sdm199847 idmap_stat
4885064Sdm199847 idmap_udt_get_error_index(idmap_udt_handle_t *udthandle,
4895696Snw141292     int64_t *error_index)
4905696Snw141292 {
4915064Sdm199847 	if (error_index)
4925064Sdm199847 		*error_index = udthandle->error_index;
4935064Sdm199847 
4945064Sdm199847 	return (IDMAP_SUCCESS);
4955064Sdm199847 }
4965064Sdm199847 
4975064Sdm199847 
4985064Sdm199847 /*
4995064Sdm199847  * Retrieve the rule which caused the batch to fail. If
5005064Sdm199847  * idmap_udt_commit didn't return error or if error_index is < 0, the
5015064Sdm199847  * retrieved rule is undefined.
5025064Sdm199847  *
5035064Sdm199847  * Return value:
5045064Sdm199847  * IDMAP_ERR_NORESULT if there is no error rule.
5055064Sdm199847  * IDMAP_SUCCESS if the rule was obtained OK.
5065064Sdm199847  * other error code (IDMAP_ERR_NOMEMORY etc)
5075064Sdm199847  */
5085064Sdm199847 
5095064Sdm199847 idmap_stat
5105064Sdm199847 idmap_udt_get_error_rule(idmap_udt_handle_t *udthandle,
5115064Sdm199847     char **windomain, char **winname,
5125696Snw141292     char **unixname, boolean_t *is_user, boolean_t *is_wuser,
5135696Snw141292     boolean_t *is_nt4, int *direction)
5145696Snw141292 {
5155064Sdm199847 	idmap_namerule_parts_clear(windomain, winname,
5165696Snw141292 	    unixname, is_user, is_wuser, is_nt4, direction);
5175064Sdm199847 
5185064Sdm199847 	if (udthandle->commit_stat == IDMAP_SUCCESS ||
5195064Sdm199847 	    udthandle->error_index < 0)
5205064Sdm199847 		return (IDMAP_ERR_NORESULT);
5215064Sdm199847 
5225064Sdm199847 	return (idmap_namerule2parts(
5235696Snw141292 	    &udthandle->error_rule,
5245696Snw141292 	    windomain,
5255696Snw141292 	    winname,
5265696Snw141292 	    unixname,
5275696Snw141292 	    is_user,
5285696Snw141292 	    is_wuser,
5295696Snw141292 	    is_nt4,
5305696Snw141292 	    direction));
5315064Sdm199847 }
5325064Sdm199847 
5335064Sdm199847 /*
5345064Sdm199847  * Retrieve the rule with which there was a conflict. TODO: retrieve
5355064Sdm199847  * the value.
5365064Sdm199847  *
5375064Sdm199847  * Return value:
5385064Sdm199847  * IDMAP_ERR_NORESULT if there is no error rule.
5395064Sdm199847  * IDMAP_SUCCESS if the rule was obtained OK.
5405064Sdm199847  * other error code (IDMAP_ERR_NOMEMORY etc)
5415064Sdm199847  */
5425064Sdm199847 
5435064Sdm199847 idmap_stat
5445064Sdm199847 idmap_udt_get_conflict_rule(idmap_udt_handle_t *udthandle,
5455064Sdm199847     char **windomain, char **winname,
5465696Snw141292     char **unixname, boolean_t *is_user, boolean_t *is_wuser,
5475696Snw141292     boolean_t *is_nt4, int *direction)
5485696Snw141292 {
5495064Sdm199847 	idmap_namerule_parts_clear(windomain, winname,
5505696Snw141292 	    unixname, is_user, is_wuser, is_nt4, direction);
5515064Sdm199847 
5525064Sdm199847 	if (udthandle->commit_stat != IDMAP_ERR_W2U_NAMERULE_CONFLICT &&
5535064Sdm199847 	    udthandle->commit_stat != IDMAP_ERR_U2W_NAMERULE_CONFLICT) {
5545696Snw141292 		return (IDMAP_ERR_NORESULT);
5555064Sdm199847 	}
5565064Sdm199847 
5575064Sdm199847 	return (idmap_namerule2parts(
5585696Snw141292 	    &udthandle->conflict_rule,
5595696Snw141292 	    windomain,
5605696Snw141292 	    winname,
5615696Snw141292 	    unixname,
5625696Snw141292 	    is_user,
5635696Snw141292 	    is_wuser,
5645696Snw141292 	    is_nt4,
5655696Snw141292 	    direction));
5664520Snw141292 }
5674520Snw141292 
5684520Snw141292 
5694520Snw141292 /*
5704520Snw141292  * Destroy the update handle
5714520Snw141292  */
5724520Snw141292 void
5735696Snw141292 idmap_udt_destroy(idmap_udt_handle_t *udthandle)
5745696Snw141292 {
5754520Snw141292 	if (udthandle == NULL)
5764520Snw141292 		return;
5774520Snw141292 	(void) xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch);
5785064Sdm199847 	(void) xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->error_rule);
5795064Sdm199847 	(void) xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->conflict_rule);
5804520Snw141292 	free(udthandle);
5814520Snw141292 }
5824520Snw141292 
5834520Snw141292 
5844520Snw141292 idmap_stat
5854520Snw141292 idmap_udt_add_namerule(idmap_udt_handle_t *udthandle, const char *windomain,
5865696Snw141292     boolean_t is_user, boolean_t is_wuser, const char *winname,
5875696Snw141292     const char *unixname, boolean_t is_nt4, int direction)
5885696Snw141292 {
5894520Snw141292 	idmap_retcode	retcode;
5904644Sbaban 	idmap_namerule	*rule = NULL;
5914520Snw141292 
5924644Sbaban 	retcode = _udt_extend_batch(udthandle);
5934520Snw141292 	if (retcode != IDMAP_SUCCESS)
5944520Snw141292 		goto errout;
5954520Snw141292 
5964520Snw141292 	rule = &udthandle->batch.
5975696Snw141292 	    idmap_update_batch_val[udthandle->next].
5985696Snw141292 	    idmap_update_op_u.rule;
5994520Snw141292 	rule->is_user = is_user;
6005696Snw141292 	rule->is_wuser = is_wuser;
6014520Snw141292 	rule->direction = direction;
6024520Snw141292 	rule->is_nt4 = is_nt4;
6035064Sdm199847 
6045064Sdm199847 	retcode = idmap_strdupnull(&rule->windomain, windomain);
6055064Sdm199847 	if (retcode != IDMAP_SUCCESS)
6065064Sdm199847 		goto errout;
6075064Sdm199847 
6085064Sdm199847 	retcode = idmap_strdupnull(&rule->winname, winname);
6095064Sdm199847 	if (retcode != IDMAP_SUCCESS)
6105064Sdm199847 		goto errout;
6115064Sdm199847 
6125064Sdm199847 	retcode = idmap_strdupnull(&rule->unixname, unixname);
6135064Sdm199847 	if (retcode != IDMAP_SUCCESS)
6145064Sdm199847 		goto errout;
6154644Sbaban 
6164644Sbaban 	udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
6174644Sbaban 	    OP_ADD_NAMERULE;
6184520Snw141292 	udthandle->next++;
6194520Snw141292 	return (IDMAP_SUCCESS);
6204520Snw141292 
6214520Snw141292 errout:
6224644Sbaban 	/* The batch should still be usable */
6234644Sbaban 	if (rule)
6244644Sbaban 		(void) xdr_free(xdr_idmap_namerule, (caddr_t)rule);
6254520Snw141292 	errno = idmap_stat2errno(retcode);
6264520Snw141292 	return (retcode);
6274520Snw141292 }
6284520Snw141292 
6294520Snw141292 
6304520Snw141292 /* ARGSUSED */
6314520Snw141292 idmap_stat
6324520Snw141292 idmap_udt_rm_namerule(idmap_udt_handle_t *udthandle, boolean_t is_user,
6335696Snw141292     boolean_t is_wuser,	const char *windomain, const char *winname,
6345696Snw141292     const char *unixname, int direction)
6355696Snw141292 {
6364520Snw141292 	idmap_retcode	retcode;
6374644Sbaban 	idmap_namerule	*rule = NULL;
6384520Snw141292 
6394644Sbaban 	retcode = _udt_extend_batch(udthandle);
6404520Snw141292 	if (retcode != IDMAP_SUCCESS)
6414520Snw141292 		goto errout;
6424520Snw141292 
6434520Snw141292 	rule = &udthandle->batch.
6445696Snw141292 	    idmap_update_batch_val[udthandle->next].
6455696Snw141292 	    idmap_update_op_u.rule;
6464520Snw141292 	rule->is_user = is_user;
6475696Snw141292 	rule->is_wuser = is_wuser;
6484520Snw141292 	rule->direction = direction;
6495064Sdm199847 
6505064Sdm199847 	retcode = idmap_strdupnull(&rule->windomain, windomain);
6515064Sdm199847 	if (retcode != IDMAP_SUCCESS)
6525064Sdm199847 		goto errout;
6535064Sdm199847 
6545064Sdm199847 	retcode = idmap_strdupnull(&rule->winname, winname);
6555064Sdm199847 	if (retcode != IDMAP_SUCCESS)
6565064Sdm199847 		goto errout;
6575064Sdm199847 
6585064Sdm199847 	retcode = idmap_strdupnull(&rule->unixname, unixname);
6595064Sdm199847 	if (retcode != IDMAP_SUCCESS)
6605064Sdm199847 		goto errout;
6615064Sdm199847 
6624644Sbaban 	udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
6634644Sbaban 	    OP_RM_NAMERULE;
6644520Snw141292 	udthandle->next++;
6654520Snw141292 	return (IDMAP_SUCCESS);
6664520Snw141292 
6674520Snw141292 errout:
6684644Sbaban 	if (rule)
6694644Sbaban 		(void) xdr_free(xdr_idmap_namerule, (caddr_t)rule);
6704520Snw141292 	errno = idmap_stat2errno(retcode);
6714520Snw141292 	return (retcode);
6724520Snw141292 }
6734520Snw141292 
6744520Snw141292 
6754520Snw141292 /* ARGSUSED */
6764520Snw141292 idmap_stat
6775696Snw141292 idmap_udt_flush_namerules(idmap_udt_handle_t *udthandle)
6785696Snw141292 {
6794520Snw141292 	idmap_retcode	retcode;
6804520Snw141292 
6814644Sbaban 	retcode = _udt_extend_batch(udthandle);
6824520Snw141292 	if (retcode != IDMAP_SUCCESS)
6834520Snw141292 		goto errout;
6844520Snw141292 
6854644Sbaban 	udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
6864644Sbaban 	    OP_FLUSH_NAMERULES;
6874520Snw141292 	udthandle->next++;
6884520Snw141292 	return (IDMAP_SUCCESS);
6894520Snw141292 
6904520Snw141292 errout:
6914520Snw141292 	errno = idmap_stat2errno(retcode);
6924520Snw141292 	return (retcode);
6934520Snw141292 }
6944520Snw141292 
6954520Snw141292 
6964520Snw141292 /*
6974520Snw141292  * Set the number of entries requested per batch by the iterator
6984520Snw141292  *
6994520Snw141292  * Input:
7004520Snw141292  * iter  - iterator
7014520Snw141292  * limit - number of entries requested per batch
7024520Snw141292  */
7034520Snw141292 idmap_stat
7045696Snw141292 idmap_iter_set_limit(idmap_iter_t *iter, uint64_t limit)
7055696Snw141292 {
7064520Snw141292 	if (iter == NULL) {
7074520Snw141292 		errno = EINVAL;
7084520Snw141292 		return (IDMAP_ERR_ARG);
7094520Snw141292 	}
7104520Snw141292 	iter->limit = limit;
7114520Snw141292 	return (IDMAP_SUCCESS);
7124520Snw141292 }
7134520Snw141292 
7144520Snw141292 
7154520Snw141292 /*
7164520Snw141292  * Create iterator to get name-based mapping rules
7174520Snw141292  *
7184520Snw141292  * Input:
7194520Snw141292  * windomain - Windows domain
7204520Snw141292  * is_user   - user or group rules
7214520Snw141292  * winname   - Windows user or group name
7224520Snw141292  * unixname  - Unix user or group name
7234520Snw141292  *
7244520Snw141292  * Output:
7254520Snw141292  * iter - iterator
7264520Snw141292  */
7274520Snw141292 idmap_stat
7284520Snw141292 idmap_iter_namerules(idmap_handle_t *handle, const char *windomain,
7295696Snw141292 		boolean_t is_user, boolean_t is_wuser, const char *winname,
7305696Snw141292 		const char *unixname, idmap_iter_t **iter)
7315696Snw141292 {
7324520Snw141292 
7334520Snw141292 	idmap_iter_t			*tmpiter;
7344520Snw141292 	idmap_list_namerules_1_argument	*arg = NULL;
7354520Snw141292 	idmap_namerule			*rule;
7364520Snw141292 	idmap_retcode			retcode;
7374520Snw141292 
7384520Snw141292 	__ITER_CREATE(tmpiter, arg, handle, IDMAP_LIST_NAMERULES);
7394520Snw141292 
7404520Snw141292 	rule = &arg->rule;
7414520Snw141292 	rule->is_user = is_user;
7425696Snw141292 	rule->is_wuser = is_wuser;
7434644Sbaban 	rule->direction = IDMAP_DIRECTION_UNDEF;
7445064Sdm199847 
7455064Sdm199847 	retcode = idmap_strdupnull(&rule->windomain, windomain);
7465064Sdm199847 	if (retcode != IDMAP_SUCCESS)
7475064Sdm199847 		goto errout;
7485064Sdm199847 
7495064Sdm199847 	retcode = idmap_strdupnull(&rule->winname, winname);
7505064Sdm199847 	if (retcode != IDMAP_SUCCESS)
7515064Sdm199847 		goto errout;
7525064Sdm199847 
7535064Sdm199847 	retcode = idmap_strdupnull(&rule->unixname, unixname);
7545064Sdm199847 	if (retcode != IDMAP_SUCCESS)
7555064Sdm199847 		goto errout;
7564520Snw141292 
7574520Snw141292 	*iter = tmpiter;
7584520Snw141292 	return (IDMAP_SUCCESS);
7594520Snw141292 
7604520Snw141292 errout:
7614520Snw141292 	__ITER_ERR_RETURN(tmpiter, arg,
7625696Snw141292 	    xdr_idmap_list_namerules_1_argument, retcode);
7634520Snw141292 }
7644520Snw141292 
7654520Snw141292 
7664520Snw141292 /*
7674520Snw141292  * Iterate through the name-based mapping rules
7684520Snw141292  *
7694520Snw141292  * Input:
7704520Snw141292  * iter - iterator
7714520Snw141292  *
7724520Snw141292  * Output:
7734520Snw141292  * windomain - Windows domain
7744520Snw141292  * winname   - Windows user or group name
7754520Snw141292  * unixname  - Unix user or group name
7764520Snw141292  * is_nt4    - NT4 or AD
7774520Snw141292  * direction - bi(0), win2unix(1), unix2win(2)
7784520Snw141292  *
7794520Snw141292  * Return value:
7804520Snw141292  * 0   - done
7814520Snw141292  * 1   - more results available
7824520Snw141292  * < 0 - error
7834520Snw141292  */
7844520Snw141292 idmap_stat
7854520Snw141292 idmap_iter_next_namerule(idmap_iter_t *iter, char **windomain,
7865696Snw141292     char **winname, char **unixname,  boolean_t *is_user,
7875696Snw141292     boolean_t *is_wuser, boolean_t *is_nt4, int *direction)
7885696Snw141292 {
7894520Snw141292 	idmap_namerules_res		*namerules;
7904520Snw141292 	idmap_list_namerules_1_argument	*arg;
7914520Snw141292 	idmap_retcode			retcode;
7924520Snw141292 
7935696Snw141292 	idmap_namerule_parts_clear(windomain, winname,
7945696Snw141292 	    unixname, is_user, is_wuser, is_nt4, direction);
7955696Snw141292 
7964520Snw141292 
7974520Snw141292 	__ITER_CHECK(iter, IDMAP_LIST_NAMERULES);
7984520Snw141292 
7994520Snw141292 	namerules = (idmap_namerules_res *)iter->retlist;
8004520Snw141292 	if (iter->retcode == IDMAP_NEXT && (namerules == NULL ||
8015696Snw141292 	    iter->next >= namerules->rules.rules_len)) {
8024520Snw141292 
8034520Snw141292 		if ((arg = iter->arg) == NULL) {
8044520Snw141292 			errno = EINVAL;
8054520Snw141292 			return (IDMAP_ERR_ARG);
8064520Snw141292 		}
8074520Snw141292 		arg->limit = iter->limit;
8084520Snw141292 
8094520Snw141292 		retcode = _iter_get_next_list(IDMAP_LIST_NAMERULES,
8105696Snw141292 		    iter, arg,
8115696Snw141292 		    (uchar_t **)&namerules, sizeof (*namerules),
8125696Snw141292 		    (xdrproc_t)xdr_idmap_list_namerules_1_argument,
8135696Snw141292 		    (xdrproc_t)xdr_idmap_namerules_res);
8144520Snw141292 		if (retcode != IDMAP_SUCCESS)
8154520Snw141292 			return (retcode);
8164520Snw141292 
8174520Snw141292 		if (IDMAP_ERROR(namerules->retcode)) {
8184520Snw141292 			retcode  = namerules->retcode;
8194520Snw141292 			xdr_free(xdr_idmap_namerules_res, (caddr_t)namerules);
8204520Snw141292 			free(namerules);
8214520Snw141292 			iter->retlist = NULL;
8224520Snw141292 			return (retcode);
8234520Snw141292 		}
8244520Snw141292 		iter->retcode = namerules->retcode;
8254520Snw141292 		arg->lastrowid = namerules->lastrowid;
8264520Snw141292 	}
8274520Snw141292 
8284520Snw141292 	if (namerules == NULL || namerules->rules.rules_len == 0)
8294520Snw141292 		return (IDMAP_SUCCESS);
8304520Snw141292 
8314520Snw141292 	if (iter->next >= namerules->rules.rules_len) {
8324520Snw141292 		return (IDMAP_ERR_ARG);
8334520Snw141292 	}
8344520Snw141292 
8355064Sdm199847 	retcode = idmap_strdupnull(windomain,
8365064Sdm199847 	    namerules->rules.rules_val[iter->next].windomain);
8375064Sdm199847 	if (retcode != IDMAP_SUCCESS)
8385064Sdm199847 		goto errout;
8395064Sdm199847 
8405064Sdm199847 	retcode = idmap_strdupnull(winname,
8415064Sdm199847 	    namerules->rules.rules_val[iter->next].winname);
8425064Sdm199847 	if (retcode != IDMAP_SUCCESS)
8435064Sdm199847 		goto errout;
8445064Sdm199847 
8455064Sdm199847 	retcode = idmap_strdupnull(unixname,
8465064Sdm199847 	    namerules->rules.rules_val[iter->next].unixname);
8475064Sdm199847 	if (retcode != IDMAP_SUCCESS)
8485064Sdm199847 		goto errout;
8495064Sdm199847 
8504520Snw141292 	if (is_nt4)
8514520Snw141292 		*is_nt4 = namerules->rules.rules_val[iter->next].is_nt4;
8525696Snw141292 	if (is_user)
8535696Snw141292 		*is_user = namerules->rules.rules_val[iter->next].is_user;
8545696Snw141292 	if (is_wuser)
8555696Snw141292 		*is_wuser = namerules->rules.rules_val[iter->next].is_wuser;
8564520Snw141292 	if (direction)
8574520Snw141292 		*direction = namerules->rules.rules_val[iter->next].direction;
8584520Snw141292 	iter->next++;
8594520Snw141292 
8604520Snw141292 	if (iter->next == namerules->rules.rules_len)
8614520Snw141292 		return (iter->retcode);
8624520Snw141292 	else
8634520Snw141292 		return (IDMAP_NEXT);
8644520Snw141292 
8654520Snw141292 errout:
8664520Snw141292 	if (windomain && *windomain)
8674520Snw141292 		free(*windomain);
8684520Snw141292 	if (winname && *winname)
8694520Snw141292 		free(*winname);
8704520Snw141292 	if (unixname && *unixname)
8714520Snw141292 		free(*unixname);
8724520Snw141292 	return (retcode);
8734520Snw141292 }
8744520Snw141292 
8754520Snw141292 
8764520Snw141292 /*
8774520Snw141292  * Create iterator to get SID to UID/GID mappings
8784520Snw141292  *
8794520Snw141292  * Output:
8804520Snw141292  * iter - iterator
8814520Snw141292  */
8824520Snw141292 idmap_stat
8836386Sjp151216 idmap_iter_mappings(idmap_handle_t *handle, idmap_iter_t **iter, int flag)
8845696Snw141292 {
8854520Snw141292 	idmap_iter_t			*tmpiter;
8864520Snw141292 	idmap_list_mappings_1_argument	*arg = NULL;
8874520Snw141292 
8884520Snw141292 	__ITER_CREATE(tmpiter, arg, handle, IDMAP_LIST_MAPPINGS);
8894520Snw141292 
8906386Sjp151216 	arg->flag = flag;
8914520Snw141292 	*iter = tmpiter;
8924520Snw141292 	return (IDMAP_SUCCESS);
8934520Snw141292 }
8944520Snw141292 
8954520Snw141292 
8964520Snw141292 /*
8974520Snw141292  * Iterate through the SID to UID/GID mappings
8984520Snw141292  *
8994520Snw141292  * Input:
9004520Snw141292  * iter - iterator
9014520Snw141292  *
9024520Snw141292  * Output:
9034520Snw141292  * sid - SID in canonical form
9044520Snw141292  * pid - UID or GID
9054520Snw141292  *
9064520Snw141292  * Return value:
9074520Snw141292  * 0   - done
9084520Snw141292  * 1   - more results available
9094520Snw141292  * < 0 - error
9104520Snw141292  */
9114520Snw141292 idmap_stat
9124520Snw141292 idmap_iter_next_mapping(idmap_iter_t *iter, char **sidprefix,
9135696Snw141292     idmap_rid_t *rid, uid_t *pid, char **winname,
9145696Snw141292     char **windomain, char **unixname, boolean_t *is_user,
9156386Sjp151216     boolean_t *is_wuser, int *direction, idmap_info *info)
9165696Snw141292 {
9174520Snw141292 	idmap_mappings_res		*mappings;
9184520Snw141292 	idmap_list_mappings_1_argument	*arg;
9194520Snw141292 	idmap_retcode			retcode;
9204520Snw141292 	char				*str;
9214520Snw141292 
9224520Snw141292 	if (sidprefix)
9234520Snw141292 		*sidprefix = NULL;
9244520Snw141292 	if (rid)
9254520Snw141292 		*rid = UINT32_MAX;
9264520Snw141292 	if (winname)
9274520Snw141292 		*winname = NULL;
9284520Snw141292 	if (windomain)
9294520Snw141292 		*windomain = NULL;
9304520Snw141292 	if (unixname)
9314520Snw141292 		*unixname = NULL;
9324520Snw141292 	if (pid)
9334520Snw141292 		*pid = UINT32_MAX;
9345696Snw141292 	if (is_user)
9355696Snw141292 		*is_user = -1;
9365696Snw141292 	if (is_wuser)
9375696Snw141292 		*is_wuser = -1;
9384520Snw141292 	if (direction)
9394644Sbaban 		*direction = IDMAP_DIRECTION_UNDEF;
9404520Snw141292 
9414520Snw141292 	__ITER_CHECK(iter, IDMAP_LIST_MAPPINGS);
9424520Snw141292 
9434520Snw141292 	mappings = (idmap_mappings_res *)iter->retlist;
9444520Snw141292 	if (iter->retcode == IDMAP_NEXT && (mappings == NULL ||
9455696Snw141292 	    iter->next >= mappings->mappings.mappings_len)) {
9464520Snw141292 
9474520Snw141292 		if ((arg = iter->arg) == NULL) {
9484520Snw141292 			errno = EINVAL;
9494520Snw141292 			return (IDMAP_ERR_ARG);
9504520Snw141292 		}
9514520Snw141292 		arg->limit = iter->limit;
9524520Snw141292 
9534520Snw141292 		retcode = _iter_get_next_list(IDMAP_LIST_MAPPINGS,
9545696Snw141292 		    iter, arg,
9555696Snw141292 		    (uchar_t **)&mappings, sizeof (*mappings),
9565696Snw141292 		    (xdrproc_t)xdr_idmap_list_mappings_1_argument,
9575696Snw141292 		    (xdrproc_t)xdr_idmap_mappings_res);
9584520Snw141292 		if (retcode != IDMAP_SUCCESS)
9594520Snw141292 			return (retcode);
9604520Snw141292 
9614520Snw141292 		if (IDMAP_ERROR(mappings->retcode)) {
9624520Snw141292 			retcode  = mappings->retcode;
9634520Snw141292 			xdr_free(xdr_idmap_mappings_res, (caddr_t)mappings);
9644520Snw141292 			free(mappings);
9654520Snw141292 			iter->retlist = NULL;
9664520Snw141292 			return (retcode);
9674520Snw141292 		}
9684520Snw141292 		iter->retcode = mappings->retcode;
9694520Snw141292 		arg->lastrowid = mappings->lastrowid;
9704520Snw141292 	}
9714520Snw141292 
9724520Snw141292 	if (mappings == NULL || mappings->mappings.mappings_len == 0)
9734520Snw141292 		return (IDMAP_SUCCESS);
9744520Snw141292 
9754520Snw141292 	if (iter->next >= mappings->mappings.mappings_len) {
9764520Snw141292 		return (IDMAP_ERR_ARG);
9774520Snw141292 	}
9784520Snw141292 
9794520Snw141292 	if (sidprefix) {
9804520Snw141292 		str = mappings->mappings.mappings_val[iter->next].id1.
9815696Snw141292 		    idmap_id_u.sid.prefix;
9824695Sbaban 		if (str && *str != '\0') {
9834520Snw141292 			*sidprefix = strdup(str);
9844526Sbaban 			if (*sidprefix == NULL) {
9854526Sbaban 				retcode = IDMAP_ERR_MEMORY;
9864526Sbaban 				goto errout;
9874526Sbaban 			}
9884520Snw141292 		}
9894520Snw141292 	}
9904520Snw141292 	if (rid)
9914520Snw141292 		*rid = mappings->mappings.mappings_val[iter->next].id1.
9925696Snw141292 		    idmap_id_u.sid.rid;
9935064Sdm199847 
9945064Sdm199847 	retcode = idmap_strdupnull(windomain,
9955064Sdm199847 	    mappings->mappings.mappings_val[iter->next].id1domain);
9965064Sdm199847 	if (retcode != IDMAP_SUCCESS)
9975064Sdm199847 		goto errout;
9985064Sdm199847 
9995064Sdm199847 	retcode = idmap_strdupnull(winname,
10005064Sdm199847 	    mappings->mappings.mappings_val[iter->next].id1name);
10015064Sdm199847 	if (retcode != IDMAP_SUCCESS)
10025064Sdm199847 		goto errout;
10035064Sdm199847 
10045064Sdm199847 	retcode = idmap_strdupnull(unixname,
10055064Sdm199847 	    mappings->mappings.mappings_val[iter->next].id2name);
10065064Sdm199847 	if (retcode != IDMAP_SUCCESS)
10075064Sdm199847 		goto errout;
10085064Sdm199847 
10095064Sdm199847 
10104520Snw141292 	if (pid)
10114520Snw141292 		*pid = mappings->mappings.mappings_val[iter->next].id2.
10125696Snw141292 		    idmap_id_u.uid;
10134520Snw141292 	if (direction)
10144520Snw141292 		*direction = mappings->mappings.mappings_val[iter->next].
10155696Snw141292 		    direction;
10165696Snw141292 	if (is_user)
10175696Snw141292 		*is_user = (mappings->mappings.mappings_val[iter->next].id2
10185696Snw141292 		    .idtype == IDMAP_UID)?1:0;
10195696Snw141292 	if (is_wuser)
10205696Snw141292 		*is_wuser = (mappings->mappings.mappings_val[iter->next].id1
10215696Snw141292 		    .idtype == IDMAP_USID)?1:0;
10225696Snw141292 
10236386Sjp151216 	if (info) {
10246386Sjp151216 		retcode = idmap_info_cpy(info,
10256386Sjp151216 		    &mappings->mappings.mappings_val[iter->next].info);
10266386Sjp151216 		if (retcode != IDMAP_SUCCESS)
10276386Sjp151216 			goto errout;
10286386Sjp151216 	}
10294520Snw141292 	iter->next++;
10304520Snw141292 
10314520Snw141292 	if (iter->next == mappings->mappings.mappings_len)
10324520Snw141292 		return (iter->retcode);
10334520Snw141292 	else
10344520Snw141292 		return (IDMAP_NEXT);
10354520Snw141292 
10364520Snw141292 errout:
10374520Snw141292 	if (sidprefix && *sidprefix)
10384520Snw141292 		free(*sidprefix);
10394520Snw141292 	if (winname && *winname)
10404520Snw141292 		free(*winname);
10414520Snw141292 	if (windomain && *windomain)
10424520Snw141292 		free(*windomain);
10434520Snw141292 	if (unixname && *unixname)
10444520Snw141292 		free(*unixname);
10454520Snw141292 	return (retcode);
10464520Snw141292 }
10474520Snw141292 
10484520Snw141292 
10494520Snw141292 /*
10504520Snw141292  * Destroy the iterator
10514520Snw141292  */
10524520Snw141292 void
10535696Snw141292 idmap_iter_destroy(idmap_iter_t *iter)
10545696Snw141292 {
10554520Snw141292 	xdrproc_t _xdr_argument, _xdr_result;
10564520Snw141292 
10574520Snw141292 	if (iter == NULL)
10584520Snw141292 		return;
10594520Snw141292 
10604520Snw141292 	switch (iter->type) {
10614520Snw141292 	case IDMAP_LIST_NAMERULES:
10624520Snw141292 		_xdr_argument = (xdrproc_t)xdr_idmap_list_namerules_1_argument;
10634520Snw141292 		_xdr_result = (xdrproc_t)xdr_idmap_namerules_res;
10644520Snw141292 		break;
10654520Snw141292 	case IDMAP_LIST_MAPPINGS:
10664520Snw141292 		_xdr_argument = (xdrproc_t)xdr_idmap_list_mappings_1_argument;
10674520Snw141292 		_xdr_result = (xdrproc_t)xdr_idmap_mappings_res;
10684520Snw141292 		break;
10694520Snw141292 	default:
10704520Snw141292 		free(iter);
10714520Snw141292 		return;
10724520Snw141292 	};
10734520Snw141292 
10744520Snw141292 	if (iter->arg) {
10754520Snw141292 		xdr_free(_xdr_argument, (caddr_t)iter->arg);
10764520Snw141292 		free(iter->arg);
10774520Snw141292 	}
10784520Snw141292 	if (iter->retlist) {
10794520Snw141292 		xdr_free(_xdr_result, (caddr_t)iter->retlist);
10804520Snw141292 		free(iter->retlist);
10814520Snw141292 	}
10824520Snw141292 	free(iter);
10834520Snw141292 }
10844520Snw141292 
10854520Snw141292 
10864520Snw141292 /*
10874520Snw141292  * Create handle to get SID to UID/GID mapping entries
10884520Snw141292  *
10894520Snw141292  * Input:
10904520Snw141292  * gh - "get mapping" handle
10914520Snw141292  */
10924520Snw141292 idmap_stat
10935696Snw141292 idmap_get_create(idmap_handle_t *handle, idmap_get_handle_t **gh)
10945696Snw141292 {
10954520Snw141292 	idmap_get_handle_t	*tmp;
10964520Snw141292 
10974520Snw141292 	/* sanity checks */
10984520Snw141292 	if (handle == NULL || gh == NULL) {
10994520Snw141292 		errno = EINVAL;
11004520Snw141292 		return (IDMAP_ERR_ARG);
11014520Snw141292 	}
11024520Snw141292 
11034520Snw141292 	/* allocate the handle */
11044520Snw141292 	if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
11054520Snw141292 		errno = ENOMEM;
11064520Snw141292 		return (IDMAP_ERR_MEMORY);
11074520Snw141292 	}
11084520Snw141292 
11094520Snw141292 	tmp->ih = handle;
11104520Snw141292 	*gh = tmp;
11114520Snw141292 	return (IDMAP_SUCCESS);
11124520Snw141292 }
11134520Snw141292 
11144520Snw141292 
11154520Snw141292 /*
11164520Snw141292  * Given SID, get UID
11174520Snw141292  *
11184520Snw141292  * Input:
11194520Snw141292  * sidprefix  - SID prefix
11204520Snw141292  * rid        - RID
11214520Snw141292  * flag       - flag
11224520Snw141292  *
11234520Snw141292  * Output:
11244520Snw141292  * stat - status of the get request
11254520Snw141292  * uid  - POSIX UID if stat = 0
11264520Snw141292  *
11274520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
11284520Snw141292  */
11294520Snw141292 idmap_stat
11304520Snw141292 idmap_get_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
11315696Snw141292 		int flag, uid_t *uid, idmap_stat *stat)
11325696Snw141292 {
11336386Sjp151216 	return (idmap_getext_uidbysid(gh, sidprefix, rid, flag, uid,
11346386Sjp151216 	    NULL, stat));
11356386Sjp151216 }
11364520Snw141292 
11376386Sjp151216 /*
11386386Sjp151216  * Given SID, get UID
11396386Sjp151216  *
11406386Sjp151216  * Input:
11416386Sjp151216  * sidprefix  - SID prefix
11426386Sjp151216  * rid        - RID
11436386Sjp151216  * flag       - flag
11446386Sjp151216  *
11456386Sjp151216  * Output:
11466386Sjp151216  * stat - status of the get request
11476386Sjp151216  * uid  - POSIX UID if stat = 0
11486386Sjp151216  * how  - mapping type if stat = 0
11496386Sjp151216  *
11506386Sjp151216  * Note: The output parameters will be set by idmap_get_mappings()
11516386Sjp151216  */
11526386Sjp151216 
11536386Sjp151216 idmap_stat
11546386Sjp151216 idmap_getext_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
11556386Sjp151216 		int flag, uid_t *uid, idmap_info *info, idmap_stat *stat)
11566386Sjp151216 {
11574520Snw141292 	idmap_retcode	retcode;
11584644Sbaban 	idmap_mapping	*mapping = NULL;
11594520Snw141292 
11604520Snw141292 	/* sanity checks */
11614520Snw141292 	if (gh == NULL)
11624520Snw141292 		return (IDMAP_ERR_ARG);
11634520Snw141292 	if (uid == NULL || sidprefix == NULL)
11644520Snw141292 		return (IDMAP_ERR_ARG);
11654520Snw141292 
11664520Snw141292 	/* Extend the request array and the return list */
11674520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
11684520Snw141292 		goto errout;
11694520Snw141292 
11704520Snw141292 	/* Setup the request */
11714520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
11724520Snw141292 	mapping->flag = flag;
11734520Snw141292 	mapping->id1.idtype = IDMAP_SID;
11744520Snw141292 	mapping->id1.idmap_id_u.sid.rid = rid;
11754520Snw141292 	if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
11764520Snw141292 		retcode = IDMAP_ERR_MEMORY;
11774520Snw141292 		goto errout;
11784520Snw141292 	}
11794520Snw141292 	mapping->id2.idtype = IDMAP_UID;
11804520Snw141292 
11814520Snw141292 	/* Setup pointers for the result */
11824520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_UID;
11834520Snw141292 	gh->retlist[gh->next].uid = uid;
11844520Snw141292 	gh->retlist[gh->next].stat = stat;
11856386Sjp151216 	gh->retlist[gh->next].info = info;
11864520Snw141292 
11874520Snw141292 	gh->next++;
11884520Snw141292 	return (IDMAP_SUCCESS);
11894520Snw141292 
11904520Snw141292 errout:
11914644Sbaban 	/* Batch created so far should still be usable */
11924644Sbaban 	if (mapping)
11934644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
11944520Snw141292 	errno = idmap_stat2errno(retcode);
11954520Snw141292 	return (retcode);
11964520Snw141292 }
11974520Snw141292 
11984520Snw141292 
11994520Snw141292 /*
12004520Snw141292  * Given SID, get GID
12014520Snw141292  *
12024520Snw141292  * Input:
12034520Snw141292  * sidprefix  - SID prefix
12044520Snw141292  * rid        - rid
12054520Snw141292  * flag       - flag
12064520Snw141292  *
12074520Snw141292  * Output:
12084520Snw141292  * stat - status of the get request
12094520Snw141292  * gid  - POSIX GID if stat = 0
12104520Snw141292  *
12114520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
12124520Snw141292  */
12134520Snw141292 idmap_stat
12144520Snw141292 idmap_get_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
12155696Snw141292 		int flag, gid_t *gid, idmap_stat *stat)
12165696Snw141292 {
12176386Sjp151216 	return (idmap_getext_gidbysid(gh, sidprefix, rid, flag, gid,
12186386Sjp151216 	    NULL, stat));
12196386Sjp151216 }
12206386Sjp151216 
12216386Sjp151216 
12226386Sjp151216 /*
12236386Sjp151216  * Given SID, get GID
12246386Sjp151216  *
12256386Sjp151216  * Input:
12266386Sjp151216  * sidprefix  - SID prefix
12276386Sjp151216  * rid        - rid
12286386Sjp151216  * flag       - flag
12296386Sjp151216  *
12306386Sjp151216  * Output:
12316386Sjp151216  * stat - status of the get request
12326386Sjp151216  * gid  - POSIX GID if stat = 0
12336386Sjp151216  * how  - mapping type if stat = 0
12346386Sjp151216  *
12356386Sjp151216  * Note: The output parameters will be set by idmap_get_mappings()
12366386Sjp151216  */
12376386Sjp151216 idmap_stat
12386386Sjp151216 idmap_getext_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
12396386Sjp151216 		int flag, gid_t *gid, idmap_info *info, idmap_stat *stat)
12406386Sjp151216 {
12414520Snw141292 
12424520Snw141292 	idmap_retcode	retcode;
12434644Sbaban 	idmap_mapping	*mapping = NULL;
12444520Snw141292 
12454520Snw141292 	/* sanity checks */
12464520Snw141292 	if (gh == NULL)
12474520Snw141292 		return (IDMAP_ERR_ARG);
12484520Snw141292 	if (gid == NULL || sidprefix == NULL)
12494520Snw141292 		return (IDMAP_ERR_ARG);
12504520Snw141292 
12514520Snw141292 	/* Extend the request array and the return list */
12524520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
12534520Snw141292 		goto errout;
12544520Snw141292 
12554520Snw141292 	/* Setup the request */
12564520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
12574520Snw141292 	mapping->flag = flag;
12584520Snw141292 	mapping->id1.idtype = IDMAP_SID;
12594520Snw141292 	mapping->id1.idmap_id_u.sid.rid = rid;
12604520Snw141292 	if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
12614520Snw141292 		retcode = IDMAP_ERR_MEMORY;
12624520Snw141292 		goto errout;
12634520Snw141292 	}
12644520Snw141292 	mapping->id2.idtype = IDMAP_GID;
12654520Snw141292 
12664520Snw141292 	/* Setup pointers for the result */
12674520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_GID;
12684520Snw141292 	gh->retlist[gh->next].gid = gid;
12694520Snw141292 	gh->retlist[gh->next].stat = stat;
12706386Sjp151216 	gh->retlist[gh->next].info = info;
12714520Snw141292 
12724520Snw141292 	gh->next++;
12734520Snw141292 	return (IDMAP_SUCCESS);
12744520Snw141292 
12754520Snw141292 errout:
12764644Sbaban 	if (mapping)
12774644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
12784520Snw141292 	errno = idmap_stat2errno(retcode);
12794520Snw141292 	return (retcode);
12804520Snw141292 }
12814520Snw141292 
12824520Snw141292 
12836386Sjp151216 
12844520Snw141292 /*
12854520Snw141292  * Given SID, get POSIX ID i.e. UID/GID
12864520Snw141292  *
12874520Snw141292  * Input:
12884520Snw141292  * sidprefix  - SID prefix
12894520Snw141292  * rid        - rid
12904520Snw141292  * flag       - flag
12914520Snw141292  *
12924520Snw141292  * Output:
12934520Snw141292  * stat    - status of the get request
12944520Snw141292  * is_user - user or group
12954520Snw141292  * pid     - POSIX UID if stat = 0 and is_user = 1
12964520Snw141292  *           POSIX GID if stat = 0 and is_user = 0
12974520Snw141292  *
12984520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
12994520Snw141292  */
13004520Snw141292 idmap_stat
13014520Snw141292 idmap_get_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
13025696Snw141292 		int flag, uid_t *pid, int *is_user, idmap_stat *stat)
13035696Snw141292 {
13046386Sjp151216 	return (idmap_getext_pidbysid(gh, sidprefix, rid, flag, pid, is_user,
13056386Sjp151216 	    NULL, stat));
13066386Sjp151216 }
13076386Sjp151216 
13086386Sjp151216 
13096386Sjp151216 
13106386Sjp151216 /*
13116386Sjp151216  * Given SID, get POSIX ID i.e. UID/GID
13126386Sjp151216  *
13136386Sjp151216  * Input:
13146386Sjp151216  * sidprefix  - SID prefix
13156386Sjp151216  * rid        - rid
13166386Sjp151216  * flag       - flag
13176386Sjp151216  *
13186386Sjp151216  * Output:
13196386Sjp151216  * stat    - status of the get request
13206386Sjp151216  * is_user - user or group
13216386Sjp151216  * pid     - POSIX UID if stat = 0 and is_user = 1
13226386Sjp151216  *           POSIX GID if stat = 0 and is_user = 0
13236386Sjp151216  * how     - mapping type if stat = 0
13246386Sjp151216  *
13256386Sjp151216  * Note: The output parameters will be set by idmap_get_mappings()
13266386Sjp151216  */
13276386Sjp151216 idmap_stat
13286386Sjp151216 idmap_getext_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
13296386Sjp151216 	int flag, uid_t *pid, int *is_user, idmap_info *info, idmap_stat *stat)
13306386Sjp151216 {
13314520Snw141292 	idmap_retcode	retcode;
13324644Sbaban 	idmap_mapping	*mapping = NULL;
13334520Snw141292 
13344520Snw141292 	/* sanity checks */
13354520Snw141292 	if (gh == NULL)
13364520Snw141292 		return (IDMAP_ERR_ARG);
13374520Snw141292 	if (pid == NULL || sidprefix == NULL || is_user == NULL)
13384520Snw141292 		return (IDMAP_ERR_ARG);
13394520Snw141292 
13404520Snw141292 	/* Extend the request array and the return list */
13414520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
13424520Snw141292 		goto errout;
13434520Snw141292 
13444520Snw141292 	/* Setup the request */
13454520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
13464520Snw141292 	mapping->flag = flag;
13474520Snw141292 	mapping->id1.idtype = IDMAP_SID;
13484520Snw141292 	mapping->id1.idmap_id_u.sid.rid = rid;
13494520Snw141292 	if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
13504520Snw141292 		retcode = IDMAP_ERR_MEMORY;
13514520Snw141292 		goto errout;
13524520Snw141292 	}
13534520Snw141292 	mapping->id2.idtype = IDMAP_POSIXID;
13544520Snw141292 
13554520Snw141292 	/* Setup pointers for the result */
13564520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_POSIXID;
13574520Snw141292 	gh->retlist[gh->next].uid = pid;
13584520Snw141292 	gh->retlist[gh->next].gid = pid;
13594520Snw141292 	gh->retlist[gh->next].is_user = is_user;
13604520Snw141292 	gh->retlist[gh->next].stat = stat;
13616386Sjp151216 	gh->retlist[gh->next].info = info;
13624520Snw141292 
13634520Snw141292 	gh->next++;
13644520Snw141292 	return (IDMAP_SUCCESS);
13654520Snw141292 
13664520Snw141292 errout:
13674644Sbaban 	if (mapping)
13684644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
13694520Snw141292 	errno = idmap_stat2errno(retcode);
13704520Snw141292 	return (retcode);
13714520Snw141292 }
13724520Snw141292 
13734520Snw141292 
13744520Snw141292 /*
13754520Snw141292  * Given UID, get SID
13764520Snw141292  *
13774520Snw141292  * Input:
13784520Snw141292  * uid  - POSIX UID
13794520Snw141292  * flag - flag
13804520Snw141292  *
13814520Snw141292  * Output:
13824520Snw141292  * stat - status of the get request
13834520Snw141292  * sid  - SID prefix (if stat == 0)
13844520Snw141292  * rid  - rid
13854520Snw141292  *
13864520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
13874520Snw141292  */
13884520Snw141292 idmap_stat
13894520Snw141292 idmap_get_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag,
13905696Snw141292 		char **sidprefix, idmap_rid_t *rid, idmap_stat *stat)
13915696Snw141292 {
13926386Sjp151216 	return (idmap_getext_sidbyuid(gh, uid, flag, sidprefix, rid,
13936386Sjp151216 	    NULL, stat));
13946386Sjp151216 }
13956386Sjp151216 
13966386Sjp151216 
13976386Sjp151216 /*
13986386Sjp151216  * Given UID, get SID
13996386Sjp151216  *
14006386Sjp151216  * Input:
14016386Sjp151216  * uid  - POSIX UID
14026386Sjp151216  * flag - flag
14036386Sjp151216  *
14046386Sjp151216  * Output:
14056386Sjp151216  * stat - status of the get request
14066386Sjp151216  * sid  - SID prefix (if stat == 0)
14076386Sjp151216  * rid  - rid
14086386Sjp151216  * how  - mapping type if stat = 0
14096386Sjp151216  *
14106386Sjp151216  * Note: The output parameters will be set by idmap_get_mappings()
14116386Sjp151216  */
14126386Sjp151216 idmap_stat
14136386Sjp151216 idmap_getext_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag,
14146386Sjp151216 	char **sidprefix, idmap_rid_t *rid, idmap_info *info, idmap_stat *stat)
14156386Sjp151216 {
14164520Snw141292 
14174520Snw141292 	idmap_retcode	retcode;
14184644Sbaban 	idmap_mapping	*mapping = NULL;
14194520Snw141292 
14204520Snw141292 	/* sanity checks */
14214520Snw141292 	if (gh == NULL)
14224520Snw141292 		return (IDMAP_ERR_ARG);
14234520Snw141292 	if (sidprefix == NULL)
14244520Snw141292 		return (IDMAP_ERR_ARG);
14254520Snw141292 
14264520Snw141292 	/* Extend the request array and the return list */
14274520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
14284520Snw141292 		goto errout;
14294520Snw141292 
14304520Snw141292 	/* Setup the request */
14314520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
14324520Snw141292 	mapping->flag = flag;
14334520Snw141292 	mapping->id1.idtype = IDMAP_UID;
14344520Snw141292 	mapping->id1.idmap_id_u.uid = uid;
14354520Snw141292 	mapping->id2.idtype = IDMAP_SID;
14364520Snw141292 
14374520Snw141292 	/* Setup pointers for the result */
14384520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_SID;
14394520Snw141292 	gh->retlist[gh->next].sidprefix = sidprefix;
14404520Snw141292 	gh->retlist[gh->next].rid = rid;
14414520Snw141292 	gh->retlist[gh->next].stat = stat;
14426386Sjp151216 	gh->retlist[gh->next].info = info;
14434520Snw141292 
14444520Snw141292 	gh->next++;
14454520Snw141292 	return (IDMAP_SUCCESS);
14464520Snw141292 
14474520Snw141292 errout:
14484644Sbaban 	if (mapping)
14494644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
14504520Snw141292 	errno = idmap_stat2errno(retcode);
14514520Snw141292 	return (retcode);
14524520Snw141292 }
14534520Snw141292 
14544520Snw141292 
14554520Snw141292 /*
14564520Snw141292  * Given GID, get SID
14574520Snw141292  *
14584520Snw141292  * Input:
14594520Snw141292  * gid  - POSIX GID
14604520Snw141292  * flag - flag
14614520Snw141292  *
14624520Snw141292  * Output:
14634520Snw141292  * stat       - status of the get request
14644520Snw141292  * sidprefix  - SID prefix (if stat == 0)
14654520Snw141292  * rid        - rid
14664520Snw141292  *
14674520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
14684520Snw141292  */
14694520Snw141292 idmap_stat
14704520Snw141292 idmap_get_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag,
14715696Snw141292 		char **sidprefix, idmap_rid_t *rid, idmap_stat *stat)
14725696Snw141292 {
14736386Sjp151216 	return (idmap_getext_sidbygid(gh, gid, flag, sidprefix, rid,
14746386Sjp151216 	    NULL, stat));
14756386Sjp151216 }
14766386Sjp151216 
14776386Sjp151216 
14786386Sjp151216 /*
14796386Sjp151216  * Given GID, get SID
14806386Sjp151216  *
14816386Sjp151216  * Input:
14826386Sjp151216  * gid  - POSIX GID
14836386Sjp151216  * flag - flag
14846386Sjp151216  *
14856386Sjp151216  * Output:
14866386Sjp151216  * stat       - status of the get request
14876386Sjp151216  * sidprefix  - SID prefix (if stat == 0)
14886386Sjp151216  * rid        - rid
14896386Sjp151216  * how        - mapping type if stat = 0
14906386Sjp151216  *
14916386Sjp151216  * Note: The output parameters will be set by idmap_get_mappings()
14926386Sjp151216  */
14936386Sjp151216 idmap_stat
14946386Sjp151216 idmap_getext_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag,
14956386Sjp151216 	char **sidprefix, idmap_rid_t *rid, idmap_info *info, idmap_stat *stat)
14966386Sjp151216 {
14974520Snw141292 
14984520Snw141292 	idmap_retcode	retcode;
14994644Sbaban 	idmap_mapping	*mapping = NULL;
15004520Snw141292 
15014520Snw141292 	/* sanity checks */
15024520Snw141292 	if (gh == NULL)
15034520Snw141292 		return (IDMAP_ERR_ARG);
15044520Snw141292 	if (sidprefix == NULL)
15054520Snw141292 		return (IDMAP_ERR_ARG);
15064520Snw141292 
15074520Snw141292 	/* Extend the request array and the return list */
15084520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
15094520Snw141292 		goto errout;
15104520Snw141292 
15114520Snw141292 	/* Setup the request */
15124520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
15134520Snw141292 	mapping->flag = flag;
15144520Snw141292 	mapping->id1.idtype = IDMAP_GID;
15154520Snw141292 	mapping->id1.idmap_id_u.gid = gid;
15164520Snw141292 	mapping->id2.idtype = IDMAP_SID;
15174520Snw141292 
15184520Snw141292 	/* Setup pointers for the result */
15194520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_SID;
15204520Snw141292 	gh->retlist[gh->next].sidprefix = sidprefix;
15214520Snw141292 	gh->retlist[gh->next].rid = rid;
15224520Snw141292 	gh->retlist[gh->next].stat = stat;
15236386Sjp151216 	gh->retlist[gh->next].info = info;
15244520Snw141292 
15254520Snw141292 	gh->next++;
15264520Snw141292 	return (IDMAP_SUCCESS);
15274520Snw141292 
15284520Snw141292 errout:
15294644Sbaban 	if (mapping)
15304644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
15314520Snw141292 	errno = idmap_stat2errno(retcode);
15324520Snw141292 	return (retcode);
15334520Snw141292 }
15344520Snw141292 
15354520Snw141292 
15364520Snw141292 /*
15374520Snw141292  * Process the batched "get mapping" requests. The results (i.e.
15384520Snw141292  * status and identity) will be available in the data areas
15394520Snw141292  * provided by individual requests.
15404520Snw141292  */
15414520Snw141292 idmap_stat
15425696Snw141292 idmap_get_mappings(idmap_get_handle_t *gh)
15435696Snw141292 {
15444520Snw141292 	CLIENT		*clnt;
15454520Snw141292 	enum clnt_stat	clntstat;
15464520Snw141292 	idmap_retcode	retcode;
15474520Snw141292 	idmap_ids_res	res;
15484520Snw141292 	idmap_id	*id;
15494520Snw141292 	int		i;
15504520Snw141292 
15514520Snw141292 	if (gh == NULL) {
15524520Snw141292 		errno = EINVAL;
15534520Snw141292 		return (IDMAP_ERR_ARG);
15544520Snw141292 	}
15554520Snw141292 	_IDMAP_GET_CLIENT_HANDLE(gh->ih, clnt);
15564520Snw141292 
15574520Snw141292 	(void) memset(&res, 0, sizeof (idmap_ids_res));
15584520Snw141292 	clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_IDS,
15595696Snw141292 	    (xdrproc_t)xdr_idmap_mapping_batch,
15605696Snw141292 	    (caddr_t)&gh->batch,
15615696Snw141292 	    (xdrproc_t)xdr_idmap_ids_res,
15625696Snw141292 	    (caddr_t)&res,
15635696Snw141292 	    TIMEOUT);
15644520Snw141292 	if (clntstat != RPC_SUCCESS) {
15654644Sbaban 		retcode = _idmap_rpc2stat(clnt);
15664520Snw141292 		goto out;
15674520Snw141292 	}
15684520Snw141292 	if (res.retcode != IDMAP_SUCCESS) {
15694520Snw141292 		retcode = res.retcode;
15704520Snw141292 		goto out;
15714520Snw141292 	}
15724520Snw141292 	for (i = 0; i < gh->next; i++) {
15734520Snw141292 		if (i >= res.ids.ids_len) {
15744520Snw141292 			*gh->retlist[i].stat = IDMAP_ERR_NORESULT;
15754520Snw141292 			continue;
15764520Snw141292 		}
15774520Snw141292 		*gh->retlist[i].stat = res.ids.ids_val[i].retcode;
15784520Snw141292 		id = &res.ids.ids_val[i].id;
15794520Snw141292 		switch (id->idtype) {
15804520Snw141292 		case IDMAP_UID:
15814520Snw141292 			if (gh->retlist[i].uid)
15824520Snw141292 				*gh->retlist[i].uid = id->idmap_id_u.uid;
15834520Snw141292 			if (gh->retlist[i].is_user)
15844520Snw141292 				*gh->retlist[i].is_user = 1;
15854520Snw141292 			break;
15864520Snw141292 		case IDMAP_GID:
15874520Snw141292 			if (gh->retlist[i].gid)
15884520Snw141292 				*gh->retlist[i].gid = id->idmap_id_u.gid;
15894520Snw141292 			if (gh->retlist[i].is_user)
15904520Snw141292 				*gh->retlist[i].is_user = 0;
15914520Snw141292 			break;
15924864Sbaban 		case IDMAP_POSIXID:
15934864Sbaban 			if (gh->retlist[i].uid)
15944864Sbaban 				*gh->retlist[i].uid = 60001;
15954864Sbaban 			if (gh->retlist[i].is_user)
15964864Sbaban 				*gh->retlist[i].is_user = -1;
15974864Sbaban 			break;
15984520Snw141292 		case IDMAP_SID:
15995696Snw141292 		case IDMAP_USID:
16005696Snw141292 		case IDMAP_GSID:
16014520Snw141292 			if (gh->retlist[i].rid)
16024520Snw141292 				*gh->retlist[i].rid = id->idmap_id_u.sid.rid;
16034520Snw141292 			if (gh->retlist[i].sidprefix) {
16044695Sbaban 				if (id->idmap_id_u.sid.prefix == NULL ||
16054695Sbaban 				    *id->idmap_id_u.sid.prefix == '\0') {
16064520Snw141292 					*gh->retlist[i].sidprefix = NULL;
16074520Snw141292 					break;
16084520Snw141292 				}
16094520Snw141292 				*gh->retlist[i].sidprefix =
16105696Snw141292 				    strdup(id->idmap_id_u.sid.prefix);
16114520Snw141292 				if (*gh->retlist[i].sidprefix == NULL)
16124520Snw141292 					*gh->retlist[i].stat =
16135696Snw141292 					    IDMAP_ERR_MEMORY;
16144520Snw141292 			}
16154520Snw141292 			break;
16164520Snw141292 		case IDMAP_NONE:
16174520Snw141292 			break;
16184520Snw141292 		default:
16194520Snw141292 			*gh->retlist[i].stat = IDMAP_ERR_NORESULT;
16204520Snw141292 			break;
16214520Snw141292 		}
16226386Sjp151216 		if (gh->retlist[i].info != NULL)
16236386Sjp151216 			(void) idmap_info_cpy(gh->retlist[i].info,
16246386Sjp151216 			    &res.ids.ids_val[i].info);
16254520Snw141292 	}
16264520Snw141292 	retcode = IDMAP_SUCCESS;
16274520Snw141292 
16284520Snw141292 out:
16294644Sbaban 	_IDMAP_RESET_GET_HANDLE(gh);
16304520Snw141292 	(void) xdr_free(xdr_idmap_ids_res, (caddr_t)&res);
16314520Snw141292 	errno = idmap_stat2errno(retcode);
16324520Snw141292 	return (retcode);
16334520Snw141292 }
16344520Snw141292 
16354520Snw141292 
16364520Snw141292 /*
16374520Snw141292  * Destroy the "get mapping" handle
16384520Snw141292  */
16394520Snw141292 void
16405696Snw141292 idmap_get_destroy(idmap_get_handle_t *gh)
16415696Snw141292 {
16424520Snw141292 	if (gh == NULL)
16434520Snw141292 		return;
16444520Snw141292 	(void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch);
16454520Snw141292 	if (gh->retlist)
16464520Snw141292 		free(gh->retlist);
16474520Snw141292 	free(gh);
16484520Snw141292 }
16494520Snw141292 
16504520Snw141292 
16514520Snw141292 /*
16524520Snw141292  * Get windows to unix mapping
16534520Snw141292  */
16544520Snw141292 idmap_stat
16554520Snw141292 idmap_get_w2u_mapping(idmap_handle_t *handle,
16564520Snw141292 		const char *sidprefix, idmap_rid_t *rid,
16574520Snw141292 		const char *winname, const char *windomain,
16585696Snw141292 		int flag, int *is_user, int *is_wuser,
16596386Sjp151216 		uid_t *pid, char **unixname, int *direction, idmap_info *info)
16605696Snw141292 {
16614520Snw141292 	CLIENT			*clnt;
16624520Snw141292 	enum clnt_stat		clntstat;
16634520Snw141292 	idmap_mapping		request, *mapping;
16644520Snw141292 	idmap_mappings_res	result;
16654520Snw141292 	idmap_retcode		retcode, rc;
16664520Snw141292 
16674520Snw141292 	if (handle == NULL) {
16684520Snw141292 		errno = EINVAL;
16694520Snw141292 		return (IDMAP_ERR_ARG);
16704520Snw141292 	}
16714520Snw141292 
16724520Snw141292 	_IDMAP_GET_CLIENT_HANDLE(handle, clnt);
16734520Snw141292 
16744520Snw141292 	(void) memset(&request, 0, sizeof (request));
16754520Snw141292 	(void) memset(&result, 0, sizeof (result));
16764520Snw141292 
16774520Snw141292 	if (pid)
16784520Snw141292 		*pid = UINT32_MAX;
16794520Snw141292 	if (unixname)
16804520Snw141292 		*unixname = NULL;
16814520Snw141292 	if (direction)
16824644Sbaban 		*direction = IDMAP_DIRECTION_UNDEF;
16834520Snw141292 
16844520Snw141292 	request.flag = flag;
16854520Snw141292 	request.id1.idtype = IDMAP_SID;
16864520Snw141292 	if (sidprefix && rid) {
16874520Snw141292 		request.id1.idmap_id_u.sid.prefix = (char *)sidprefix;
16884520Snw141292 		request.id1.idmap_id_u.sid.rid = *rid;
16894520Snw141292 	} else if (winname) {
16905064Sdm199847 		retcode = idmap_strdupnull(&request.id1name, winname);
16915247Sbaban 		if (retcode != IDMAP_SUCCESS)
16924520Snw141292 			goto out;
16935064Sdm199847 
16945064Sdm199847 		retcode = idmap_strdupnull(&request.id1domain, windomain);
16955247Sbaban 		if (retcode != IDMAP_SUCCESS)
16965064Sdm199847 			goto out;
16975064Sdm199847 
16984520Snw141292 		request.id1.idmap_id_u.sid.prefix = NULL;
16994520Snw141292 	} else {
17004520Snw141292 		errno = EINVAL;
17014520Snw141292 		return (IDMAP_ERR_ARG);
17024520Snw141292 	}
17034520Snw141292 
17045696Snw141292 	if (*is_user == 1)
17054520Snw141292 		request.id2.idtype = IDMAP_UID;
17064520Snw141292 	else if (*is_user == 0)
17074520Snw141292 		request.id2.idtype = IDMAP_GID;
17084520Snw141292 	else
17094520Snw141292 		request.id2.idtype = IDMAP_POSIXID;
17104520Snw141292 
17115696Snw141292 	if (*is_wuser == 1)
17125696Snw141292 		request.id1.idtype = IDMAP_USID;
17135696Snw141292 	else if (*is_wuser == 0)
17145696Snw141292 		request.id1.idtype = IDMAP_GSID;
17155696Snw141292 	else
17165696Snw141292 		request.id1.idtype = IDMAP_SID;
17175696Snw141292 
17184520Snw141292 	clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_ID_BY_NAME,
17195696Snw141292 	    (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request,
17205696Snw141292 	    (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result,
17215696Snw141292 	    TIMEOUT);
17224520Snw141292 
17234644Sbaban 	if (clntstat != RPC_SUCCESS)
17244644Sbaban 		return (_idmap_rpc2stat(clnt));
17254520Snw141292 
17264520Snw141292 	retcode = result.retcode;
17274520Snw141292 
17284520Snw141292 	if ((mapping = result.mappings.mappings_val) == NULL) {
17294520Snw141292 		if (retcode == IDMAP_SUCCESS)
17304520Snw141292 			retcode = IDMAP_ERR_NORESULT;
17314520Snw141292 		goto out;
17324520Snw141292 	}
17334520Snw141292 
17344864Sbaban 	if (mapping->id2.idtype == IDMAP_UID) {
17355696Snw141292 		*is_user = 1;
17364864Sbaban 	} else if (mapping->id2.idtype == IDMAP_GID) {
17375696Snw141292 		*is_user = 0;
17384864Sbaban 	} else {
17394864Sbaban 		goto out;
17404864Sbaban 	}
17415696Snw141292 
17425696Snw141292 	if (mapping->id1.idtype == IDMAP_USID) {
17435696Snw141292 		*is_wuser = 1;
17445696Snw141292 	} else if (mapping->id1.idtype == IDMAP_GSID) {
17455696Snw141292 		*is_wuser = 0;
17465696Snw141292 	} else {
17475696Snw141292 		goto out;
17485696Snw141292 	}
17495696Snw141292 
17504520Snw141292 	if (direction)
17514520Snw141292 		*direction = mapping->direction;
17524520Snw141292 	if (pid)
17534520Snw141292 		*pid = mapping->id2.idmap_id_u.uid;
17545064Sdm199847 
17555064Sdm199847 	rc = idmap_strdupnull(unixname, mapping->id2name);
17565064Sdm199847 	if (rc != IDMAP_SUCCESS)
17575064Sdm199847 		retcode = rc;
17584520Snw141292 
17596386Sjp151216 	rc = idmap_info_cpy(info, &mapping->info);
17606386Sjp151216 	if (rc != IDMAP_SUCCESS)
17616386Sjp151216 		retcode = rc;
17626386Sjp151216 
17634520Snw141292 out:
17644520Snw141292 	xdr_free(xdr_idmap_mappings_res, (caddr_t)&result);
17654520Snw141292 	if (retcode != IDMAP_SUCCESS)
17664520Snw141292 		errno = idmap_stat2errno(retcode);
17674520Snw141292 	return (retcode);
17684520Snw141292 }
17694520Snw141292 
17704520Snw141292 
17714520Snw141292 /*
17724520Snw141292  * Get unix to windows mapping
17734520Snw141292  */
17744520Snw141292 idmap_stat
17754520Snw141292 idmap_get_u2w_mapping(idmap_handle_t *handle,
17764520Snw141292 		uid_t *pid, const char *unixname,
17775696Snw141292 		int flag, int is_user, int *is_wuser,
17784520Snw141292 		char **sidprefix, idmap_rid_t *rid,
17794520Snw141292 		char **winname, char **windomain,
17806386Sjp151216 		int *direction, idmap_info *info)
17815696Snw141292 {
17824520Snw141292 	CLIENT			*clnt;
17834520Snw141292 	enum clnt_stat		clntstat;
17844520Snw141292 	idmap_mapping		request, *mapping;
17854520Snw141292 	idmap_mappings_res	result;
17864520Snw141292 	idmap_retcode		retcode, rc;
17874520Snw141292 
17884520Snw141292 	if (handle == NULL) {
17894520Snw141292 		errno = EINVAL;
17904520Snw141292 		return (IDMAP_ERR_ARG);
17914520Snw141292 	}
17924520Snw141292 
17934520Snw141292 	_IDMAP_GET_CLIENT_HANDLE(handle, clnt);
17944520Snw141292 
17954520Snw141292 	if (sidprefix)
17964520Snw141292 		*sidprefix = NULL;
17974520Snw141292 	if (winname)
17984520Snw141292 		*winname = NULL;
17994520Snw141292 	if (windomain)
18004520Snw141292 		*windomain = NULL;
18014520Snw141292 	if (rid)
18024520Snw141292 		*rid = UINT32_MAX;
18034520Snw141292 	if (direction)
18044644Sbaban 		*direction = IDMAP_DIRECTION_UNDEF;
18054520Snw141292 
18064520Snw141292 	(void) memset(&request, 0, sizeof (request));
18074520Snw141292 	(void) memset(&result, 0, sizeof (result));
18084520Snw141292 
18094520Snw141292 	request.flag = flag;
18104520Snw141292 	request.id1.idtype = is_user?IDMAP_UID:IDMAP_GID;
18114520Snw141292 
18124520Snw141292 	if (pid && *pid != UINT32_MAX) {
18134520Snw141292 		request.id1.idmap_id_u.uid = *pid;
18144520Snw141292 	} else if (unixname) {
18155064Sdm199847 		request.id1name = (char *)unixname;
18164520Snw141292 		request.id1.idmap_id_u.uid = UINT32_MAX;
18174520Snw141292 	} else {
18184520Snw141292 		errno = EINVAL;
18194520Snw141292 		return (IDMAP_ERR_ARG);
18204520Snw141292 	}
18214520Snw141292 
18225696Snw141292 	if (is_wuser == NULL)
18235696Snw141292 		request.id2.idtype = IDMAP_SID;
18245696Snw141292 	else if (*is_wuser == -1)
18255696Snw141292 		request.id2.idtype = IDMAP_SID;
18265696Snw141292 	else if (*is_wuser == 0)
18275696Snw141292 		request.id2.idtype = IDMAP_GSID;
18285696Snw141292 	else if (*is_wuser == 1)
18295696Snw141292 		request.id2.idtype = IDMAP_USID;
18304520Snw141292 
18314520Snw141292 	clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_ID_BY_NAME,
18325696Snw141292 	    (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request,
18335696Snw141292 	    (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result,
18345696Snw141292 	    TIMEOUT);
18354520Snw141292 
18364644Sbaban 	if (clntstat != RPC_SUCCESS)
18374644Sbaban 		return (_idmap_rpc2stat(clnt));
18384520Snw141292 
18394520Snw141292 	retcode = result.retcode;
18404520Snw141292 
18414520Snw141292 	if ((mapping = result.mappings.mappings_val) == NULL) {
18424520Snw141292 		if (retcode == IDMAP_SUCCESS)
18434520Snw141292 			retcode = IDMAP_ERR_NORESULT;
18444520Snw141292 		goto out;
18454520Snw141292 	}
18464520Snw141292 
18475696Snw141292 	if (direction != NULL)
18484520Snw141292 		*direction = mapping->direction;
18495696Snw141292 
18506386Sjp151216 	if (is_wuser != NULL) {
18516386Sjp151216 		if (mapping->id2.idtype == IDMAP_USID)
18526386Sjp151216 			*is_wuser = 1;
18536386Sjp151216 		else if (mapping->id2.idtype == IDMAP_GSID)
18546386Sjp151216 			*is_wuser = 0;
18556386Sjp151216 		else
18566386Sjp151216 			*is_wuser = -1;
18576386Sjp151216 	}
18585696Snw141292 
18594695Sbaban 	if (sidprefix && mapping->id2.idmap_id_u.sid.prefix &&
18604695Sbaban 	    *mapping->id2.idmap_id_u.sid.prefix != '\0') {
18614520Snw141292 		*sidprefix = strdup(mapping->id2.idmap_id_u.sid.prefix);
18624520Snw141292 		if (*sidprefix == NULL) {
18634520Snw141292 			retcode = IDMAP_ERR_MEMORY;
18644520Snw141292 			goto errout;
18654520Snw141292 		}
18664520Snw141292 	}
18674520Snw141292 	if (rid)
18684520Snw141292 		*rid = mapping->id2.idmap_id_u.sid.rid;
18695064Sdm199847 
18705064Sdm199847 	rc = idmap_strdupnull(winname, mapping->id2name);
18715064Sdm199847 	if (rc != IDMAP_SUCCESS)
18725064Sdm199847 		retcode = rc;
18735064Sdm199847 
18745064Sdm199847 	rc = idmap_strdupnull(windomain, mapping->id2domain);
18755064Sdm199847 	if (rc != IDMAP_SUCCESS)
18765064Sdm199847 		retcode = rc;
18774520Snw141292 
18786386Sjp151216 	rc = idmap_info_cpy(info, &mapping->info);
18796386Sjp151216 	if (rc != IDMAP_SUCCESS)
18806386Sjp151216 		retcode = rc;
18816386Sjp151216 
18824520Snw141292 	goto out;
18834520Snw141292 
18844520Snw141292 errout:
18854520Snw141292 	if (sidprefix && *sidprefix) {
18864520Snw141292 		free(*sidprefix);
18874520Snw141292 		*sidprefix = NULL;
18884520Snw141292 	}
18894520Snw141292 	if (winname && *winname) {
18904520Snw141292 		free(*winname);
18914520Snw141292 		*winname = NULL;
18924520Snw141292 	}
18934520Snw141292 	if (windomain && *windomain) {
18944520Snw141292 		free(*windomain);
18954520Snw141292 		*windomain = NULL;
18964520Snw141292 	}
18974520Snw141292 
18984520Snw141292 out:
18994520Snw141292 	xdr_free(xdr_idmap_mappings_res, (caddr_t)&result);
19004520Snw141292 	if (retcode != IDMAP_SUCCESS)
19014520Snw141292 		errno = idmap_stat2errno(retcode);
19024520Snw141292 	return (retcode);
19034520Snw141292 }
19044520Snw141292 
19054520Snw141292 
19064520Snw141292 
19074520Snw141292 #define	gettext(s)	s
19084520Snw141292 static stat_table_t stattable[] = {
19094520Snw141292 	{IDMAP_SUCCESS, gettext("Success"), 0},
19104520Snw141292 	{IDMAP_NEXT, gettext("More results available"), 0},
19114520Snw141292 	{IDMAP_ERR_OTHER, gettext("Undefined error"), EINVAL},
19124520Snw141292 	{IDMAP_ERR_INTERNAL, gettext("Internal error"), EINVAL},
19134520Snw141292 	{IDMAP_ERR_MEMORY, gettext("Out of memory"), ENOMEM},
19144520Snw141292 	{IDMAP_ERR_NORESULT, gettext("No results available"), EINVAL},
19154520Snw141292 	{IDMAP_ERR_NOTUSER, gettext("Not a user"), EINVAL},
19164520Snw141292 	{IDMAP_ERR_NOTGROUP, gettext("Not a group"), EINVAL},
19174644Sbaban 	{IDMAP_ERR_NOTSUPPORTED, gettext("Operation not supported"), ENOTSUP},
19184520Snw141292 	{IDMAP_ERR_W2U_NAMERULE,
19194520Snw141292 		gettext("Invalid Windows to UNIX name-based rule"), EINVAL},
19204520Snw141292 	{IDMAP_ERR_U2W_NAMERULE,
19214520Snw141292 		gettext("Invalid UNIX to Windows name-based rule"), EINVAL},
19224520Snw141292 	{IDMAP_ERR_CACHE, gettext("Invalid cache"), EINVAL},
19234520Snw141292 	{IDMAP_ERR_DB, gettext("Invalid database"), EINVAL},
19244520Snw141292 	{IDMAP_ERR_ARG, gettext("Invalid argument"), EINVAL},
19254520Snw141292 	{IDMAP_ERR_SID, gettext("Invalid SID"), EINVAL},
19264520Snw141292 	{IDMAP_ERR_IDTYPE, gettext("Invalid identity type"), EINVAL},
19274644Sbaban 	{IDMAP_ERR_RPC_HANDLE, gettext("Bad RPC handle"), EBADF},
19284520Snw141292 	{IDMAP_ERR_RPC, gettext("RPC error"), EINVAL},
19294520Snw141292 	{IDMAP_ERR_CLIENT_HANDLE, gettext("Bad client handle"), EINVAL},
19304644Sbaban 	{IDMAP_ERR_BUSY, gettext("Server is busy"), EBUSY},
19314695Sbaban 	{IDMAP_ERR_PERMISSION_DENIED, gettext("Permission denied"), EACCES},
19324520Snw141292 	{IDMAP_ERR_NOMAPPING,
19334520Snw141292 		gettext("Mapping not found or inhibited"), EINVAL},
19344520Snw141292 	{IDMAP_ERR_NEW_ID_ALLOC_REQD,
19354520Snw141292 		gettext("New mapping needs to be created"), EINVAL},
19364520Snw141292 	{IDMAP_ERR_DOMAIN, gettext("Invalid domain"), EINVAL},
19374520Snw141292 	{IDMAP_ERR_SECURITY, gettext("Security issue"), EINVAL},
19384520Snw141292 	{IDMAP_ERR_NOTFOUND, gettext("Not found"), EINVAL},
19394520Snw141292 	{IDMAP_ERR_DOMAIN_NOTFOUND, gettext("Domain not found"), EINVAL},
19404520Snw141292 	{IDMAP_ERR_UPDATE_NOTALLOWED, gettext("Update not allowed"), EINVAL},
19414520Snw141292 	{IDMAP_ERR_CFG, gettext("Configuration error"), EINVAL},
19424520Snw141292 	{IDMAP_ERR_CFG_CHANGE, gettext("Invalid configuration change"), EINVAL},
19434520Snw141292 	{IDMAP_ERR_NOTMAPPED_WELLKNOWN,
19444520Snw141292 		gettext("No mapping for well-known SID"), EINVAL},
19454520Snw141292 	{IDMAP_ERR_RETRIABLE_NET_ERR,
19464864Sbaban 		gettext("Windows lookup failed"), EINVAL},
19474864Sbaban 	{IDMAP_ERR_W2U_NAMERULE_CONFLICT,
19484864Sbaban 		gettext("Duplicate rule or conflicts with an existing "
19494864Sbaban 		"Windows to UNIX name-based rule"), EINVAL},
19504864Sbaban 	{IDMAP_ERR_U2W_NAMERULE_CONFLICT,
19514864Sbaban 		gettext("Duplicate rule or conflicts with an existing "
19524864Sbaban 		"Unix to Windows name-based rule"), EINVAL},
19535968Snw141292 	{IDMAP_ERR_BAD_UTF8,
19545968Snw141292 		gettext("Invalid or illegal UTF-8 sequence found in "
19555968Snw141292 		"a given Windows entity name or domain name"), EINVAL},
19566386Sjp151216 	{IDMAP_ERR_NONEGENERATED,
19576386Sjp151216 		gettext("Mapping not found and none created (see -c option)"),
19586386Sjp151216 		EINVAL},
1959*6616Sdm199847 	{IDMAP_ERR_PROP_UNKNOWN,
1960*6616Sdm199847 		gettext("Undefined property"),
1961*6616Sdm199847 		EINVAL},
1962*6616Sdm199847 	{IDMAP_ERR_NS_LDAP_CFG,
1963*6616Sdm199847 		gettext("Native LDAP configuration error"), EINVAL},
1964*6616Sdm199847 	{IDMAP_ERR_NS_LDAP_PARTIAL,
1965*6616Sdm199847 		gettext("Partial result from Native LDAP"), EINVAL},
1966*6616Sdm199847 	{IDMAP_ERR_NS_LDAP_OP_FAILED,
1967*6616Sdm199847 		gettext("Native LDAP operation failed"), EINVAL},
1968*6616Sdm199847 	{IDMAP_ERR_NS_LDAP_BAD_WINNAME,
1969*6616Sdm199847 		gettext("Improper winname form found in Native LDAP"), EINVAL},
19704520Snw141292 	{-1, NULL, 0}
19714520Snw141292 };
19724520Snw141292 #undef	gettext
19734520Snw141292 
19744520Snw141292 
19754520Snw141292 /*
19764520Snw141292  * Get description of status code
19774520Snw141292  *
19784520Snw141292  * Input:
19794520Snw141292  * status - Status code returned by libidmap API call
19804520Snw141292  *
19814520Snw141292  * Return Value:
19824520Snw141292  * human-readable localized description of idmap_stat
19834520Snw141292  */
19844520Snw141292 /* ARGSUSED */
19854520Snw141292 const char *
19865696Snw141292 idmap_stat2string(idmap_handle_t *handle, idmap_stat status)
19875696Snw141292 {
19884520Snw141292 	int i;
19894520Snw141292 
19904520Snw141292 	for (i = 0; stattable[i].msg; i++) {
19914520Snw141292 		if (stattable[i].retcode == status)
19924526Sbaban 			return (gettext(stattable[i].msg));
19934520Snw141292 	}
19944520Snw141292 	return (gettext("Unknown error"));
19954520Snw141292 }
19964520Snw141292 
19974520Snw141292 
19984520Snw141292 static int
19995696Snw141292 idmap_stat2errno(idmap_stat stat)
20005696Snw141292 {
20014520Snw141292 	int i;
20024520Snw141292 	for (i = 0; stattable[i].msg; i++) {
20034520Snw141292 		if (stattable[i].retcode == stat)
20044520Snw141292 			return (stattable[i].errnum);
20054520Snw141292 	}
20064520Snw141292 	return (EINVAL);
20074520Snw141292 }
20084520Snw141292 
20094520Snw141292 
20104520Snw141292 /*
20114520Snw141292  * Get status code from string
20124520Snw141292  */
20134520Snw141292 idmap_stat
20145696Snw141292 idmap_string2stat(const char *str)
20155696Snw141292 {
20164520Snw141292 	if (str == NULL)
20174520Snw141292 		return (IDMAP_ERR_INTERNAL);
20184520Snw141292 
20194520Snw141292 #define	return_cmp(a) \
20204520Snw141292 	if (0 == strcmp(str, "IDMAP_ERR_" #a)) \
20214520Snw141292 		return (IDMAP_ERR_ ## a);
20224520Snw141292 
20234520Snw141292 	return_cmp(OTHER);
20244520Snw141292 	return_cmp(INTERNAL);
20254520Snw141292 	return_cmp(MEMORY);
20264520Snw141292 	return_cmp(NORESULT);
20274520Snw141292 	return_cmp(NOTUSER);
20284520Snw141292 	return_cmp(NOTGROUP);
20294520Snw141292 	return_cmp(NOTSUPPORTED);
20304520Snw141292 	return_cmp(W2U_NAMERULE);
20314520Snw141292 	return_cmp(U2W_NAMERULE);
20324520Snw141292 	return_cmp(CACHE);
20334520Snw141292 	return_cmp(DB);
20344520Snw141292 	return_cmp(ARG);
20354520Snw141292 	return_cmp(SID);
20364520Snw141292 	return_cmp(IDTYPE);
20374520Snw141292 	return_cmp(RPC_HANDLE);
20384520Snw141292 	return_cmp(RPC);
20394520Snw141292 	return_cmp(CLIENT_HANDLE);
20404520Snw141292 	return_cmp(BUSY);
20414520Snw141292 	return_cmp(PERMISSION_DENIED);
20424520Snw141292 	return_cmp(NOMAPPING);
20434520Snw141292 	return_cmp(NEW_ID_ALLOC_REQD);
20444520Snw141292 	return_cmp(DOMAIN);
20454520Snw141292 	return_cmp(SECURITY);
20464520Snw141292 	return_cmp(NOTFOUND);
20474520Snw141292 	return_cmp(DOMAIN_NOTFOUND);
20484520Snw141292 	return_cmp(MEMORY);
20494520Snw141292 	return_cmp(UPDATE_NOTALLOWED);
20504520Snw141292 	return_cmp(CFG);
20514520Snw141292 	return_cmp(CFG_CHANGE);
20524520Snw141292 	return_cmp(NOTMAPPED_WELLKNOWN);
20534520Snw141292 	return_cmp(RETRIABLE_NET_ERR);
20544864Sbaban 	return_cmp(W2U_NAMERULE_CONFLICT);
20554864Sbaban 	return_cmp(U2W_NAMERULE_CONFLICT);
2056*6616Sdm199847 	return_cmp(BAD_UTF8);
2057*6616Sdm199847 	return_cmp(NONEGENERATED);
2058*6616Sdm199847 	return_cmp(PROP_UNKNOWN);
2059*6616Sdm199847 	return_cmp(NS_LDAP_CFG);
2060*6616Sdm199847 	return_cmp(NS_LDAP_PARTIAL);
2061*6616Sdm199847 	return_cmp(NS_LDAP_OP_FAILED);
2062*6616Sdm199847 	return_cmp(NS_LDAP_BAD_WINNAME);
20634520Snw141292 #undef return_cmp
20644520Snw141292 
20654520Snw141292 	return (IDMAP_ERR_OTHER);
20664520Snw141292 }
20674520Snw141292 
20684520Snw141292 
20694520Snw141292 /*
20704520Snw141292  * Map the given status to one that can be returned by the protocol
20714520Snw141292  */
20724520Snw141292 idmap_stat
20735696Snw141292 idmap_stat4prot(idmap_stat status)
20745696Snw141292 {
20754520Snw141292 	switch (status) {
20764520Snw141292 	case IDMAP_ERR_MEMORY:
20774520Snw141292 	case IDMAP_ERR_CACHE:
20784520Snw141292 		return (IDMAP_ERR_INTERNAL);
20794520Snw141292 	}
20804520Snw141292 	return (status);
20814520Snw141292 }
20825043Sbaban 
20835043Sbaban 
20845043Sbaban /*
20855247Sbaban  * This is a convenience routine which duplicates a string after
20865247Sbaban  * checking for NULL pointers. This function will return success if
20875247Sbaban  * either the 'to' OR 'from' pointers are NULL.
20885064Sdm199847  */
20895064Sdm199847 static idmap_stat
20905696Snw141292 idmap_strdupnull(char **to, const char *from)
20915696Snw141292 {
20925247Sbaban 	if (to == NULL)
20935247Sbaban 		return (IDMAP_SUCCESS);
20945247Sbaban 
20955064Sdm199847 	if (from == NULL || *from == '\0') {
20965064Sdm199847 		*to = NULL;
20975064Sdm199847 		return (IDMAP_SUCCESS);
20985064Sdm199847 	}
20995064Sdm199847 
21005064Sdm199847 	*to = strdup(from);
21015064Sdm199847 	if (*to == NULL)
21025064Sdm199847 		return (IDMAP_ERR_MEMORY);
21035064Sdm199847 	return (IDMAP_SUCCESS);
21045064Sdm199847 }
21055064Sdm199847 
21066386Sjp151216 
21075064Sdm199847 idmap_stat
21085696Snw141292 idmap_namerule_cpy(idmap_namerule *to, idmap_namerule *from)
21095696Snw141292 {
21105064Sdm199847 	idmap_stat retval;
21115064Sdm199847 
21126386Sjp151216 	if (to == NULL)
21136386Sjp151216 		return (IDMAP_SUCCESS);
21146386Sjp151216 
21155064Sdm199847 	(void) memcpy(to, from, sizeof (idmap_namerule));
21166386Sjp151216 	to->windomain = NULL;
21176386Sjp151216 	to->winname = NULL;
21186386Sjp151216 	to->unixname = NULL;
21195064Sdm199847 
21205064Sdm199847 	retval = idmap_strdupnull(&to->windomain, from->windomain);
21215064Sdm199847 	if (retval != IDMAP_SUCCESS)
21225064Sdm199847 		return (retval);
21235064Sdm199847 
21245064Sdm199847 	retval = idmap_strdupnull(&to->winname, from->winname);
21256386Sjp151216 	if (retval != IDMAP_SUCCESS) {
21266386Sjp151216 		free(to->windomain);
21276386Sjp151216 		to->windomain = NULL;
21286386Sjp151216 		return (retval);
21296386Sjp151216 	}
21306386Sjp151216 
21316386Sjp151216 	retval = idmap_strdupnull(&to->unixname, from->unixname);
21326386Sjp151216 	if (retval != IDMAP_SUCCESS) {
21336386Sjp151216 		free(to->windomain);
21346386Sjp151216 		to->windomain = NULL;
21356386Sjp151216 		free(to->winname);
21366386Sjp151216 		to->winname = NULL;
21376386Sjp151216 		return (retval);
21386386Sjp151216 	}
21396386Sjp151216 
21406386Sjp151216 	return (retval);
21416386Sjp151216 }
21426386Sjp151216 
21436386Sjp151216 
21446386Sjp151216 static
21456386Sjp151216 idmap_stat
21466386Sjp151216 idmap_how_ds_based_cpy(idmap_how_ds_based *to, idmap_how_ds_based *from)
21476386Sjp151216 {
21486386Sjp151216 	idmap_stat retval;
21496386Sjp151216 
21506386Sjp151216 	if (to == NULL)
21516386Sjp151216 		return (IDMAP_SUCCESS);
21526386Sjp151216 
21536386Sjp151216 	retval = idmap_strdupnull(&to->dn, from->dn);
21545064Sdm199847 	if (retval != IDMAP_SUCCESS)
21555064Sdm199847 		return (retval);
21565064Sdm199847 
21576386Sjp151216 	retval = idmap_strdupnull(&to->attr, from->attr);
21586386Sjp151216 	if (retval != IDMAP_SUCCESS) {
21596386Sjp151216 		free(to->dn);
21606386Sjp151216 		to->dn = NULL;
21616386Sjp151216 		return (retval);
21626386Sjp151216 	}
21636386Sjp151216 
21646386Sjp151216 	retval = idmap_strdupnull(&to->value, from->value);
21656386Sjp151216 	if (retval != IDMAP_SUCCESS) {
21666386Sjp151216 		free(to->dn);
21676386Sjp151216 		to->dn = NULL;
21686386Sjp151216 		free(to->attr);
21696386Sjp151216 		to->attr = NULL;
21706386Sjp151216 		return (retval);
21716386Sjp151216 	}
21725064Sdm199847 
21735064Sdm199847 	return (retval);
21745064Sdm199847 }
21755064Sdm199847 
21765064Sdm199847 
21776386Sjp151216 idmap_stat
21786386Sjp151216 idmap_info_cpy(idmap_info *to, idmap_info *from)
21796386Sjp151216 {
21806386Sjp151216 	idmap_stat retval = IDMAP_SUCCESS;
21816386Sjp151216 
21826386Sjp151216 	if (to == NULL)
21836386Sjp151216 		return (IDMAP_SUCCESS);
21846386Sjp151216 
21856386Sjp151216 	(void) memset(to, 0, sizeof (idmap_info));
21866386Sjp151216 
21876386Sjp151216 	to->src = from->src;
21886386Sjp151216 	to->how.map_type = from->how.map_type;
21896386Sjp151216 	switch (to->how.map_type) {
21906386Sjp151216 	case IDMAP_MAP_TYPE_DS_AD:
21916386Sjp151216 		retval = idmap_how_ds_based_cpy(&to->how.idmap_how_u.ad,
21926386Sjp151216 		    &from->how.idmap_how_u.ad);
21936386Sjp151216 		break;
21946386Sjp151216 
21956386Sjp151216 	case IDMAP_MAP_TYPE_DS_NLDAP:
21966386Sjp151216 		retval = idmap_how_ds_based_cpy(&to->how.idmap_how_u.nldap,
21976386Sjp151216 		    &from->how.idmap_how_u.nldap);
21986386Sjp151216 		break;
21996386Sjp151216 
22006386Sjp151216 	case IDMAP_MAP_TYPE_RULE_BASED:
22016386Sjp151216 		retval = idmap_namerule_cpy(&to->how.idmap_how_u.rule,
22026386Sjp151216 		    &from->how.idmap_how_u.rule);
22036386Sjp151216 		break;
22046386Sjp151216 
22056386Sjp151216 	case IDMAP_MAP_TYPE_EPHEMERAL:
22066386Sjp151216 		break;
22076386Sjp151216 
22086386Sjp151216 	case IDMAP_MAP_TYPE_LOCAL_SID:
22096386Sjp151216 		break;
22106386Sjp151216 
22116386Sjp151216 	case IDMAP_MAP_TYPE_KNOWN_SID:
22126386Sjp151216 		break;
22136386Sjp151216 	}
22146386Sjp151216 	return (retval);
22156386Sjp151216 }
22166386Sjp151216 
22176386Sjp151216 
22186386Sjp151216 /*
22196386Sjp151216  * This routine is similar to idmap_info_cpy, but the strings
22206386Sjp151216  * are moved from the "from" info to the "to" info.
22216386Sjp151216  * This routine is equivelent of:
22226386Sjp151216  *
22236386Sjp151216  *	idmap_info_cpy(to,from);
22246386Sjp151216  *	idmap_info_free(from);
22256386Sjp151216  */
22266386Sjp151216 idmap_stat
22276386Sjp151216 idmap_info_mov(idmap_info *to, idmap_info *from)
22286386Sjp151216 {
22296386Sjp151216 	idmap_stat retval = IDMAP_SUCCESS;
22306386Sjp151216 
22316386Sjp151216 	if (to == NULL) {
22326386Sjp151216 		idmap_info_free(from);
22336386Sjp151216 		return (IDMAP_SUCCESS);
22346386Sjp151216 	}
22356386Sjp151216 	(void) memcpy(to, from, sizeof (idmap_info));
22366386Sjp151216 
22376386Sjp151216 	(void) memset(from, 0, sizeof (idmap_info));
22386386Sjp151216 
22396386Sjp151216 	return (retval);
22406386Sjp151216 }
22416386Sjp151216 
22426386Sjp151216 
22436386Sjp151216 void
22446386Sjp151216 idmap_info_free(idmap_info *info)
22456386Sjp151216 {
22466386Sjp151216 	idmap_how *how;
22476386Sjp151216 
22486386Sjp151216 	if (info == NULL)
22496386Sjp151216 		return;
22506386Sjp151216 
22516386Sjp151216 	how = &info->how;
22526386Sjp151216 	switch (how->map_type) {
22536386Sjp151216 	case IDMAP_MAP_TYPE_DS_AD:
22546386Sjp151216 		free(how->idmap_how_u.ad.dn);
22556386Sjp151216 		how->idmap_how_u.ad.dn = NULL;
22566386Sjp151216 		free(how->idmap_how_u.ad.attr);
22576386Sjp151216 		how->idmap_how_u.ad.attr = NULL;
22586386Sjp151216 		free(how->idmap_how_u.ad.value);
22596386Sjp151216 		how->idmap_how_u.ad.value = NULL;
22606386Sjp151216 		break;
22616386Sjp151216 
22626386Sjp151216 	case IDMAP_MAP_TYPE_DS_NLDAP:
22636386Sjp151216 		free(how->idmap_how_u.nldap.dn);
22646386Sjp151216 		how->idmap_how_u.nldap.dn = NULL;
22656386Sjp151216 		free(how->idmap_how_u.nldap.attr);
22666386Sjp151216 		how->idmap_how_u.nldap.attr = NULL;
22676386Sjp151216 		free(how->idmap_how_u.nldap.value);
22686386Sjp151216 		how->idmap_how_u.nldap.value = NULL;
22696386Sjp151216 		break;
22706386Sjp151216 
22716386Sjp151216 	case IDMAP_MAP_TYPE_RULE_BASED:
22726386Sjp151216 		free(how->idmap_how_u.rule.windomain);
22736386Sjp151216 		how->idmap_how_u.rule.windomain = NULL;
22746386Sjp151216 		free(how->idmap_how_u.rule.winname);
22756386Sjp151216 		how->idmap_how_u.rule.winname = NULL;
22766386Sjp151216 		free(how->idmap_how_u.rule.unixname);
22776386Sjp151216 		how->idmap_how_u.rule.unixname = NULL;
22786386Sjp151216 		break;
22796386Sjp151216 
22806386Sjp151216 	case IDMAP_MAP_TYPE_EPHEMERAL:
22816386Sjp151216 		break;
22826386Sjp151216 
22836386Sjp151216 	case IDMAP_MAP_TYPE_LOCAL_SID:
22846386Sjp151216 		break;
22856386Sjp151216 	}
22866386Sjp151216 	how->map_type = IDMAP_MAP_TYPE_UNKNOWN;
22876386Sjp151216 	info->src = IDMAP_MAP_SRC_UNKNOWN;
22886386Sjp151216 }
22896386Sjp151216 
22906386Sjp151216 
22915064Sdm199847 /*
22925043Sbaban  * Get uid given Windows name
22935043Sbaban  */
22945043Sbaban idmap_stat
22955696Snw141292 idmap_getuidbywinname(const char *name, const char *domain, uid_t *uid)
22965696Snw141292 {
22975043Sbaban 	idmap_handle_t	*ih;
22985043Sbaban 	idmap_retcode	rc;
22995696Snw141292 	int		is_user = 1;
23005696Snw141292 	int		is_wuser = -1;
23015043Sbaban 
23025043Sbaban 	if (uid == NULL)
23035043Sbaban 		return (IDMAP_ERR_ARG);
23045043Sbaban 
23055043Sbaban 	/* Get mapping */
23065043Sbaban 	if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS)
23075043Sbaban 		return (rc);
23085043Sbaban 	rc = idmap_get_w2u_mapping(ih, NULL, NULL, name, domain, 0,
23096386Sjp151216 	    &is_user, &is_wuser, uid, NULL, NULL, NULL);
23105043Sbaban 	(void) idmap_fini(ih);
23115043Sbaban 
23125043Sbaban 	/*
23135043Sbaban 	 * XXX Until we have diagonal mapping support, check if
23145043Sbaban 	 * the given name belongs to a user
23155043Sbaban 	 */
23165043Sbaban 	if (rc == IDMAP_SUCCESS && !is_user)
23175043Sbaban 		return (IDMAP_ERR_NOTUSER);
23185043Sbaban 	return (rc);
23195043Sbaban }
23205043Sbaban 
23215043Sbaban 
23225043Sbaban /*
23235043Sbaban  * Get gid given Windows name
23245043Sbaban  */
23255043Sbaban idmap_stat
23265696Snw141292 idmap_getgidbywinname(const char *name, const char *domain, gid_t *gid)
23275696Snw141292 {
23285043Sbaban 	idmap_handle_t	*ih;
23295043Sbaban 	idmap_retcode	rc;
23305696Snw141292 	int		is_user = 0;
23315696Snw141292 	int		is_wuser = -1;
23325043Sbaban 
23335043Sbaban 	if (gid == NULL)
23345043Sbaban 		return (IDMAP_ERR_ARG);
23355043Sbaban 
23365043Sbaban 	/* Get mapping */
23375043Sbaban 	if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS)
23385043Sbaban 		return (rc);
23395043Sbaban 	rc = idmap_get_w2u_mapping(ih, NULL, NULL, name, domain, 0,
23406386Sjp151216 	    &is_user, &is_wuser, gid, NULL, NULL, NULL);
23415043Sbaban 	(void) idmap_fini(ih);
23425043Sbaban 
23435043Sbaban 	/*
23445043Sbaban 	 * XXX Until we have diagonal mapping support, check if
23455043Sbaban 	 * the given name belongs to a group
23465043Sbaban 	 */
23475043Sbaban 	if (rc == IDMAP_SUCCESS && is_user)
23485043Sbaban 		return (IDMAP_ERR_NOTGROUP);
23495043Sbaban 	return (rc);
23505043Sbaban }
23515043Sbaban 
23525043Sbaban 
23535043Sbaban /*
23545043Sbaban  * Get winname given pid
23555043Sbaban  */
23565043Sbaban static idmap_retcode
23575696Snw141292 idmap_getwinnamebypid(uid_t pid, int is_user, char **name, char **domain)
23585696Snw141292 {
23595043Sbaban 	idmap_handle_t	*ih;
23605043Sbaban 	idmap_retcode	rc;
23615043Sbaban 	int		len;
23625043Sbaban 	char		*winname, *windomain;
23635043Sbaban 
23645043Sbaban 	if (name == NULL)
23655043Sbaban 		return (IDMAP_ERR_ARG);
23665043Sbaban 
23675043Sbaban 	/* Get mapping */
23685043Sbaban 	if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS)
23695043Sbaban 		return (rc);
23705696Snw141292 	rc = idmap_get_u2w_mapping(ih, &pid, NULL, 0, is_user, NULL, NULL,
23716386Sjp151216 	    NULL, &winname, &windomain, NULL, NULL);
23725043Sbaban 	(void) idmap_fini(ih);
23735043Sbaban 
23745043Sbaban 	/* Return on error */
23755043Sbaban 	if (rc != IDMAP_SUCCESS)
23765043Sbaban 		return (rc);
23775043Sbaban 
23785043Sbaban 	/*
23795043Sbaban 	 * The given PID may have been mapped to a locally
23805043Sbaban 	 * generated SID in which case there isn't any
23815043Sbaban 	 * Windows name
23825043Sbaban 	 */
23835043Sbaban 	if (winname == NULL || windomain == NULL) {
23845043Sbaban 		idmap_free(winname);
23855043Sbaban 		idmap_free(windomain);
23865043Sbaban 		return (IDMAP_ERR_NORESULT);
23875043Sbaban 	}
23885043Sbaban 
23895043Sbaban 	if (domain != NULL) {
23905043Sbaban 		*name = winname;
23915043Sbaban 		*domain = windomain;
23925043Sbaban 	} else {
23935043Sbaban 		len = strlen(winname) + strlen(windomain) + 2;
23945043Sbaban 		if ((*name = malloc(len)) != NULL)
23955043Sbaban 			(void) snprintf(*name, len, "%s@%s", winname,
23965043Sbaban 			    windomain);
23975043Sbaban 		else
23985043Sbaban 			rc = IDMAP_ERR_MEMORY;
23995043Sbaban 		idmap_free(winname);
24005043Sbaban 		idmap_free(windomain);
24015043Sbaban 	}
24025043Sbaban 	return (rc);
24035043Sbaban }
24045043Sbaban 
24055043Sbaban 
24065043Sbaban /*
24075043Sbaban  * Get winname given uid
24085043Sbaban  */
24095043Sbaban idmap_stat
24105696Snw141292 idmap_getwinnamebyuid(uid_t uid, char **name, char **domain)
24115696Snw141292 {
24125043Sbaban 	return (idmap_getwinnamebypid(uid, 1, name, domain));
24135043Sbaban }
24145043Sbaban 
24155043Sbaban 
24165043Sbaban /*
24175043Sbaban  * Get winname given gid
24185043Sbaban  */
24195043Sbaban idmap_stat
24205696Snw141292 idmap_getwinnamebygid(gid_t gid, char **name, char **domain)
24215696Snw141292 {
24225043Sbaban 	return (idmap_getwinnamebypid(gid, 0, name, domain));
24235043Sbaban }
2424*6616Sdm199847 
2425*6616Sdm199847 
2426*6616Sdm199847 /* printflike */
2427*6616Sdm199847 void
2428*6616Sdm199847 idmapdlog(int pri, const char *format, ...) {
2429*6616Sdm199847 	va_list args;
2430*6616Sdm199847 
2431*6616Sdm199847 	va_start(args, format);
2432*6616Sdm199847 	if (pri <= logstate.max_pri) {
2433*6616Sdm199847 		(void) vfprintf(stderr, format, args);
2434*6616Sdm199847 		(void) fprintf(stderr, "\n");
2435*6616Sdm199847 	}
2436*6616Sdm199847 
2437*6616Sdm199847 	/*
2438*6616Sdm199847 	 * We don't want to fill up the logs with useless messages when
2439*6616Sdm199847 	 * we're degraded, but we still want to log.
2440*6616Sdm199847 	 */
2441*6616Sdm199847 	if (logstate.degraded)
2442*6616Sdm199847 		pri = LOG_DEBUG;
2443*6616Sdm199847 
2444*6616Sdm199847 	if (logstate.write_syslog)
2445*6616Sdm199847 		(void) vsyslog(pri, format, args);
2446*6616Sdm199847 	va_end(args);
2447*6616Sdm199847 }
2448*6616Sdm199847 
2449*6616Sdm199847 void
2450*6616Sdm199847 idmap_log_stderr(int pri)
2451*6616Sdm199847 {
2452*6616Sdm199847 	logstate.max_pri = pri;
2453*6616Sdm199847 }
2454*6616Sdm199847 
2455*6616Sdm199847 void
2456*6616Sdm199847 idmap_log_syslog(bool_t what)
2457*6616Sdm199847 {
2458*6616Sdm199847 	logstate.write_syslog = what;
2459*6616Sdm199847 }
2460*6616Sdm199847 
2461*6616Sdm199847 void
2462*6616Sdm199847 idmap_log_degraded(bool_t what)
2463*6616Sdm199847 {
2464*6616Sdm199847 	logstate.degraded = what;
2465*6616Sdm199847 }
2466