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 /*
224520Snw141292  * Copyright 2007 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>
334520Snw141292 #include <inttypes.h>
344520Snw141292 #include <errno.h>
354520Snw141292 #include <strings.h>
364520Snw141292 #include <ctype.h>
374520Snw141292 #include <sys/param.h>
384520Snw141292 #include <sys/types.h>
394520Snw141292 #include <sys/stat.h>
404520Snw141292 #include <dlfcn.h>
414520Snw141292 #include <libintl.h>
424520Snw141292 #include "idmap_impl.h"
434520Snw141292 
444520Snw141292 static struct timeval TIMEOUT = { 25, 0 };
454520Snw141292 
464520Snw141292 static int idmap_stat2errno(idmap_stat);
47*5064Sdm199847 static idmap_stat idmap_strdupnull(char **, const char *);
484520Snw141292 
494520Snw141292 #define	__ITER_CREATE(itera, argu, handl, ityp)\
504520Snw141292 	if (handl == NULL) {\
514520Snw141292 		errno = EINVAL;\
524520Snw141292 		return (IDMAP_ERR_ARG);\
534520Snw141292 	}\
544520Snw141292 	itera = calloc(1, sizeof (*itera));\
554520Snw141292 	if (itera == NULL) {\
564520Snw141292 		errno = ENOMEM;\
574520Snw141292 		return (IDMAP_ERR_MEMORY);\
584520Snw141292 	}\
594520Snw141292 	argu = calloc(1, sizeof (*argu));\
604520Snw141292 	if (argu == NULL) {\
614520Snw141292 		free(itera);\
624520Snw141292 		errno = ENOMEM;\
634520Snw141292 		return (IDMAP_ERR_MEMORY);\
644520Snw141292 	}\
654520Snw141292 	itera->ih = handl;\
664520Snw141292 	itera->type = ityp;\
674520Snw141292 	itera->retcode = IDMAP_NEXT;\
684520Snw141292 	itera->limit = 1024;\
694520Snw141292 	itera->arg = argu;
704520Snw141292 
714520Snw141292 
724520Snw141292 #define	__ITER_ERR_RETURN(itera, argu, xdr_argu, iretcod)\
734520Snw141292 	if (argu) {\
744520Snw141292 		xdr_free(xdr_argu, (caddr_t)argu);\
754520Snw141292 		free(argu);\
764520Snw141292 	}\
774520Snw141292 	if (itera)\
784520Snw141292 		free(itera);\
794520Snw141292 	return (iretcod);
804520Snw141292 
814520Snw141292 
824520Snw141292 #define	__ITER_CHECK(itera, ityp)\
834520Snw141292 	if (itera == NULL) {\
844520Snw141292 		errno = EINVAL;\
854520Snw141292 		return (IDMAP_ERR_ARG);\
864520Snw141292 	}\
874520Snw141292 	if (itera->type != ityp) {\
884520Snw141292 		errno = EINVAL;\
894520Snw141292 		return (IDMAP_ERR_ARG);\
904520Snw141292 	}
914520Snw141292 
92*5064Sdm199847 #define	EMPTY_STRING(str)	(str == NULL || *str == '\0')
934520Snw141292 
944520Snw141292 /*
954520Snw141292  * Free memory allocated by libidmap API
964520Snw141292  *
974520Snw141292  * Input:
984520Snw141292  * ptr - memory to be freed
994520Snw141292  */
1004520Snw141292 void
1014520Snw141292 idmap_free(void *ptr) {
1024520Snw141292 	free(ptr);
1034520Snw141292 }
1044520Snw141292 
1054520Snw141292 
1064520Snw141292 /*
1074520Snw141292  * Create and Initialize idmap client handle for rpc/doors
1084520Snw141292  *
1094520Snw141292  * Output:
1104520Snw141292  * handle - idmap handle
1114520Snw141292  */
1124520Snw141292 idmap_stat
1134520Snw141292 idmap_init(idmap_handle_t **handle) {
1144520Snw141292 	CLIENT			*clnt = NULL;
1154520Snw141292 	struct idmap_handle	*hptr;
1164520Snw141292 
1174520Snw141292 	*handle = NULL;
1184520Snw141292 	hptr = (struct idmap_handle *)calloc(1, sizeof (*hptr));
1194520Snw141292 	if (hptr == NULL)
1204520Snw141292 		return (IDMAP_ERR_MEMORY);
1214520Snw141292 
1224520Snw141292 	clnt = clnt_door_create(IDMAP_PROG, IDMAP_V1, 0);
1234520Snw141292 	if (clnt == NULL) {
1244520Snw141292 		free(hptr);
1254520Snw141292 		return (IDMAP_ERR_RPC);
1264520Snw141292 	}
1274520Snw141292 	hptr->type = _IDMAP_HANDLE_RPC_DOORS;
1284520Snw141292 	hptr->privhandle = clnt;
1294520Snw141292 	*handle = hptr;
1304520Snw141292 	return (IDMAP_SUCCESS);
1314520Snw141292 }
1324520Snw141292 
1334520Snw141292 
1344520Snw141292 /*
1354520Snw141292  * Finalize idmap handle
1364520Snw141292  *
1374520Snw141292  * Input:
1384520Snw141292  * handle - idmap handle
1394520Snw141292  */
1404520Snw141292 idmap_stat
1414520Snw141292 idmap_fini(idmap_handle_t *handle) {
1424520Snw141292 	CLIENT			*clnt;
1434520Snw141292 	struct idmap_handle	*hptr;
1444520Snw141292 
1454520Snw141292 	if (handle == NULL)
1464520Snw141292 		return (IDMAP_SUCCESS);
1474520Snw141292 
1484520Snw141292 	hptr = (struct idmap_handle *)handle;
1494520Snw141292 
1504520Snw141292 	switch (hptr->type) {
1514520Snw141292 	case _IDMAP_HANDLE_RPC_DOORS:
1524520Snw141292 		clnt = (CLIENT *)hptr->privhandle;
1534520Snw141292 		if (clnt) {
1544520Snw141292 			if (clnt->cl_auth)
1554520Snw141292 				auth_destroy(clnt->cl_auth);
1564520Snw141292 			clnt_destroy(clnt);
1574520Snw141292 		}
1584520Snw141292 		break;
1594520Snw141292 	default:
1604520Snw141292 		break;
1614520Snw141292 	}
1624520Snw141292 	free(hptr);
1634520Snw141292 	return (IDMAP_SUCCESS);
1644520Snw141292 }
1654520Snw141292 
1664520Snw141292 
1674520Snw141292 
1684520Snw141292 /*
1694520Snw141292  * Create/Initialize handle for updates
1704520Snw141292  *
1714520Snw141292  * Output:
1724520Snw141292  * udthandle - update handle
1734520Snw141292  */
1744520Snw141292 idmap_stat
1754520Snw141292 idmap_udt_create(idmap_handle_t *handle, idmap_udt_handle_t **udthandle) {
1764520Snw141292 	idmap_udt_handle_t	*tmp;
1774520Snw141292 
1784520Snw141292 	if (handle == NULL || udthandle == NULL) {
1794520Snw141292 		errno = EINVAL;
1804520Snw141292 		return (IDMAP_ERR_ARG);
1814520Snw141292 	}
1824520Snw141292 	if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
1834520Snw141292 		errno = ENOMEM;
1844520Snw141292 		return (IDMAP_ERR_MEMORY);
1854520Snw141292 	}
1864520Snw141292 
1874520Snw141292 	tmp->ih = handle;
1884520Snw141292 	*udthandle = tmp;
1894520Snw141292 	return (IDMAP_SUCCESS);
1904520Snw141292 }
1914520Snw141292 
1924520Snw141292 
1934520Snw141292 /*
1944520Snw141292  * All the updates specified by the update handle are committed
1954520Snw141292  * in a single transaction. i.e either all succeed or none.
1964520Snw141292  *
1974520Snw141292  * Input:
1984520Snw141292  * udthandle - update handle with the update requests
1994520Snw141292  *
2004520Snw141292  * Return value:
2014520Snw141292  * Status of the commit
2024520Snw141292  */
2034520Snw141292 idmap_stat
2044520Snw141292 idmap_udt_commit(idmap_udt_handle_t *udthandle) {
2054520Snw141292 	CLIENT			*clnt;
2064520Snw141292 	enum clnt_stat		clntstat;
207*5064Sdm199847 	idmap_update_res	res;
208*5064Sdm199847 	idmap_stat		retcode;
2094520Snw141292 
2104520Snw141292 	if (udthandle == NULL) {
2114520Snw141292 		errno = EINVAL;
2124520Snw141292 		return (IDMAP_ERR_ARG);
2134520Snw141292 	}
214*5064Sdm199847 
215*5064Sdm199847 	(void) memset(&res, 0, sizeof (res));
216*5064Sdm199847 
2174520Snw141292 	_IDMAP_GET_CLIENT_HANDLE(udthandle->ih, clnt);
2184520Snw141292 	clntstat = clnt_call(clnt, IDMAP_UPDATE,
2194520Snw141292 		(xdrproc_t)xdr_idmap_update_batch, (caddr_t)&udthandle->batch,
220*5064Sdm199847 		(xdrproc_t)xdr_idmap_update_res, (caddr_t)&res,
2214520Snw141292 		TIMEOUT);
2224644Sbaban 
223*5064Sdm199847 	if (clntstat != RPC_SUCCESS) {
224*5064Sdm199847 		retcode = _idmap_rpc2stat(clnt);
225*5064Sdm199847 		goto out;
226*5064Sdm199847 	}
227*5064Sdm199847 
228*5064Sdm199847 	retcode = udthandle->commit_stat = res.retcode;
229*5064Sdm199847 	udthandle->error_index = res.error_index;
230*5064Sdm199847 
231*5064Sdm199847 	if (retcode != IDMAP_SUCCESS) {
232*5064Sdm199847 
233*5064Sdm199847 		if (udthandle->error_index < 0)
234*5064Sdm199847 			goto out;
235*5064Sdm199847 
236*5064Sdm199847 		retcode = idmap_namerule_cpy(&udthandle->error_rule,
237*5064Sdm199847 		    &res.error_rule);
238*5064Sdm199847 		if (retcode != IDMAP_SUCCESS) {
239*5064Sdm199847 			udthandle->error_index = -2;
240*5064Sdm199847 			goto out;
241*5064Sdm199847 		}
242*5064Sdm199847 
243*5064Sdm199847 		retcode = idmap_namerule_cpy(&udthandle->conflict_rule,
244*5064Sdm199847 		    &res.conflict_rule);
245*5064Sdm199847 		if (retcode != IDMAP_SUCCESS) {
246*5064Sdm199847 			udthandle->error_index = -2;
247*5064Sdm199847 			goto out;
248*5064Sdm199847 		}
249*5064Sdm199847 	}
250*5064Sdm199847 
251*5064Sdm199847 	retcode = res.retcode;
252*5064Sdm199847 
253*5064Sdm199847 
254*5064Sdm199847 out:
2554644Sbaban 	/* reset handle so that it can be used again */
256*5064Sdm199847 	if (retcode == IDMAP_SUCCESS) {
257*5064Sdm199847 		_IDMAP_RESET_UDT_HANDLE(udthandle);
258*5064Sdm199847 	}
259*5064Sdm199847 
260*5064Sdm199847 	(void) xdr_free(xdr_idmap_update_res, (caddr_t)&res);
261*5064Sdm199847 	errno = idmap_stat2errno(retcode);
262*5064Sdm199847 	return (retcode);
263*5064Sdm199847 }
264*5064Sdm199847 
265*5064Sdm199847 
266*5064Sdm199847 static void
267*5064Sdm199847 idmap_namerule_parts_clear(char **windomain, char **winname,
268*5064Sdm199847     char **unixname, boolean_t *is_user, boolean_t *is_nt4,
269*5064Sdm199847     int *direction) {
270*5064Sdm199847 	if (windomain)
271*5064Sdm199847 		*windomain = NULL;
272*5064Sdm199847 	if (winname)
273*5064Sdm199847 		*winname = NULL;
274*5064Sdm199847 	if (unixname)
275*5064Sdm199847 		*unixname = NULL;
276*5064Sdm199847 
277*5064Sdm199847 	if (is_nt4)
278*5064Sdm199847 		*is_nt4 = 0;
279*5064Sdm199847 	if (is_user)
280*5064Sdm199847 		*is_user = -1;
281*5064Sdm199847 	if (direction)
282*5064Sdm199847 		*direction = IDMAP_DIRECTION_UNDEF;
283*5064Sdm199847 }
284*5064Sdm199847 
285*5064Sdm199847 static idmap_stat
286*5064Sdm199847 idmap_namerule2parts(idmap_namerule	*rule,
287*5064Sdm199847     char **windomain, char **winname,
288*5064Sdm199847     char **unixname, boolean_t *is_user, boolean_t *is_nt4,
289*5064Sdm199847     int *direction) {
290*5064Sdm199847 	idmap_stat retcode;
291*5064Sdm199847 
292*5064Sdm199847 	if (EMPTY_STRING(rule->winname) && EMPTY_STRING(rule->unixname))
293*5064Sdm199847 		return (IDMAP_ERR_NORESULT);
294*5064Sdm199847 
295*5064Sdm199847 
296*5064Sdm199847 	retcode = idmap_strdupnull(windomain, rule->windomain);
297*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
298*5064Sdm199847 		goto errout;
299*5064Sdm199847 
300*5064Sdm199847 	retcode = idmap_strdupnull(winname, rule->winname);
301*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
302*5064Sdm199847 		goto errout;
303*5064Sdm199847 
304*5064Sdm199847 	retcode = idmap_strdupnull(unixname, rule->unixname);
305*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
306*5064Sdm199847 		goto errout;
307*5064Sdm199847 
308*5064Sdm199847 
309*5064Sdm199847 	if (is_user)
310*5064Sdm199847 		*is_user = rule->is_user;
311*5064Sdm199847 	if (is_nt4)
312*5064Sdm199847 		*is_nt4 = rule->is_nt4;
313*5064Sdm199847 	if (direction)
314*5064Sdm199847 		*direction = rule->direction;
315*5064Sdm199847 
316*5064Sdm199847 
317*5064Sdm199847 	return (IDMAP_SUCCESS);
3184644Sbaban 
319*5064Sdm199847 errout:
320*5064Sdm199847 	if (windomain && *windomain)
321*5064Sdm199847 		free(*windomain);
322*5064Sdm199847 	if (winname && *winname)
323*5064Sdm199847 		free(*winname);
324*5064Sdm199847 	if (unixname && *unixname)
325*5064Sdm199847 		free(*unixname);
326*5064Sdm199847 
327*5064Sdm199847 	idmap_namerule_parts_clear(windomain, winname,
328*5064Sdm199847 	    unixname, is_user, is_nt4, direction);
329*5064Sdm199847 
3304520Snw141292 	return (retcode);
331*5064Sdm199847 
332*5064Sdm199847 }
333*5064Sdm199847 
334*5064Sdm199847 /*
335*5064Sdm199847  * Retrieve the index of the failed batch element. error_index == -1
336*5064Sdm199847  * indicates failure at the beginning, -2 at the end.
337*5064Sdm199847  *
338*5064Sdm199847  * If idmap_udt_commit didn't return error, the returned value is undefined.
339*5064Sdm199847  *
340*5064Sdm199847  * Return value:
341*5064Sdm199847  * IDMAP_SUCCESS
342*5064Sdm199847  */
343*5064Sdm199847 
344*5064Sdm199847 idmap_stat
345*5064Sdm199847 idmap_udt_get_error_index(idmap_udt_handle_t *udthandle,
346*5064Sdm199847     int64_t *error_index) {
347*5064Sdm199847 	if (error_index)
348*5064Sdm199847 		*error_index = udthandle->error_index;
349*5064Sdm199847 
350*5064Sdm199847 	return (IDMAP_SUCCESS);
351*5064Sdm199847 }
352*5064Sdm199847 
353*5064Sdm199847 
354*5064Sdm199847 /*
355*5064Sdm199847  * Retrieve the rule which caused the batch to fail. If
356*5064Sdm199847  * idmap_udt_commit didn't return error or if error_index is < 0, the
357*5064Sdm199847  * retrieved rule is undefined.
358*5064Sdm199847  *
359*5064Sdm199847  * Return value:
360*5064Sdm199847  * IDMAP_ERR_NORESULT if there is no error rule.
361*5064Sdm199847  * IDMAP_SUCCESS if the rule was obtained OK.
362*5064Sdm199847  * other error code (IDMAP_ERR_NOMEMORY etc)
363*5064Sdm199847  */
364*5064Sdm199847 
365*5064Sdm199847 idmap_stat
366*5064Sdm199847 idmap_udt_get_error_rule(idmap_udt_handle_t *udthandle,
367*5064Sdm199847     char **windomain, char **winname,
368*5064Sdm199847     char **unixname, boolean_t *is_user, boolean_t *is_nt4,
369*5064Sdm199847     int *direction) {
370*5064Sdm199847 	idmap_namerule_parts_clear(windomain, winname,
371*5064Sdm199847 	    unixname, is_user, is_nt4, direction);
372*5064Sdm199847 
373*5064Sdm199847 	if (udthandle->commit_stat == IDMAP_SUCCESS ||
374*5064Sdm199847 	    udthandle->error_index < 0)
375*5064Sdm199847 		return (IDMAP_ERR_NORESULT);
376*5064Sdm199847 
377*5064Sdm199847 	return (idmap_namerule2parts(
378*5064Sdm199847 			&udthandle->error_rule,
379*5064Sdm199847 			    windomain,
380*5064Sdm199847 			    winname,
381*5064Sdm199847 			    unixname,
382*5064Sdm199847 			    is_user,
383*5064Sdm199847 			    is_nt4,
384*5064Sdm199847 			    direction));
385*5064Sdm199847 }
386*5064Sdm199847 
387*5064Sdm199847 /*
388*5064Sdm199847  * Retrieve the rule with which there was a conflict. TODO: retrieve
389*5064Sdm199847  * the value.
390*5064Sdm199847  *
391*5064Sdm199847  * Return value:
392*5064Sdm199847  * IDMAP_ERR_NORESULT if there is no error rule.
393*5064Sdm199847  * IDMAP_SUCCESS if the rule was obtained OK.
394*5064Sdm199847  * other error code (IDMAP_ERR_NOMEMORY etc)
395*5064Sdm199847  */
396*5064Sdm199847 
397*5064Sdm199847 idmap_stat
398*5064Sdm199847 idmap_udt_get_conflict_rule(idmap_udt_handle_t *udthandle,
399*5064Sdm199847     char **windomain, char **winname,
400*5064Sdm199847     char **unixname, boolean_t *is_user, boolean_t *is_nt4,
401*5064Sdm199847     int *direction) {
402*5064Sdm199847 	idmap_namerule_parts_clear(windomain, winname,
403*5064Sdm199847 	    unixname, is_user, is_nt4, direction);
404*5064Sdm199847 
405*5064Sdm199847 	if (udthandle->commit_stat != IDMAP_ERR_W2U_NAMERULE_CONFLICT &&
406*5064Sdm199847 	    udthandle->commit_stat != IDMAP_ERR_U2W_NAMERULE_CONFLICT) {
407*5064Sdm199847 		    return (IDMAP_ERR_NORESULT);
408*5064Sdm199847 	}
409*5064Sdm199847 
410*5064Sdm199847 	return (idmap_namerule2parts(
411*5064Sdm199847 			&udthandle->conflict_rule,
412*5064Sdm199847 			    windomain,
413*5064Sdm199847 			    winname,
414*5064Sdm199847 			    unixname,
415*5064Sdm199847 			    is_user,
416*5064Sdm199847 			    is_nt4,
417*5064Sdm199847 			    direction));
4184520Snw141292 }
4194520Snw141292 
4204520Snw141292 
4214520Snw141292 /*
4224520Snw141292  * Destroy the update handle
4234520Snw141292  */
4244520Snw141292 void
4254520Snw141292 idmap_udt_destroy(idmap_udt_handle_t *udthandle) {
4264520Snw141292 	if (udthandle == NULL)
4274520Snw141292 		return;
4284520Snw141292 	(void) xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch);
429*5064Sdm199847 	(void) xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->error_rule);
430*5064Sdm199847 	(void) xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->conflict_rule);
4314520Snw141292 	free(udthandle);
4324520Snw141292 }
4334520Snw141292 
4344520Snw141292 
4354520Snw141292 idmap_stat
4364520Snw141292 idmap_udt_add_namerule(idmap_udt_handle_t *udthandle, const char *windomain,
4374520Snw141292 		boolean_t is_user, const char *winname, const char *unixname,
4384520Snw141292 		boolean_t is_nt4, int direction) {
4394520Snw141292 	idmap_retcode	retcode;
4404644Sbaban 	idmap_namerule	*rule = NULL;
4414520Snw141292 
4424644Sbaban 	retcode = _udt_extend_batch(udthandle);
4434520Snw141292 	if (retcode != IDMAP_SUCCESS)
4444520Snw141292 		goto errout;
4454520Snw141292 
4464520Snw141292 	rule = &udthandle->batch.
4474520Snw141292 		idmap_update_batch_val[udthandle->next].
4484520Snw141292 		idmap_update_op_u.rule;
4494520Snw141292 	rule->is_user = is_user;
4504520Snw141292 	rule->direction = direction;
4514520Snw141292 	rule->is_nt4 = is_nt4;
452*5064Sdm199847 
453*5064Sdm199847 	retcode = idmap_strdupnull(&rule->windomain, windomain);
454*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
455*5064Sdm199847 		goto errout;
456*5064Sdm199847 
457*5064Sdm199847 	retcode = idmap_strdupnull(&rule->winname, winname);
458*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
459*5064Sdm199847 		goto errout;
460*5064Sdm199847 
461*5064Sdm199847 	retcode = idmap_strdupnull(&rule->unixname, unixname);
462*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
463*5064Sdm199847 		goto errout;
4644644Sbaban 
4654644Sbaban 	udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
4664644Sbaban 	    OP_ADD_NAMERULE;
4674520Snw141292 	udthandle->next++;
4684520Snw141292 	return (IDMAP_SUCCESS);
4694520Snw141292 
4704520Snw141292 errout:
4714644Sbaban 	/* The batch should still be usable */
4724644Sbaban 	if (rule)
4734644Sbaban 		(void) xdr_free(xdr_idmap_namerule, (caddr_t)rule);
4744520Snw141292 	errno = idmap_stat2errno(retcode);
4754520Snw141292 	return (retcode);
4764520Snw141292 }
4774520Snw141292 
4784520Snw141292 
4794520Snw141292 /* ARGSUSED */
4804520Snw141292 idmap_stat
4814520Snw141292 idmap_udt_rm_namerule(idmap_udt_handle_t *udthandle, boolean_t is_user,
4824520Snw141292 		const char *windomain, const char *winname,
4834520Snw141292 		const char *unixname, int direction) {
4844520Snw141292 	idmap_retcode	retcode;
4854644Sbaban 	idmap_namerule	*rule = NULL;
4864520Snw141292 
4874644Sbaban 	retcode = _udt_extend_batch(udthandle);
4884520Snw141292 	if (retcode != IDMAP_SUCCESS)
4894520Snw141292 		goto errout;
4904520Snw141292 
4914520Snw141292 	rule = &udthandle->batch.
4924520Snw141292 		idmap_update_batch_val[udthandle->next].
4934520Snw141292 		idmap_update_op_u.rule;
4944520Snw141292 	rule->is_user = is_user;
4954520Snw141292 	rule->direction = direction;
496*5064Sdm199847 
497*5064Sdm199847 	retcode = idmap_strdupnull(&rule->windomain, windomain);
498*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
499*5064Sdm199847 		goto errout;
500*5064Sdm199847 
501*5064Sdm199847 	retcode = idmap_strdupnull(&rule->winname, winname);
502*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
503*5064Sdm199847 		goto errout;
504*5064Sdm199847 
505*5064Sdm199847 	retcode = idmap_strdupnull(&rule->unixname, unixname);
506*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
507*5064Sdm199847 		goto errout;
508*5064Sdm199847 
5094644Sbaban 	udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
5104644Sbaban 	    OP_RM_NAMERULE;
5114520Snw141292 	udthandle->next++;
5124520Snw141292 	return (IDMAP_SUCCESS);
5134520Snw141292 
5144520Snw141292 errout:
5154644Sbaban 	if (rule)
5164644Sbaban 		(void) xdr_free(xdr_idmap_namerule, (caddr_t)rule);
5174520Snw141292 	errno = idmap_stat2errno(retcode);
5184520Snw141292 	return (retcode);
5194520Snw141292 }
5204520Snw141292 
5214520Snw141292 
5224520Snw141292 /* ARGSUSED */
5234520Snw141292 idmap_stat
5244520Snw141292 idmap_udt_flush_namerules(idmap_udt_handle_t *udthandle, boolean_t is_user) {
5254520Snw141292 	idmap_retcode	retcode;
5264520Snw141292 
5274644Sbaban 	retcode = _udt_extend_batch(udthandle);
5284520Snw141292 	if (retcode != IDMAP_SUCCESS)
5294520Snw141292 		goto errout;
5304520Snw141292 
5314520Snw141292 	udthandle->batch.idmap_update_batch_val[udthandle->next].
5324520Snw141292 		idmap_update_op_u.is_user = is_user;
5334520Snw141292 
5344644Sbaban 	udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
5354644Sbaban 	    OP_FLUSH_NAMERULES;
5364520Snw141292 	udthandle->next++;
5374520Snw141292 	return (IDMAP_SUCCESS);
5384520Snw141292 
5394520Snw141292 errout:
5404520Snw141292 	errno = idmap_stat2errno(retcode);
5414520Snw141292 	return (retcode);
5424520Snw141292 }
5434520Snw141292 
5444520Snw141292 
5454520Snw141292 /*
5464520Snw141292  * Set the number of entries requested per batch by the iterator
5474520Snw141292  *
5484520Snw141292  * Input:
5494520Snw141292  * iter  - iterator
5504520Snw141292  * limit - number of entries requested per batch
5514520Snw141292  */
5524520Snw141292 idmap_stat
5534520Snw141292 idmap_iter_set_limit(idmap_iter_t *iter, uint64_t limit) {
5544520Snw141292 	if (iter == NULL) {
5554520Snw141292 		errno = EINVAL;
5564520Snw141292 		return (IDMAP_ERR_ARG);
5574520Snw141292 	}
5584520Snw141292 	iter->limit = limit;
5594520Snw141292 	return (IDMAP_SUCCESS);
5604520Snw141292 }
5614520Snw141292 
5624520Snw141292 
5634520Snw141292 /*
5644520Snw141292  * Create iterator to get name-based mapping rules
5654520Snw141292  *
5664520Snw141292  * Input:
5674520Snw141292  * windomain - Windows domain
5684520Snw141292  * is_user   - user or group rules
5694520Snw141292  * winname   - Windows user or group name
5704520Snw141292  * unixname  - Unix user or group name
5714520Snw141292  *
5724520Snw141292  * Output:
5734520Snw141292  * iter - iterator
5744520Snw141292  */
5754520Snw141292 idmap_stat
5764520Snw141292 idmap_iter_namerules(idmap_handle_t *handle, const char *windomain,
5774520Snw141292 		boolean_t is_user, const char *winname,
5784520Snw141292 		const char *unixname, idmap_iter_t **iter) {
5794520Snw141292 
5804520Snw141292 	idmap_iter_t			*tmpiter;
5814520Snw141292 	idmap_list_namerules_1_argument	*arg = NULL;
5824520Snw141292 	idmap_namerule			*rule;
5834520Snw141292 	idmap_retcode			retcode;
5844520Snw141292 
5854520Snw141292 	__ITER_CREATE(tmpiter, arg, handle, IDMAP_LIST_NAMERULES);
5864520Snw141292 
5874520Snw141292 	rule = &arg->rule;
5884520Snw141292 	rule->is_user = is_user;
5894644Sbaban 	rule->direction = IDMAP_DIRECTION_UNDEF;
590*5064Sdm199847 
591*5064Sdm199847 	retcode = idmap_strdupnull(&rule->windomain, windomain);
592*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
593*5064Sdm199847 		goto errout;
594*5064Sdm199847 
595*5064Sdm199847 	retcode = idmap_strdupnull(&rule->winname, winname);
596*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
597*5064Sdm199847 		goto errout;
598*5064Sdm199847 
599*5064Sdm199847 	retcode = idmap_strdupnull(&rule->unixname, unixname);
600*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
601*5064Sdm199847 		goto errout;
6024520Snw141292 
6034520Snw141292 	*iter = tmpiter;
6044520Snw141292 	return (IDMAP_SUCCESS);
6054520Snw141292 
6064520Snw141292 errout:
6074520Snw141292 	__ITER_ERR_RETURN(tmpiter, arg,
6084520Snw141292 		xdr_idmap_list_namerules_1_argument, retcode);
6094520Snw141292 }
6104520Snw141292 
6114520Snw141292 
6124520Snw141292 /*
6134520Snw141292  * Iterate through the name-based mapping rules
6144520Snw141292  *
6154520Snw141292  * Input:
6164520Snw141292  * iter - iterator
6174520Snw141292  *
6184520Snw141292  * Output:
6194520Snw141292  * windomain - Windows domain
6204520Snw141292  * winname   - Windows user or group name
6214520Snw141292  * unixname  - Unix user or group name
6224520Snw141292  * is_nt4    - NT4 or AD
6234520Snw141292  * direction - bi(0), win2unix(1), unix2win(2)
6244520Snw141292  *
6254520Snw141292  * Return value:
6264520Snw141292  * 0   - done
6274520Snw141292  * 1   - more results available
6284520Snw141292  * < 0 - error
6294520Snw141292  */
6304520Snw141292 idmap_stat
6314520Snw141292 idmap_iter_next_namerule(idmap_iter_t *iter, char **windomain,
6324520Snw141292 		char **winname, char **unixname, boolean_t *is_nt4,
6334520Snw141292 		int *direction) {
6344520Snw141292 	idmap_namerules_res		*namerules;
6354520Snw141292 	idmap_list_namerules_1_argument	*arg;
6364520Snw141292 	idmap_retcode			retcode;
6374520Snw141292 
6384520Snw141292 	if (windomain)
6394520Snw141292 		*windomain = NULL;
6404520Snw141292 	if (winname)
6414520Snw141292 		*winname = NULL;
6424520Snw141292 	if (unixname)
6434520Snw141292 		*unixname = NULL;
6444520Snw141292 	if (is_nt4)
6454520Snw141292 		*is_nt4 = 0;
6464520Snw141292 	if (direction)
6474644Sbaban 		*direction = IDMAP_DIRECTION_UNDEF;
6484520Snw141292 
6494520Snw141292 	__ITER_CHECK(iter, IDMAP_LIST_NAMERULES);
6504520Snw141292 
6514520Snw141292 	namerules = (idmap_namerules_res *)iter->retlist;
6524520Snw141292 	if (iter->retcode == IDMAP_NEXT && (namerules == NULL ||
6534520Snw141292 			iter->next >= namerules->rules.rules_len)) {
6544520Snw141292 
6554520Snw141292 		if ((arg = iter->arg) == NULL) {
6564520Snw141292 			errno = EINVAL;
6574520Snw141292 			return (IDMAP_ERR_ARG);
6584520Snw141292 		}
6594520Snw141292 		arg->limit = iter->limit;
6604520Snw141292 
6614520Snw141292 		retcode = _iter_get_next_list(IDMAP_LIST_NAMERULES,
6624520Snw141292 			iter, arg,
6634520Snw141292 			(uchar_t **)&namerules, sizeof (*namerules),
6644520Snw141292 			(xdrproc_t)xdr_idmap_list_namerules_1_argument,
6654520Snw141292 			(xdrproc_t)xdr_idmap_namerules_res);
6664520Snw141292 		if (retcode != IDMAP_SUCCESS)
6674520Snw141292 			return (retcode);
6684520Snw141292 
6694520Snw141292 		if (IDMAP_ERROR(namerules->retcode)) {
6704520Snw141292 			retcode  = namerules->retcode;
6714520Snw141292 			xdr_free(xdr_idmap_namerules_res, (caddr_t)namerules);
6724520Snw141292 			free(namerules);
6734520Snw141292 			iter->retlist = NULL;
6744520Snw141292 			return (retcode);
6754520Snw141292 		}
6764520Snw141292 		iter->retcode = namerules->retcode;
6774520Snw141292 		arg->lastrowid = namerules->lastrowid;
6784520Snw141292 	}
6794520Snw141292 
6804520Snw141292 	if (namerules == NULL || namerules->rules.rules_len == 0)
6814520Snw141292 		return (IDMAP_SUCCESS);
6824520Snw141292 
6834520Snw141292 	if (iter->next >= namerules->rules.rules_len) {
6844520Snw141292 		return (IDMAP_ERR_ARG);
6854520Snw141292 	}
6864520Snw141292 
687*5064Sdm199847 	retcode = idmap_strdupnull(windomain,
688*5064Sdm199847 	    namerules->rules.rules_val[iter->next].windomain);
689*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
690*5064Sdm199847 		goto errout;
691*5064Sdm199847 
692*5064Sdm199847 	retcode = idmap_strdupnull(winname,
693*5064Sdm199847 	    namerules->rules.rules_val[iter->next].winname);
694*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
695*5064Sdm199847 		goto errout;
696*5064Sdm199847 
697*5064Sdm199847 	retcode = idmap_strdupnull(unixname,
698*5064Sdm199847 	    namerules->rules.rules_val[iter->next].unixname);
699*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
700*5064Sdm199847 		goto errout;
701*5064Sdm199847 
7024520Snw141292 	if (is_nt4)
7034520Snw141292 		*is_nt4 = namerules->rules.rules_val[iter->next].is_nt4;
7044520Snw141292 	if (direction)
7054520Snw141292 		*direction = namerules->rules.rules_val[iter->next].direction;
7064520Snw141292 	iter->next++;
7074520Snw141292 
7084520Snw141292 	if (iter->next == namerules->rules.rules_len)
7094520Snw141292 		return (iter->retcode);
7104520Snw141292 	else
7114520Snw141292 		return (IDMAP_NEXT);
7124520Snw141292 
7134520Snw141292 errout:
7144520Snw141292 	if (windomain && *windomain)
7154520Snw141292 		free(*windomain);
7164520Snw141292 	if (winname && *winname)
7174520Snw141292 		free(*winname);
7184520Snw141292 	if (unixname && *unixname)
7194520Snw141292 		free(*unixname);
7204520Snw141292 	return (retcode);
7214520Snw141292 }
7224520Snw141292 
7234520Snw141292 
7244520Snw141292 /*
7254520Snw141292  * Create iterator to get SID to UID/GID mappings
7264520Snw141292  *
7274520Snw141292  * Input:
7284520Snw141292  * is_user - user or group
7294520Snw141292  *
7304520Snw141292  * Output:
7314520Snw141292  * iter - iterator
7324520Snw141292  */
7334520Snw141292 idmap_stat
7344520Snw141292 idmap_iter_mappings(idmap_handle_t *handle, boolean_t is_user,
7354520Snw141292 		idmap_iter_t **iter) {
7364520Snw141292 	idmap_iter_t			*tmpiter;
7374520Snw141292 	idmap_list_mappings_1_argument	*arg = NULL;
7384520Snw141292 
7394520Snw141292 	__ITER_CREATE(tmpiter, arg, handle, IDMAP_LIST_MAPPINGS);
7404520Snw141292 
7414520Snw141292 	arg->is_user = is_user;
7424520Snw141292 	*iter = tmpiter;
7434520Snw141292 	return (IDMAP_SUCCESS);
7444520Snw141292 }
7454520Snw141292 
7464520Snw141292 
7474520Snw141292 /*
7484520Snw141292  * Iterate through the SID to UID/GID mappings
7494520Snw141292  *
7504520Snw141292  * Input:
7514520Snw141292  * iter - iterator
7524520Snw141292  *
7534520Snw141292  * Output:
7544520Snw141292  * sid - SID in canonical form
7554520Snw141292  * pid - UID or GID
7564520Snw141292  *
7574520Snw141292  * Return value:
7584520Snw141292  * 0   - done
7594520Snw141292  * 1   - more results available
7604520Snw141292  * < 0 - error
7614520Snw141292  */
7624520Snw141292 idmap_stat
7634520Snw141292 idmap_iter_next_mapping(idmap_iter_t *iter, char **sidprefix,
7644520Snw141292 		idmap_rid_t *rid, uid_t *pid, char **winname,
7654520Snw141292 		char **windomain, char **unixname, int *direction) {
7664520Snw141292 	idmap_mappings_res		*mappings;
7674520Snw141292 	idmap_list_mappings_1_argument	*arg;
7684520Snw141292 	idmap_retcode			retcode;
7694520Snw141292 	char				*str;
7704520Snw141292 
7714520Snw141292 	if (sidprefix)
7724520Snw141292 		*sidprefix = NULL;
7734520Snw141292 	if (rid)
7744520Snw141292 		*rid = UINT32_MAX;
7754520Snw141292 	if (winname)
7764520Snw141292 		*winname = NULL;
7774520Snw141292 	if (windomain)
7784520Snw141292 		*windomain = NULL;
7794520Snw141292 	if (unixname)
7804520Snw141292 		*unixname = NULL;
7814520Snw141292 	if (pid)
7824520Snw141292 		*pid = UINT32_MAX;
7834520Snw141292 	if (direction)
7844644Sbaban 		*direction = IDMAP_DIRECTION_UNDEF;
7854520Snw141292 
7864520Snw141292 	__ITER_CHECK(iter, IDMAP_LIST_MAPPINGS);
7874520Snw141292 
7884520Snw141292 	mappings = (idmap_mappings_res *)iter->retlist;
7894520Snw141292 	if (iter->retcode == IDMAP_NEXT && (mappings == NULL ||
7904520Snw141292 			iter->next >= mappings->mappings.mappings_len)) {
7914520Snw141292 
7924520Snw141292 		if ((arg = iter->arg) == NULL) {
7934520Snw141292 			errno = EINVAL;
7944520Snw141292 			return (IDMAP_ERR_ARG);
7954520Snw141292 		}
7964520Snw141292 		arg->limit = iter->limit;
7974520Snw141292 
7984520Snw141292 		retcode = _iter_get_next_list(IDMAP_LIST_MAPPINGS,
7994520Snw141292 			iter, arg,
8004520Snw141292 			(uchar_t **)&mappings, sizeof (*mappings),
8014520Snw141292 			(xdrproc_t)xdr_idmap_list_mappings_1_argument,
8024520Snw141292 			(xdrproc_t)xdr_idmap_mappings_res);
8034520Snw141292 		if (retcode != IDMAP_SUCCESS)
8044520Snw141292 			return (retcode);
8054520Snw141292 
8064520Snw141292 		if (IDMAP_ERROR(mappings->retcode)) {
8074520Snw141292 			retcode  = mappings->retcode;
8084520Snw141292 			xdr_free(xdr_idmap_mappings_res, (caddr_t)mappings);
8094520Snw141292 			free(mappings);
8104520Snw141292 			iter->retlist = NULL;
8114520Snw141292 			return (retcode);
8124520Snw141292 		}
8134520Snw141292 		iter->retcode = mappings->retcode;
8144520Snw141292 		arg->lastrowid = mappings->lastrowid;
8154520Snw141292 	}
8164520Snw141292 
8174520Snw141292 	if (mappings == NULL || mappings->mappings.mappings_len == 0)
8184520Snw141292 		return (IDMAP_SUCCESS);
8194520Snw141292 
8204520Snw141292 	if (iter->next >= mappings->mappings.mappings_len) {
8214520Snw141292 		return (IDMAP_ERR_ARG);
8224520Snw141292 	}
8234520Snw141292 
8244520Snw141292 	if (sidprefix) {
8254520Snw141292 		str = mappings->mappings.mappings_val[iter->next].id1.
8264520Snw141292 			idmap_id_u.sid.prefix;
8274695Sbaban 		if (str && *str != '\0') {
8284520Snw141292 			*sidprefix = strdup(str);
8294526Sbaban 			if (*sidprefix == NULL) {
8304526Sbaban 				retcode = IDMAP_ERR_MEMORY;
8314526Sbaban 				goto errout;
8324526Sbaban 			}
8334520Snw141292 		}
8344520Snw141292 	}
8354520Snw141292 	if (rid)
8364520Snw141292 		*rid = mappings->mappings.mappings_val[iter->next].id1.
8374520Snw141292 			idmap_id_u.sid.rid;
838*5064Sdm199847 
839*5064Sdm199847 	retcode = idmap_strdupnull(windomain,
840*5064Sdm199847 	    mappings->mappings.mappings_val[iter->next].id1domain);
841*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
842*5064Sdm199847 		goto errout;
843*5064Sdm199847 
844*5064Sdm199847 	retcode = idmap_strdupnull(winname,
845*5064Sdm199847 	    mappings->mappings.mappings_val[iter->next].id1name);
846*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
847*5064Sdm199847 		goto errout;
848*5064Sdm199847 
849*5064Sdm199847 	retcode = idmap_strdupnull(unixname,
850*5064Sdm199847 	    mappings->mappings.mappings_val[iter->next].id2name);
851*5064Sdm199847 	if (retcode != IDMAP_SUCCESS)
852*5064Sdm199847 		goto errout;
853*5064Sdm199847 
854*5064Sdm199847 
8554520Snw141292 	if (pid)
8564520Snw141292 		*pid = mappings->mappings.mappings_val[iter->next].id2.
8574520Snw141292 			idmap_id_u.uid;
8584520Snw141292 	if (direction)
8594520Snw141292 		*direction = mappings->mappings.mappings_val[iter->next].
8604520Snw141292 			direction;
8614520Snw141292 	iter->next++;
8624520Snw141292 
8634520Snw141292 	if (iter->next == mappings->mappings.mappings_len)
8644520Snw141292 		return (iter->retcode);
8654520Snw141292 	else
8664520Snw141292 		return (IDMAP_NEXT);
8674520Snw141292 
8684520Snw141292 errout:
8694520Snw141292 	if (sidprefix && *sidprefix)
8704520Snw141292 		free(*sidprefix);
8714520Snw141292 	if (winname && *winname)
8724520Snw141292 		free(*winname);
8734520Snw141292 	if (windomain && *windomain)
8744520Snw141292 		free(*windomain);
8754520Snw141292 	if (unixname && *unixname)
8764520Snw141292 		free(*unixname);
8774520Snw141292 	return (retcode);
8784520Snw141292 }
8794520Snw141292 
8804520Snw141292 
8814520Snw141292 /*
8824520Snw141292  * Destroy the iterator
8834520Snw141292  */
8844520Snw141292 void
8854520Snw141292 idmap_iter_destroy(idmap_iter_t *iter) {
8864520Snw141292 	xdrproc_t _xdr_argument, _xdr_result;
8874520Snw141292 
8884520Snw141292 	if (iter == NULL)
8894520Snw141292 		return;
8904520Snw141292 
8914520Snw141292 	switch (iter->type) {
8924520Snw141292 	case IDMAP_LIST_NAMERULES:
8934520Snw141292 		_xdr_argument = (xdrproc_t)xdr_idmap_list_namerules_1_argument;
8944520Snw141292 		_xdr_result = (xdrproc_t)xdr_idmap_namerules_res;
8954520Snw141292 		break;
8964520Snw141292 	case IDMAP_LIST_MAPPINGS:
8974520Snw141292 		_xdr_argument = (xdrproc_t)xdr_idmap_list_mappings_1_argument;
8984520Snw141292 		_xdr_result = (xdrproc_t)xdr_idmap_mappings_res;
8994520Snw141292 		break;
9004520Snw141292 	default:
9014520Snw141292 		free(iter);
9024520Snw141292 		return;
9034520Snw141292 	};
9044520Snw141292 
9054520Snw141292 	if (iter->arg) {
9064520Snw141292 		xdr_free(_xdr_argument, (caddr_t)iter->arg);
9074520Snw141292 		free(iter->arg);
9084520Snw141292 	}
9094520Snw141292 	if (iter->retlist) {
9104520Snw141292 		xdr_free(_xdr_result, (caddr_t)iter->retlist);
9114520Snw141292 		free(iter->retlist);
9124520Snw141292 	}
9134520Snw141292 	free(iter);
9144520Snw141292 }
9154520Snw141292 
9164520Snw141292 
9174520Snw141292 /*
9184520Snw141292  * Create handle to get SID to UID/GID mapping entries
9194520Snw141292  *
9204520Snw141292  * Input:
9214520Snw141292  * gh - "get mapping" handle
9224520Snw141292  */
9234520Snw141292 idmap_stat
9244520Snw141292 idmap_get_create(idmap_handle_t *handle, idmap_get_handle_t **gh) {
9254520Snw141292 	idmap_get_handle_t	*tmp;
9264520Snw141292 
9274520Snw141292 	/* sanity checks */
9284520Snw141292 	if (handle == NULL || gh == NULL) {
9294520Snw141292 		errno = EINVAL;
9304520Snw141292 		return (IDMAP_ERR_ARG);
9314520Snw141292 	}
9324520Snw141292 
9334520Snw141292 	/* allocate the handle */
9344520Snw141292 	if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
9354520Snw141292 		errno = ENOMEM;
9364520Snw141292 		return (IDMAP_ERR_MEMORY);
9374520Snw141292 	}
9384520Snw141292 
9394520Snw141292 	tmp->ih = handle;
9404520Snw141292 	*gh = tmp;
9414520Snw141292 	return (IDMAP_SUCCESS);
9424520Snw141292 }
9434520Snw141292 
9444520Snw141292 
9454520Snw141292 /*
9464520Snw141292  * Given SID, get UID
9474520Snw141292  *
9484520Snw141292  * Input:
9494520Snw141292  * sidprefix  - SID prefix
9504520Snw141292  * rid        - RID
9514520Snw141292  * flag       - flag
9524520Snw141292  *
9534520Snw141292  * Output:
9544520Snw141292  * stat - status of the get request
9554520Snw141292  * uid  - POSIX UID if stat = 0
9564520Snw141292  *
9574520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
9584520Snw141292  */
9594520Snw141292 idmap_stat
9604520Snw141292 idmap_get_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
9614520Snw141292 		int flag, uid_t *uid, idmap_stat *stat) {
9624520Snw141292 
9634520Snw141292 	idmap_retcode	retcode;
9644644Sbaban 	idmap_mapping	*mapping = NULL;
9654520Snw141292 
9664520Snw141292 	/* sanity checks */
9674520Snw141292 	if (gh == NULL)
9684520Snw141292 		return (IDMAP_ERR_ARG);
9694520Snw141292 	if (uid == NULL || sidprefix == NULL)
9704520Snw141292 		return (IDMAP_ERR_ARG);
9714520Snw141292 
9724520Snw141292 	/* Extend the request array and the return list */
9734520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
9744520Snw141292 		goto errout;
9754520Snw141292 
9764520Snw141292 	/* Setup the request */
9774520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
9784520Snw141292 	mapping->flag = flag;
9794520Snw141292 	mapping->id1.idtype = IDMAP_SID;
9804520Snw141292 	mapping->id1.idmap_id_u.sid.rid = rid;
9814520Snw141292 	if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
9824520Snw141292 		retcode = IDMAP_ERR_MEMORY;
9834520Snw141292 		goto errout;
9844520Snw141292 	}
9854520Snw141292 	mapping->id2.idtype = IDMAP_UID;
9864520Snw141292 
9874520Snw141292 	/* Setup pointers for the result */
9884520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_UID;
9894520Snw141292 	gh->retlist[gh->next].uid = uid;
9904520Snw141292 	gh->retlist[gh->next].stat = stat;
9914520Snw141292 
9924520Snw141292 	gh->next++;
9934520Snw141292 	return (IDMAP_SUCCESS);
9944520Snw141292 
9954520Snw141292 errout:
9964644Sbaban 	/* Batch created so far should still be usable */
9974644Sbaban 	if (mapping)
9984644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
9994520Snw141292 	errno = idmap_stat2errno(retcode);
10004520Snw141292 	return (retcode);
10014520Snw141292 }
10024520Snw141292 
10034520Snw141292 
10044520Snw141292 /*
10054520Snw141292  * Given SID, get GID
10064520Snw141292  *
10074520Snw141292  * Input:
10084520Snw141292  * sidprefix  - SID prefix
10094520Snw141292  * rid        - rid
10104520Snw141292  * flag       - flag
10114520Snw141292  *
10124520Snw141292  * Output:
10134520Snw141292  * stat - status of the get request
10144520Snw141292  * gid  - POSIX GID if stat = 0
10154520Snw141292  *
10164520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
10174520Snw141292  */
10184520Snw141292 idmap_stat
10194520Snw141292 idmap_get_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
10204520Snw141292 		int flag, gid_t *gid, idmap_stat *stat) {
10214520Snw141292 
10224520Snw141292 	idmap_retcode	retcode;
10234644Sbaban 	idmap_mapping	*mapping = NULL;
10244520Snw141292 
10254520Snw141292 	/* sanity checks */
10264520Snw141292 	if (gh == NULL)
10274520Snw141292 		return (IDMAP_ERR_ARG);
10284520Snw141292 	if (gid == NULL || sidprefix == NULL)
10294520Snw141292 		return (IDMAP_ERR_ARG);
10304520Snw141292 
10314520Snw141292 	/* Extend the request array and the return list */
10324520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
10334520Snw141292 		goto errout;
10344520Snw141292 
10354520Snw141292 	/* Setup the request */
10364520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
10374520Snw141292 	mapping->flag = flag;
10384520Snw141292 	mapping->id1.idtype = IDMAP_SID;
10394520Snw141292 	mapping->id1.idmap_id_u.sid.rid = rid;
10404520Snw141292 	if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
10414520Snw141292 		retcode = IDMAP_ERR_MEMORY;
10424520Snw141292 		goto errout;
10434520Snw141292 	}
10444520Snw141292 	mapping->id2.idtype = IDMAP_GID;
10454520Snw141292 
10464520Snw141292 	/* Setup pointers for the result */
10474520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_GID;
10484520Snw141292 	gh->retlist[gh->next].gid = gid;
10494520Snw141292 	gh->retlist[gh->next].stat = stat;
10504520Snw141292 
10514520Snw141292 	gh->next++;
10524520Snw141292 	return (IDMAP_SUCCESS);
10534520Snw141292 
10544520Snw141292 errout:
10554644Sbaban 	if (mapping)
10564644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
10574520Snw141292 	errno = idmap_stat2errno(retcode);
10584520Snw141292 	return (retcode);
10594520Snw141292 }
10604520Snw141292 
10614520Snw141292 
10624520Snw141292 /*
10634520Snw141292  * Given SID, get POSIX ID i.e. UID/GID
10644520Snw141292  *
10654520Snw141292  * Input:
10664520Snw141292  * sidprefix  - SID prefix
10674520Snw141292  * rid        - rid
10684520Snw141292  * flag       - flag
10694520Snw141292  *
10704520Snw141292  * Output:
10714520Snw141292  * stat    - status of the get request
10724520Snw141292  * is_user - user or group
10734520Snw141292  * pid     - POSIX UID if stat = 0 and is_user = 1
10744520Snw141292  *           POSIX GID if stat = 0 and is_user = 0
10754520Snw141292  *
10764520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
10774520Snw141292  */
10784520Snw141292 idmap_stat
10794520Snw141292 idmap_get_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
10804520Snw141292 		int flag, uid_t *pid, int *is_user, idmap_stat *stat) {
10814520Snw141292 	idmap_retcode	retcode;
10824644Sbaban 	idmap_mapping	*mapping = NULL;
10834520Snw141292 
10844520Snw141292 	/* sanity checks */
10854520Snw141292 	if (gh == NULL)
10864520Snw141292 		return (IDMAP_ERR_ARG);
10874520Snw141292 	if (pid == NULL || sidprefix == NULL || is_user == NULL)
10884520Snw141292 		return (IDMAP_ERR_ARG);
10894520Snw141292 
10904520Snw141292 	/* Extend the request array and the return list */
10914520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
10924520Snw141292 		goto errout;
10934520Snw141292 
10944520Snw141292 	/* Setup the request */
10954520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
10964520Snw141292 	mapping->flag = flag;
10974520Snw141292 	mapping->id1.idtype = IDMAP_SID;
10984520Snw141292 	mapping->id1.idmap_id_u.sid.rid = rid;
10994520Snw141292 	if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
11004520Snw141292 		retcode = IDMAP_ERR_MEMORY;
11014520Snw141292 		goto errout;
11024520Snw141292 	}
11034520Snw141292 	mapping->id2.idtype = IDMAP_POSIXID;
11044520Snw141292 
11054520Snw141292 	/* Setup pointers for the result */
11064520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_POSIXID;
11074520Snw141292 	gh->retlist[gh->next].uid = pid;
11084520Snw141292 	gh->retlist[gh->next].gid = pid;
11094520Snw141292 	gh->retlist[gh->next].is_user = is_user;
11104520Snw141292 	gh->retlist[gh->next].stat = stat;
11114520Snw141292 
11124520Snw141292 	gh->next++;
11134520Snw141292 	return (IDMAP_SUCCESS);
11144520Snw141292 
11154520Snw141292 errout:
11164644Sbaban 	if (mapping)
11174644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
11184520Snw141292 	errno = idmap_stat2errno(retcode);
11194520Snw141292 	return (retcode);
11204520Snw141292 }
11214520Snw141292 
11224520Snw141292 
11234520Snw141292 /*
11244520Snw141292  * Given UID, get SID
11254520Snw141292  *
11264520Snw141292  * Input:
11274520Snw141292  * uid  - POSIX UID
11284520Snw141292  * flag - flag
11294520Snw141292  *
11304520Snw141292  * Output:
11314520Snw141292  * stat - status of the get request
11324520Snw141292  * sid  - SID prefix (if stat == 0)
11334520Snw141292  * rid  - rid
11344520Snw141292  *
11354520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
11364520Snw141292  */
11374520Snw141292 idmap_stat
11384520Snw141292 idmap_get_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag,
11394520Snw141292 		char **sidprefix, idmap_rid_t *rid, idmap_stat *stat) {
11404520Snw141292 
11414520Snw141292 	idmap_retcode	retcode;
11424644Sbaban 	idmap_mapping	*mapping = NULL;
11434520Snw141292 
11444520Snw141292 	/* sanity checks */
11454520Snw141292 	if (gh == NULL)
11464520Snw141292 		return (IDMAP_ERR_ARG);
11474520Snw141292 	if (sidprefix == NULL)
11484520Snw141292 		return (IDMAP_ERR_ARG);
11494520Snw141292 
11504520Snw141292 	/* Extend the request array and the return list */
11514520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
11524520Snw141292 		goto errout;
11534520Snw141292 
11544520Snw141292 	/* Setup the request */
11554520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
11564520Snw141292 	mapping->flag = flag;
11574520Snw141292 	mapping->id1.idtype = IDMAP_UID;
11584520Snw141292 	mapping->id1.idmap_id_u.uid = uid;
11594520Snw141292 	mapping->id2.idtype = IDMAP_SID;
11604520Snw141292 
11614520Snw141292 	/* Setup pointers for the result */
11624520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_SID;
11634520Snw141292 	gh->retlist[gh->next].sidprefix = sidprefix;
11644520Snw141292 	gh->retlist[gh->next].rid = rid;
11654520Snw141292 	gh->retlist[gh->next].stat = stat;
11664520Snw141292 
11674520Snw141292 	gh->next++;
11684520Snw141292 	return (IDMAP_SUCCESS);
11694520Snw141292 
11704520Snw141292 errout:
11714644Sbaban 	if (mapping)
11724644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
11734520Snw141292 	errno = idmap_stat2errno(retcode);
11744520Snw141292 	return (retcode);
11754520Snw141292 }
11764520Snw141292 
11774520Snw141292 
11784520Snw141292 /*
11794520Snw141292  * Given GID, get SID
11804520Snw141292  *
11814520Snw141292  * Input:
11824520Snw141292  * gid  - POSIX GID
11834520Snw141292  * flag - flag
11844520Snw141292  *
11854520Snw141292  * Output:
11864520Snw141292  * stat       - status of the get request
11874520Snw141292  * sidprefix  - SID prefix (if stat == 0)
11884520Snw141292  * rid        - rid
11894520Snw141292  *
11904520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
11914520Snw141292  */
11924520Snw141292 idmap_stat
11934520Snw141292 idmap_get_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag,
11944520Snw141292 		char **sidprefix, idmap_rid_t *rid, idmap_stat *stat) {
11954520Snw141292 
11964520Snw141292 	idmap_retcode	retcode;
11974644Sbaban 	idmap_mapping	*mapping = NULL;
11984520Snw141292 
11994520Snw141292 	/* sanity checks */
12004520Snw141292 	if (gh == NULL)
12014520Snw141292 		return (IDMAP_ERR_ARG);
12024520Snw141292 	if (sidprefix == NULL)
12034520Snw141292 		return (IDMAP_ERR_ARG);
12044520Snw141292 
12054520Snw141292 	/* Extend the request array and the return list */
12064520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
12074520Snw141292 		goto errout;
12084520Snw141292 
12094520Snw141292 	/* Setup the request */
12104520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
12114520Snw141292 	mapping->flag = flag;
12124520Snw141292 	mapping->id1.idtype = IDMAP_GID;
12134520Snw141292 	mapping->id1.idmap_id_u.gid = gid;
12144520Snw141292 	mapping->id2.idtype = IDMAP_SID;
12154520Snw141292 
12164520Snw141292 	/* Setup pointers for the result */
12174520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_SID;
12184520Snw141292 	gh->retlist[gh->next].sidprefix = sidprefix;
12194520Snw141292 	gh->retlist[gh->next].rid = rid;
12204520Snw141292 	gh->retlist[gh->next].stat = stat;
12214520Snw141292 
12224520Snw141292 	gh->next++;
12234520Snw141292 	return (IDMAP_SUCCESS);
12244520Snw141292 
12254520Snw141292 errout:
12264644Sbaban 	if (mapping)
12274644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
12284520Snw141292 	errno = idmap_stat2errno(retcode);
12294520Snw141292 	return (retcode);
12304520Snw141292 }
12314520Snw141292 
12324520Snw141292 
12334520Snw141292 /*
12344520Snw141292  * Process the batched "get mapping" requests. The results (i.e.
12354520Snw141292  * status and identity) will be available in the data areas
12364520Snw141292  * provided by individual requests.
12374520Snw141292  */
12384520Snw141292 idmap_stat
12394520Snw141292 idmap_get_mappings(idmap_get_handle_t *gh) {
12404520Snw141292 	CLIENT		*clnt;
12414520Snw141292 	enum clnt_stat	clntstat;
12424520Snw141292 	idmap_retcode	retcode;
12434520Snw141292 	idmap_ids_res	res;
12444520Snw141292 	idmap_id	*id;
12454520Snw141292 	int		i;
12464520Snw141292 
12474520Snw141292 	if (gh == NULL) {
12484520Snw141292 		errno = EINVAL;
12494520Snw141292 		return (IDMAP_ERR_ARG);
12504520Snw141292 	}
12514520Snw141292 	_IDMAP_GET_CLIENT_HANDLE(gh->ih, clnt);
12524520Snw141292 
12534520Snw141292 	(void) memset(&res, 0, sizeof (idmap_ids_res));
12544520Snw141292 	clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_IDS,
12554520Snw141292 		(xdrproc_t)xdr_idmap_mapping_batch,
12564520Snw141292 		(caddr_t)&gh->batch,
12574520Snw141292 		(xdrproc_t)xdr_idmap_ids_res,
12584520Snw141292 		(caddr_t)&res,
12594520Snw141292 		TIMEOUT);
12604520Snw141292 	if (clntstat != RPC_SUCCESS) {
12614644Sbaban 		retcode = _idmap_rpc2stat(clnt);
12624520Snw141292 		goto out;
12634520Snw141292 	}
12644520Snw141292 	if (res.retcode != IDMAP_SUCCESS) {
12654520Snw141292 		retcode = res.retcode;
12664520Snw141292 		goto out;
12674520Snw141292 	}
12684520Snw141292 	for (i = 0; i < gh->next; i++) {
12694520Snw141292 		if (i >= res.ids.ids_len) {
12704520Snw141292 			*gh->retlist[i].stat = IDMAP_ERR_NORESULT;
12714520Snw141292 			continue;
12724520Snw141292 		}
12734520Snw141292 		*gh->retlist[i].stat = res.ids.ids_val[i].retcode;
12744520Snw141292 		id = &res.ids.ids_val[i].id;
12754520Snw141292 		switch (id->idtype) {
12764520Snw141292 		case IDMAP_UID:
12774520Snw141292 			if (gh->retlist[i].uid)
12784520Snw141292 				*gh->retlist[i].uid = id->idmap_id_u.uid;
12794520Snw141292 			if (gh->retlist[i].is_user)
12804520Snw141292 				*gh->retlist[i].is_user = 1;
12814520Snw141292 			break;
12824520Snw141292 		case IDMAP_GID:
12834520Snw141292 			if (gh->retlist[i].gid)
12844520Snw141292 				*gh->retlist[i].gid = id->idmap_id_u.gid;
12854520Snw141292 			if (gh->retlist[i].is_user)
12864520Snw141292 				*gh->retlist[i].is_user = 0;
12874520Snw141292 			break;
12884864Sbaban 		case IDMAP_POSIXID:
12894864Sbaban 			if (gh->retlist[i].uid)
12904864Sbaban 				*gh->retlist[i].uid = 60001;
12914864Sbaban 			if (gh->retlist[i].is_user)
12924864Sbaban 				*gh->retlist[i].is_user = -1;
12934864Sbaban 			break;
12944520Snw141292 		case IDMAP_SID:
12954520Snw141292 			if (gh->retlist[i].rid)
12964520Snw141292 				*gh->retlist[i].rid = id->idmap_id_u.sid.rid;
12974520Snw141292 			if (gh->retlist[i].sidprefix) {
12984695Sbaban 				if (id->idmap_id_u.sid.prefix == NULL ||
12994695Sbaban 				    *id->idmap_id_u.sid.prefix == '\0') {
13004520Snw141292 					*gh->retlist[i].sidprefix = NULL;
13014520Snw141292 					break;
13024520Snw141292 				}
13034520Snw141292 				*gh->retlist[i].sidprefix =
13044520Snw141292 					strdup(id->idmap_id_u.sid.prefix);
13054520Snw141292 				if (*gh->retlist[i].sidprefix == NULL)
13064520Snw141292 					*gh->retlist[i].stat =
13074520Snw141292 						IDMAP_ERR_MEMORY;
13084520Snw141292 			}
13094520Snw141292 			break;
13104520Snw141292 		case IDMAP_NONE:
13114520Snw141292 			break;
13124520Snw141292 		default:
13134520Snw141292 			*gh->retlist[i].stat = IDMAP_ERR_NORESULT;
13144520Snw141292 			break;
13154520Snw141292 		}
13164520Snw141292 	}
13174520Snw141292 	retcode = IDMAP_SUCCESS;
13184520Snw141292 
13194520Snw141292 out:
13204644Sbaban 	_IDMAP_RESET_GET_HANDLE(gh);
13214520Snw141292 	(void) xdr_free(xdr_idmap_ids_res, (caddr_t)&res);
13224520Snw141292 	errno = idmap_stat2errno(retcode);
13234520Snw141292 	return (retcode);
13244520Snw141292 }
13254520Snw141292 
13264520Snw141292 
13274520Snw141292 /*
13284520Snw141292  * Destroy the "get mapping" handle
13294520Snw141292  */
13304520Snw141292 void
13314520Snw141292 idmap_get_destroy(idmap_get_handle_t *gh) {
13324520Snw141292 	if (gh == NULL)
13334520Snw141292 		return;
13344520Snw141292 	(void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch);
13354520Snw141292 	if (gh->retlist)
13364520Snw141292 		free(gh->retlist);
13374520Snw141292 	free(gh);
13384520Snw141292 }
13394520Snw141292 
13404520Snw141292 
13414520Snw141292 /*
13424520Snw141292  * Get windows to unix mapping
13434520Snw141292  */
13444520Snw141292 idmap_stat
13454520Snw141292 idmap_get_w2u_mapping(idmap_handle_t *handle,
13464520Snw141292 		const char *sidprefix, idmap_rid_t *rid,
13474520Snw141292 		const char *winname, const char *windomain,
13484520Snw141292 		int flag, int *is_user,
13494520Snw141292 		uid_t *pid, char **unixname, int *direction) {
13504520Snw141292 	CLIENT			*clnt;
13514520Snw141292 	enum clnt_stat		clntstat;
13524520Snw141292 	idmap_mapping		request, *mapping;
13534520Snw141292 	idmap_mappings_res	result;
13544520Snw141292 	idmap_retcode		retcode, rc;
13554520Snw141292 
13564520Snw141292 	if (handle == NULL) {
13574520Snw141292 		errno = EINVAL;
13584520Snw141292 		return (IDMAP_ERR_ARG);
13594520Snw141292 	}
13604520Snw141292 
13614520Snw141292 	_IDMAP_GET_CLIENT_HANDLE(handle, clnt);
13624520Snw141292 
13634520Snw141292 	(void) memset(&request, 0, sizeof (request));
13644520Snw141292 	(void) memset(&result, 0, sizeof (result));
13654520Snw141292 
13664864Sbaban 	if (is_user)
13674864Sbaban 		*is_user = -1;
13684520Snw141292 	if (pid)
13694520Snw141292 		*pid = UINT32_MAX;
13704520Snw141292 	if (unixname)
13714520Snw141292 		*unixname = NULL;
13724520Snw141292 	if (direction)
13734644Sbaban 		*direction = IDMAP_DIRECTION_UNDEF;
13744520Snw141292 
13754520Snw141292 	request.flag = flag;
13764520Snw141292 	request.id1.idtype = IDMAP_SID;
13774520Snw141292 	if (sidprefix && rid) {
13784520Snw141292 		request.id1.idmap_id_u.sid.prefix = (char *)sidprefix;
13794520Snw141292 		request.id1.idmap_id_u.sid.rid = *rid;
13804520Snw141292 	} else if (winname) {
1381*5064Sdm199847 		retcode = idmap_strdupnull(&request.id1name, winname);
1382*5064Sdm199847 		if (retcode != SUCCESS)
13834520Snw141292 			goto out;
1384*5064Sdm199847 
1385*5064Sdm199847 		retcode = idmap_strdupnull(&request.id1domain, windomain);
1386*5064Sdm199847 		if (retcode != SUCCESS)
1387*5064Sdm199847 			goto out;
1388*5064Sdm199847 
13894520Snw141292 		request.id1.idmap_id_u.sid.prefix = NULL;
13904520Snw141292 	} else {
13914520Snw141292 		errno = EINVAL;
13924520Snw141292 		return (IDMAP_ERR_ARG);
13934520Snw141292 	}
13944520Snw141292 
13954520Snw141292 	if (is_user == NULL)
13964520Snw141292 		request.id2.idtype = IDMAP_POSIXID;
13974520Snw141292 	else if (*is_user == 1)
13984520Snw141292 		request.id2.idtype = IDMAP_UID;
13994520Snw141292 	else if (*is_user == 0)
14004520Snw141292 		request.id2.idtype = IDMAP_GID;
14014520Snw141292 	else
14024520Snw141292 		request.id2.idtype = IDMAP_POSIXID;
14034520Snw141292 
14044520Snw141292 	clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_ID_BY_NAME,
14054520Snw141292 		(xdrproc_t)xdr_idmap_mapping, (caddr_t)&request,
14064520Snw141292 		(xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result,
14074520Snw141292 		TIMEOUT);
14084520Snw141292 
14094644Sbaban 	if (clntstat != RPC_SUCCESS)
14104644Sbaban 		return (_idmap_rpc2stat(clnt));
14114520Snw141292 
14124520Snw141292 	retcode = result.retcode;
14134520Snw141292 
14144520Snw141292 	if ((mapping = result.mappings.mappings_val) == NULL) {
14154520Snw141292 		if (retcode == IDMAP_SUCCESS)
14164520Snw141292 			retcode = IDMAP_ERR_NORESULT;
14174520Snw141292 		goto out;
14184520Snw141292 	}
14194520Snw141292 
14204864Sbaban 	if (mapping->id2.idtype == IDMAP_UID) {
14214864Sbaban 		if (is_user) *is_user = 1;
14224864Sbaban 	} else if (mapping->id2.idtype == IDMAP_GID) {
14234864Sbaban 		if (is_user) *is_user = 0;
14244864Sbaban 	} else {
14254864Sbaban 		goto out;
14264864Sbaban 	}
14274520Snw141292 	if (direction)
14284520Snw141292 		*direction = mapping->direction;
14294520Snw141292 	if (pid)
14304520Snw141292 		*pid = mapping->id2.idmap_id_u.uid;
1431*5064Sdm199847 
1432*5064Sdm199847 	rc = idmap_strdupnull(unixname, mapping->id2name);
1433*5064Sdm199847 	if (rc != IDMAP_SUCCESS)
1434*5064Sdm199847 		retcode = rc;
14354520Snw141292 
14364520Snw141292 out:
14374520Snw141292 	xdr_free(xdr_idmap_mappings_res, (caddr_t)&result);
14384520Snw141292 	if (retcode != IDMAP_SUCCESS)
14394520Snw141292 		errno = idmap_stat2errno(retcode);
14404520Snw141292 	return (retcode);
14414520Snw141292 }
14424520Snw141292 
14434520Snw141292 
14444520Snw141292 /*
14454520Snw141292  * Get unix to windows mapping
14464520Snw141292  */
14474520Snw141292 idmap_stat
14484520Snw141292 idmap_get_u2w_mapping(idmap_handle_t *handle,
14494520Snw141292 		uid_t *pid, const char *unixname,
14504520Snw141292 		int flag, int is_user,
14514520Snw141292 		char **sidprefix, idmap_rid_t *rid,
14524520Snw141292 		char **winname, char **windomain,
14534520Snw141292 		int *direction) {
14544520Snw141292 	CLIENT			*clnt;
14554520Snw141292 	enum clnt_stat		clntstat;
14564520Snw141292 	idmap_mapping		request, *mapping;
14574520Snw141292 	idmap_mappings_res	result;
14584520Snw141292 	idmap_retcode		retcode, rc;
14594520Snw141292 
14604520Snw141292 	if (handle == NULL) {
14614520Snw141292 		errno = EINVAL;
14624520Snw141292 		return (IDMAP_ERR_ARG);
14634520Snw141292 	}
14644520Snw141292 
14654520Snw141292 	_IDMAP_GET_CLIENT_HANDLE(handle, clnt);
14664520Snw141292 
14674520Snw141292 	if (sidprefix)
14684520Snw141292 		*sidprefix = NULL;
14694520Snw141292 	if (winname)
14704520Snw141292 		*winname = NULL;
14714520Snw141292 	if (windomain)
14724520Snw141292 		*windomain = NULL;
14734520Snw141292 	if (rid)
14744520Snw141292 		*rid = UINT32_MAX;
14754520Snw141292 	if (direction)
14764644Sbaban 		*direction = IDMAP_DIRECTION_UNDEF;
14774520Snw141292 
14784520Snw141292 	(void) memset(&request, 0, sizeof (request));
14794520Snw141292 	(void) memset(&result, 0, sizeof (result));
14804520Snw141292 
14814520Snw141292 	request.flag = flag;
14824520Snw141292 	request.id1.idtype = is_user?IDMAP_UID:IDMAP_GID;
14834520Snw141292 
14844520Snw141292 	if (pid && *pid != UINT32_MAX) {
14854520Snw141292 		request.id1.idmap_id_u.uid = *pid;
14864520Snw141292 	} else if (unixname) {
1487*5064Sdm199847 		request.id1name = (char *)unixname;
14884520Snw141292 		request.id1.idmap_id_u.uid = UINT32_MAX;
14894520Snw141292 	} else {
14904520Snw141292 		errno = EINVAL;
14914520Snw141292 		return (IDMAP_ERR_ARG);
14924520Snw141292 	}
14934520Snw141292 
14944520Snw141292 	request.id2.idtype = IDMAP_SID;
14954520Snw141292 
14964520Snw141292 	clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_ID_BY_NAME,
14974520Snw141292 		(xdrproc_t)xdr_idmap_mapping, (caddr_t)&request,
14984520Snw141292 		(xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result,
14994520Snw141292 		TIMEOUT);
15004520Snw141292 
15014644Sbaban 	if (clntstat != RPC_SUCCESS)
15024644Sbaban 		return (_idmap_rpc2stat(clnt));
15034520Snw141292 
15044520Snw141292 	retcode = result.retcode;
15054520Snw141292 
15064520Snw141292 	if ((mapping = result.mappings.mappings_val) == NULL) {
15074520Snw141292 		if (retcode == IDMAP_SUCCESS)
15084520Snw141292 			retcode = IDMAP_ERR_NORESULT;
15094520Snw141292 		goto out;
15104520Snw141292 	}
15114520Snw141292 
15124520Snw141292 	if (direction)
15134520Snw141292 		*direction = mapping->direction;
15144695Sbaban 	if (sidprefix && mapping->id2.idmap_id_u.sid.prefix &&
15154695Sbaban 	    *mapping->id2.idmap_id_u.sid.prefix != '\0') {
15164520Snw141292 		*sidprefix = strdup(mapping->id2.idmap_id_u.sid.prefix);
15174520Snw141292 		if (*sidprefix == NULL) {
15184520Snw141292 			retcode = IDMAP_ERR_MEMORY;
15194520Snw141292 			goto errout;
15204520Snw141292 		}
15214520Snw141292 	}
15224520Snw141292 	if (rid)
15234520Snw141292 		*rid = mapping->id2.idmap_id_u.sid.rid;
1524*5064Sdm199847 
1525*5064Sdm199847 	rc = idmap_strdupnull(winname, mapping->id2name);
1526*5064Sdm199847 	if (rc != IDMAP_SUCCESS)
1527*5064Sdm199847 		retcode = rc;
1528*5064Sdm199847 
1529*5064Sdm199847 	rc = idmap_strdupnull(windomain, mapping->id2domain);
1530*5064Sdm199847 	if (rc != IDMAP_SUCCESS)
1531*5064Sdm199847 		retcode = rc;
15324520Snw141292 
15334520Snw141292 	goto out;
15344520Snw141292 
15354520Snw141292 errout:
15364520Snw141292 	if (sidprefix && *sidprefix) {
15374520Snw141292 		free(*sidprefix);
15384520Snw141292 		*sidprefix = NULL;
15394520Snw141292 	}
15404520Snw141292 	if (winname && *winname) {
15414520Snw141292 		free(*winname);
15424520Snw141292 		*winname = NULL;
15434520Snw141292 	}
15444520Snw141292 	if (windomain && *windomain) {
15454520Snw141292 		free(*windomain);
15464520Snw141292 		*windomain = NULL;
15474520Snw141292 	}
15484520Snw141292 
15494520Snw141292 out:
15504520Snw141292 	xdr_free(xdr_idmap_mappings_res, (caddr_t)&result);
15514520Snw141292 	if (retcode != IDMAP_SUCCESS)
15524520Snw141292 		errno = idmap_stat2errno(retcode);
15534520Snw141292 	return (retcode);
15544520Snw141292 }
15554520Snw141292 
15564520Snw141292 
15574520Snw141292 
15584520Snw141292 #define	gettext(s)	s
15594520Snw141292 static stat_table_t stattable[] = {
15604520Snw141292 	{IDMAP_SUCCESS, gettext("Success"), 0},
15614520Snw141292 	{IDMAP_NEXT, gettext("More results available"), 0},
15624520Snw141292 	{IDMAP_ERR_OTHER, gettext("Undefined error"), EINVAL},
15634520Snw141292 	{IDMAP_ERR_INTERNAL, gettext("Internal error"), EINVAL},
15644520Snw141292 	{IDMAP_ERR_MEMORY, gettext("Out of memory"), ENOMEM},
15654520Snw141292 	{IDMAP_ERR_NORESULT, gettext("No results available"), EINVAL},
15664520Snw141292 	{IDMAP_ERR_NOTUSER, gettext("Not a user"), EINVAL},
15674520Snw141292 	{IDMAP_ERR_NOTGROUP, gettext("Not a group"), EINVAL},
15684644Sbaban 	{IDMAP_ERR_NOTSUPPORTED, gettext("Operation not supported"), ENOTSUP},
15694520Snw141292 	{IDMAP_ERR_W2U_NAMERULE,
15704520Snw141292 		gettext("Invalid Windows to UNIX name-based rule"), EINVAL},
15714520Snw141292 	{IDMAP_ERR_U2W_NAMERULE,
15724520Snw141292 		gettext("Invalid UNIX to Windows name-based rule"), EINVAL},
15734520Snw141292 	{IDMAP_ERR_CACHE, gettext("Invalid cache"), EINVAL},
15744520Snw141292 	{IDMAP_ERR_DB, gettext("Invalid database"), EINVAL},
15754520Snw141292 	{IDMAP_ERR_ARG, gettext("Invalid argument"), EINVAL},
15764520Snw141292 	{IDMAP_ERR_SID, gettext("Invalid SID"), EINVAL},
15774520Snw141292 	{IDMAP_ERR_IDTYPE, gettext("Invalid identity type"), EINVAL},
15784644Sbaban 	{IDMAP_ERR_RPC_HANDLE, gettext("Bad RPC handle"), EBADF},
15794520Snw141292 	{IDMAP_ERR_RPC, gettext("RPC error"), EINVAL},
15804520Snw141292 	{IDMAP_ERR_CLIENT_HANDLE, gettext("Bad client handle"), EINVAL},
15814644Sbaban 	{IDMAP_ERR_BUSY, gettext("Server is busy"), EBUSY},
15824695Sbaban 	{IDMAP_ERR_PERMISSION_DENIED, gettext("Permission denied"), EACCES},
15834520Snw141292 	{IDMAP_ERR_NOMAPPING,
15844520Snw141292 		gettext("Mapping not found or inhibited"), EINVAL},
15854520Snw141292 	{IDMAP_ERR_NEW_ID_ALLOC_REQD,
15864520Snw141292 		gettext("New mapping needs to be created"), EINVAL},
15874520Snw141292 	{IDMAP_ERR_DOMAIN, gettext("Invalid domain"), EINVAL},
15884520Snw141292 	{IDMAP_ERR_SECURITY, gettext("Security issue"), EINVAL},
15894520Snw141292 	{IDMAP_ERR_NOTFOUND, gettext("Not found"), EINVAL},
15904520Snw141292 	{IDMAP_ERR_DOMAIN_NOTFOUND, gettext("Domain not found"), EINVAL},
15914520Snw141292 	{IDMAP_ERR_UPDATE_NOTALLOWED, gettext("Update not allowed"), EINVAL},
15924520Snw141292 	{IDMAP_ERR_CFG, gettext("Configuration error"), EINVAL},
15934520Snw141292 	{IDMAP_ERR_CFG_CHANGE, gettext("Invalid configuration change"), EINVAL},
15944520Snw141292 	{IDMAP_ERR_NOTMAPPED_WELLKNOWN,
15954520Snw141292 		gettext("No mapping for well-known SID"), EINVAL},
15964520Snw141292 	{IDMAP_ERR_RETRIABLE_NET_ERR,
15974864Sbaban 		gettext("Windows lookup failed"), EINVAL},
15984864Sbaban 	{IDMAP_ERR_W2U_NAMERULE_CONFLICT,
15994864Sbaban 		gettext("Duplicate rule or conflicts with an existing "
16004864Sbaban 		"Windows to UNIX name-based rule"), EINVAL},
16014864Sbaban 	{IDMAP_ERR_U2W_NAMERULE_CONFLICT,
16024864Sbaban 		gettext("Duplicate rule or conflicts with an existing "
16034864Sbaban 		"Unix to Windows name-based rule"), EINVAL},
16044520Snw141292 	{-1, NULL, 0}
16054520Snw141292 };
16064520Snw141292 #undef	gettext
16074520Snw141292 
16084520Snw141292 
16094520Snw141292 /*
16104520Snw141292  * Get description of status code
16114520Snw141292  *
16124520Snw141292  * Input:
16134520Snw141292  * status - Status code returned by libidmap API call
16144520Snw141292  *
16154520Snw141292  * Return Value:
16164520Snw141292  * human-readable localized description of idmap_stat
16174520Snw141292  */
16184520Snw141292 /* ARGSUSED */
16194520Snw141292 const char *
16204520Snw141292 idmap_stat2string(idmap_handle_t *handle, idmap_stat status) {
16214520Snw141292 	int i;
16224520Snw141292 
16234520Snw141292 	for (i = 0; stattable[i].msg; i++) {
16244520Snw141292 		if (stattable[i].retcode == status)
16254526Sbaban 			return (gettext(stattable[i].msg));
16264520Snw141292 	}
16274520Snw141292 	return (gettext("Unknown error"));
16284520Snw141292 }
16294520Snw141292 
16304520Snw141292 
16314520Snw141292 static int
16324520Snw141292 idmap_stat2errno(idmap_stat stat) {
16334520Snw141292 	int i;
16344520Snw141292 	for (i = 0; stattable[i].msg; i++) {
16354520Snw141292 		if (stattable[i].retcode == stat)
16364520Snw141292 			return (stattable[i].errnum);
16374520Snw141292 	}
16384520Snw141292 	return (EINVAL);
16394520Snw141292 }
16404520Snw141292 
16414520Snw141292 
16424520Snw141292 /*
16434520Snw141292  * Get status code from string
16444520Snw141292  */
16454520Snw141292 idmap_stat
16464520Snw141292 idmap_string2stat(const char *str) {
16474520Snw141292 	if (str == NULL)
16484520Snw141292 		return (IDMAP_ERR_INTERNAL);
16494520Snw141292 
16504520Snw141292 #define	return_cmp(a) \
16514520Snw141292 	if (0 == strcmp(str, "IDMAP_ERR_" #a)) \
16524520Snw141292 		return (IDMAP_ERR_ ## a);
16534520Snw141292 
16544520Snw141292 	return_cmp(OTHER);
16554520Snw141292 	return_cmp(INTERNAL);
16564520Snw141292 	return_cmp(MEMORY);
16574520Snw141292 	return_cmp(NORESULT);
16584520Snw141292 	return_cmp(NOTUSER);
16594520Snw141292 	return_cmp(NOTGROUP);
16604520Snw141292 	return_cmp(NOTSUPPORTED);
16614520Snw141292 	return_cmp(W2U_NAMERULE);
16624520Snw141292 	return_cmp(U2W_NAMERULE);
16634520Snw141292 	return_cmp(CACHE);
16644520Snw141292 	return_cmp(DB);
16654520Snw141292 	return_cmp(ARG);
16664520Snw141292 	return_cmp(SID);
16674520Snw141292 	return_cmp(IDTYPE);
16684520Snw141292 	return_cmp(RPC_HANDLE);
16694520Snw141292 	return_cmp(RPC);
16704520Snw141292 	return_cmp(CLIENT_HANDLE);
16714520Snw141292 	return_cmp(BUSY);
16724520Snw141292 	return_cmp(PERMISSION_DENIED);
16734520Snw141292 	return_cmp(NOMAPPING);
16744520Snw141292 	return_cmp(NEW_ID_ALLOC_REQD);
16754520Snw141292 	return_cmp(DOMAIN);
16764520Snw141292 	return_cmp(SECURITY);
16774520Snw141292 	return_cmp(NOTFOUND);
16784520Snw141292 	return_cmp(DOMAIN_NOTFOUND);
16794520Snw141292 	return_cmp(MEMORY);
16804520Snw141292 	return_cmp(UPDATE_NOTALLOWED);
16814520Snw141292 	return_cmp(CFG);
16824520Snw141292 	return_cmp(CFG_CHANGE);
16834520Snw141292 	return_cmp(NOTMAPPED_WELLKNOWN);
16844520Snw141292 	return_cmp(RETRIABLE_NET_ERR);
16854864Sbaban 	return_cmp(W2U_NAMERULE_CONFLICT);
16864864Sbaban 	return_cmp(U2W_NAMERULE_CONFLICT);
16874520Snw141292 #undef return_cmp
16884520Snw141292 
16894520Snw141292 	return (IDMAP_ERR_OTHER);
16904520Snw141292 }
16914520Snw141292 
16924520Snw141292 
16934520Snw141292 /*
16944520Snw141292  * Map the given status to one that can be returned by the protocol
16954520Snw141292  */
16964520Snw141292 idmap_stat
16974520Snw141292 idmap_stat4prot(idmap_stat status) {
16984520Snw141292 	switch (status) {
16994520Snw141292 	case IDMAP_ERR_MEMORY:
17004520Snw141292 	case IDMAP_ERR_CACHE:
17014520Snw141292 		return (IDMAP_ERR_INTERNAL);
17024520Snw141292 	}
17034520Snw141292 	return (status);
17044520Snw141292 }
17055043Sbaban 
17065043Sbaban 
17075043Sbaban /*
1708*5064Sdm199847  * duplicate a string, possibly null
1709*5064Sdm199847  */
1710*5064Sdm199847 static idmap_stat
1711*5064Sdm199847 idmap_strdupnull(char **to, const char *from) {
1712*5064Sdm199847 	if (from == NULL || *from == '\0') {
1713*5064Sdm199847 		*to = NULL;
1714*5064Sdm199847 		return (IDMAP_SUCCESS);
1715*5064Sdm199847 	}
1716*5064Sdm199847 
1717*5064Sdm199847 	*to = strdup(from);
1718*5064Sdm199847 	if (*to == NULL)
1719*5064Sdm199847 		return (IDMAP_ERR_MEMORY);
1720*5064Sdm199847 	return (IDMAP_SUCCESS);
1721*5064Sdm199847 }
1722*5064Sdm199847 
1723*5064Sdm199847 idmap_stat
1724*5064Sdm199847 idmap_namerule_cpy(idmap_namerule *to, idmap_namerule *from) {
1725*5064Sdm199847 	idmap_stat retval;
1726*5064Sdm199847 
1727*5064Sdm199847 	(void) memcpy(to, from, sizeof (idmap_namerule));
1728*5064Sdm199847 
1729*5064Sdm199847 	retval = idmap_strdupnull(&to->windomain, from->windomain);
1730*5064Sdm199847 	if (retval != IDMAP_SUCCESS)
1731*5064Sdm199847 		return (retval);
1732*5064Sdm199847 
1733*5064Sdm199847 	retval = idmap_strdupnull(&to->winname, from->winname);
1734*5064Sdm199847 	if (retval != IDMAP_SUCCESS)
1735*5064Sdm199847 		return (retval);
1736*5064Sdm199847 
1737*5064Sdm199847 	retval = idmap_strdupnull(&to->unixname, from->unixname);
1738*5064Sdm199847 
1739*5064Sdm199847 	return (retval);
1740*5064Sdm199847 }
1741*5064Sdm199847 
1742*5064Sdm199847 
1743*5064Sdm199847 /*
17445043Sbaban  * Get uid given Windows name
17455043Sbaban  */
17465043Sbaban idmap_stat
17475043Sbaban idmap_getuidbywinname(const char *name, const char *domain, uid_t *uid) {
17485043Sbaban 	idmap_handle_t	*ih;
17495043Sbaban 	idmap_retcode	rc;
17505043Sbaban 	int		is_user;
17515043Sbaban 
17525043Sbaban 	if (uid == NULL)
17535043Sbaban 		return (IDMAP_ERR_ARG);
17545043Sbaban 
17555043Sbaban 	/* Get mapping */
17565043Sbaban 	if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS)
17575043Sbaban 		return (rc);
17585043Sbaban 	rc = idmap_get_w2u_mapping(ih, NULL, NULL, name, domain, 0,
17595043Sbaban 	    &is_user, uid, NULL, NULL);
17605043Sbaban 	(void) idmap_fini(ih);
17615043Sbaban 
17625043Sbaban 	/*
17635043Sbaban 	 * XXX Until we have diagonal mapping support, check if
17645043Sbaban 	 * the given name belongs to a user
17655043Sbaban 	 */
17665043Sbaban 	if (rc == IDMAP_SUCCESS && !is_user)
17675043Sbaban 		return (IDMAP_ERR_NOTUSER);
17685043Sbaban 	return (rc);
17695043Sbaban }
17705043Sbaban 
17715043Sbaban 
17725043Sbaban /*
17735043Sbaban  * Get gid given Windows name
17745043Sbaban  */
17755043Sbaban idmap_stat
17765043Sbaban idmap_getgidbywinname(const char *name, const char *domain, gid_t *gid) {
17775043Sbaban 	idmap_handle_t	*ih;
17785043Sbaban 	idmap_retcode	rc;
17795043Sbaban 	int		is_user;
17805043Sbaban 
17815043Sbaban 	if (gid == NULL)
17825043Sbaban 		return (IDMAP_ERR_ARG);
17835043Sbaban 
17845043Sbaban 	/* Get mapping */
17855043Sbaban 	if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS)
17865043Sbaban 		return (rc);
17875043Sbaban 	rc = idmap_get_w2u_mapping(ih, NULL, NULL, name, domain, 0,
17885043Sbaban 	    &is_user, gid, NULL, NULL);
17895043Sbaban 	(void) idmap_fini(ih);
17905043Sbaban 
17915043Sbaban 	/*
17925043Sbaban 	 * XXX Until we have diagonal mapping support, check if
17935043Sbaban 	 * the given name belongs to a group
17945043Sbaban 	 */
17955043Sbaban 	if (rc == IDMAP_SUCCESS && is_user)
17965043Sbaban 		return (IDMAP_ERR_NOTGROUP);
17975043Sbaban 	return (rc);
17985043Sbaban }
17995043Sbaban 
18005043Sbaban 
18015043Sbaban /*
18025043Sbaban  * Get winname given pid
18035043Sbaban  */
18045043Sbaban static idmap_retcode
18055043Sbaban idmap_getwinnamebypid(uid_t pid, int is_user, char **name, char **domain) {
18065043Sbaban 	idmap_handle_t	*ih;
18075043Sbaban 	idmap_retcode	rc;
18085043Sbaban 	int		len;
18095043Sbaban 	char		*winname, *windomain;
18105043Sbaban 
18115043Sbaban 	if (name == NULL)
18125043Sbaban 		return (IDMAP_ERR_ARG);
18135043Sbaban 
18145043Sbaban 	/* Get mapping */
18155043Sbaban 	if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS)
18165043Sbaban 		return (rc);
18175043Sbaban 	rc = idmap_get_u2w_mapping(ih, &pid, NULL, 0, is_user, NULL,
18185043Sbaban 	    NULL, &winname, &windomain, NULL);
18195043Sbaban 	(void) idmap_fini(ih);
18205043Sbaban 
18215043Sbaban 	/* Return on error */
18225043Sbaban 	if (rc != IDMAP_SUCCESS)
18235043Sbaban 		return (rc);
18245043Sbaban 
18255043Sbaban 	/*
18265043Sbaban 	 * The given PID may have been mapped to a locally
18275043Sbaban 	 * generated SID in which case there isn't any
18285043Sbaban 	 * Windows name
18295043Sbaban 	 */
18305043Sbaban 	if (winname == NULL || windomain == NULL) {
18315043Sbaban 		idmap_free(winname);
18325043Sbaban 		idmap_free(windomain);
18335043Sbaban 		return (IDMAP_ERR_NORESULT);
18345043Sbaban 	}
18355043Sbaban 
18365043Sbaban 	if (domain != NULL) {
18375043Sbaban 		*name = winname;
18385043Sbaban 		*domain = windomain;
18395043Sbaban 	} else {
18405043Sbaban 		len = strlen(winname) + strlen(windomain) + 2;
18415043Sbaban 		if ((*name = malloc(len)) != NULL)
18425043Sbaban 			(void) snprintf(*name, len, "%s@%s", winname,
18435043Sbaban 			    windomain);
18445043Sbaban 		else
18455043Sbaban 			rc = IDMAP_ERR_MEMORY;
18465043Sbaban 		idmap_free(winname);
18475043Sbaban 		idmap_free(windomain);
18485043Sbaban 	}
18495043Sbaban 	return (rc);
18505043Sbaban }
18515043Sbaban 
18525043Sbaban 
18535043Sbaban /*
18545043Sbaban  * Get winname given uid
18555043Sbaban  */
18565043Sbaban idmap_stat
18575043Sbaban idmap_getwinnamebyuid(uid_t uid, char **name, char **domain) {
18585043Sbaban 	return (idmap_getwinnamebypid(uid, 1, name, domain));
18595043Sbaban }
18605043Sbaban 
18615043Sbaban 
18625043Sbaban /*
18635043Sbaban  * Get winname given gid
18645043Sbaban  */
18655043Sbaban idmap_stat
18665043Sbaban idmap_getwinnamebygid(gid_t gid, char **name, char **domain) {
18675043Sbaban 	return (idmap_getwinnamebypid(gid, 0, name, domain));
18685043Sbaban }
1869