xref: /onnv-gate/usr/src/lib/libidmap/common/idmap_api.c (revision 12914:e95332bf1454)
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 /*
2212065SKeyur.Desai@Sun.COM  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
234520Snw141292  */
244520Snw141292 
254520Snw141292 
264520Snw141292 /*
274520Snw141292  * libidmap API
284520Snw141292  */
294520Snw141292 
304520Snw141292 #include <stdlib.h>
316616Sdm199847 #include <sys/varargs.h>
324520Snw141292 #include <inttypes.h>
334520Snw141292 #include <errno.h>
344520Snw141292 #include <strings.h>
354520Snw141292 #include <ctype.h>
364520Snw141292 #include <sys/param.h>
374520Snw141292 #include <sys/types.h>
384520Snw141292 #include <sys/stat.h>
394520Snw141292 #include <dlfcn.h>
404520Snw141292 #include <libintl.h>
4112065SKeyur.Desai@Sun.COM #include <syslog.h>
4212508Samw@Sun.COM #include <assert.h>
434520Snw141292 #include "idmap_impl.h"
447369SJulian.Pullen@Sun.COM #include "idmap_cache.h"
454520Snw141292 
464520Snw141292 static struct timeval TIMEOUT = { 25, 0 };
474520Snw141292 
484520Snw141292 static int idmap_stat2errno(idmap_stat);
496616Sdm199847 static idmap_stat	idmap_strdupnull(char **, const char *);
504520Snw141292 
51*12914SJoyce.McIntosh@Sun.COM #define	__ITER_CREATE(itera, argu, ityp)\
524520Snw141292 	itera = calloc(1, sizeof (*itera));\
534520Snw141292 	if (itera == NULL) {\
544520Snw141292 		errno = ENOMEM;\
554520Snw141292 		return (IDMAP_ERR_MEMORY);\
564520Snw141292 	}\
574520Snw141292 	argu = calloc(1, sizeof (*argu));\
584520Snw141292 	if (argu == NULL) {\
594520Snw141292 		free(itera);\
604520Snw141292 		errno = ENOMEM;\
614520Snw141292 		return (IDMAP_ERR_MEMORY);\
624520Snw141292 	}\
634520Snw141292 	itera->type = ityp;\
644520Snw141292 	itera->retcode = IDMAP_NEXT;\
654520Snw141292 	itera->limit = 1024;\
664520Snw141292 	itera->arg = argu;
674520Snw141292 
684520Snw141292 
694520Snw141292 #define	__ITER_ERR_RETURN(itera, argu, xdr_argu, iretcod)\
704520Snw141292 	if (argu) {\
714520Snw141292 		xdr_free(xdr_argu, (caddr_t)argu);\
724520Snw141292 		free(argu);\
734520Snw141292 	}\
744520Snw141292 	if (itera)\
754520Snw141292 		free(itera);\
764520Snw141292 	return (iretcod);
774520Snw141292 
784520Snw141292 
794520Snw141292 #define	__ITER_CHECK(itera, ityp)\
804520Snw141292 	if (itera == NULL) {\
814520Snw141292 		errno = EINVAL;\
824520Snw141292 		return (IDMAP_ERR_ARG);\
834520Snw141292 	}\
844520Snw141292 	if (itera->type != ityp) {\
854520Snw141292 		errno = EINVAL;\
864520Snw141292 		return (IDMAP_ERR_ARG);\
874520Snw141292 	}
884520Snw141292 
894520Snw141292 /*
904520Snw141292  * Free memory allocated by libidmap API
914520Snw141292  *
924520Snw141292  * Input:
934520Snw141292  * ptr - memory to be freed
944520Snw141292  */
954520Snw141292 void
idmap_free(void * ptr)965696Snw141292 idmap_free(void *ptr)
975696Snw141292 {
984520Snw141292 	free(ptr);
994520Snw141292 }
1004520Snw141292 
1014520Snw141292 
102*12914SJoyce.McIntosh@Sun.COM static idmap_stat
idmap_get_prop(idmap_prop_type pr,idmap_prop_res * res)103*12914SJoyce.McIntosh@Sun.COM idmap_get_prop(idmap_prop_type pr, idmap_prop_res *res)
1045696Snw141292 {
105*12914SJoyce.McIntosh@Sun.COM 	idmap_stat retcode;
1066616Sdm199847 
1076616Sdm199847 	(void) memset(res, 0, sizeof (*res));
1086616Sdm199847 
109*12914SJoyce.McIntosh@Sun.COM 	retcode = _idmap_clnt_call(IDMAP_GET_PROP,
1106616Sdm199847 	    (xdrproc_t)xdr_idmap_prop_type, (caddr_t)&pr,
1116616Sdm199847 	    (xdrproc_t)xdr_idmap_prop_res, (caddr_t)res, TIMEOUT);
112*12914SJoyce.McIntosh@Sun.COM 	if (retcode != IDMAP_SUCCESS)
113*12914SJoyce.McIntosh@Sun.COM 		return (retcode);
1146616Sdm199847 
1156616Sdm199847 	return (res->retcode); /* This might not be IDMAP_SUCCESS! */
1166616Sdm199847 }
1176616Sdm199847 
1188361SJulian.Pullen@Sun.COM 
1196616Sdm199847 idmap_stat
idmap_get_prop_ds(idmap_prop_type pr,idmap_ad_disc_ds_t * dc)120*12914SJoyce.McIntosh@Sun.COM idmap_get_prop_ds(idmap_prop_type pr, idmap_ad_disc_ds_t *dc)
1216616Sdm199847 {
1226616Sdm199847 	idmap_prop_res res;
1236616Sdm199847 	idmap_stat rc = IDMAP_SUCCESS;
1246616Sdm199847 
125*12914SJoyce.McIntosh@Sun.COM 	rc = idmap_get_prop(pr, &res);
1266616Sdm199847 	if (rc < 0)
1276616Sdm199847 		return (rc);
1286616Sdm199847 
1296616Sdm199847 	dc->port = res.value.idmap_prop_val_u.dsval.port;
1306616Sdm199847 	(void) strlcpy(dc->host, res.value.idmap_prop_val_u.dsval.host,
1316616Sdm199847 	    AD_DISC_MAXHOSTNAME);
1326616Sdm199847 
1336616Sdm199847 	/* xdr doesn't guarantee 0-termination of char[]: */
1346616Sdm199847 	dc->host[AD_DISC_MAXHOSTNAME - 1] = '\0';
1356616Sdm199847 
1366616Sdm199847 	return (rc);
1376616Sdm199847 }
1386616Sdm199847 
1396616Sdm199847 
1406616Sdm199847 /*
1416616Sdm199847  * Sometimes the property is not set. In that case, str is set to NULL but
1426616Sdm199847  * otherwise IDMAP_SUCCESS is returned.
1436616Sdm199847  */
1446616Sdm199847 idmap_stat
idmap_get_prop_str(idmap_prop_type pr,char ** str)145*12914SJoyce.McIntosh@Sun.COM idmap_get_prop_str(idmap_prop_type pr, char **str)
1466616Sdm199847 {
1476616Sdm199847 	idmap_prop_res res;
1486616Sdm199847 	idmap_stat rc = IDMAP_SUCCESS;
1496616Sdm199847 
150*12914SJoyce.McIntosh@Sun.COM 	rc = idmap_get_prop(pr, &res);
1516616Sdm199847 	if (rc < 0)
1526616Sdm199847 		return (rc);
1536616Sdm199847 
1546616Sdm199847 	rc = idmap_strdupnull(str, res.value.idmap_prop_val_u.utf8val);
1556616Sdm199847 	return (rc);
1566616Sdm199847 }
1574520Snw141292 
1584520Snw141292 /*
1594520Snw141292  * Create/Initialize handle for updates
1604520Snw141292  *
1614520Snw141292  * Output:
1624520Snw141292  * udthandle - update handle
1634520Snw141292  */
1644520Snw141292 idmap_stat
idmap_udt_create(idmap_udt_handle_t ** udthandle)165*12914SJoyce.McIntosh@Sun.COM idmap_udt_create(idmap_udt_handle_t **udthandle)
1665696Snw141292 {
1674520Snw141292 	idmap_udt_handle_t	*tmp;
1684520Snw141292 
169*12914SJoyce.McIntosh@Sun.COM 	if (udthandle == NULL) {
1704520Snw141292 		errno = EINVAL;
1714520Snw141292 		return (IDMAP_ERR_ARG);
1724520Snw141292 	}
1734520Snw141292 	if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
1744520Snw141292 		errno = ENOMEM;
1754520Snw141292 		return (IDMAP_ERR_MEMORY);
1764520Snw141292 	}
1774520Snw141292 
1784520Snw141292 	*udthandle = tmp;
1794520Snw141292 	return (IDMAP_SUCCESS);
1804520Snw141292 }
1814520Snw141292 
1824520Snw141292 
1834520Snw141292 /*
1844520Snw141292  * All the updates specified by the update handle are committed
1854520Snw141292  * in a single transaction. i.e either all succeed or none.
1864520Snw141292  *
1874520Snw141292  * Input:
1884520Snw141292  * udthandle - update handle with the update requests
1894520Snw141292  *
1904520Snw141292  * Return value:
1914520Snw141292  * Status of the commit
1924520Snw141292  */
1934520Snw141292 idmap_stat
idmap_udt_commit(idmap_udt_handle_t * udthandle)1945696Snw141292 idmap_udt_commit(idmap_udt_handle_t *udthandle)
1955696Snw141292 {
1965064Sdm199847 	idmap_update_res	res;
1975064Sdm199847 	idmap_stat		retcode;
1984520Snw141292 
1994520Snw141292 	if (udthandle == NULL) {
2004520Snw141292 		errno = EINVAL;
2014520Snw141292 		return (IDMAP_ERR_ARG);
2024520Snw141292 	}
2035064Sdm199847 
2045064Sdm199847 	(void) memset(&res, 0, sizeof (res));
2055064Sdm199847 
206*12914SJoyce.McIntosh@Sun.COM 	retcode = _idmap_clnt_call(IDMAP_UPDATE,
2075696Snw141292 	    (xdrproc_t)xdr_idmap_update_batch, (caddr_t)&udthandle->batch,
2085696Snw141292 	    (xdrproc_t)xdr_idmap_update_res, (caddr_t)&res,
2095696Snw141292 	    TIMEOUT);
210*12914SJoyce.McIntosh@Sun.COM 	if (retcode != IDMAP_SUCCESS)
2115064Sdm199847 		goto out;
2125064Sdm199847 
2135064Sdm199847 	retcode = udthandle->commit_stat = res.retcode;
2145064Sdm199847 	udthandle->error_index = res.error_index;
2155064Sdm199847 
2165064Sdm199847 	if (retcode != IDMAP_SUCCESS) {
2175064Sdm199847 
2185064Sdm199847 		if (udthandle->error_index < 0)
2195064Sdm199847 			goto out;
2205064Sdm199847 
2215064Sdm199847 		retcode = idmap_namerule_cpy(&udthandle->error_rule,
2225064Sdm199847 		    &res.error_rule);
2235064Sdm199847 		if (retcode != IDMAP_SUCCESS) {
2245064Sdm199847 			udthandle->error_index = -2;
2255064Sdm199847 			goto out;
2265064Sdm199847 		}
2275064Sdm199847 
2285064Sdm199847 		retcode = idmap_namerule_cpy(&udthandle->conflict_rule,
2295064Sdm199847 		    &res.conflict_rule);
2305064Sdm199847 		if (retcode != IDMAP_SUCCESS) {
2315064Sdm199847 			udthandle->error_index = -2;
2325064Sdm199847 			goto out;
2335064Sdm199847 		}
2345064Sdm199847 	}
2355064Sdm199847 
2365064Sdm199847 	retcode = res.retcode;
2375064Sdm199847 
2385064Sdm199847 
2395064Sdm199847 out:
2404644Sbaban 	/* reset handle so that it can be used again */
2415064Sdm199847 	if (retcode == IDMAP_SUCCESS) {
2425064Sdm199847 		_IDMAP_RESET_UDT_HANDLE(udthandle);
2435064Sdm199847 	}
2445064Sdm199847 
2455064Sdm199847 	(void) xdr_free(xdr_idmap_update_res, (caddr_t)&res);
2465064Sdm199847 	errno = idmap_stat2errno(retcode);
2475064Sdm199847 	return (retcode);
2485064Sdm199847 }
2495064Sdm199847 
2505064Sdm199847 
2515064Sdm199847 static void
idmap_namerule_parts_clear(char ** windomain,char ** winname,char ** unixname,boolean_t * is_user,boolean_t * is_wuser,boolean_t * is_nt4,int * direction)2525064Sdm199847 idmap_namerule_parts_clear(char **windomain, char **winname,
2535696Snw141292     char **unixname, boolean_t *is_user, boolean_t *is_wuser,
2545696Snw141292     boolean_t *is_nt4, int *direction)
2555696Snw141292 {
2565064Sdm199847 	if (windomain)
2575064Sdm199847 		*windomain = NULL;
2585064Sdm199847 	if (winname)
2595064Sdm199847 		*winname = NULL;
2605064Sdm199847 	if (unixname)
2615064Sdm199847 		*unixname = NULL;
2625064Sdm199847 
2635064Sdm199847 	if (is_nt4)
2645064Sdm199847 		*is_nt4 = 0;
2655064Sdm199847 	if (is_user)
2665064Sdm199847 		*is_user = -1;
2675696Snw141292 	if (is_wuser)
2685696Snw141292 		*is_wuser = -1;
2695064Sdm199847 	if (direction)
2705064Sdm199847 		*direction = IDMAP_DIRECTION_UNDEF;
2715064Sdm199847 }
2725064Sdm199847 
2735064Sdm199847 static idmap_stat
idmap_namerule2parts(idmap_namerule * rule,char ** windomain,char ** winname,char ** unixname,boolean_t * is_user,boolean_t * is_wuser,boolean_t * is_nt4,int * direction)2745696Snw141292 idmap_namerule2parts(idmap_namerule *rule,
2755064Sdm199847     char **windomain, char **winname,
2765696Snw141292     char **unixname, boolean_t *is_user, boolean_t *is_wuser,
2775696Snw141292     boolean_t *is_nt4, int *direction)
2785696Snw141292 {
2795064Sdm199847 	idmap_stat retcode;
2805064Sdm199847 
2815064Sdm199847 	if (EMPTY_STRING(rule->winname) && EMPTY_STRING(rule->unixname))
2825064Sdm199847 		return (IDMAP_ERR_NORESULT);
2835064Sdm199847 
2845064Sdm199847 
2855064Sdm199847 	retcode = idmap_strdupnull(windomain, rule->windomain);
2865064Sdm199847 	if (retcode != IDMAP_SUCCESS)
2875064Sdm199847 		goto errout;
2885064Sdm199847 
2895064Sdm199847 	retcode = idmap_strdupnull(winname, rule->winname);
2905064Sdm199847 	if (retcode != IDMAP_SUCCESS)
2915064Sdm199847 		goto errout;
2925064Sdm199847 
2935064Sdm199847 	retcode = idmap_strdupnull(unixname, rule->unixname);
2945064Sdm199847 	if (retcode != IDMAP_SUCCESS)
2955064Sdm199847 		goto errout;
2965064Sdm199847 
2975064Sdm199847 
2985064Sdm199847 	if (is_user)
2995064Sdm199847 		*is_user = rule->is_user;
3005696Snw141292 	if (is_wuser)
3015696Snw141292 		*is_wuser = rule->is_wuser;
3025064Sdm199847 	if (is_nt4)
3035064Sdm199847 		*is_nt4 = rule->is_nt4;
3045064Sdm199847 	if (direction)
3055064Sdm199847 		*direction = rule->direction;
3065064Sdm199847 
3075064Sdm199847 
3085064Sdm199847 	return (IDMAP_SUCCESS);
3094644Sbaban 
3105064Sdm199847 errout:
3115064Sdm199847 	if (windomain && *windomain)
3125064Sdm199847 		free(*windomain);
3135064Sdm199847 	if (winname && *winname)
3145064Sdm199847 		free(*winname);
3155064Sdm199847 	if (unixname && *unixname)
3165064Sdm199847 		free(*unixname);
3175064Sdm199847 
3185064Sdm199847 	idmap_namerule_parts_clear(windomain, winname,
3195696Snw141292 	    unixname, is_user, is_wuser, is_nt4, direction);
3205064Sdm199847 
3214520Snw141292 	return (retcode);
3225064Sdm199847 
3235064Sdm199847 }
3245064Sdm199847 
3255064Sdm199847 /*
3265064Sdm199847  * Retrieve the index of the failed batch element. error_index == -1
3275064Sdm199847  * indicates failure at the beginning, -2 at the end.
3285064Sdm199847  *
3295064Sdm199847  * If idmap_udt_commit didn't return error, the returned value is undefined.
3305064Sdm199847  *
3315064Sdm199847  * Return value:
3325064Sdm199847  * IDMAP_SUCCESS
3335064Sdm199847  */
3345064Sdm199847 
3355064Sdm199847 idmap_stat
idmap_udt_get_error_index(idmap_udt_handle_t * udthandle,int64_t * error_index)3365064Sdm199847 idmap_udt_get_error_index(idmap_udt_handle_t *udthandle,
3375696Snw141292     int64_t *error_index)
3385696Snw141292 {
3395064Sdm199847 	if (error_index)
3405064Sdm199847 		*error_index = udthandle->error_index;
3415064Sdm199847 
3425064Sdm199847 	return (IDMAP_SUCCESS);
3435064Sdm199847 }
3445064Sdm199847 
3455064Sdm199847 
3465064Sdm199847 /*
3475064Sdm199847  * Retrieve the rule which caused the batch to fail. If
3485064Sdm199847  * idmap_udt_commit didn't return error or if error_index is < 0, the
3495064Sdm199847  * retrieved rule is undefined.
3505064Sdm199847  *
3515064Sdm199847  * Return value:
3525064Sdm199847  * IDMAP_ERR_NORESULT if there is no error rule.
3535064Sdm199847  * IDMAP_SUCCESS if the rule was obtained OK.
3545064Sdm199847  * other error code (IDMAP_ERR_NOMEMORY etc)
3555064Sdm199847  */
3565064Sdm199847 
3575064Sdm199847 idmap_stat
idmap_udt_get_error_rule(idmap_udt_handle_t * udthandle,char ** windomain,char ** winname,char ** unixname,boolean_t * is_user,boolean_t * is_wuser,boolean_t * is_nt4,int * direction)3585064Sdm199847 idmap_udt_get_error_rule(idmap_udt_handle_t *udthandle,
3595064Sdm199847     char **windomain, char **winname,
3605696Snw141292     char **unixname, boolean_t *is_user, boolean_t *is_wuser,
3615696Snw141292     boolean_t *is_nt4, int *direction)
3625696Snw141292 {
3635064Sdm199847 	idmap_namerule_parts_clear(windomain, winname,
3645696Snw141292 	    unixname, is_user, is_wuser, is_nt4, direction);
3655064Sdm199847 
3665064Sdm199847 	if (udthandle->commit_stat == IDMAP_SUCCESS ||
3675064Sdm199847 	    udthandle->error_index < 0)
3685064Sdm199847 		return (IDMAP_ERR_NORESULT);
3695064Sdm199847 
3705064Sdm199847 	return (idmap_namerule2parts(
3715696Snw141292 	    &udthandle->error_rule,
3725696Snw141292 	    windomain,
3735696Snw141292 	    winname,
3745696Snw141292 	    unixname,
3755696Snw141292 	    is_user,
3765696Snw141292 	    is_wuser,
3775696Snw141292 	    is_nt4,
3785696Snw141292 	    direction));
3795064Sdm199847 }
3805064Sdm199847 
3815064Sdm199847 /*
3825064Sdm199847  * Retrieve the rule with which there was a conflict. TODO: retrieve
3835064Sdm199847  * the value.
3845064Sdm199847  *
3855064Sdm199847  * Return value:
3865064Sdm199847  * IDMAP_ERR_NORESULT if there is no error rule.
3875064Sdm199847  * IDMAP_SUCCESS if the rule was obtained OK.
3885064Sdm199847  * other error code (IDMAP_ERR_NOMEMORY etc)
3895064Sdm199847  */
3905064Sdm199847 
3915064Sdm199847 idmap_stat
idmap_udt_get_conflict_rule(idmap_udt_handle_t * udthandle,char ** windomain,char ** winname,char ** unixname,boolean_t * is_user,boolean_t * is_wuser,boolean_t * is_nt4,int * direction)3925064Sdm199847 idmap_udt_get_conflict_rule(idmap_udt_handle_t *udthandle,
3935064Sdm199847     char **windomain, char **winname,
3945696Snw141292     char **unixname, boolean_t *is_user, boolean_t *is_wuser,
3955696Snw141292     boolean_t *is_nt4, int *direction)
3965696Snw141292 {
3975064Sdm199847 	idmap_namerule_parts_clear(windomain, winname,
3985696Snw141292 	    unixname, is_user, is_wuser, is_nt4, direction);
3995064Sdm199847 
4005064Sdm199847 	if (udthandle->commit_stat != IDMAP_ERR_W2U_NAMERULE_CONFLICT &&
4015064Sdm199847 	    udthandle->commit_stat != IDMAP_ERR_U2W_NAMERULE_CONFLICT) {
4025696Snw141292 		return (IDMAP_ERR_NORESULT);
4035064Sdm199847 	}
4045064Sdm199847 
4055064Sdm199847 	return (idmap_namerule2parts(
4065696Snw141292 	    &udthandle->conflict_rule,
4075696Snw141292 	    windomain,
4085696Snw141292 	    winname,
4095696Snw141292 	    unixname,
4105696Snw141292 	    is_user,
4115696Snw141292 	    is_wuser,
4125696Snw141292 	    is_nt4,
4135696Snw141292 	    direction));
4144520Snw141292 }
4154520Snw141292 
4164520Snw141292 
4174520Snw141292 /*
4184520Snw141292  * Destroy the update handle
4194520Snw141292  */
4204520Snw141292 void
idmap_udt_destroy(idmap_udt_handle_t * udthandle)4215696Snw141292 idmap_udt_destroy(idmap_udt_handle_t *udthandle)
4225696Snw141292 {
4234520Snw141292 	if (udthandle == NULL)
4244520Snw141292 		return;
4254520Snw141292 	(void) xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch);
4265064Sdm199847 	(void) xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->error_rule);
4275064Sdm199847 	(void) xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->conflict_rule);
4284520Snw141292 	free(udthandle);
4294520Snw141292 }
4304520Snw141292 
4314520Snw141292 
4324520Snw141292 idmap_stat
idmap_udt_add_namerule(idmap_udt_handle_t * udthandle,const char * windomain,boolean_t is_user,boolean_t is_wuser,const char * winname,const char * unixname,boolean_t is_nt4,int direction)4334520Snw141292 idmap_udt_add_namerule(idmap_udt_handle_t *udthandle, const char *windomain,
4345696Snw141292     boolean_t is_user, boolean_t is_wuser, const char *winname,
4355696Snw141292     const char *unixname, boolean_t is_nt4, int direction)
4365696Snw141292 {
4374520Snw141292 	idmap_retcode	retcode;
4384644Sbaban 	idmap_namerule	*rule = NULL;
4394520Snw141292 
4404644Sbaban 	retcode = _udt_extend_batch(udthandle);
4414520Snw141292 	if (retcode != IDMAP_SUCCESS)
4424520Snw141292 		goto errout;
4434520Snw141292 
4444520Snw141292 	rule = &udthandle->batch.
4455696Snw141292 	    idmap_update_batch_val[udthandle->next].
4465696Snw141292 	    idmap_update_op_u.rule;
4474520Snw141292 	rule->is_user = is_user;
4485696Snw141292 	rule->is_wuser = is_wuser;
4494520Snw141292 	rule->direction = direction;
4504520Snw141292 	rule->is_nt4 = is_nt4;
4515064Sdm199847 
4525064Sdm199847 	retcode = idmap_strdupnull(&rule->windomain, windomain);
4535064Sdm199847 	if (retcode != IDMAP_SUCCESS)
4545064Sdm199847 		goto errout;
4555064Sdm199847 
4565064Sdm199847 	retcode = idmap_strdupnull(&rule->winname, winname);
4575064Sdm199847 	if (retcode != IDMAP_SUCCESS)
4585064Sdm199847 		goto errout;
4595064Sdm199847 
4605064Sdm199847 	retcode = idmap_strdupnull(&rule->unixname, unixname);
4615064Sdm199847 	if (retcode != IDMAP_SUCCESS)
4625064Sdm199847 		goto errout;
4634644Sbaban 
4644644Sbaban 	udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
4654644Sbaban 	    OP_ADD_NAMERULE;
4664520Snw141292 	udthandle->next++;
4674520Snw141292 	return (IDMAP_SUCCESS);
4684520Snw141292 
4694520Snw141292 errout:
4704644Sbaban 	/* The batch should still be usable */
4714644Sbaban 	if (rule)
4724644Sbaban 		(void) xdr_free(xdr_idmap_namerule, (caddr_t)rule);
4734520Snw141292 	errno = idmap_stat2errno(retcode);
4744520Snw141292 	return (retcode);
4754520Snw141292 }
4764520Snw141292 
4774520Snw141292 
4784520Snw141292 /* ARGSUSED */
4794520Snw141292 idmap_stat
idmap_udt_rm_namerule(idmap_udt_handle_t * udthandle,boolean_t is_user,boolean_t is_wuser,const char * windomain,const char * winname,const char * unixname,int direction)4804520Snw141292 idmap_udt_rm_namerule(idmap_udt_handle_t *udthandle, boolean_t is_user,
4815696Snw141292     boolean_t is_wuser,	const char *windomain, const char *winname,
4825696Snw141292     const char *unixname, int direction)
4835696Snw141292 {
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.
4925696Snw141292 	    idmap_update_batch_val[udthandle->next].
4935696Snw141292 	    idmap_update_op_u.rule;
4944520Snw141292 	rule->is_user = is_user;
4955696Snw141292 	rule->is_wuser = is_wuser;
4964520Snw141292 	rule->direction = direction;
4975064Sdm199847 
4985064Sdm199847 	retcode = idmap_strdupnull(&rule->windomain, windomain);
4995064Sdm199847 	if (retcode != IDMAP_SUCCESS)
5005064Sdm199847 		goto errout;
5015064Sdm199847 
5025064Sdm199847 	retcode = idmap_strdupnull(&rule->winname, winname);
5035064Sdm199847 	if (retcode != IDMAP_SUCCESS)
5045064Sdm199847 		goto errout;
5055064Sdm199847 
5065064Sdm199847 	retcode = idmap_strdupnull(&rule->unixname, unixname);
5075064Sdm199847 	if (retcode != IDMAP_SUCCESS)
5085064Sdm199847 		goto errout;
5095064Sdm199847 
5104644Sbaban 	udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
5114644Sbaban 	    OP_RM_NAMERULE;
5124520Snw141292 	udthandle->next++;
5134520Snw141292 	return (IDMAP_SUCCESS);
5144520Snw141292 
5154520Snw141292 errout:
5164644Sbaban 	if (rule)
5174644Sbaban 		(void) xdr_free(xdr_idmap_namerule, (caddr_t)rule);
5184520Snw141292 	errno = idmap_stat2errno(retcode);
5194520Snw141292 	return (retcode);
5204520Snw141292 }
5214520Snw141292 
5224520Snw141292 
5234520Snw141292 /* ARGSUSED */
5244520Snw141292 idmap_stat
idmap_udt_flush_namerules(idmap_udt_handle_t * udthandle)5255696Snw141292 idmap_udt_flush_namerules(idmap_udt_handle_t *udthandle)
5265696Snw141292 {
5274520Snw141292 	idmap_retcode	retcode;
5284520Snw141292 
5294644Sbaban 	retcode = _udt_extend_batch(udthandle);
5304520Snw141292 	if (retcode != IDMAP_SUCCESS)
5314520Snw141292 		goto errout;
5324520Snw141292 
5334644Sbaban 	udthandle->batch.idmap_update_batch_val[udthandle->next].opnum =
5344644Sbaban 	    OP_FLUSH_NAMERULES;
5354520Snw141292 	udthandle->next++;
5364520Snw141292 	return (IDMAP_SUCCESS);
5374520Snw141292 
5384520Snw141292 errout:
5394520Snw141292 	errno = idmap_stat2errno(retcode);
5404520Snw141292 	return (retcode);
5414520Snw141292 }
5424520Snw141292 
5434520Snw141292 
5444520Snw141292 /*
5454520Snw141292  * Set the number of entries requested per batch by the iterator
5464520Snw141292  *
5474520Snw141292  * Input:
5484520Snw141292  * iter  - iterator
5494520Snw141292  * limit - number of entries requested per batch
5504520Snw141292  */
5514520Snw141292 idmap_stat
idmap_iter_set_limit(idmap_iter_t * iter,uint64_t limit)5525696Snw141292 idmap_iter_set_limit(idmap_iter_t *iter, uint64_t limit)
5535696Snw141292 {
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
idmap_iter_namerules(const char * windomain,boolean_t is_user,boolean_t is_wuser,const char * winname,const char * unixname,idmap_iter_t ** iter)576*12914SJoyce.McIntosh@Sun.COM idmap_iter_namerules(const char *windomain,
5775696Snw141292 		boolean_t is_user, boolean_t is_wuser, const char *winname,
5785696Snw141292 		const char *unixname, idmap_iter_t **iter)
5795696Snw141292 {
5804520Snw141292 
5814520Snw141292 	idmap_iter_t			*tmpiter;
5824520Snw141292 	idmap_list_namerules_1_argument	*arg = NULL;
5834520Snw141292 	idmap_namerule			*rule;
5844520Snw141292 	idmap_retcode			retcode;
5854520Snw141292 
586*12914SJoyce.McIntosh@Sun.COM 	__ITER_CREATE(tmpiter, arg, IDMAP_LIST_NAMERULES);
5874520Snw141292 
5884520Snw141292 	rule = &arg->rule;
5894520Snw141292 	rule->is_user = is_user;
5905696Snw141292 	rule->is_wuser = is_wuser;
5914644Sbaban 	rule->direction = IDMAP_DIRECTION_UNDEF;
5925064Sdm199847 
5935064Sdm199847 	retcode = idmap_strdupnull(&rule->windomain, windomain);
5945064Sdm199847 	if (retcode != IDMAP_SUCCESS)
5955064Sdm199847 		goto errout;
5965064Sdm199847 
5975064Sdm199847 	retcode = idmap_strdupnull(&rule->winname, winname);
5985064Sdm199847 	if (retcode != IDMAP_SUCCESS)
5995064Sdm199847 		goto errout;
6005064Sdm199847 
6015064Sdm199847 	retcode = idmap_strdupnull(&rule->unixname, unixname);
6025064Sdm199847 	if (retcode != IDMAP_SUCCESS)
6035064Sdm199847 		goto errout;
6044520Snw141292 
6054520Snw141292 	*iter = tmpiter;
6064520Snw141292 	return (IDMAP_SUCCESS);
6074520Snw141292 
6084520Snw141292 errout:
6094520Snw141292 	__ITER_ERR_RETURN(tmpiter, arg,
6105696Snw141292 	    xdr_idmap_list_namerules_1_argument, retcode);
6114520Snw141292 }
6124520Snw141292 
6134520Snw141292 
6144520Snw141292 /*
6154520Snw141292  * Iterate through the name-based mapping rules
6164520Snw141292  *
6174520Snw141292  * Input:
6184520Snw141292  * iter - iterator
6194520Snw141292  *
6204520Snw141292  * Output:
6214520Snw141292  * windomain - Windows domain
6224520Snw141292  * winname   - Windows user or group name
6234520Snw141292  * unixname  - Unix user or group name
6244520Snw141292  * is_nt4    - NT4 or AD
6254520Snw141292  * direction - bi(0), win2unix(1), unix2win(2)
6264520Snw141292  *
6274520Snw141292  * Return value:
6284520Snw141292  * 0   - done
6294520Snw141292  * 1   - more results available
6304520Snw141292  * < 0 - error
6314520Snw141292  */
6324520Snw141292 idmap_stat
idmap_iter_next_namerule(idmap_iter_t * iter,char ** windomain,char ** winname,char ** unixname,boolean_t * is_user,boolean_t * is_wuser,boolean_t * is_nt4,int * direction)6334520Snw141292 idmap_iter_next_namerule(idmap_iter_t *iter, char **windomain,
6345696Snw141292     char **winname, char **unixname,  boolean_t *is_user,
6355696Snw141292     boolean_t *is_wuser, boolean_t *is_nt4, int *direction)
6365696Snw141292 {
6374520Snw141292 	idmap_namerules_res		*namerules;
6384520Snw141292 	idmap_list_namerules_1_argument	*arg;
6394520Snw141292 	idmap_retcode			retcode;
6404520Snw141292 
6415696Snw141292 	idmap_namerule_parts_clear(windomain, winname,
6425696Snw141292 	    unixname, is_user, is_wuser, is_nt4, direction);
6435696Snw141292 
6444520Snw141292 
6454520Snw141292 	__ITER_CHECK(iter, IDMAP_LIST_NAMERULES);
6464520Snw141292 
6474520Snw141292 	namerules = (idmap_namerules_res *)iter->retlist;
6484520Snw141292 	if (iter->retcode == IDMAP_NEXT && (namerules == NULL ||
6495696Snw141292 	    iter->next >= namerules->rules.rules_len)) {
6504520Snw141292 
6514520Snw141292 		if ((arg = iter->arg) == NULL) {
6524520Snw141292 			errno = EINVAL;
6534520Snw141292 			return (IDMAP_ERR_ARG);
6544520Snw141292 		}
6554520Snw141292 		arg->limit = iter->limit;
6564520Snw141292 
6574520Snw141292 		retcode = _iter_get_next_list(IDMAP_LIST_NAMERULES,
6585696Snw141292 		    iter, arg,
6595696Snw141292 		    (uchar_t **)&namerules, sizeof (*namerules),
6605696Snw141292 		    (xdrproc_t)xdr_idmap_list_namerules_1_argument,
6615696Snw141292 		    (xdrproc_t)xdr_idmap_namerules_res);
6624520Snw141292 		if (retcode != IDMAP_SUCCESS)
6634520Snw141292 			return (retcode);
6644520Snw141292 
6654520Snw141292 		if (IDMAP_ERROR(namerules->retcode)) {
6664520Snw141292 			retcode  = namerules->retcode;
6674520Snw141292 			xdr_free(xdr_idmap_namerules_res, (caddr_t)namerules);
6684520Snw141292 			free(namerules);
6694520Snw141292 			iter->retlist = NULL;
6704520Snw141292 			return (retcode);
6714520Snw141292 		}
6724520Snw141292 		iter->retcode = namerules->retcode;
6734520Snw141292 		arg->lastrowid = namerules->lastrowid;
6744520Snw141292 	}
6754520Snw141292 
6764520Snw141292 	if (namerules == NULL || namerules->rules.rules_len == 0)
6774520Snw141292 		return (IDMAP_SUCCESS);
6784520Snw141292 
6794520Snw141292 	if (iter->next >= namerules->rules.rules_len) {
6804520Snw141292 		return (IDMAP_ERR_ARG);
6814520Snw141292 	}
6824520Snw141292 
6835064Sdm199847 	retcode = idmap_strdupnull(windomain,
6845064Sdm199847 	    namerules->rules.rules_val[iter->next].windomain);
6855064Sdm199847 	if (retcode != IDMAP_SUCCESS)
6865064Sdm199847 		goto errout;
6875064Sdm199847 
6885064Sdm199847 	retcode = idmap_strdupnull(winname,
6895064Sdm199847 	    namerules->rules.rules_val[iter->next].winname);
6905064Sdm199847 	if (retcode != IDMAP_SUCCESS)
6915064Sdm199847 		goto errout;
6925064Sdm199847 
6935064Sdm199847 	retcode = idmap_strdupnull(unixname,
6945064Sdm199847 	    namerules->rules.rules_val[iter->next].unixname);
6955064Sdm199847 	if (retcode != IDMAP_SUCCESS)
6965064Sdm199847 		goto errout;
6975064Sdm199847 
6984520Snw141292 	if (is_nt4)
6994520Snw141292 		*is_nt4 = namerules->rules.rules_val[iter->next].is_nt4;
7005696Snw141292 	if (is_user)
7015696Snw141292 		*is_user = namerules->rules.rules_val[iter->next].is_user;
7025696Snw141292 	if (is_wuser)
7035696Snw141292 		*is_wuser = namerules->rules.rules_val[iter->next].is_wuser;
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  * Output:
7284520Snw141292  * iter - iterator
7294520Snw141292  */
7304520Snw141292 idmap_stat
idmap_iter_mappings(idmap_iter_t ** iter,int flag)731*12914SJoyce.McIntosh@Sun.COM idmap_iter_mappings(idmap_iter_t **iter, int flag)
7325696Snw141292 {
7334520Snw141292 	idmap_iter_t			*tmpiter;
7344520Snw141292 	idmap_list_mappings_1_argument	*arg = NULL;
7354520Snw141292 
736*12914SJoyce.McIntosh@Sun.COM 	__ITER_CREATE(tmpiter, arg, IDMAP_LIST_MAPPINGS);
7374520Snw141292 
7386386Sjp151216 	arg->flag = flag;
7394520Snw141292 	*iter = tmpiter;
7404520Snw141292 	return (IDMAP_SUCCESS);
7414520Snw141292 }
7424520Snw141292 
7434520Snw141292 
7444520Snw141292 /*
7454520Snw141292  * Iterate through the SID to UID/GID mappings
7464520Snw141292  *
7474520Snw141292  * Input:
7484520Snw141292  * iter - iterator
7494520Snw141292  *
7504520Snw141292  * Output:
7514520Snw141292  * sid - SID in canonical form
7524520Snw141292  * pid - UID or GID
7534520Snw141292  *
7544520Snw141292  * Return value:
7554520Snw141292  * 0   - done
7564520Snw141292  * 1   - more results available
7574520Snw141292  * < 0 - error
7584520Snw141292  */
7594520Snw141292 idmap_stat
idmap_iter_next_mapping(idmap_iter_t * iter,char ** sidprefix,idmap_rid_t * rid,uid_t * pid,char ** winname,char ** windomain,char ** unixname,boolean_t * is_user,boolean_t * is_wuser,int * direction,idmap_info * info)7604520Snw141292 idmap_iter_next_mapping(idmap_iter_t *iter, char **sidprefix,
7615696Snw141292     idmap_rid_t *rid, uid_t *pid, char **winname,
7625696Snw141292     char **windomain, char **unixname, boolean_t *is_user,
7636386Sjp151216     boolean_t *is_wuser, int *direction, idmap_info *info)
7645696Snw141292 {
7654520Snw141292 	idmap_mappings_res		*mappings;
7664520Snw141292 	idmap_list_mappings_1_argument	*arg;
7674520Snw141292 	idmap_retcode			retcode;
7684520Snw141292 	char				*str;
7694520Snw141292 
7704520Snw141292 	if (sidprefix)
7714520Snw141292 		*sidprefix = NULL;
7724520Snw141292 	if (rid)
7734520Snw141292 		*rid = UINT32_MAX;
7744520Snw141292 	if (winname)
7754520Snw141292 		*winname = NULL;
7764520Snw141292 	if (windomain)
7774520Snw141292 		*windomain = NULL;
7784520Snw141292 	if (unixname)
7794520Snw141292 		*unixname = NULL;
7804520Snw141292 	if (pid)
7814520Snw141292 		*pid = UINT32_MAX;
7825696Snw141292 	if (is_user)
7835696Snw141292 		*is_user = -1;
7845696Snw141292 	if (is_wuser)
7855696Snw141292 		*is_wuser = -1;
7864520Snw141292 	if (direction)
7874644Sbaban 		*direction = IDMAP_DIRECTION_UNDEF;
7884520Snw141292 
7894520Snw141292 	__ITER_CHECK(iter, IDMAP_LIST_MAPPINGS);
7904520Snw141292 
7914520Snw141292 	mappings = (idmap_mappings_res *)iter->retlist;
7924520Snw141292 	if (iter->retcode == IDMAP_NEXT && (mappings == NULL ||
7935696Snw141292 	    iter->next >= mappings->mappings.mappings_len)) {
7944520Snw141292 
7954520Snw141292 		if ((arg = iter->arg) == NULL) {
7964520Snw141292 			errno = EINVAL;
7974520Snw141292 			return (IDMAP_ERR_ARG);
7984520Snw141292 		}
7994520Snw141292 		arg->limit = iter->limit;
8004520Snw141292 
8014520Snw141292 		retcode = _iter_get_next_list(IDMAP_LIST_MAPPINGS,
8025696Snw141292 		    iter, arg,
8035696Snw141292 		    (uchar_t **)&mappings, sizeof (*mappings),
8045696Snw141292 		    (xdrproc_t)xdr_idmap_list_mappings_1_argument,
8055696Snw141292 		    (xdrproc_t)xdr_idmap_mappings_res);
8064520Snw141292 		if (retcode != IDMAP_SUCCESS)
8074520Snw141292 			return (retcode);
8084520Snw141292 
8094520Snw141292 		if (IDMAP_ERROR(mappings->retcode)) {
8104520Snw141292 			retcode  = mappings->retcode;
8114520Snw141292 			xdr_free(xdr_idmap_mappings_res, (caddr_t)mappings);
8124520Snw141292 			free(mappings);
8134520Snw141292 			iter->retlist = NULL;
8144520Snw141292 			return (retcode);
8154520Snw141292 		}
8164520Snw141292 		iter->retcode = mappings->retcode;
8174520Snw141292 		arg->lastrowid = mappings->lastrowid;
8184520Snw141292 	}
8194520Snw141292 
8204520Snw141292 	if (mappings == NULL || mappings->mappings.mappings_len == 0)
8214520Snw141292 		return (IDMAP_SUCCESS);
8224520Snw141292 
8234520Snw141292 	if (iter->next >= mappings->mappings.mappings_len) {
8244520Snw141292 		return (IDMAP_ERR_ARG);
8254520Snw141292 	}
8264520Snw141292 
8274520Snw141292 	if (sidprefix) {
8284520Snw141292 		str = mappings->mappings.mappings_val[iter->next].id1.
8295696Snw141292 		    idmap_id_u.sid.prefix;
8304695Sbaban 		if (str && *str != '\0') {
8314520Snw141292 			*sidprefix = strdup(str);
8324526Sbaban 			if (*sidprefix == NULL) {
8334526Sbaban 				retcode = IDMAP_ERR_MEMORY;
8344526Sbaban 				goto errout;
8354526Sbaban 			}
8364520Snw141292 		}
8374520Snw141292 	}
8384520Snw141292 	if (rid)
8394520Snw141292 		*rid = mappings->mappings.mappings_val[iter->next].id1.
8405696Snw141292 		    idmap_id_u.sid.rid;
8415064Sdm199847 
8425064Sdm199847 	retcode = idmap_strdupnull(windomain,
8435064Sdm199847 	    mappings->mappings.mappings_val[iter->next].id1domain);
8445064Sdm199847 	if (retcode != IDMAP_SUCCESS)
8455064Sdm199847 		goto errout;
8465064Sdm199847 
8475064Sdm199847 	retcode = idmap_strdupnull(winname,
8485064Sdm199847 	    mappings->mappings.mappings_val[iter->next].id1name);
8495064Sdm199847 	if (retcode != IDMAP_SUCCESS)
8505064Sdm199847 		goto errout;
8515064Sdm199847 
8525064Sdm199847 	retcode = idmap_strdupnull(unixname,
8535064Sdm199847 	    mappings->mappings.mappings_val[iter->next].id2name);
8545064Sdm199847 	if (retcode != IDMAP_SUCCESS)
8555064Sdm199847 		goto errout;
8565064Sdm199847 
8575064Sdm199847 
8584520Snw141292 	if (pid)
8594520Snw141292 		*pid = mappings->mappings.mappings_val[iter->next].id2.
8605696Snw141292 		    idmap_id_u.uid;
8614520Snw141292 	if (direction)
8624520Snw141292 		*direction = mappings->mappings.mappings_val[iter->next].
8635696Snw141292 		    direction;
8645696Snw141292 	if (is_user)
8655696Snw141292 		*is_user = (mappings->mappings.mappings_val[iter->next].id2
8665696Snw141292 		    .idtype == IDMAP_UID)?1:0;
8675696Snw141292 	if (is_wuser)
8685696Snw141292 		*is_wuser = (mappings->mappings.mappings_val[iter->next].id1
8695696Snw141292 		    .idtype == IDMAP_USID)?1:0;
8705696Snw141292 
8716386Sjp151216 	if (info) {
87212508Samw@Sun.COM 		idmap_info_mov(info,
8736386Sjp151216 		    &mappings->mappings.mappings_val[iter->next].info);
8746386Sjp151216 	}
8754520Snw141292 	iter->next++;
8764520Snw141292 
8774520Snw141292 	if (iter->next == mappings->mappings.mappings_len)
8784520Snw141292 		return (iter->retcode);
8794520Snw141292 	else
8804520Snw141292 		return (IDMAP_NEXT);
8814520Snw141292 
8824520Snw141292 errout:
8834520Snw141292 	if (sidprefix && *sidprefix)
8844520Snw141292 		free(*sidprefix);
8854520Snw141292 	if (winname && *winname)
8864520Snw141292 		free(*winname);
8874520Snw141292 	if (windomain && *windomain)
8884520Snw141292 		free(*windomain);
8894520Snw141292 	if (unixname && *unixname)
8904520Snw141292 		free(*unixname);
8914520Snw141292 	return (retcode);
8924520Snw141292 }
8934520Snw141292 
8944520Snw141292 
8954520Snw141292 /*
8964520Snw141292  * Destroy the iterator
8974520Snw141292  */
8984520Snw141292 void
idmap_iter_destroy(idmap_iter_t * iter)8995696Snw141292 idmap_iter_destroy(idmap_iter_t *iter)
9005696Snw141292 {
9014520Snw141292 	xdrproc_t _xdr_argument, _xdr_result;
9024520Snw141292 
9034520Snw141292 	if (iter == NULL)
9044520Snw141292 		return;
9054520Snw141292 
9064520Snw141292 	switch (iter->type) {
9074520Snw141292 	case IDMAP_LIST_NAMERULES:
9084520Snw141292 		_xdr_argument = (xdrproc_t)xdr_idmap_list_namerules_1_argument;
9094520Snw141292 		_xdr_result = (xdrproc_t)xdr_idmap_namerules_res;
9104520Snw141292 		break;
9114520Snw141292 	case IDMAP_LIST_MAPPINGS:
9124520Snw141292 		_xdr_argument = (xdrproc_t)xdr_idmap_list_mappings_1_argument;
9134520Snw141292 		_xdr_result = (xdrproc_t)xdr_idmap_mappings_res;
9144520Snw141292 		break;
9154520Snw141292 	default:
9164520Snw141292 		free(iter);
9174520Snw141292 		return;
9184520Snw141292 	};
9194520Snw141292 
9204520Snw141292 	if (iter->arg) {
9214520Snw141292 		xdr_free(_xdr_argument, (caddr_t)iter->arg);
9224520Snw141292 		free(iter->arg);
9234520Snw141292 	}
9244520Snw141292 	if (iter->retlist) {
9254520Snw141292 		xdr_free(_xdr_result, (caddr_t)iter->retlist);
9264520Snw141292 		free(iter->retlist);
9274520Snw141292 	}
9284520Snw141292 	free(iter);
9294520Snw141292 }
9304520Snw141292 
9314520Snw141292 
9324520Snw141292 /*
9334520Snw141292  * Create handle to get SID to UID/GID mapping entries
9344520Snw141292  *
9354520Snw141292  * Input:
9364520Snw141292  * gh - "get mapping" handle
9374520Snw141292  */
9384520Snw141292 idmap_stat
idmap_get_create(idmap_get_handle_t ** gh)939*12914SJoyce.McIntosh@Sun.COM idmap_get_create(idmap_get_handle_t **gh)
9405696Snw141292 {
9414520Snw141292 	idmap_get_handle_t	*tmp;
9424520Snw141292 
9434520Snw141292 	/* allocate the handle */
9444520Snw141292 	if ((tmp = calloc(1, sizeof (*tmp))) == NULL) {
9454520Snw141292 		errno = ENOMEM;
9464520Snw141292 		return (IDMAP_ERR_MEMORY);
9474520Snw141292 	}
9484520Snw141292 
9494520Snw141292 	*gh = tmp;
9504520Snw141292 	return (IDMAP_SUCCESS);
9514520Snw141292 }
9524520Snw141292 
9534520Snw141292 
9544520Snw141292 /*
9554520Snw141292  * Given SID, get UID
9564520Snw141292  *
9574520Snw141292  * Input:
9584520Snw141292  * sidprefix  - SID prefix
9594520Snw141292  * rid        - RID
9604520Snw141292  * flag       - flag
9614520Snw141292  *
9624520Snw141292  * Output:
9634520Snw141292  * stat - status of the get request
9644520Snw141292  * uid  - POSIX UID if stat = 0
9654520Snw141292  *
9664520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
9674520Snw141292  */
9684520Snw141292 idmap_stat
idmap_get_uidbysid(idmap_get_handle_t * gh,char * sidprefix,idmap_rid_t rid,int flag,uid_t * uid,idmap_stat * stat)9694520Snw141292 idmap_get_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
9705696Snw141292 		int flag, uid_t *uid, idmap_stat *stat)
9715696Snw141292 {
9726386Sjp151216 	return (idmap_getext_uidbysid(gh, sidprefix, rid, flag, uid,
9736386Sjp151216 	    NULL, stat));
9746386Sjp151216 }
9754520Snw141292 
9766386Sjp151216 /*
9776386Sjp151216  * Given SID, get UID
9786386Sjp151216  *
9796386Sjp151216  * Input:
9806386Sjp151216  * sidprefix  - SID prefix
9816386Sjp151216  * rid        - RID
9826386Sjp151216  * flag       - flag
9836386Sjp151216  *
9846386Sjp151216  * Output:
9856386Sjp151216  * stat - status of the get request
9866386Sjp151216  * uid  - POSIX UID if stat = 0
9876386Sjp151216  * how  - mapping type if stat = 0
9886386Sjp151216  *
9896386Sjp151216  * Note: The output parameters will be set by idmap_get_mappings()
9906386Sjp151216  */
9916386Sjp151216 
9926386Sjp151216 idmap_stat
idmap_getext_uidbysid(idmap_get_handle_t * gh,char * sidprefix,idmap_rid_t rid,int flag,uid_t * uid,idmap_info * info,idmap_stat * stat)9936386Sjp151216 idmap_getext_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
9946386Sjp151216 		int flag, uid_t *uid, idmap_info *info, idmap_stat *stat)
9956386Sjp151216 {
9964520Snw141292 	idmap_retcode	retcode;
9974644Sbaban 	idmap_mapping	*mapping = NULL;
9984520Snw141292 
9994520Snw141292 	/* sanity checks */
10004520Snw141292 	if (gh == NULL)
10014520Snw141292 		return (IDMAP_ERR_ARG);
10024520Snw141292 	if (uid == NULL || sidprefix == NULL)
10034520Snw141292 		return (IDMAP_ERR_ARG);
10044520Snw141292 
10057369SJulian.Pullen@Sun.COM 	if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
10067369SJulian.Pullen@Sun.COM 	    !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
10077369SJulian.Pullen@Sun.COM 		retcode = idmap_cache_lookup_uidbysid(sidprefix, rid, uid);
10087369SJulian.Pullen@Sun.COM 		if (retcode  == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
10097369SJulian.Pullen@Sun.COM 			*stat = retcode;
10107369SJulian.Pullen@Sun.COM 			return (retcode);
10117369SJulian.Pullen@Sun.COM 		}
10127369SJulian.Pullen@Sun.COM 	}
10137369SJulian.Pullen@Sun.COM 
10144520Snw141292 	/* Extend the request array and the return list */
10154520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
10164520Snw141292 		goto errout;
10174520Snw141292 
10184520Snw141292 	/* Setup the request */
10194520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
10204520Snw141292 	mapping->flag = flag;
10214520Snw141292 	mapping->id1.idtype = IDMAP_SID;
10224520Snw141292 	mapping->id1.idmap_id_u.sid.rid = rid;
10234520Snw141292 	if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
10244520Snw141292 		retcode = IDMAP_ERR_MEMORY;
10254520Snw141292 		goto errout;
10264520Snw141292 	}
10274520Snw141292 	mapping->id2.idtype = IDMAP_UID;
10284520Snw141292 
10294520Snw141292 	/* Setup pointers for the result */
10304520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_UID;
10314520Snw141292 	gh->retlist[gh->next].uid = uid;
10324520Snw141292 	gh->retlist[gh->next].stat = stat;
10336386Sjp151216 	gh->retlist[gh->next].info = info;
10347369SJulian.Pullen@Sun.COM 	gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
10354520Snw141292 
10364520Snw141292 	gh->next++;
10374520Snw141292 	return (IDMAP_SUCCESS);
10384520Snw141292 
10394520Snw141292 errout:
10404644Sbaban 	/* Batch created so far should still be usable */
10414644Sbaban 	if (mapping)
10424644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
10434520Snw141292 	errno = idmap_stat2errno(retcode);
10444520Snw141292 	return (retcode);
10454520Snw141292 }
10464520Snw141292 
10474520Snw141292 
10484520Snw141292 /*
10494520Snw141292  * Given SID, get GID
10504520Snw141292  *
10514520Snw141292  * Input:
10524520Snw141292  * sidprefix  - SID prefix
10534520Snw141292  * rid        - rid
10544520Snw141292  * flag       - flag
10554520Snw141292  *
10564520Snw141292  * Output:
10574520Snw141292  * stat - status of the get request
10584520Snw141292  * gid  - POSIX GID if stat = 0
10594520Snw141292  *
10604520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
10614520Snw141292  */
10624520Snw141292 idmap_stat
idmap_get_gidbysid(idmap_get_handle_t * gh,char * sidprefix,idmap_rid_t rid,int flag,gid_t * gid,idmap_stat * stat)10634520Snw141292 idmap_get_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
10645696Snw141292 		int flag, gid_t *gid, idmap_stat *stat)
10655696Snw141292 {
10666386Sjp151216 	return (idmap_getext_gidbysid(gh, sidprefix, rid, flag, gid,
10676386Sjp151216 	    NULL, stat));
10686386Sjp151216 }
10696386Sjp151216 
10706386Sjp151216 
10716386Sjp151216 /*
10726386Sjp151216  * Given SID, get GID
10736386Sjp151216  *
10746386Sjp151216  * Input:
10756386Sjp151216  * sidprefix  - SID prefix
10766386Sjp151216  * rid        - rid
10776386Sjp151216  * flag       - flag
10786386Sjp151216  *
10796386Sjp151216  * Output:
10806386Sjp151216  * stat - status of the get request
10816386Sjp151216  * gid  - POSIX GID if stat = 0
10826386Sjp151216  * how  - mapping type if stat = 0
10836386Sjp151216  *
10846386Sjp151216  * Note: The output parameters will be set by idmap_get_mappings()
10856386Sjp151216  */
10866386Sjp151216 idmap_stat
idmap_getext_gidbysid(idmap_get_handle_t * gh,char * sidprefix,idmap_rid_t rid,int flag,gid_t * gid,idmap_info * info,idmap_stat * stat)10876386Sjp151216 idmap_getext_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
10886386Sjp151216 		int flag, gid_t *gid, idmap_info *info, idmap_stat *stat)
10896386Sjp151216 {
10904520Snw141292 
10914520Snw141292 	idmap_retcode	retcode;
10924644Sbaban 	idmap_mapping	*mapping = NULL;
10934520Snw141292 
10944520Snw141292 	/* sanity checks */
10954520Snw141292 	if (gh == NULL)
10964520Snw141292 		return (IDMAP_ERR_ARG);
10974520Snw141292 	if (gid == NULL || sidprefix == NULL)
10984520Snw141292 		return (IDMAP_ERR_ARG);
10994520Snw141292 
11007369SJulian.Pullen@Sun.COM 	if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
11017369SJulian.Pullen@Sun.COM 	    !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
11027369SJulian.Pullen@Sun.COM 		retcode = idmap_cache_lookup_gidbysid(sidprefix, rid, gid);
11037369SJulian.Pullen@Sun.COM 		if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
11047369SJulian.Pullen@Sun.COM 			*stat = retcode;
11057369SJulian.Pullen@Sun.COM 			return (retcode);
11067369SJulian.Pullen@Sun.COM 		}
11077369SJulian.Pullen@Sun.COM 	}
11087369SJulian.Pullen@Sun.COM 
11094520Snw141292 	/* Extend the request array and the return list */
11104520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
11114520Snw141292 		goto errout;
11124520Snw141292 
11134520Snw141292 	/* Setup the request */
11144520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
11154520Snw141292 	mapping->flag = flag;
11164520Snw141292 	mapping->id1.idtype = IDMAP_SID;
11174520Snw141292 	mapping->id1.idmap_id_u.sid.rid = rid;
11184520Snw141292 	if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
11194520Snw141292 		retcode = IDMAP_ERR_MEMORY;
11204520Snw141292 		goto errout;
11214520Snw141292 	}
11224520Snw141292 	mapping->id2.idtype = IDMAP_GID;
11234520Snw141292 
11244520Snw141292 	/* Setup pointers for the result */
11254520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_GID;
11264520Snw141292 	gh->retlist[gh->next].gid = gid;
11274520Snw141292 	gh->retlist[gh->next].stat = stat;
11286386Sjp151216 	gh->retlist[gh->next].info = info;
11297369SJulian.Pullen@Sun.COM 	gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
11304520Snw141292 
11314520Snw141292 	gh->next++;
11324520Snw141292 	return (IDMAP_SUCCESS);
11334520Snw141292 
11344520Snw141292 errout:
11354644Sbaban 	if (mapping)
11364644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
11374520Snw141292 	errno = idmap_stat2errno(retcode);
11384520Snw141292 	return (retcode);
11394520Snw141292 }
11404520Snw141292 
11414520Snw141292 
11426386Sjp151216 
11434520Snw141292 /*
11444520Snw141292  * Given SID, get POSIX ID i.e. UID/GID
11454520Snw141292  *
11464520Snw141292  * Input:
11474520Snw141292  * sidprefix  - SID prefix
11484520Snw141292  * rid        - rid
11494520Snw141292  * flag       - flag
11504520Snw141292  *
11514520Snw141292  * Output:
11524520Snw141292  * stat    - status of the get request
11534520Snw141292  * is_user - user or group
11544520Snw141292  * pid     - POSIX UID if stat = 0 and is_user = 1
11554520Snw141292  *           POSIX GID if stat = 0 and is_user = 0
11564520Snw141292  *
11574520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
11584520Snw141292  */
11594520Snw141292 idmap_stat
idmap_get_pidbysid(idmap_get_handle_t * gh,char * sidprefix,idmap_rid_t rid,int flag,uid_t * pid,int * is_user,idmap_stat * stat)11604520Snw141292 idmap_get_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
11615696Snw141292 		int flag, uid_t *pid, int *is_user, idmap_stat *stat)
11625696Snw141292 {
11636386Sjp151216 	return (idmap_getext_pidbysid(gh, sidprefix, rid, flag, pid, is_user,
11646386Sjp151216 	    NULL, stat));
11656386Sjp151216 }
11666386Sjp151216 
11676386Sjp151216 
11686386Sjp151216 
11696386Sjp151216 /*
11706386Sjp151216  * Given SID, get POSIX ID i.e. UID/GID
11716386Sjp151216  *
11726386Sjp151216  * Input:
11736386Sjp151216  * sidprefix  - SID prefix
11746386Sjp151216  * rid        - rid
11756386Sjp151216  * flag       - flag
11766386Sjp151216  *
11776386Sjp151216  * Output:
11786386Sjp151216  * stat    - status of the get request
11796386Sjp151216  * is_user - user or group
11806386Sjp151216  * pid     - POSIX UID if stat = 0 and is_user = 1
11816386Sjp151216  *           POSIX GID if stat = 0 and is_user = 0
11826386Sjp151216  * how     - mapping type if stat = 0
11836386Sjp151216  *
11846386Sjp151216  * Note: The output parameters will be set by idmap_get_mappings()
11856386Sjp151216  */
11866386Sjp151216 idmap_stat
idmap_getext_pidbysid(idmap_get_handle_t * gh,char * sidprefix,idmap_rid_t rid,int flag,uid_t * pid,int * is_user,idmap_info * info,idmap_stat * stat)11876386Sjp151216 idmap_getext_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid,
11886386Sjp151216 	int flag, uid_t *pid, int *is_user, idmap_info *info, idmap_stat *stat)
11896386Sjp151216 {
11904520Snw141292 	idmap_retcode	retcode;
11914644Sbaban 	idmap_mapping	*mapping = NULL;
11924520Snw141292 
11934520Snw141292 	/* sanity checks */
11944520Snw141292 	if (gh == NULL)
11954520Snw141292 		return (IDMAP_ERR_ARG);
11964520Snw141292 	if (pid == NULL || sidprefix == NULL || is_user == NULL)
11974520Snw141292 		return (IDMAP_ERR_ARG);
11984520Snw141292 
11997369SJulian.Pullen@Sun.COM 	if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
12007369SJulian.Pullen@Sun.COM 	    !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
12017369SJulian.Pullen@Sun.COM 		retcode = idmap_cache_lookup_pidbysid(sidprefix, rid, pid,
12027369SJulian.Pullen@Sun.COM 		    is_user);
12037369SJulian.Pullen@Sun.COM 		if (retcode  == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
12047369SJulian.Pullen@Sun.COM 			*stat = retcode;
12057369SJulian.Pullen@Sun.COM 			return (retcode);
12067369SJulian.Pullen@Sun.COM 		}
12077369SJulian.Pullen@Sun.COM 	}
12087369SJulian.Pullen@Sun.COM 
12094520Snw141292 	/* Extend the request array and the return list */
12104520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
12114520Snw141292 		goto errout;
12124520Snw141292 
12134520Snw141292 	/* Setup the request */
12144520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
12154520Snw141292 	mapping->flag = flag;
12164520Snw141292 	mapping->id1.idtype = IDMAP_SID;
12174520Snw141292 	mapping->id1.idmap_id_u.sid.rid = rid;
12184520Snw141292 	if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) {
12194520Snw141292 		retcode = IDMAP_ERR_MEMORY;
12204520Snw141292 		goto errout;
12214520Snw141292 	}
12224520Snw141292 	mapping->id2.idtype = IDMAP_POSIXID;
12234520Snw141292 
12244520Snw141292 	/* Setup pointers for the result */
12254520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_POSIXID;
12264520Snw141292 	gh->retlist[gh->next].uid = pid;
12274520Snw141292 	gh->retlist[gh->next].gid = pid;
12284520Snw141292 	gh->retlist[gh->next].is_user = is_user;
12294520Snw141292 	gh->retlist[gh->next].stat = stat;
12306386Sjp151216 	gh->retlist[gh->next].info = info;
12317369SJulian.Pullen@Sun.COM 	gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
12324520Snw141292 
12334520Snw141292 	gh->next++;
12344520Snw141292 	return (IDMAP_SUCCESS);
12354520Snw141292 
12364520Snw141292 errout:
12374644Sbaban 	if (mapping)
12384644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
12394520Snw141292 	errno = idmap_stat2errno(retcode);
12404520Snw141292 	return (retcode);
12414520Snw141292 }
12424520Snw141292 
12434520Snw141292 
12444520Snw141292 /*
12454520Snw141292  * Given UID, get SID
12464520Snw141292  *
12474520Snw141292  * Input:
12484520Snw141292  * uid  - POSIX UID
12494520Snw141292  * flag - flag
12504520Snw141292  *
12514520Snw141292  * Output:
12524520Snw141292  * stat - status of the get request
12534520Snw141292  * sid  - SID prefix (if stat == 0)
12544520Snw141292  * rid  - rid
12554520Snw141292  *
12564520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
12574520Snw141292  */
12584520Snw141292 idmap_stat
idmap_get_sidbyuid(idmap_get_handle_t * gh,uid_t uid,int flag,char ** sidprefix,idmap_rid_t * rid,idmap_stat * stat)12594520Snw141292 idmap_get_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag,
12605696Snw141292 		char **sidprefix, idmap_rid_t *rid, idmap_stat *stat)
12615696Snw141292 {
12626386Sjp151216 	return (idmap_getext_sidbyuid(gh, uid, flag, sidprefix, rid,
12636386Sjp151216 	    NULL, stat));
12646386Sjp151216 }
12656386Sjp151216 
12666386Sjp151216 
12676386Sjp151216 /*
12686386Sjp151216  * Given UID, get SID
12696386Sjp151216  *
12706386Sjp151216  * Input:
12716386Sjp151216  * uid  - POSIX UID
12726386Sjp151216  * flag - flag
12736386Sjp151216  *
12746386Sjp151216  * Output:
12756386Sjp151216  * stat - status of the get request
12766386Sjp151216  * sid  - SID prefix (if stat == 0)
12776386Sjp151216  * rid  - rid
12786386Sjp151216  * how  - mapping type if stat = 0
12796386Sjp151216  *
12806386Sjp151216  * Note: The output parameters will be set by idmap_get_mappings()
12816386Sjp151216  */
12826386Sjp151216 idmap_stat
idmap_getext_sidbyuid(idmap_get_handle_t * gh,uid_t uid,int flag,char ** sidprefix,idmap_rid_t * rid,idmap_info * info,idmap_stat * stat)12836386Sjp151216 idmap_getext_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag,
12846386Sjp151216 	char **sidprefix, idmap_rid_t *rid, idmap_info *info, idmap_stat *stat)
12856386Sjp151216 {
12864520Snw141292 
12874520Snw141292 	idmap_retcode	retcode;
12884644Sbaban 	idmap_mapping	*mapping = NULL;
12894520Snw141292 
12904520Snw141292 	/* sanity checks */
12914520Snw141292 	if (gh == NULL)
12924520Snw141292 		return (IDMAP_ERR_ARG);
12934520Snw141292 	if (sidprefix == NULL)
12944520Snw141292 		return (IDMAP_ERR_ARG);
12954520Snw141292 
12967369SJulian.Pullen@Sun.COM 	if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
12977369SJulian.Pullen@Sun.COM 	    !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
12987369SJulian.Pullen@Sun.COM 		retcode = idmap_cache_lookup_sidbyuid(sidprefix, rid, uid);
12997369SJulian.Pullen@Sun.COM 		if (retcode  == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
13007369SJulian.Pullen@Sun.COM 			*stat = retcode;
13017369SJulian.Pullen@Sun.COM 			return (retcode);
13027369SJulian.Pullen@Sun.COM 		}
13037369SJulian.Pullen@Sun.COM 	}
13047369SJulian.Pullen@Sun.COM 
13054520Snw141292 	/* Extend the request array and the return list */
13064520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
13074520Snw141292 		goto errout;
13084520Snw141292 
13094520Snw141292 	/* Setup the request */
13104520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
13114520Snw141292 	mapping->flag = flag;
13124520Snw141292 	mapping->id1.idtype = IDMAP_UID;
13134520Snw141292 	mapping->id1.idmap_id_u.uid = uid;
13144520Snw141292 	mapping->id2.idtype = IDMAP_SID;
13154520Snw141292 
13164520Snw141292 	/* Setup pointers for the result */
13174520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_SID;
13184520Snw141292 	gh->retlist[gh->next].sidprefix = sidprefix;
13194520Snw141292 	gh->retlist[gh->next].rid = rid;
13204520Snw141292 	gh->retlist[gh->next].stat = stat;
13216386Sjp151216 	gh->retlist[gh->next].info = info;
13227369SJulian.Pullen@Sun.COM 	gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
13234520Snw141292 
13244520Snw141292 	gh->next++;
13254520Snw141292 	return (IDMAP_SUCCESS);
13264520Snw141292 
13274520Snw141292 errout:
13284644Sbaban 	if (mapping)
13294644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
13304520Snw141292 	errno = idmap_stat2errno(retcode);
13314520Snw141292 	return (retcode);
13324520Snw141292 }
13334520Snw141292 
13344520Snw141292 
13354520Snw141292 /*
13364520Snw141292  * Given GID, get SID
13374520Snw141292  *
13384520Snw141292  * Input:
13394520Snw141292  * gid  - POSIX GID
13404520Snw141292  * flag - flag
13414520Snw141292  *
13424520Snw141292  * Output:
13434520Snw141292  * stat       - status of the get request
13444520Snw141292  * sidprefix  - SID prefix (if stat == 0)
13454520Snw141292  * rid        - rid
13464520Snw141292  *
13474520Snw141292  * Note: The output parameters will be set by idmap_get_mappings()
13484520Snw141292  */
13494520Snw141292 idmap_stat
idmap_get_sidbygid(idmap_get_handle_t * gh,gid_t gid,int flag,char ** sidprefix,idmap_rid_t * rid,idmap_stat * stat)13504520Snw141292 idmap_get_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag,
13515696Snw141292 		char **sidprefix, idmap_rid_t *rid, idmap_stat *stat)
13525696Snw141292 {
13536386Sjp151216 	return (idmap_getext_sidbygid(gh, gid, flag, sidprefix, rid,
13546386Sjp151216 	    NULL, stat));
13556386Sjp151216 }
13566386Sjp151216 
13576386Sjp151216 
13586386Sjp151216 /*
13596386Sjp151216  * Given GID, get SID
13606386Sjp151216  *
13616386Sjp151216  * Input:
13626386Sjp151216  * gid  - POSIX GID
13636386Sjp151216  * flag - flag
13646386Sjp151216  *
13656386Sjp151216  * Output:
13666386Sjp151216  * stat       - status of the get request
13676386Sjp151216  * sidprefix  - SID prefix (if stat == 0)
13686386Sjp151216  * rid        - rid
13696386Sjp151216  * how        - mapping type if stat = 0
13706386Sjp151216  *
13716386Sjp151216  * Note: The output parameters will be set by idmap_get_mappings()
13726386Sjp151216  */
13736386Sjp151216 idmap_stat
idmap_getext_sidbygid(idmap_get_handle_t * gh,gid_t gid,int flag,char ** sidprefix,idmap_rid_t * rid,idmap_info * info,idmap_stat * stat)13746386Sjp151216 idmap_getext_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag,
13756386Sjp151216 	char **sidprefix, idmap_rid_t *rid, idmap_info *info, idmap_stat *stat)
13766386Sjp151216 {
13774520Snw141292 
13784520Snw141292 	idmap_retcode	retcode;
13794644Sbaban 	idmap_mapping	*mapping = NULL;
13804520Snw141292 
13814520Snw141292 	/* sanity checks */
13824520Snw141292 	if (gh == NULL)
13834520Snw141292 		return (IDMAP_ERR_ARG);
13844520Snw141292 	if (sidprefix == NULL)
13854520Snw141292 		return (IDMAP_ERR_ARG);
13864520Snw141292 
13877369SJulian.Pullen@Sun.COM 	if ((flag & IDMAP_REQ_FLG_USE_CACHE) &&
13887369SJulian.Pullen@Sun.COM 	    !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) {
13897369SJulian.Pullen@Sun.COM 		retcode = idmap_cache_lookup_sidbygid(sidprefix, rid, gid);
13907369SJulian.Pullen@Sun.COM 		if (retcode  == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) {
13917369SJulian.Pullen@Sun.COM 			*stat = retcode;
13927369SJulian.Pullen@Sun.COM 			return (retcode);
13937369SJulian.Pullen@Sun.COM 		}
13947369SJulian.Pullen@Sun.COM 	}
13957369SJulian.Pullen@Sun.COM 
13964520Snw141292 	/* Extend the request array and the return list */
13974520Snw141292 	if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS)
13984520Snw141292 		goto errout;
13994520Snw141292 
14004520Snw141292 	/* Setup the request */
14014520Snw141292 	mapping = &gh->batch.idmap_mapping_batch_val[gh->next];
14024520Snw141292 	mapping->flag = flag;
14034520Snw141292 	mapping->id1.idtype = IDMAP_GID;
14044520Snw141292 	mapping->id1.idmap_id_u.gid = gid;
14054520Snw141292 	mapping->id2.idtype = IDMAP_SID;
14064520Snw141292 
14074520Snw141292 	/* Setup pointers for the result */
14084520Snw141292 	gh->retlist[gh->next].idtype = IDMAP_SID;
14094520Snw141292 	gh->retlist[gh->next].sidprefix = sidprefix;
14104520Snw141292 	gh->retlist[gh->next].rid = rid;
14114520Snw141292 	gh->retlist[gh->next].stat = stat;
14126386Sjp151216 	gh->retlist[gh->next].info = info;
14137369SJulian.Pullen@Sun.COM 	gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE;
14144520Snw141292 
14154520Snw141292 	gh->next++;
14164520Snw141292 	return (IDMAP_SUCCESS);
14174520Snw141292 
14184520Snw141292 errout:
14194644Sbaban 	if (mapping)
14204644Sbaban 		(void) memset(mapping, 0, sizeof (*mapping));
14214520Snw141292 	errno = idmap_stat2errno(retcode);
14224520Snw141292 	return (retcode);
14234520Snw141292 }
14244520Snw141292 
14254520Snw141292 
14264520Snw141292 /*
14274520Snw141292  * Process the batched "get mapping" requests. The results (i.e.
14284520Snw141292  * status and identity) will be available in the data areas
14294520Snw141292  * provided by individual requests.
14304520Snw141292  */
14314520Snw141292 idmap_stat
idmap_get_mappings(idmap_get_handle_t * gh)14325696Snw141292 idmap_get_mappings(idmap_get_handle_t *gh)
14335696Snw141292 {
14344520Snw141292 	idmap_retcode	retcode;
14354520Snw141292 	idmap_ids_res	res;
14367369SJulian.Pullen@Sun.COM 	idmap_id	*res_id;
14374520Snw141292 	int		i;
14387369SJulian.Pullen@Sun.COM 	idmap_id	*req_id;
14397369SJulian.Pullen@Sun.COM 	int		direction;
14404520Snw141292 
14414520Snw141292 	if (gh == NULL) {
14424520Snw141292 		errno = EINVAL;
14434520Snw141292 		return (IDMAP_ERR_ARG);
14444520Snw141292 	}
14454520Snw141292 
14464520Snw141292 	(void) memset(&res, 0, sizeof (idmap_ids_res));
1447*12914SJoyce.McIntosh@Sun.COM 	retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_IDS,
14485696Snw141292 	    (xdrproc_t)xdr_idmap_mapping_batch,
14495696Snw141292 	    (caddr_t)&gh->batch,
14505696Snw141292 	    (xdrproc_t)xdr_idmap_ids_res,
14515696Snw141292 	    (caddr_t)&res,
14525696Snw141292 	    TIMEOUT);
1453*12914SJoyce.McIntosh@Sun.COM 	if (retcode != IDMAP_SUCCESS) {
14544520Snw141292 		goto out;
14554520Snw141292 	}
14564520Snw141292 	if (res.retcode != IDMAP_SUCCESS) {
14574520Snw141292 		retcode = res.retcode;
14584520Snw141292 		goto out;
14594520Snw141292 	}
14604520Snw141292 	for (i = 0; i < gh->next; i++) {
14614520Snw141292 		if (i >= res.ids.ids_len) {
14624520Snw141292 			*gh->retlist[i].stat = IDMAP_ERR_NORESULT;
14634520Snw141292 			continue;
14644520Snw141292 		}
14654520Snw141292 		*gh->retlist[i].stat = res.ids.ids_val[i].retcode;
14667369SJulian.Pullen@Sun.COM 		res_id = &res.ids.ids_val[i].id;
14677369SJulian.Pullen@Sun.COM 		direction = res.ids.ids_val[i].direction;
14687369SJulian.Pullen@Sun.COM 		req_id = &gh->batch.idmap_mapping_batch_val[i].id1;
14697369SJulian.Pullen@Sun.COM 		switch (res_id->idtype) {
14704520Snw141292 		case IDMAP_UID:
14714520Snw141292 			if (gh->retlist[i].uid)
14727369SJulian.Pullen@Sun.COM 				*gh->retlist[i].uid = res_id->idmap_id_u.uid;
14734520Snw141292 			if (gh->retlist[i].is_user)
14744520Snw141292 				*gh->retlist[i].is_user = 1;
14757369SJulian.Pullen@Sun.COM 
14767369SJulian.Pullen@Sun.COM 			if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS &&
14777369SJulian.Pullen@Sun.COM 			    gh->retlist[i].cache_res) {
14787369SJulian.Pullen@Sun.COM 				if (gh->retlist[i].is_user != NULL)
14797369SJulian.Pullen@Sun.COM 					idmap_cache_add_sid2pid(
14807369SJulian.Pullen@Sun.COM 					    req_id->idmap_id_u.sid.prefix,
14817369SJulian.Pullen@Sun.COM 					    req_id->idmap_id_u.sid.rid,
14827369SJulian.Pullen@Sun.COM 					    res_id->idmap_id_u.uid, 1,
14837369SJulian.Pullen@Sun.COM 					    direction);
14847369SJulian.Pullen@Sun.COM 				else
14857369SJulian.Pullen@Sun.COM 					idmap_cache_add_sid2uid(
14867369SJulian.Pullen@Sun.COM 					    req_id->idmap_id_u.sid.prefix,
14877369SJulian.Pullen@Sun.COM 					    req_id->idmap_id_u.sid.rid,
14887369SJulian.Pullen@Sun.COM 					    res_id->idmap_id_u.uid,
14897369SJulian.Pullen@Sun.COM 					    direction);
14907369SJulian.Pullen@Sun.COM 			}
14914520Snw141292 			break;
14927369SJulian.Pullen@Sun.COM 
14934520Snw141292 		case IDMAP_GID:
14944520Snw141292 			if (gh->retlist[i].gid)
14957369SJulian.Pullen@Sun.COM 				*gh->retlist[i].gid = res_id->idmap_id_u.gid;
14964520Snw141292 			if (gh->retlist[i].is_user)
14974520Snw141292 				*gh->retlist[i].is_user = 0;
14987369SJulian.Pullen@Sun.COM 
14997369SJulian.Pullen@Sun.COM 			if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS &&
15007369SJulian.Pullen@Sun.COM 			    gh->retlist[i].cache_res) {
15017369SJulian.Pullen@Sun.COM 				if (gh->retlist[i].is_user != NULL)
15027369SJulian.Pullen@Sun.COM 					idmap_cache_add_sid2pid(
15037369SJulian.Pullen@Sun.COM 					    req_id->idmap_id_u.sid.prefix,
15047369SJulian.Pullen@Sun.COM 					    req_id->idmap_id_u.sid.rid,
15057369SJulian.Pullen@Sun.COM 					    res_id->idmap_id_u.gid, 0,
15067369SJulian.Pullen@Sun.COM 					    direction);
15077369SJulian.Pullen@Sun.COM 				else
15087369SJulian.Pullen@Sun.COM 					idmap_cache_add_sid2gid(
15097369SJulian.Pullen@Sun.COM 					    req_id->idmap_id_u.sid.prefix,
15107369SJulian.Pullen@Sun.COM 					    req_id->idmap_id_u.sid.rid,
15117369SJulian.Pullen@Sun.COM 					    res_id->idmap_id_u.gid,
15127369SJulian.Pullen@Sun.COM 					    direction);
15137369SJulian.Pullen@Sun.COM 			}
15144520Snw141292 			break;
15157369SJulian.Pullen@Sun.COM 
15164864Sbaban 		case IDMAP_POSIXID:
15174864Sbaban 			if (gh->retlist[i].uid)
15184864Sbaban 				*gh->retlist[i].uid = 60001;
15194864Sbaban 			if (gh->retlist[i].is_user)
15204864Sbaban 				*gh->retlist[i].is_user = -1;
15214864Sbaban 			break;
15227369SJulian.Pullen@Sun.COM 
15234520Snw141292 		case IDMAP_SID:
15245696Snw141292 		case IDMAP_USID:
15255696Snw141292 		case IDMAP_GSID:
15264520Snw141292 			if (gh->retlist[i].rid)
15277369SJulian.Pullen@Sun.COM 				*gh->retlist[i].rid =
15287369SJulian.Pullen@Sun.COM 				    res_id->idmap_id_u.sid.rid;
15294520Snw141292 			if (gh->retlist[i].sidprefix) {
15307369SJulian.Pullen@Sun.COM 				if (res_id->idmap_id_u.sid.prefix == NULL ||
15317369SJulian.Pullen@Sun.COM 				    *res_id->idmap_id_u.sid.prefix == '\0') {
15324520Snw141292 					*gh->retlist[i].sidprefix = NULL;
15334520Snw141292 					break;
15344520Snw141292 				}
15354520Snw141292 				*gh->retlist[i].sidprefix =
15367369SJulian.Pullen@Sun.COM 				    strdup(res_id->idmap_id_u.sid.prefix);
15374520Snw141292 				if (*gh->retlist[i].sidprefix == NULL)
15384520Snw141292 					*gh->retlist[i].stat =
15395696Snw141292 					    IDMAP_ERR_MEMORY;
15404520Snw141292 			}
15417369SJulian.Pullen@Sun.COM 			if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS &&
15427369SJulian.Pullen@Sun.COM 			    gh->retlist[i].cache_res) {
15437369SJulian.Pullen@Sun.COM 				if (req_id->idtype == IDMAP_UID)
15447369SJulian.Pullen@Sun.COM 					idmap_cache_add_sid2uid(
15457369SJulian.Pullen@Sun.COM 					    res_id->idmap_id_u.sid.prefix,
15467369SJulian.Pullen@Sun.COM 					    res_id->idmap_id_u.sid.rid,
15477369SJulian.Pullen@Sun.COM 					    req_id->idmap_id_u.uid,
15487369SJulian.Pullen@Sun.COM 					    direction);
15497369SJulian.Pullen@Sun.COM 				else /* req_id->idtype == IDMAP_GID */
15507369SJulian.Pullen@Sun.COM 					idmap_cache_add_sid2gid(
15517369SJulian.Pullen@Sun.COM 					    res_id->idmap_id_u.sid.prefix,
15527369SJulian.Pullen@Sun.COM 					    res_id->idmap_id_u.sid.rid,
15537369SJulian.Pullen@Sun.COM 					    req_id->idmap_id_u.gid,
15547369SJulian.Pullen@Sun.COM 					    direction);
15557369SJulian.Pullen@Sun.COM 			}
15564520Snw141292 			break;
15577369SJulian.Pullen@Sun.COM 
15584520Snw141292 		case IDMAP_NONE:
15594520Snw141292 			break;
15607369SJulian.Pullen@Sun.COM 
15614520Snw141292 		default:
15624520Snw141292 			*gh->retlist[i].stat = IDMAP_ERR_NORESULT;
15634520Snw141292 			break;
15644520Snw141292 		}
156512508Samw@Sun.COM 		if (gh->retlist[i].info != NULL) {
156612508Samw@Sun.COM 			idmap_info_mov(gh->retlist[i].info,
15676386Sjp151216 			    &res.ids.ids_val[i].info);
156812508Samw@Sun.COM 		}
15694520Snw141292 	}
15704520Snw141292 	retcode = IDMAP_SUCCESS;
15714520Snw141292 
15724520Snw141292 out:
15734644Sbaban 	_IDMAP_RESET_GET_HANDLE(gh);
15744520Snw141292 	(void) xdr_free(xdr_idmap_ids_res, (caddr_t)&res);
15754520Snw141292 	errno = idmap_stat2errno(retcode);
15764520Snw141292 	return (retcode);
15774520Snw141292 }
15784520Snw141292 
15794520Snw141292 
15804520Snw141292 /*
15814520Snw141292  * Destroy the "get mapping" handle
15824520Snw141292  */
15834520Snw141292 void
idmap_get_destroy(idmap_get_handle_t * gh)15845696Snw141292 idmap_get_destroy(idmap_get_handle_t *gh)
15855696Snw141292 {
15864520Snw141292 	if (gh == NULL)
15874520Snw141292 		return;
15884520Snw141292 	(void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch);
15894520Snw141292 	if (gh->retlist)
15904520Snw141292 		free(gh->retlist);
15914520Snw141292 	free(gh);
15924520Snw141292 }
15934520Snw141292 
15944520Snw141292 
15954520Snw141292 /*
15964520Snw141292  * Get windows to unix mapping
15974520Snw141292  */
15984520Snw141292 idmap_stat
idmap_get_w2u_mapping(const char * sidprefix,idmap_rid_t * rid,const char * winname,const char * windomain,int flag,int * is_user,int * is_wuser,uid_t * pid,char ** unixname,int * direction,idmap_info * info)1599*12914SJoyce.McIntosh@Sun.COM idmap_get_w2u_mapping(
16004520Snw141292 		const char *sidprefix, idmap_rid_t *rid,
16014520Snw141292 		const char *winname, const char *windomain,
16025696Snw141292 		int flag, int *is_user, int *is_wuser,
16036386Sjp151216 		uid_t *pid, char **unixname, int *direction, idmap_info *info)
16045696Snw141292 {
16054520Snw141292 	idmap_mapping		request, *mapping;
16064520Snw141292 	idmap_mappings_res	result;
16074520Snw141292 	idmap_retcode		retcode, rc;
16084520Snw141292 
16094520Snw141292 	(void) memset(&request, 0, sizeof (request));
16104520Snw141292 	(void) memset(&result, 0, sizeof (result));
16114520Snw141292 
16124520Snw141292 	if (pid)
16134520Snw141292 		*pid = UINT32_MAX;
16144520Snw141292 	if (unixname)
16154520Snw141292 		*unixname = NULL;
16164520Snw141292 	if (direction)
16174644Sbaban 		*direction = IDMAP_DIRECTION_UNDEF;
16184520Snw141292 
16194520Snw141292 	request.flag = flag;
16204520Snw141292 	request.id1.idtype = IDMAP_SID;
16214520Snw141292 	if (sidprefix && rid) {
16224520Snw141292 		request.id1.idmap_id_u.sid.prefix = (char *)sidprefix;
16234520Snw141292 		request.id1.idmap_id_u.sid.rid = *rid;
16244520Snw141292 	} else if (winname) {
16255064Sdm199847 		retcode = idmap_strdupnull(&request.id1name, winname);
16265247Sbaban 		if (retcode != IDMAP_SUCCESS)
16274520Snw141292 			goto out;
16285064Sdm199847 
16295064Sdm199847 		retcode = idmap_strdupnull(&request.id1domain, windomain);
16305247Sbaban 		if (retcode != IDMAP_SUCCESS)
16315064Sdm199847 			goto out;
16325064Sdm199847 
16334520Snw141292 		request.id1.idmap_id_u.sid.prefix = NULL;
16344520Snw141292 	} else {
16354520Snw141292 		errno = EINVAL;
16364520Snw141292 		return (IDMAP_ERR_ARG);
16374520Snw141292 	}
16384520Snw141292 
16395696Snw141292 	if (*is_user == 1)
16404520Snw141292 		request.id2.idtype = IDMAP_UID;
16414520Snw141292 	else if (*is_user == 0)
16424520Snw141292 		request.id2.idtype = IDMAP_GID;
16434520Snw141292 	else
16444520Snw141292 		request.id2.idtype = IDMAP_POSIXID;
16454520Snw141292 
16465696Snw141292 	if (*is_wuser == 1)
16475696Snw141292 		request.id1.idtype = IDMAP_USID;
16485696Snw141292 	else if (*is_wuser == 0)
16495696Snw141292 		request.id1.idtype = IDMAP_GSID;
16505696Snw141292 	else
16515696Snw141292 		request.id1.idtype = IDMAP_SID;
16525696Snw141292 
1653*12914SJoyce.McIntosh@Sun.COM 	retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_ID_BY_NAME,
16545696Snw141292 	    (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request,
16555696Snw141292 	    (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result,
16565696Snw141292 	    TIMEOUT);
16574520Snw141292 
1658*12914SJoyce.McIntosh@Sun.COM 	if (retcode != IDMAP_SUCCESS)
1659*12914SJoyce.McIntosh@Sun.COM 		return (retcode);
16604520Snw141292 
16614520Snw141292 	retcode = result.retcode;
16624520Snw141292 
16634520Snw141292 	if ((mapping = result.mappings.mappings_val) == NULL) {
16644520Snw141292 		if (retcode == IDMAP_SUCCESS)
16654520Snw141292 			retcode = IDMAP_ERR_NORESULT;
16664520Snw141292 		goto out;
16674520Snw141292 	}
16684520Snw141292 
166912508Samw@Sun.COM 	if (info != NULL)
167012508Samw@Sun.COM 		idmap_info_mov(info, &mapping->info);
167112508Samw@Sun.COM 
16724864Sbaban 	if (mapping->id2.idtype == IDMAP_UID) {
16735696Snw141292 		*is_user = 1;
16744864Sbaban 	} else if (mapping->id2.idtype == IDMAP_GID) {
16755696Snw141292 		*is_user = 0;
16764864Sbaban 	} else {
16774864Sbaban 		goto out;
16784864Sbaban 	}
16795696Snw141292 
16805696Snw141292 	if (mapping->id1.idtype == IDMAP_USID) {
16815696Snw141292 		*is_wuser = 1;
16825696Snw141292 	} else if (mapping->id1.idtype == IDMAP_GSID) {
16835696Snw141292 		*is_wuser = 0;
16845696Snw141292 	} else {
16855696Snw141292 		goto out;
16865696Snw141292 	}
16875696Snw141292 
16884520Snw141292 	if (direction)
16894520Snw141292 		*direction = mapping->direction;
16904520Snw141292 	if (pid)
16914520Snw141292 		*pid = mapping->id2.idmap_id_u.uid;
16925064Sdm199847 
16935064Sdm199847 	rc = idmap_strdupnull(unixname, mapping->id2name);
16945064Sdm199847 	if (rc != IDMAP_SUCCESS)
16955064Sdm199847 		retcode = rc;
16964520Snw141292 
16974520Snw141292 out:
16986966Sjp151216 	if (request.id1name != NULL)
16996966Sjp151216 		free(request.id1name);
17006966Sjp151216 	if (request.id1domain != NULL)
17016966Sjp151216 		free(request.id1domain);
17024520Snw141292 	xdr_free(xdr_idmap_mappings_res, (caddr_t)&result);
17034520Snw141292 	if (retcode != IDMAP_SUCCESS)
17044520Snw141292 		errno = idmap_stat2errno(retcode);
17054520Snw141292 	return (retcode);
17064520Snw141292 }
17074520Snw141292 
17084520Snw141292 
17094520Snw141292 /*
17104520Snw141292  * Get unix to windows mapping
17114520Snw141292  */
17124520Snw141292 idmap_stat
idmap_get_u2w_mapping(uid_t * pid,const char * unixname,int flag,int is_user,int * is_wuser,char ** sidprefix,idmap_rid_t * rid,char ** winname,char ** windomain,int * direction,idmap_info * info)1713*12914SJoyce.McIntosh@Sun.COM idmap_get_u2w_mapping(
17144520Snw141292 		uid_t *pid, const char *unixname,
17155696Snw141292 		int flag, int is_user, int *is_wuser,
17164520Snw141292 		char **sidprefix, idmap_rid_t *rid,
17174520Snw141292 		char **winname, char **windomain,
17186386Sjp151216 		int *direction, idmap_info *info)
17195696Snw141292 {
17204520Snw141292 	idmap_mapping		request, *mapping;
17214520Snw141292 	idmap_mappings_res	result;
17224520Snw141292 	idmap_retcode		retcode, rc;
17234520Snw141292 
17244520Snw141292 	if (sidprefix)
17254520Snw141292 		*sidprefix = NULL;
17264520Snw141292 	if (winname)
17274520Snw141292 		*winname = NULL;
17284520Snw141292 	if (windomain)
17294520Snw141292 		*windomain = NULL;
17304520Snw141292 	if (rid)
17314520Snw141292 		*rid = UINT32_MAX;
17324520Snw141292 	if (direction)
17334644Sbaban 		*direction = IDMAP_DIRECTION_UNDEF;
17344520Snw141292 
17354520Snw141292 	(void) memset(&request, 0, sizeof (request));
17364520Snw141292 	(void) memset(&result, 0, sizeof (result));
17374520Snw141292 
17384520Snw141292 	request.flag = flag;
17394520Snw141292 	request.id1.idtype = is_user?IDMAP_UID:IDMAP_GID;
17404520Snw141292 
17414520Snw141292 	if (pid && *pid != UINT32_MAX) {
17424520Snw141292 		request.id1.idmap_id_u.uid = *pid;
17434520Snw141292 	} else if (unixname) {
17445064Sdm199847 		request.id1name = (char *)unixname;
17454520Snw141292 		request.id1.idmap_id_u.uid = UINT32_MAX;
17464520Snw141292 	} else {
17474520Snw141292 		errno = EINVAL;
17484520Snw141292 		return (IDMAP_ERR_ARG);
17494520Snw141292 	}
17504520Snw141292 
17515696Snw141292 	if (is_wuser == NULL)
17525696Snw141292 		request.id2.idtype = IDMAP_SID;
17535696Snw141292 	else if (*is_wuser == -1)
17545696Snw141292 		request.id2.idtype = IDMAP_SID;
17555696Snw141292 	else if (*is_wuser == 0)
17565696Snw141292 		request.id2.idtype = IDMAP_GSID;
17575696Snw141292 	else if (*is_wuser == 1)
17585696Snw141292 		request.id2.idtype = IDMAP_USID;
17594520Snw141292 
1760*12914SJoyce.McIntosh@Sun.COM 	retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_ID_BY_NAME,
17615696Snw141292 	    (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request,
17625696Snw141292 	    (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result,
17635696Snw141292 	    TIMEOUT);
17644520Snw141292 
1765*12914SJoyce.McIntosh@Sun.COM 	if (retcode != IDMAP_SUCCESS)
1766*12914SJoyce.McIntosh@Sun.COM 		return (retcode);
17674520Snw141292 
17684520Snw141292 	retcode = result.retcode;
17694520Snw141292 
17704520Snw141292 	if ((mapping = result.mappings.mappings_val) == NULL) {
17714520Snw141292 		if (retcode == IDMAP_SUCCESS)
17724520Snw141292 			retcode = IDMAP_ERR_NORESULT;
17734520Snw141292 		goto out;
17744520Snw141292 	}
17754520Snw141292 
177612508Samw@Sun.COM 	if (info != NULL)
177712508Samw@Sun.COM 		idmap_info_mov(info, &mapping->info);
177812508Samw@Sun.COM 
17795696Snw141292 	if (direction != NULL)
17804520Snw141292 		*direction = mapping->direction;
17815696Snw141292 
17826386Sjp151216 	if (is_wuser != NULL) {
17836386Sjp151216 		if (mapping->id2.idtype == IDMAP_USID)
17846386Sjp151216 			*is_wuser = 1;
17856386Sjp151216 		else if (mapping->id2.idtype == IDMAP_GSID)
17866386Sjp151216 			*is_wuser = 0;
17876386Sjp151216 		else
17886386Sjp151216 			*is_wuser = -1;
17896386Sjp151216 	}
17905696Snw141292 
17914695Sbaban 	if (sidprefix && mapping->id2.idmap_id_u.sid.prefix &&
17924695Sbaban 	    *mapping->id2.idmap_id_u.sid.prefix != '\0') {
17934520Snw141292 		*sidprefix = strdup(mapping->id2.idmap_id_u.sid.prefix);
17944520Snw141292 		if (*sidprefix == NULL) {
17954520Snw141292 			retcode = IDMAP_ERR_MEMORY;
17964520Snw141292 			goto errout;
17974520Snw141292 		}
17984520Snw141292 	}
17994520Snw141292 	if (rid)
18004520Snw141292 		*rid = mapping->id2.idmap_id_u.sid.rid;
18015064Sdm199847 
18025064Sdm199847 	rc = idmap_strdupnull(winname, mapping->id2name);
18035064Sdm199847 	if (rc != IDMAP_SUCCESS)
18045064Sdm199847 		retcode = rc;
18055064Sdm199847 
18065064Sdm199847 	rc = idmap_strdupnull(windomain, mapping->id2domain);
18075064Sdm199847 	if (rc != IDMAP_SUCCESS)
18085064Sdm199847 		retcode = rc;
18094520Snw141292 
18104520Snw141292 	goto out;
18114520Snw141292 
18124520Snw141292 errout:
18134520Snw141292 	if (sidprefix && *sidprefix) {
18144520Snw141292 		free(*sidprefix);
18154520Snw141292 		*sidprefix = NULL;
18164520Snw141292 	}
18174520Snw141292 	if (winname && *winname) {
18184520Snw141292 		free(*winname);
18194520Snw141292 		*winname = NULL;
18204520Snw141292 	}
18214520Snw141292 	if (windomain && *windomain) {
18224520Snw141292 		free(*windomain);
18234520Snw141292 		*windomain = NULL;
18244520Snw141292 	}
18254520Snw141292 
18264520Snw141292 out:
18274520Snw141292 	xdr_free(xdr_idmap_mappings_res, (caddr_t)&result);
18284520Snw141292 	if (retcode != IDMAP_SUCCESS)
18294520Snw141292 		errno = idmap_stat2errno(retcode);
18304520Snw141292 	return (retcode);
18314520Snw141292 }
18324520Snw141292 
18334520Snw141292 
18344520Snw141292 
18354520Snw141292 #define	gettext(s)	s
18364520Snw141292 static stat_table_t stattable[] = {
18374520Snw141292 	{IDMAP_SUCCESS, gettext("Success"), 0},
18384520Snw141292 	{IDMAP_NEXT, gettext("More results available"), 0},
18394520Snw141292 	{IDMAP_ERR_OTHER, gettext("Undefined error"), EINVAL},
18404520Snw141292 	{IDMAP_ERR_INTERNAL, gettext("Internal error"), EINVAL},
18414520Snw141292 	{IDMAP_ERR_MEMORY, gettext("Out of memory"), ENOMEM},
18424520Snw141292 	{IDMAP_ERR_NORESULT, gettext("No results available"), EINVAL},
18434520Snw141292 	{IDMAP_ERR_NOTUSER, gettext("Not a user"), EINVAL},
18444520Snw141292 	{IDMAP_ERR_NOTGROUP, gettext("Not a group"), EINVAL},
18454644Sbaban 	{IDMAP_ERR_NOTSUPPORTED, gettext("Operation not supported"), ENOTSUP},
18464520Snw141292 	{IDMAP_ERR_W2U_NAMERULE,
18474520Snw141292 		gettext("Invalid Windows to UNIX name-based rule"), EINVAL},
18484520Snw141292 	{IDMAP_ERR_U2W_NAMERULE,
18494520Snw141292 		gettext("Invalid UNIX to Windows name-based rule"), EINVAL},
18504520Snw141292 	{IDMAP_ERR_CACHE, gettext("Invalid cache"), EINVAL},
18514520Snw141292 	{IDMAP_ERR_DB, gettext("Invalid database"), EINVAL},
18524520Snw141292 	{IDMAP_ERR_ARG, gettext("Invalid argument"), EINVAL},
18534520Snw141292 	{IDMAP_ERR_SID, gettext("Invalid SID"), EINVAL},
18544520Snw141292 	{IDMAP_ERR_IDTYPE, gettext("Invalid identity type"), EINVAL},
18554644Sbaban 	{IDMAP_ERR_RPC_HANDLE, gettext("Bad RPC handle"), EBADF},
18564520Snw141292 	{IDMAP_ERR_RPC, gettext("RPC error"), EINVAL},
18574520Snw141292 	{IDMAP_ERR_CLIENT_HANDLE, gettext("Bad client handle"), EINVAL},
18584644Sbaban 	{IDMAP_ERR_BUSY, gettext("Server is busy"), EBUSY},
18594695Sbaban 	{IDMAP_ERR_PERMISSION_DENIED, gettext("Permission denied"), EACCES},
18604520Snw141292 	{IDMAP_ERR_NOMAPPING,
18614520Snw141292 		gettext("Mapping not found or inhibited"), EINVAL},
18624520Snw141292 	{IDMAP_ERR_NEW_ID_ALLOC_REQD,
18634520Snw141292 		gettext("New mapping needs to be created"), EINVAL},
18644520Snw141292 	{IDMAP_ERR_DOMAIN, gettext("Invalid domain"), EINVAL},
18654520Snw141292 	{IDMAP_ERR_SECURITY, gettext("Security issue"), EINVAL},
18664520Snw141292 	{IDMAP_ERR_NOTFOUND, gettext("Not found"), EINVAL},
18674520Snw141292 	{IDMAP_ERR_DOMAIN_NOTFOUND, gettext("Domain not found"), EINVAL},
18684520Snw141292 	{IDMAP_ERR_UPDATE_NOTALLOWED, gettext("Update not allowed"), EINVAL},
18694520Snw141292 	{IDMAP_ERR_CFG, gettext("Configuration error"), EINVAL},
18704520Snw141292 	{IDMAP_ERR_CFG_CHANGE, gettext("Invalid configuration change"), EINVAL},
18714520Snw141292 	{IDMAP_ERR_NOTMAPPED_WELLKNOWN,
18724520Snw141292 		gettext("No mapping for well-known SID"), EINVAL},
18734520Snw141292 	{IDMAP_ERR_RETRIABLE_NET_ERR,
18744864Sbaban 		gettext("Windows lookup failed"), EINVAL},
18754864Sbaban 	{IDMAP_ERR_W2U_NAMERULE_CONFLICT,
18764864Sbaban 		gettext("Duplicate rule or conflicts with an existing "
18774864Sbaban 		"Windows to UNIX name-based rule"), EINVAL},
18784864Sbaban 	{IDMAP_ERR_U2W_NAMERULE_CONFLICT,
18794864Sbaban 		gettext("Duplicate rule or conflicts with an existing "
18804864Sbaban 		"Unix to Windows name-based rule"), EINVAL},
18815968Snw141292 	{IDMAP_ERR_BAD_UTF8,
18825968Snw141292 		gettext("Invalid or illegal UTF-8 sequence found in "
18835968Snw141292 		"a given Windows entity name or domain name"), EINVAL},
18848361SJulian.Pullen@Sun.COM 	{IDMAP_ERR_NONE_GENERATED,
18856386Sjp151216 		gettext("Mapping not found and none created (see -c option)"),
18866386Sjp151216 		EINVAL},
18876616Sdm199847 	{IDMAP_ERR_PROP_UNKNOWN,
18886616Sdm199847 		gettext("Undefined property"),
18896616Sdm199847 		EINVAL},
18906616Sdm199847 	{IDMAP_ERR_NS_LDAP_CFG,
18916616Sdm199847 		gettext("Native LDAP configuration error"), EINVAL},
18926616Sdm199847 	{IDMAP_ERR_NS_LDAP_PARTIAL,
18936616Sdm199847 		gettext("Partial result from Native LDAP"), EINVAL},
18946616Sdm199847 	{IDMAP_ERR_NS_LDAP_OP_FAILED,
18956616Sdm199847 		gettext("Native LDAP operation failed"), EINVAL},
18966616Sdm199847 	{IDMAP_ERR_NS_LDAP_BAD_WINNAME,
18976616Sdm199847 		gettext("Improper winname form found in Native LDAP"), EINVAL},
18988361SJulian.Pullen@Sun.COM 	{IDMAP_ERR_NO_ACTIVEDIRECTORY,
18998361SJulian.Pullen@Sun.COM 		gettext("No AD servers"),
19008361SJulian.Pullen@Sun.COM 		EINVAL},
19014520Snw141292 	{-1, NULL, 0}
19024520Snw141292 };
19034520Snw141292 #undef	gettext
19044520Snw141292 
19054520Snw141292 
19064520Snw141292 /*
19074520Snw141292  * Get description of status code
19084520Snw141292  *
19094520Snw141292  * Input:
19104520Snw141292  * status - Status code returned by libidmap API call
19114520Snw141292  *
19124520Snw141292  * Return Value:
19134520Snw141292  * human-readable localized description of idmap_stat
19144520Snw141292  */
19154520Snw141292 const char *
idmap_stat2string(idmap_stat status)1916*12914SJoyce.McIntosh@Sun.COM idmap_stat2string(idmap_stat status)
19175696Snw141292 {
19184520Snw141292 	int i;
19194520Snw141292 
19204520Snw141292 	for (i = 0; stattable[i].msg; i++) {
19214520Snw141292 		if (stattable[i].retcode == status)
192210122SJordan.Brown@Sun.COM 			return (dgettext(TEXT_DOMAIN, stattable[i].msg));
19234520Snw141292 	}
192410122SJordan.Brown@Sun.COM 	return (dgettext(TEXT_DOMAIN, "Unknown error"));
19254520Snw141292 }
19264520Snw141292 
19274520Snw141292 
19284520Snw141292 static int
idmap_stat2errno(idmap_stat stat)19295696Snw141292 idmap_stat2errno(idmap_stat stat)
19305696Snw141292 {
19314520Snw141292 	int i;
19324520Snw141292 	for (i = 0; stattable[i].msg; i++) {
19334520Snw141292 		if (stattable[i].retcode == stat)
19344520Snw141292 			return (stattable[i].errnum);
19354520Snw141292 	}
19364520Snw141292 	return (EINVAL);
19374520Snw141292 }
19384520Snw141292 
19394520Snw141292 
19404520Snw141292 /*
19414520Snw141292  * Get status code from string
19424520Snw141292  */
19434520Snw141292 idmap_stat
idmap_string2stat(const char * str)19445696Snw141292 idmap_string2stat(const char *str)
19455696Snw141292 {
19464520Snw141292 	if (str == NULL)
19474520Snw141292 		return (IDMAP_ERR_INTERNAL);
19484520Snw141292 
19494520Snw141292 #define	return_cmp(a) \
19504520Snw141292 	if (0 == strcmp(str, "IDMAP_ERR_" #a)) \
19514520Snw141292 		return (IDMAP_ERR_ ## a);
19524520Snw141292 
19534520Snw141292 	return_cmp(OTHER);
19544520Snw141292 	return_cmp(INTERNAL);
19554520Snw141292 	return_cmp(MEMORY);
19564520Snw141292 	return_cmp(NORESULT);
19574520Snw141292 	return_cmp(NOTUSER);
19584520Snw141292 	return_cmp(NOTGROUP);
19594520Snw141292 	return_cmp(NOTSUPPORTED);
19604520Snw141292 	return_cmp(W2U_NAMERULE);
19614520Snw141292 	return_cmp(U2W_NAMERULE);
19624520Snw141292 	return_cmp(CACHE);
19634520Snw141292 	return_cmp(DB);
19644520Snw141292 	return_cmp(ARG);
19654520Snw141292 	return_cmp(SID);
19664520Snw141292 	return_cmp(IDTYPE);
19674520Snw141292 	return_cmp(RPC_HANDLE);
19684520Snw141292 	return_cmp(RPC);
19694520Snw141292 	return_cmp(CLIENT_HANDLE);
19704520Snw141292 	return_cmp(BUSY);
19714520Snw141292 	return_cmp(PERMISSION_DENIED);
19724520Snw141292 	return_cmp(NOMAPPING);
19734520Snw141292 	return_cmp(NEW_ID_ALLOC_REQD);
19744520Snw141292 	return_cmp(DOMAIN);
19754520Snw141292 	return_cmp(SECURITY);
19764520Snw141292 	return_cmp(NOTFOUND);
19774520Snw141292 	return_cmp(DOMAIN_NOTFOUND);
19784520Snw141292 	return_cmp(MEMORY);
19794520Snw141292 	return_cmp(UPDATE_NOTALLOWED);
19804520Snw141292 	return_cmp(CFG);
19814520Snw141292 	return_cmp(CFG_CHANGE);
19824520Snw141292 	return_cmp(NOTMAPPED_WELLKNOWN);
19834520Snw141292 	return_cmp(RETRIABLE_NET_ERR);
19844864Sbaban 	return_cmp(W2U_NAMERULE_CONFLICT);
19854864Sbaban 	return_cmp(U2W_NAMERULE_CONFLICT);
19866616Sdm199847 	return_cmp(BAD_UTF8);
19878361SJulian.Pullen@Sun.COM 	return_cmp(NONE_GENERATED);
19886616Sdm199847 	return_cmp(PROP_UNKNOWN);
19896616Sdm199847 	return_cmp(NS_LDAP_CFG);
19906616Sdm199847 	return_cmp(NS_LDAP_PARTIAL);
19916616Sdm199847 	return_cmp(NS_LDAP_OP_FAILED);
19926616Sdm199847 	return_cmp(NS_LDAP_BAD_WINNAME);
19938361SJulian.Pullen@Sun.COM 	return_cmp(NO_ACTIVEDIRECTORY);
19944520Snw141292 #undef return_cmp
19954520Snw141292 
19964520Snw141292 	return (IDMAP_ERR_OTHER);
19974520Snw141292 }
19984520Snw141292 
19994520Snw141292 
20004520Snw141292 /*
20014520Snw141292  * Map the given status to one that can be returned by the protocol
20024520Snw141292  */
20034520Snw141292 idmap_stat
idmap_stat4prot(idmap_stat status)20045696Snw141292 idmap_stat4prot(idmap_stat status)
20055696Snw141292 {
20064520Snw141292 	switch (status) {
20074520Snw141292 	case IDMAP_ERR_MEMORY:
20084520Snw141292 	case IDMAP_ERR_CACHE:
20094520Snw141292 		return (IDMAP_ERR_INTERNAL);
20104520Snw141292 	}
20114520Snw141292 	return (status);
20124520Snw141292 }
20135043Sbaban 
20145043Sbaban 
20155043Sbaban /*
20165247Sbaban  * This is a convenience routine which duplicates a string after
20175247Sbaban  * checking for NULL pointers. This function will return success if
20185247Sbaban  * either the 'to' OR 'from' pointers are NULL.
20195064Sdm199847  */
20205064Sdm199847 static idmap_stat
idmap_strdupnull(char ** to,const char * from)20215696Snw141292 idmap_strdupnull(char **to, const char *from)
20225696Snw141292 {
20235247Sbaban 	if (to == NULL)
20245247Sbaban 		return (IDMAP_SUCCESS);
20255247Sbaban 
20265064Sdm199847 	if (from == NULL || *from == '\0') {
20275064Sdm199847 		*to = NULL;
20285064Sdm199847 		return (IDMAP_SUCCESS);
20295064Sdm199847 	}
20305064Sdm199847 
20315064Sdm199847 	*to = strdup(from);
20325064Sdm199847 	if (*to == NULL)
20335064Sdm199847 		return (IDMAP_ERR_MEMORY);
20345064Sdm199847 	return (IDMAP_SUCCESS);
20355064Sdm199847 }
20365064Sdm199847 
20376386Sjp151216 
20385064Sdm199847 idmap_stat
idmap_namerule_cpy(idmap_namerule * to,idmap_namerule * from)20395696Snw141292 idmap_namerule_cpy(idmap_namerule *to, idmap_namerule *from)
20405696Snw141292 {
20415064Sdm199847 	idmap_stat retval;
20425064Sdm199847 
20436386Sjp151216 	if (to == NULL)
20446386Sjp151216 		return (IDMAP_SUCCESS);
20456386Sjp151216 
20465064Sdm199847 	(void) memcpy(to, from, sizeof (idmap_namerule));
20476386Sjp151216 	to->windomain = NULL;
20486386Sjp151216 	to->winname = NULL;
20496386Sjp151216 	to->unixname = NULL;
20505064Sdm199847 
20515064Sdm199847 	retval = idmap_strdupnull(&to->windomain, from->windomain);
20525064Sdm199847 	if (retval != IDMAP_SUCCESS)
20535064Sdm199847 		return (retval);
20545064Sdm199847 
20555064Sdm199847 	retval = idmap_strdupnull(&to->winname, from->winname);
20566386Sjp151216 	if (retval != IDMAP_SUCCESS) {
20576386Sjp151216 		free(to->windomain);
20586386Sjp151216 		to->windomain = NULL;
20596386Sjp151216 		return (retval);
20606386Sjp151216 	}
20616386Sjp151216 
20626386Sjp151216 	retval = idmap_strdupnull(&to->unixname, from->unixname);
20636386Sjp151216 	if (retval != IDMAP_SUCCESS) {
20646386Sjp151216 		free(to->windomain);
20656386Sjp151216 		to->windomain = NULL;
20666386Sjp151216 		free(to->winname);
20676386Sjp151216 		to->winname = NULL;
20686386Sjp151216 		return (retval);
20696386Sjp151216 	}
20706386Sjp151216 
20716386Sjp151216 	return (retval);
20726386Sjp151216 }
20736386Sjp151216 
20746386Sjp151216 
20756386Sjp151216 /*
207612508Samw@Sun.COM  * Move the contents of the "info" structure from "from" to "to".
20776386Sjp151216  */
207812508Samw@Sun.COM void
idmap_info_mov(idmap_info * to,idmap_info * from)20796386Sjp151216 idmap_info_mov(idmap_info *to, idmap_info *from)
20806386Sjp151216 {
20816386Sjp151216 	(void) memcpy(to, from, sizeof (idmap_info));
20826386Sjp151216 	(void) memset(from, 0, sizeof (idmap_info));
20836386Sjp151216 }
20846386Sjp151216 
20856386Sjp151216 
20866386Sjp151216 void
idmap_info_free(idmap_info * info)20876386Sjp151216 idmap_info_free(idmap_info *info)
20886386Sjp151216 {
20896386Sjp151216 	if (info == NULL)
20906386Sjp151216 		return;
20916386Sjp151216 
209212508Samw@Sun.COM 	xdr_free(xdr_idmap_info, (caddr_t)info);
209312508Samw@Sun.COM 	(void) memset(info, 0, sizeof (idmap_info));
209412508Samw@Sun.COM }
20956386Sjp151216 
20966386Sjp151216 
209712508Samw@Sun.COM void
idmap_how_clear(idmap_how * how)209812508Samw@Sun.COM idmap_how_clear(idmap_how *how)
209912508Samw@Sun.COM {
210012508Samw@Sun.COM 	xdr_free(xdr_idmap_how, (caddr_t)how);
210112508Samw@Sun.COM 	(void) memset(how, 0, sizeof (*how));
21026386Sjp151216 }
21036386Sjp151216 
21046386Sjp151216 
21055064Sdm199847 /*
21065043Sbaban  * Get uid given Windows name
21075043Sbaban  */
21085043Sbaban idmap_stat
idmap_getuidbywinname(const char * name,const char * domain,int flag,uid_t * uid)21097369SJulian.Pullen@Sun.COM idmap_getuidbywinname(const char *name, const char *domain, int flag,
21107369SJulian.Pullen@Sun.COM 	uid_t *uid)
21115696Snw141292 {
21125043Sbaban 	idmap_retcode	rc;
21135696Snw141292 	int		is_user = 1;
21145696Snw141292 	int		is_wuser = -1;
21157369SJulian.Pullen@Sun.COM 	int 		direction;
21165043Sbaban 
21175043Sbaban 	if (uid == NULL)
21185043Sbaban 		return (IDMAP_ERR_ARG);
21195043Sbaban 
21207369SJulian.Pullen@Sun.COM 	if (flag & IDMAP_REQ_FLG_USE_CACHE) {
21217369SJulian.Pullen@Sun.COM 		rc = idmap_cache_lookup_uidbywinname(name, domain, uid);
21227369SJulian.Pullen@Sun.COM 		if (rc == IDMAP_SUCCESS || rc == IDMAP_ERR_MEMORY)
21237369SJulian.Pullen@Sun.COM 			return (rc);
21247369SJulian.Pullen@Sun.COM 	}
21255043Sbaban 	/* Get mapping */
2126*12914SJoyce.McIntosh@Sun.COM 	rc = idmap_get_w2u_mapping(NULL, NULL, name, domain, flag,
21277369SJulian.Pullen@Sun.COM 	    &is_user, &is_wuser, uid, NULL, &direction, NULL);
21285043Sbaban 
21297369SJulian.Pullen@Sun.COM 	if (rc == IDMAP_SUCCESS && (flag & IDMAP_REQ_FLG_USE_CACHE)) {
21307369SJulian.Pullen@Sun.COM 		/* If we have not got the domain don't store UID to winname */
21317369SJulian.Pullen@Sun.COM 		if (domain == NULL)
21327369SJulian.Pullen@Sun.COM 			direction = IDMAP_DIRECTION_W2U;
21337369SJulian.Pullen@Sun.COM 		idmap_cache_add_winname2uid(name, domain, *uid, direction);
21347369SJulian.Pullen@Sun.COM 	}
21357369SJulian.Pullen@Sun.COM 
21365043Sbaban 	return (rc);
21375043Sbaban }
21385043Sbaban 
21395043Sbaban 
21405043Sbaban /*
21415043Sbaban  * Get gid given Windows name
21425043Sbaban  */
21435043Sbaban idmap_stat
idmap_getgidbywinname(const char * name,const char * domain,int flag,gid_t * gid)21447369SJulian.Pullen@Sun.COM idmap_getgidbywinname(const char *name, const char *domain, int flag,
21457369SJulian.Pullen@Sun.COM 	gid_t *gid)
21465696Snw141292 {
21475043Sbaban 	idmap_retcode	rc;
21485696Snw141292 	int		is_user = 0;
21495696Snw141292 	int		is_wuser = -1;
21507369SJulian.Pullen@Sun.COM 	int		direction;
21515043Sbaban 
21525043Sbaban 	if (gid == NULL)
21535043Sbaban 		return (IDMAP_ERR_ARG);
21545043Sbaban 
21557369SJulian.Pullen@Sun.COM 	if (flag & IDMAP_REQ_FLG_USE_CACHE) {
21567369SJulian.Pullen@Sun.COM 		rc = idmap_cache_lookup_gidbywinname(name, domain, gid);
21577369SJulian.Pullen@Sun.COM 		if (rc == IDMAP_SUCCESS || rc == IDMAP_ERR_MEMORY)
21587369SJulian.Pullen@Sun.COM 			return (rc);
21597369SJulian.Pullen@Sun.COM 	}
21607369SJulian.Pullen@Sun.COM 
21615043Sbaban 	/* Get mapping */
2162*12914SJoyce.McIntosh@Sun.COM 	rc = idmap_get_w2u_mapping(NULL, NULL, name, domain, flag,
21637369SJulian.Pullen@Sun.COM 	    &is_user, &is_wuser, gid, NULL, &direction, NULL);
21645043Sbaban 
21657369SJulian.Pullen@Sun.COM 	if (rc == IDMAP_SUCCESS && (flag & IDMAP_REQ_FLG_USE_CACHE)) {
21667369SJulian.Pullen@Sun.COM 		/* If we have not got the domain don't store GID to winname */
21677369SJulian.Pullen@Sun.COM 		if (domain == NULL)
21687369SJulian.Pullen@Sun.COM 			direction = IDMAP_DIRECTION_W2U;
21697369SJulian.Pullen@Sun.COM 		idmap_cache_add_winname2gid(name, domain, *gid, direction);
21707369SJulian.Pullen@Sun.COM 	}
21717369SJulian.Pullen@Sun.COM 
21725043Sbaban 	return (rc);
21735043Sbaban }
21745043Sbaban 
21755043Sbaban 
21765043Sbaban /*
21775043Sbaban  * Get winname given pid
21785043Sbaban  */
21795043Sbaban static idmap_retcode
idmap_getwinnamebypid(uid_t pid,int is_user,int flag,char ** name,char ** domain)21807369SJulian.Pullen@Sun.COM idmap_getwinnamebypid(uid_t pid, int is_user, int flag, char **name,
21817369SJulian.Pullen@Sun.COM 	char **domain)
21825696Snw141292 {
21835043Sbaban 	idmap_retcode	rc;
21845043Sbaban 	int		len;
21855043Sbaban 	char		*winname, *windomain;
21867369SJulian.Pullen@Sun.COM 	int		direction;
21875043Sbaban 
21885043Sbaban 	if (name == NULL)
21895043Sbaban 		return (IDMAP_ERR_ARG);
21905043Sbaban 
21917369SJulian.Pullen@Sun.COM 	if (flag & IDMAP_REQ_FLG_USE_CACHE) {
21927369SJulian.Pullen@Sun.COM 		if (is_user)
21937369SJulian.Pullen@Sun.COM 			rc = idmap_cache_lookup_winnamebyuid(&winname,
21947369SJulian.Pullen@Sun.COM 			    &windomain, pid);
21957369SJulian.Pullen@Sun.COM 		else
21967369SJulian.Pullen@Sun.COM 			rc = idmap_cache_lookup_winnamebygid(&winname,
21977369SJulian.Pullen@Sun.COM 			    &windomain, pid);
21987369SJulian.Pullen@Sun.COM 		if (rc == IDMAP_SUCCESS)
21997369SJulian.Pullen@Sun.COM 			goto out;
22007369SJulian.Pullen@Sun.COM 		if (rc == IDMAP_ERR_MEMORY)
22017369SJulian.Pullen@Sun.COM 			return (rc);
22027369SJulian.Pullen@Sun.COM 	}
22037369SJulian.Pullen@Sun.COM 
22045043Sbaban 	/* Get mapping */
2205*12914SJoyce.McIntosh@Sun.COM 	rc = idmap_get_u2w_mapping(&pid, NULL, flag, is_user, NULL,
22067369SJulian.Pullen@Sun.COM 	    NULL, NULL, &winname, &windomain, &direction, NULL);
22075043Sbaban 
22085043Sbaban 	/* Return on error */
22095043Sbaban 	if (rc != IDMAP_SUCCESS)
22105043Sbaban 		return (rc);
22115043Sbaban 
22125043Sbaban 	/*
22135043Sbaban 	 * The given PID may have been mapped to a locally
22145043Sbaban 	 * generated SID in which case there isn't any
22155043Sbaban 	 * Windows name
22165043Sbaban 	 */
22175043Sbaban 	if (winname == NULL || windomain == NULL) {
22185043Sbaban 		idmap_free(winname);
22195043Sbaban 		idmap_free(windomain);
22205043Sbaban 		return (IDMAP_ERR_NORESULT);
22215043Sbaban 	}
22225043Sbaban 
22237369SJulian.Pullen@Sun.COM 	if (flag & IDMAP_REQ_FLG_USE_CACHE) {
22247369SJulian.Pullen@Sun.COM 		if (is_user)
22257369SJulian.Pullen@Sun.COM 			idmap_cache_add_winname2uid(winname, windomain,
22267369SJulian.Pullen@Sun.COM 			    pid, direction);
22277369SJulian.Pullen@Sun.COM 		else
22287369SJulian.Pullen@Sun.COM 			idmap_cache_add_winname2gid(winname, windomain,
22297369SJulian.Pullen@Sun.COM 			    pid, direction);
22307369SJulian.Pullen@Sun.COM 	}
22317369SJulian.Pullen@Sun.COM 
22327369SJulian.Pullen@Sun.COM out:
22335043Sbaban 	if (domain != NULL) {
22345043Sbaban 		*name = winname;
22355043Sbaban 		*domain = windomain;
22365043Sbaban 	} else {
22375043Sbaban 		len = strlen(winname) + strlen(windomain) + 2;
22385043Sbaban 		if ((*name = malloc(len)) != NULL)
22395043Sbaban 			(void) snprintf(*name, len, "%s@%s", winname,
22405043Sbaban 			    windomain);
22415043Sbaban 		else
22425043Sbaban 			rc = IDMAP_ERR_MEMORY;
22435043Sbaban 		idmap_free(winname);
22445043Sbaban 		idmap_free(windomain);
22455043Sbaban 	}
22467369SJulian.Pullen@Sun.COM 
22475043Sbaban 	return (rc);
22485043Sbaban }
22495043Sbaban 
22505043Sbaban 
22515043Sbaban /*
22525043Sbaban  * Get winname given uid
22535043Sbaban  */
22545043Sbaban idmap_stat
idmap_getwinnamebyuid(uid_t uid,int flag,char ** name,char ** domain)22557369SJulian.Pullen@Sun.COM idmap_getwinnamebyuid(uid_t uid, int flag, char **name, char **domain)
22565696Snw141292 {
22577369SJulian.Pullen@Sun.COM 	return (idmap_getwinnamebypid(uid, 1, flag, name, domain));
22585043Sbaban }
22595043Sbaban 
22605043Sbaban 
22615043Sbaban /*
22625043Sbaban  * Get winname given gid
22635043Sbaban  */
22645043Sbaban idmap_stat
idmap_getwinnamebygid(gid_t gid,int flag,char ** name,char ** domain)22657369SJulian.Pullen@Sun.COM idmap_getwinnamebygid(gid_t gid, int flag, char **name, char **domain)
22665696Snw141292 {
22677369SJulian.Pullen@Sun.COM 	return (idmap_getwinnamebypid(gid, 0, flag, name, domain));
22685043Sbaban }
226911963SAfshin.Ardakani@Sun.COM 
227011963SAfshin.Ardakani@Sun.COM idmap_stat
idmap_flush(idmap_flush_op op)2271*12914SJoyce.McIntosh@Sun.COM idmap_flush(idmap_flush_op op)
227211963SAfshin.Ardakani@Sun.COM {
2273*12914SJoyce.McIntosh@Sun.COM 	idmap_retcode		rc1, rc2;
227411963SAfshin.Ardakani@Sun.COM 
2275*12914SJoyce.McIntosh@Sun.COM 	rc1 = _idmap_clnt_call(IDMAP_FLUSH,
227611963SAfshin.Ardakani@Sun.COM 	    (xdrproc_t)xdr_idmap_flush_op, (caddr_t)&op,
2277*12914SJoyce.McIntosh@Sun.COM 	    (xdrproc_t)xdr_idmap_retcode, (caddr_t)&rc2, TIMEOUT);
227811963SAfshin.Ardakani@Sun.COM 
2279*12914SJoyce.McIntosh@Sun.COM 	if (rc1 != IDMAP_SUCCESS)
2280*12914SJoyce.McIntosh@Sun.COM 		return (rc1);
2281*12914SJoyce.McIntosh@Sun.COM 	return (rc2);
228211963SAfshin.Ardakani@Sun.COM }
228312065SKeyur.Desai@Sun.COM 
228412065SKeyur.Desai@Sun.COM 
228512065SKeyur.Desai@Sun.COM /*
228612065SKeyur.Desai@Sun.COM  * syslog is the default logger.
228712065SKeyur.Desai@Sun.COM  * It can be overwritten by supplying a logger
228812065SKeyur.Desai@Sun.COM  * with  idmap_set_logger()
228912065SKeyur.Desai@Sun.COM  */
229012065SKeyur.Desai@Sun.COM idmap_logger_t logger = syslog;
229112065SKeyur.Desai@Sun.COM 
229212065SKeyur.Desai@Sun.COM 
229312065SKeyur.Desai@Sun.COM void
idmap_set_logger(idmap_logger_t funct)229412065SKeyur.Desai@Sun.COM idmap_set_logger(idmap_logger_t funct)
229512065SKeyur.Desai@Sun.COM {
229612065SKeyur.Desai@Sun.COM 	logger = funct;
229712065SKeyur.Desai@Sun.COM }
229812508Samw@Sun.COM 
229912508Samw@Sun.COM /*
230012508Samw@Sun.COM  * Helper functions that concatenate two parts of a name and then
230112508Samw@Sun.COM  * look up a value, so that the same set of functions can be used to
230212508Samw@Sun.COM  * process both "in" and "out" parameters.
230312508Samw@Sun.COM  */
230412508Samw@Sun.COM static
230512508Samw@Sun.COM boolean_t
idmap_trace_get_str(nvlist_t * entry,char * n1,char * n2,char ** ret)230612508Samw@Sun.COM idmap_trace_get_str(nvlist_t *entry, char *n1, char *n2, char **ret)
230712508Samw@Sun.COM {
230812508Samw@Sun.COM 	char name[IDMAP_TRACE_NAME_MAX+1];	/* Max used is about 11 */
230912508Samw@Sun.COM 	int err;
231012508Samw@Sun.COM 
231112508Samw@Sun.COM 	(void) strlcpy(name, n1, sizeof (name));
231212508Samw@Sun.COM 	if (n2 != NULL)
231312508Samw@Sun.COM 		(void) strlcat(name, n2, sizeof (name));
231412508Samw@Sun.COM 
231512508Samw@Sun.COM 	err = nvlist_lookup_string(entry, name, ret);
231612508Samw@Sun.COM 	return (err == 0);
231712508Samw@Sun.COM }
231812508Samw@Sun.COM 
231912508Samw@Sun.COM static
232012508Samw@Sun.COM boolean_t
idmap_trace_get_int(nvlist_t * entry,char * n1,char * n2,int64_t * ret)232112508Samw@Sun.COM idmap_trace_get_int(nvlist_t *entry, char *n1, char *n2, int64_t *ret)
232212508Samw@Sun.COM {
232312508Samw@Sun.COM 	char name[IDMAP_TRACE_NAME_MAX+1];	/* Max used is about 11 */
232412508Samw@Sun.COM 	int err;
232512508Samw@Sun.COM 
232612508Samw@Sun.COM 	(void) strlcpy(name, n1, sizeof (name));
232712508Samw@Sun.COM 	if (n2 != NULL)
232812508Samw@Sun.COM 		(void) strlcat(name, n2, sizeof (name));
232912508Samw@Sun.COM 
233012508Samw@Sun.COM 	err = nvlist_lookup_int64(entry, name, ret);
233112508Samw@Sun.COM 	return (err == 0);
233212508Samw@Sun.COM }
233312508Samw@Sun.COM 
233412508Samw@Sun.COM static
233512508Samw@Sun.COM void
idmap_trace_print_id(FILE * out,nvlist_t * entry,char * fromto)233612508Samw@Sun.COM idmap_trace_print_id(FILE *out, nvlist_t *entry, char *fromto)
233712508Samw@Sun.COM {
233812508Samw@Sun.COM 	char *s;
233912508Samw@Sun.COM 	int64_t i64;
234012508Samw@Sun.COM 
234112508Samw@Sun.COM 	if (idmap_trace_get_int(entry, fromto, IDMAP_TRACE_TYPE, &i64)) {
234212508Samw@Sun.COM 		switch (i64) {
234312508Samw@Sun.COM 		case IDMAP_POSIXID:
234412508Samw@Sun.COM 			(void) fprintf(out, "unixname ");
234512508Samw@Sun.COM 			break;
234612508Samw@Sun.COM 		case IDMAP_UID:
234712508Samw@Sun.COM 			(void) fprintf(out, "unixuser ");
234812508Samw@Sun.COM 			break;
234912508Samw@Sun.COM 		case IDMAP_GID:
235012508Samw@Sun.COM 			(void) fprintf(out, "unixgroup ");
235112508Samw@Sun.COM 			break;
235212508Samw@Sun.COM 		case IDMAP_SID:
235312508Samw@Sun.COM 			(void) fprintf(out, "winname ");
235412508Samw@Sun.COM 			break;
235512508Samw@Sun.COM 		case IDMAP_USID:
235612508Samw@Sun.COM 			(void) fprintf(out, "winuser ");
235712508Samw@Sun.COM 			break;
235812508Samw@Sun.COM 		case IDMAP_GSID:
235912508Samw@Sun.COM 			(void) fprintf(out, "wingroup ");
236012508Samw@Sun.COM 			break;
236112508Samw@Sun.COM 		case IDMAP_NONE:
236212508Samw@Sun.COM 			(void) fprintf(out, gettext("unknown "));
236312508Samw@Sun.COM 			break;
236412508Samw@Sun.COM 		default:
236512508Samw@Sun.COM 			(void) fprintf(out, gettext("bad %d "), (int)i64);
236612508Samw@Sun.COM 			break;
236712508Samw@Sun.COM 		}
236812508Samw@Sun.COM 	}
236912508Samw@Sun.COM 
237012508Samw@Sun.COM 	if (idmap_trace_get_str(entry, fromto, IDMAP_TRACE_NAME, &s))
237112508Samw@Sun.COM 		(void) fprintf(out, "%s ", s);
237212508Samw@Sun.COM 
237312508Samw@Sun.COM 	if (idmap_trace_get_str(entry, fromto, IDMAP_TRACE_SID, &s))
237412508Samw@Sun.COM 		(void) fprintf(out, "%s ", s);
237512508Samw@Sun.COM 
237612508Samw@Sun.COM 	if (idmap_trace_get_int(entry, fromto, IDMAP_TRACE_UNIXID, &i64))
237712508Samw@Sun.COM 		(void) fprintf(out, "%u ", (uid_t)i64);
237812508Samw@Sun.COM }
237912508Samw@Sun.COM 
238012508Samw@Sun.COM void
idmap_trace_print_1(FILE * out,char * prefix,nvlist_t * entry)238112508Samw@Sun.COM idmap_trace_print_1(FILE *out, char *prefix, nvlist_t *entry)
238212508Samw@Sun.COM {
238312508Samw@Sun.COM 	char *s;
238412508Samw@Sun.COM 	int64_t i64;
238512508Samw@Sun.COM 
238612508Samw@Sun.COM 	(void) fprintf(out, "%s", prefix);
238712508Samw@Sun.COM 	idmap_trace_print_id(out, entry, "from");
238812508Samw@Sun.COM 	(void) fprintf(out, "-> ");
238912508Samw@Sun.COM 	idmap_trace_print_id(out, entry, "to");
239012508Samw@Sun.COM 	if (idmap_trace_get_int(entry, IDMAP_TRACE_ERROR, NULL, &i64))
239112508Samw@Sun.COM 		(void) fprintf(out, gettext("Error %d "), (int)i64);
239212508Samw@Sun.COM 	(void) fprintf(out, "-");
239312508Samw@Sun.COM 	if (idmap_trace_get_str(entry, IDMAP_TRACE_MESSAGE, NULL, &s))
239412508Samw@Sun.COM 		(void) fprintf(out, " %s", s);
239512508Samw@Sun.COM 	(void) fprintf(out, "\n");
239612508Samw@Sun.COM }
239712508Samw@Sun.COM 
239812508Samw@Sun.COM void
idmap_trace_print(FILE * out,char * prefix,nvlist_t * trace)239912508Samw@Sun.COM idmap_trace_print(FILE *out, char *prefix, nvlist_t *trace)
240012508Samw@Sun.COM {
240112508Samw@Sun.COM 	nvpair_t *nvp;
240212508Samw@Sun.COM 
240312508Samw@Sun.COM 	for (nvp = nvlist_next_nvpair(trace, NULL);
240412508Samw@Sun.COM 	    nvp != NULL;
240512508Samw@Sun.COM 	    nvp = nvlist_next_nvpair(trace, nvp)) {
240612508Samw@Sun.COM 		nvlist_t *entry;
240712508Samw@Sun.COM 		int err;
240812508Samw@Sun.COM 
240912508Samw@Sun.COM 		err = nvpair_value_nvlist(nvp, &entry);
241012508Samw@Sun.COM 		assert(err == 0);
241112508Samw@Sun.COM 
241212508Samw@Sun.COM 		idmap_trace_print_1(out, prefix, entry);
241312508Samw@Sun.COM 	}
241412508Samw@Sun.COM }
2415