xref: /titanic_53/usr/src/cmd/idmap/idmapd/server.c (revision fe1c642d06e14b412cd83ae2179303186ab08972)
1c5c4113dSnw141292 /*
2c5c4113dSnw141292  * CDDL HEADER START
3c5c4113dSnw141292  *
4c5c4113dSnw141292  * The contents of this file are subject to the terms of the
5c5c4113dSnw141292  * Common Development and Distribution License (the "License").
6c5c4113dSnw141292  * You may not use this file except in compliance with the License.
7c5c4113dSnw141292  *
8c5c4113dSnw141292  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9c5c4113dSnw141292  * or http://www.opensolaris.org/os/licensing.
10c5c4113dSnw141292  * See the License for the specific language governing permissions
11c5c4113dSnw141292  * and limitations under the License.
12c5c4113dSnw141292  *
13c5c4113dSnw141292  * When distributing Covered Code, include this CDDL HEADER in each
14c5c4113dSnw141292  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15c5c4113dSnw141292  * If applicable, add the following below this CDDL HEADER, with the
16c5c4113dSnw141292  * fields enclosed by brackets "[]" replaced with your own identifying
17c5c4113dSnw141292  * information: Portions Copyright [yyyy] [name of copyright owner]
18c5c4113dSnw141292  *
19c5c4113dSnw141292  * CDDL HEADER END
20c5c4113dSnw141292  */
21c5c4113dSnw141292 /*
221fcced4cSJordan Brown  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23c5c4113dSnw141292  * Use is subject to license terms.
24c5c4113dSnw141292  */
25c5c4113dSnw141292 
26c5c4113dSnw141292 
27c5c4113dSnw141292 /*
28c5c4113dSnw141292  * Service routines
29c5c4113dSnw141292  */
30c5c4113dSnw141292 
31c5c4113dSnw141292 #include "idmapd.h"
32c5c4113dSnw141292 #include "idmap_priv.h"
33e8c27ec8Sbaban #include "nldaputils.h"
34c5c4113dSnw141292 #include <signal.h>
35c5c4113dSnw141292 #include <thread.h>
36c5c4113dSnw141292 #include <string.h>
37c5c4113dSnw141292 #include <strings.h>
38c5c4113dSnw141292 #include <errno.h>
39c5c4113dSnw141292 #include <assert.h>
40c5c4113dSnw141292 #include <sys/types.h>
41c5c4113dSnw141292 #include <sys/stat.h>
42c5c4113dSnw141292 #include <ucred.h>
43c5c4113dSnw141292 #include <pwd.h>
44c5c4113dSnw141292 #include <auth_attr.h>
45c5c4113dSnw141292 #include <secdb.h>
460dcc7149Snw141292 #include <sys/u8_textprep.h>
471fcced4cSJordan Brown #include <note.h>
48c5c4113dSnw141292 
49c5c4113dSnw141292 #define	_VALIDATE_LIST_CB_DATA(col, val, siz)\
50c5c4113dSnw141292 	retcode = validate_list_cb_data(cb_data, argc, argv, col,\
51c5c4113dSnw141292 			(uchar_t **)val, siz);\
52c5c4113dSnw141292 	if (retcode == IDMAP_NEXT) {\
53c5c4113dSnw141292 		result->retcode = IDMAP_NEXT;\
54c5c4113dSnw141292 		return (0);\
55c5c4113dSnw141292 	} else if (retcode < 0) {\
56c5c4113dSnw141292 		result->retcode = retcode;\
57c5c4113dSnw141292 		return (1);\
58c5c4113dSnw141292 	}
59c5c4113dSnw141292 
6048258c6bSjp151216 #define	PROCESS_LIST_SVC_SQL(rcode, db, dbname, sql, limit, flag, cb, res, len)\
6148258c6bSjp151216 	rcode = process_list_svc_sql(db, dbname, sql, limit, flag, cb, res);\
62c5c4113dSnw141292 	if (rcode == IDMAP_ERR_BUSY)\
63c5c4113dSnw141292 		res->retcode = IDMAP_ERR_BUSY;\
64c5c4113dSnw141292 	else if (rcode == IDMAP_SUCCESS && len == 0)\
65c5c4113dSnw141292 		res->retcode = IDMAP_ERR_NOTFOUND;
66c5c4113dSnw141292 
67c5c4113dSnw141292 
688e228215Sdm199847 #define	STRDUP_OR_FAIL(to, from) \
698e228215Sdm199847 	if ((from) == NULL) \
708e228215Sdm199847 		to = NULL; \
718e228215Sdm199847 	else { \
728e228215Sdm199847 		if ((to = strdup(from)) == NULL) \
738e228215Sdm199847 			return (1); \
748e228215Sdm199847 	}
758e228215Sdm199847 
76479ac375Sdm199847 #define	STRDUP_CHECK(to, from) \
77479ac375Sdm199847 	if ((from) != NULL) { \
78479ac375Sdm199847 		to = strdup(from); \
79479ac375Sdm199847 		if (to == NULL) { \
80479ac375Sdm199847 			result->retcode = IDMAP_ERR_MEMORY; \
81479ac375Sdm199847 			goto out; \
82479ac375Sdm199847 		} \
83479ac375Sdm199847 	}
84479ac375Sdm199847 
85c5c4113dSnw141292 /* ARGSUSED */
86c5c4113dSnw141292 bool_t
87cd37da74Snw141292 idmap_null_1_svc(void *result, struct svc_req *rqstp)
88cd37da74Snw141292 {
89c5c4113dSnw141292 	return (TRUE);
90c5c4113dSnw141292 }
91c5c4113dSnw141292 
92334e3463Sbaban /*
93334e3463Sbaban  * RPC layer allocates empty strings to replace NULL char *.
94334e3463Sbaban  * This utility function frees these empty strings.
95334e3463Sbaban  */
96e8c27ec8Sbaban static
97e8c27ec8Sbaban void
98334e3463Sbaban sanitize_mapping_request(idmap_mapping *req)
99334e3463Sbaban {
100*fe1c642dSBill Krier 	if (EMPTY_STRING(req->id1name)) {
101334e3463Sbaban 		free(req->id1name);
102334e3463Sbaban 		req->id1name = NULL;
103*fe1c642dSBill Krier 	}
104*fe1c642dSBill Krier 	if (EMPTY_STRING(req->id1domain)) {
105334e3463Sbaban 		free(req->id1domain);
106334e3463Sbaban 		req->id1domain = NULL;
107*fe1c642dSBill Krier 	}
108*fe1c642dSBill Krier 	if (EMPTY_STRING(req->id2name)) {
109334e3463Sbaban 		free(req->id2name);
110334e3463Sbaban 		req->id2name = NULL;
111*fe1c642dSBill Krier 	}
112*fe1c642dSBill Krier 	if (EMPTY_STRING(req->id2domain)) {
113334e3463Sbaban 		free(req->id2domain);
114334e3463Sbaban 		req->id2domain = NULL;
115*fe1c642dSBill Krier 	}
116e8c27ec8Sbaban 	req->direction = _IDMAP_F_DONE;
117334e3463Sbaban }
118334e3463Sbaban 
1190dcc7149Snw141292 static
1200dcc7149Snw141292 int
1210dcc7149Snw141292 validate_mapped_id_by_name_req(idmap_mapping *req)
1220dcc7149Snw141292 {
1230dcc7149Snw141292 	int e;
1240dcc7149Snw141292 
1250dcc7149Snw141292 	if (IS_REQUEST_UID(*req) || IS_REQUEST_GID(*req))
1260dcc7149Snw141292 		return (IDMAP_SUCCESS);
1270dcc7149Snw141292 
1280dcc7149Snw141292 	if (IS_REQUEST_SID(*req, 1)) {
1290dcc7149Snw141292 		if (!EMPTY_STRING(req->id1name) &&
1300dcc7149Snw141292 		    u8_validate(req->id1name, strlen(req->id1name),
1310dcc7149Snw141292 		    NULL, U8_VALIDATE_ENTIRE, &e) < 0)
1320dcc7149Snw141292 			return (IDMAP_ERR_BAD_UTF8);
1330dcc7149Snw141292 		if (!EMPTY_STRING(req->id1domain) &&
1340dcc7149Snw141292 		    u8_validate(req->id1domain, strlen(req->id1domain),
1350dcc7149Snw141292 		    NULL, U8_VALIDATE_ENTIRE, &e) < 0)
1360dcc7149Snw141292 			return (IDMAP_ERR_BAD_UTF8);
1370dcc7149Snw141292 	}
1380dcc7149Snw141292 
1390dcc7149Snw141292 	return (IDMAP_SUCCESS);
1400dcc7149Snw141292 }
1410dcc7149Snw141292 
1420dcc7149Snw141292 static
1430dcc7149Snw141292 int
1440dcc7149Snw141292 validate_rule(idmap_namerule *rule)
1450dcc7149Snw141292 {
1460dcc7149Snw141292 	int e;
1470dcc7149Snw141292 
1480dcc7149Snw141292 	if (!EMPTY_STRING(rule->winname) &&
1490dcc7149Snw141292 	    u8_validate(rule->winname, strlen(rule->winname),
1500dcc7149Snw141292 	    NULL, U8_VALIDATE_ENTIRE, &e) < 0)
1510dcc7149Snw141292 		return (IDMAP_ERR_BAD_UTF8);
1520dcc7149Snw141292 
1530dcc7149Snw141292 	if (!EMPTY_STRING(rule->windomain) &&
1540dcc7149Snw141292 	    u8_validate(rule->windomain, strlen(rule->windomain),
1550dcc7149Snw141292 	    NULL, U8_VALIDATE_ENTIRE, &e) < 0)
1560dcc7149Snw141292 		return (IDMAP_ERR_BAD_UTF8);
1570dcc7149Snw141292 
1580dcc7149Snw141292 	return (IDMAP_SUCCESS);
1590dcc7149Snw141292 
1600dcc7149Snw141292 }
1610dcc7149Snw141292 
1620dcc7149Snw141292 static
1630dcc7149Snw141292 bool_t
1640dcc7149Snw141292 validate_rules(idmap_update_batch *batch)
1650dcc7149Snw141292 {
1660dcc7149Snw141292 	idmap_update_op	*up;
1670dcc7149Snw141292 	int i;
1680dcc7149Snw141292 
1690dcc7149Snw141292 	for (i = 0; i < batch->idmap_update_batch_len; i++) {
1700dcc7149Snw141292 		up = &(batch->idmap_update_batch_val[i]);
1710dcc7149Snw141292 		if (validate_rule(&(up->idmap_update_op_u.rule))
1720dcc7149Snw141292 		    != IDMAP_SUCCESS)
1730dcc7149Snw141292 			return (IDMAP_ERR_BAD_UTF8);
1740dcc7149Snw141292 	}
1750dcc7149Snw141292 
1760dcc7149Snw141292 	return (IDMAP_SUCCESS);
1770dcc7149Snw141292 }
1780dcc7149Snw141292 
179c5c4113dSnw141292 /* ARGSUSED */
180c5c4113dSnw141292 bool_t
181c5c4113dSnw141292 idmap_get_mapped_ids_1_svc(idmap_mapping_batch batch,
182cd37da74Snw141292 		idmap_ids_res *result, struct svc_req *rqstp)
183cd37da74Snw141292 {
184c5c4113dSnw141292 	sqlite		*cache = NULL, *db = NULL;
185c5c4113dSnw141292 	lookup_state_t	state;
186e8c27ec8Sbaban 	idmap_retcode	retcode;
18762c60062Sbaban 	uint_t		i;
188c5c4113dSnw141292 
189c5c4113dSnw141292 	/* Init */
190c5c4113dSnw141292 	(void) memset(result, 0, sizeof (*result));
191c5c4113dSnw141292 	(void) memset(&state, 0, sizeof (state));
192c5c4113dSnw141292 
193c5c4113dSnw141292 	/* Return success if nothing was requested */
194c5c4113dSnw141292 	if (batch.idmap_mapping_batch_len < 1)
195c5c4113dSnw141292 		goto out;
196c5c4113dSnw141292 
197c5c4113dSnw141292 	/* Get cache handle */
198c5c4113dSnw141292 	result->retcode = get_cache_handle(&cache);
199c5c4113dSnw141292 	if (result->retcode != IDMAP_SUCCESS)
200c5c4113dSnw141292 		goto out;
201479ac375Sdm199847 	state.cache = cache;
202c5c4113dSnw141292 
203c5c4113dSnw141292 	/* Get db handle */
204c5c4113dSnw141292 	result->retcode = get_db_handle(&db);
205c5c4113dSnw141292 	if (result->retcode != IDMAP_SUCCESS)
206c5c4113dSnw141292 		goto out;
207479ac375Sdm199847 	state.db = db;
208c5c4113dSnw141292 
209c5c4113dSnw141292 	/* Allocate result array */
210c5c4113dSnw141292 	result->ids.ids_val = calloc(batch.idmap_mapping_batch_len,
211c5c4113dSnw141292 	    sizeof (idmap_id_res));
212c5c4113dSnw141292 	if (result->ids.ids_val == NULL) {
213c5c4113dSnw141292 		idmapdlog(LOG_ERR, "Out of memory");
214c5c4113dSnw141292 		result->retcode = IDMAP_ERR_MEMORY;
215c5c4113dSnw141292 		goto out;
216c5c4113dSnw141292 	}
217c5c4113dSnw141292 	result->ids.ids_len = batch.idmap_mapping_batch_len;
218c5c4113dSnw141292 
21962c60062Sbaban 	/* Allocate hash table to check for duplicate sids */
22062c60062Sbaban 	state.sid_history = calloc(batch.idmap_mapping_batch_len,
22162c60062Sbaban 	    sizeof (*state.sid_history));
22262c60062Sbaban 	if (state.sid_history == NULL) {
22362c60062Sbaban 		idmapdlog(LOG_ERR, "Out of memory");
22462c60062Sbaban 		result->retcode = IDMAP_ERR_MEMORY;
22562c60062Sbaban 		goto out;
22662c60062Sbaban 	}
22762c60062Sbaban 	state.sid_history_size = batch.idmap_mapping_batch_len;
22862c60062Sbaban 	for (i = 0; i < state.sid_history_size; i++) {
22962c60062Sbaban 		state.sid_history[i].key = state.sid_history_size;
23062c60062Sbaban 		state.sid_history[i].next = state.sid_history_size;
23162c60062Sbaban 	}
23262c60062Sbaban 	state.batch = &batch;
23362c60062Sbaban 	state.result = result;
23462c60062Sbaban 
235e8c27ec8Sbaban 	/* Get directory-based name mapping info */
236479ac375Sdm199847 	result->retcode = load_cfg_in_state(&state);
237e8c27ec8Sbaban 	if (result->retcode != IDMAP_SUCCESS)
238e8c27ec8Sbaban 		goto out;
239e8c27ec8Sbaban 
240c5c4113dSnw141292 	/* Init our 'done' flags */
241c5c4113dSnw141292 	state.sid2pid_done = state.pid2sid_done = TRUE;
242c5c4113dSnw141292 
243c5c4113dSnw141292 	/* First stage */
244c5c4113dSnw141292 	for (i = 0; i < batch.idmap_mapping_batch_len; i++) {
24562c60062Sbaban 		state.curpos = i;
246334e3463Sbaban 		(void) sanitize_mapping_request(
247334e3463Sbaban 		    &batch.idmap_mapping_batch_val[i]);
248c5c4113dSnw141292 		if (IS_BATCH_SID(batch, i)) {
249c5c4113dSnw141292 			retcode = sid2pid_first_pass(
250c5c4113dSnw141292 			    &state,
251c5c4113dSnw141292 			    &batch.idmap_mapping_batch_val[i],
252c5c4113dSnw141292 			    &result->ids.ids_val[i]);
253c5c4113dSnw141292 		} else if (IS_BATCH_UID(batch, i)) {
254c5c4113dSnw141292 			retcode = pid2sid_first_pass(
255c5c4113dSnw141292 			    &state,
256c5c4113dSnw141292 			    &batch.idmap_mapping_batch_val[i],
257*fe1c642dSBill Krier 			    &result->ids.ids_val[i], 1);
258c5c4113dSnw141292 		} else if (IS_BATCH_GID(batch, i)) {
259c5c4113dSnw141292 			retcode = pid2sid_first_pass(
260c5c4113dSnw141292 			    &state,
261c5c4113dSnw141292 			    &batch.idmap_mapping_batch_val[i],
262*fe1c642dSBill Krier 			    &result->ids.ids_val[i], 0);
263c5c4113dSnw141292 		} else {
264c5c4113dSnw141292 			result->ids.ids_val[i].retcode = IDMAP_ERR_IDTYPE;
265c5c4113dSnw141292 			continue;
266c5c4113dSnw141292 		}
267c5c4113dSnw141292 		if (IDMAP_FATAL_ERROR(retcode)) {
268c5c4113dSnw141292 			result->retcode = retcode;
269c5c4113dSnw141292 			goto out;
270c5c4113dSnw141292 		}
271c5c4113dSnw141292 	}
272c5c4113dSnw141292 
273c5c4113dSnw141292 	/* Check if we are done */
274c5c4113dSnw141292 	if (state.sid2pid_done == TRUE && state.pid2sid_done == TRUE)
275c5c4113dSnw141292 		goto out;
276c5c4113dSnw141292 
277e8c27ec8Sbaban 	/*
278e8c27ec8Sbaban 	 * native LDAP lookups:
279479ac375Sdm199847 	 *  pid2sid:
280479ac375Sdm199847 	 *	- nldap or mixed mode. Lookup nldap by pid or unixname to get
281479ac375Sdm199847 	 *	  winname.
282479ac375Sdm199847 	 *  sid2pid:
283479ac375Sdm199847 	 *	- nldap mode. Got winname and sid (either given or found in
284479ac375Sdm199847 	 *	  name_cache). Lookup nldap by winname to get pid and
285479ac375Sdm199847 	 *	  unixname.
286e8c27ec8Sbaban 	 */
287e8c27ec8Sbaban 	if (state.nldap_nqueries) {
288e8c27ec8Sbaban 		retcode = nldap_lookup_batch(&state, &batch, result);
289e8c27ec8Sbaban 		if (IDMAP_FATAL_ERROR(retcode)) {
290e8c27ec8Sbaban 			result->retcode = retcode;
291c5c4113dSnw141292 			goto out;
292c5c4113dSnw141292 		}
293e8c27ec8Sbaban 	}
294c5c4113dSnw141292 
295e8c27ec8Sbaban 	/*
296e8c27ec8Sbaban 	 * AD lookups:
297479ac375Sdm199847 	 *  pid2sid:
298479ac375Sdm199847 	 *	- nldap or mixed mode. Got winname from nldap lookup.
299479ac375Sdm199847 	 *	  winname2sid could not be resolved locally. Lookup AD
300479ac375Sdm199847 	 *	  by winname to get sid.
301479ac375Sdm199847 	 *	- ad mode. Got unixname. Lookup AD by unixname to get
302479ac375Sdm199847 	 *	  winname and sid.
303479ac375Sdm199847 	 *  sid2pid:
304479ac375Sdm199847 	 *	- ad or mixed mode. Lookup AD by sid or winname to get
305479ac375Sdm199847 	 *	  winname, sid and unixname.
306479ac375Sdm199847 	 *	- any mode. Got either sid or winname but not both. Lookup
307479ac375Sdm199847 	 *	  AD by sid or winname to get winname, sid.
308e8c27ec8Sbaban 	 */
309e8c27ec8Sbaban 	if (state.ad_nqueries) {
310e8c27ec8Sbaban 		retcode = ad_lookup_batch(&state, &batch, result);
311e8c27ec8Sbaban 		if (IDMAP_FATAL_ERROR(retcode)) {
312e8c27ec8Sbaban 			result->retcode = retcode;
313e8c27ec8Sbaban 			goto out;
314e8c27ec8Sbaban 		}
315e8c27ec8Sbaban 	}
316e8c27ec8Sbaban 
317e8c27ec8Sbaban 	/*
318e8c27ec8Sbaban 	 * native LDAP lookups:
319479ac375Sdm199847 	 *  sid2pid:
320479ac375Sdm199847 	 *	- nldap mode. Got winname and sid from AD lookup. Lookup nldap
321479ac375Sdm199847 	 *	  by winname to get pid and unixname.
322e8c27ec8Sbaban 	 */
323e8c27ec8Sbaban 	if (state.nldap_nqueries) {
324e8c27ec8Sbaban 		retcode = nldap_lookup_batch(&state, &batch, result);
325e8c27ec8Sbaban 		if (IDMAP_FATAL_ERROR(retcode)) {
326e8c27ec8Sbaban 			result->retcode = retcode;
327e8c27ec8Sbaban 			goto out;
328e8c27ec8Sbaban 		}
329e8c27ec8Sbaban 	}
330e8c27ec8Sbaban 
331e8c27ec8Sbaban 	/* Reset 'done' flags */
332e8c27ec8Sbaban 	state.sid2pid_done = state.pid2sid_done = TRUE;
333c5c4113dSnw141292 
334c5c4113dSnw141292 	/* Second stage */
335c5c4113dSnw141292 	for (i = 0; i < batch.idmap_mapping_batch_len; i++) {
33662c60062Sbaban 		state.curpos = i;
337c5c4113dSnw141292 		if (IS_BATCH_SID(batch, i)) {
338c5c4113dSnw141292 			retcode = sid2pid_second_pass(
339c5c4113dSnw141292 			    &state,
340c5c4113dSnw141292 			    &batch.idmap_mapping_batch_val[i],
341c5c4113dSnw141292 			    &result->ids.ids_val[i]);
342e8c27ec8Sbaban 		} else if (IS_BATCH_UID(batch, i)) {
343e8c27ec8Sbaban 			retcode = pid2sid_second_pass(
344e8c27ec8Sbaban 			    &state,
345e8c27ec8Sbaban 			    &batch.idmap_mapping_batch_val[i],
346e8c27ec8Sbaban 			    &result->ids.ids_val[i], 1);
347e8c27ec8Sbaban 		} else if (IS_BATCH_GID(batch, i)) {
348e8c27ec8Sbaban 			retcode = pid2sid_second_pass(
349e8c27ec8Sbaban 			    &state,
350e8c27ec8Sbaban 			    &batch.idmap_mapping_batch_val[i],
351e8c27ec8Sbaban 			    &result->ids.ids_val[i], 0);
352e8c27ec8Sbaban 		} else {
353e8c27ec8Sbaban 			/* First stage has already set the error */
354e8c27ec8Sbaban 			continue;
355e8c27ec8Sbaban 		}
356c5c4113dSnw141292 		if (IDMAP_FATAL_ERROR(retcode)) {
357c5c4113dSnw141292 			result->retcode = retcode;
358c5c4113dSnw141292 			goto out;
359c5c4113dSnw141292 		}
360c5c4113dSnw141292 	}
361c5c4113dSnw141292 
362c5c4113dSnw141292 	/* Check if we are done */
363c5c4113dSnw141292 	if (state.sid2pid_done == TRUE && state.pid2sid_done == TRUE)
364c5c4113dSnw141292 		goto out;
365c5c4113dSnw141292 
366c5c4113dSnw141292 	/* Reset our 'done' flags */
367c5c4113dSnw141292 	state.sid2pid_done = state.pid2sid_done = TRUE;
368c5c4113dSnw141292 
369c5c4113dSnw141292 	/* Update cache in a single transaction */
37071590c90Snw141292 	if (sql_exec_no_cb(cache, IDMAP_CACHENAME, "BEGIN TRANSACTION;")
37171590c90Snw141292 	    != IDMAP_SUCCESS)
372c5c4113dSnw141292 		goto out;
373c5c4113dSnw141292 
374c5c4113dSnw141292 	for (i = 0; i < batch.idmap_mapping_batch_len; i++) {
37562c60062Sbaban 		state.curpos = i;
376c5c4113dSnw141292 		if (IS_BATCH_SID(batch, i)) {
377c5c4113dSnw141292 			(void) update_cache_sid2pid(
378c5c4113dSnw141292 			    &state,
379c5c4113dSnw141292 			    &batch.idmap_mapping_batch_val[i],
380c5c4113dSnw141292 			    &result->ids.ids_val[i]);
381c5c4113dSnw141292 		} else if ((IS_BATCH_UID(batch, i)) ||
382c5c4113dSnw141292 		    (IS_BATCH_GID(batch, i))) {
383c5c4113dSnw141292 			(void) update_cache_pid2sid(
384c5c4113dSnw141292 			    &state,
385c5c4113dSnw141292 			    &batch.idmap_mapping_batch_val[i],
386c5c4113dSnw141292 			    &result->ids.ids_val[i]);
387c5c4113dSnw141292 		}
388c5c4113dSnw141292 	}
389c5c4113dSnw141292 
390c5c4113dSnw141292 	/* Commit if we have at least one successful update */
391c5c4113dSnw141292 	if (state.sid2pid_done == FALSE || state.pid2sid_done == FALSE)
39271590c90Snw141292 		(void) sql_exec_no_cb(cache, IDMAP_CACHENAME,
39371590c90Snw141292 		    "COMMIT TRANSACTION;");
394c5c4113dSnw141292 	else
39571590c90Snw141292 		(void) sql_exec_no_cb(cache, IDMAP_CACHENAME,
39671590c90Snw141292 		    "END TRANSACTION;");
397c5c4113dSnw141292 
398c5c4113dSnw141292 out:
399e8c27ec8Sbaban 	cleanup_lookup_state(&state);
400c5c4113dSnw141292 	if (IDMAP_ERROR(result->retcode)) {
401c5c4113dSnw141292 		xdr_free(xdr_idmap_ids_res, (caddr_t)result);
402c5c4113dSnw141292 		result->ids.ids_len = 0;
403c5c4113dSnw141292 		result->ids.ids_val = NULL;
404c5c4113dSnw141292 	}
405c5c4113dSnw141292 	result->retcode = idmap_stat4prot(result->retcode);
406c5c4113dSnw141292 	return (TRUE);
407c5c4113dSnw141292 }
408c5c4113dSnw141292 
409c5c4113dSnw141292 
410c5c4113dSnw141292 /* ARGSUSED */
411cd37da74Snw141292 static
412cd37da74Snw141292 int
413cd37da74Snw141292 list_mappings_cb(void *parg, int argc, char **argv, char **colnames)
414cd37da74Snw141292 {
415c5c4113dSnw141292 	list_cb_data_t		*cb_data;
416c5c4113dSnw141292 	char			*str;
417c5c4113dSnw141292 	idmap_mappings_res	*result;
418c5c4113dSnw141292 	idmap_retcode		retcode;
419c5c4113dSnw141292 	int			w2u, u2w;
420c5c4113dSnw141292 	char			*end;
421cd37da74Snw141292 	static int		validated_column_names = 0;
42248258c6bSjp151216 	idmap_how		*how;
42348258c6bSjp151216 
42448258c6bSjp151216 	cb_data = (list_cb_data_t *)parg;
425cd37da74Snw141292 
426cd37da74Snw141292 	if (!validated_column_names) {
427cd37da74Snw141292 		assert(strcmp(colnames[0], "rowid") == 0);
428cd37da74Snw141292 		assert(strcmp(colnames[1], "sidprefix") == 0);
429cd37da74Snw141292 		assert(strcmp(colnames[2], "rid") == 0);
430cd37da74Snw141292 		assert(strcmp(colnames[3], "pid") == 0);
431cd37da74Snw141292 		assert(strcmp(colnames[4], "w2u") == 0);
432cd37da74Snw141292 		assert(strcmp(colnames[5], "u2w") == 0);
433cd37da74Snw141292 		assert(strcmp(colnames[6], "windomain") == 0);
434cd37da74Snw141292 		assert(strcmp(colnames[7], "canon_winname") == 0);
435cd37da74Snw141292 		assert(strcmp(colnames[8], "unixname") == 0);
436cd37da74Snw141292 		assert(strcmp(colnames[9], "is_user") == 0);
437cd37da74Snw141292 		assert(strcmp(colnames[10], "is_wuser") == 0);
43848258c6bSjp151216 		assert(strcmp(colnames[11], "map_type") == 0);
43948258c6bSjp151216 		assert(strcmp(colnames[12], "map_dn") == 0);
44048258c6bSjp151216 		assert(strcmp(colnames[13], "map_attr") == 0);
44148258c6bSjp151216 		assert(strcmp(colnames[14], "map_value") == 0);
44248258c6bSjp151216 		assert(strcmp(colnames[15], "map_windomain") == 0);
44348258c6bSjp151216 		assert(strcmp(colnames[16], "map_winname") == 0);
44448258c6bSjp151216 		assert(strcmp(colnames[17], "map_unixname") == 0);
44548258c6bSjp151216 		assert(strcmp(colnames[18], "map_is_nt4") == 0);
446cd37da74Snw141292 		validated_column_names = 1;
447cd37da74Snw141292 	}
448cd37da74Snw141292 
449c5c4113dSnw141292 	result = (idmap_mappings_res *)cb_data->result;
450c5c4113dSnw141292 
45148258c6bSjp151216 	_VALIDATE_LIST_CB_DATA(19, &result->mappings.mappings_val,
452c5c4113dSnw141292 	    sizeof (idmap_mapping));
453c5c4113dSnw141292 
454c5c4113dSnw141292 	result->mappings.mappings_len++;
455c5c4113dSnw141292 
456c5c4113dSnw141292 	if ((str = strdup(argv[1])) == NULL)
457c5c4113dSnw141292 		return (1);
458c5c4113dSnw141292 	result->mappings.mappings_val[cb_data->next].id1.idmap_id_u.sid.prefix =
459c5c4113dSnw141292 	    str;
460c5c4113dSnw141292 	result->mappings.mappings_val[cb_data->next].id1.idmap_id_u.sid.rid =
461c5c4113dSnw141292 	    strtoul(argv[2], &end, 10);
462cd37da74Snw141292 	result->mappings.mappings_val[cb_data->next].id1.idtype =
463cd37da74Snw141292 	    strtol(argv[10], &end, 10) ? IDMAP_USID : IDMAP_GSID;
464c5c4113dSnw141292 
465c5c4113dSnw141292 	result->mappings.mappings_val[cb_data->next].id2.idmap_id_u.uid =
466c5c4113dSnw141292 	    strtoul(argv[3], &end, 10);
467cd37da74Snw141292 	result->mappings.mappings_val[cb_data->next].id2.idtype =
468cd37da74Snw141292 	    strtol(argv[9], &end, 10) ? IDMAP_UID : IDMAP_GID;
469c5c4113dSnw141292 
470c5c4113dSnw141292 	w2u = argv[4] ? strtol(argv[4], &end, 10) : 0;
471c5c4113dSnw141292 	u2w = argv[5] ? strtol(argv[5], &end, 10) : 0;
472c5c4113dSnw141292 
473c5c4113dSnw141292 	if (w2u > 0 && u2w == 0)
474651c0131Sbaban 		result->mappings.mappings_val[cb_data->next].direction =
475651c0131Sbaban 		    IDMAP_DIRECTION_W2U;
476c5c4113dSnw141292 	else if (w2u == 0 && u2w > 0)
477651c0131Sbaban 		result->mappings.mappings_val[cb_data->next].direction =
478651c0131Sbaban 		    IDMAP_DIRECTION_U2W;
479c5c4113dSnw141292 	else
480651c0131Sbaban 		result->mappings.mappings_val[cb_data->next].direction =
481651c0131Sbaban 		    IDMAP_DIRECTION_BI;
482c5c4113dSnw141292 
4838e228215Sdm199847 	STRDUP_OR_FAIL(result->mappings.mappings_val[cb_data->next].id1domain,
4848e228215Sdm199847 	    argv[6]);
485c5c4113dSnw141292 
4868e228215Sdm199847 	STRDUP_OR_FAIL(result->mappings.mappings_val[cb_data->next].id1name,
4878e228215Sdm199847 	    argv[7]);
488c5c4113dSnw141292 
4898e228215Sdm199847 	STRDUP_OR_FAIL(result->mappings.mappings_val[cb_data->next].id2name,
4908e228215Sdm199847 	    argv[8]);
4918e228215Sdm199847 
49248258c6bSjp151216 	if (cb_data->flag & IDMAP_REQ_FLG_MAPPING_INFO) {
49348258c6bSjp151216 		how = &result->mappings.mappings_val[cb_data->next].info.how;
49448258c6bSjp151216 		how->map_type = strtoul(argv[11], &end, 10);
49548258c6bSjp151216 		switch (how->map_type) {
49648258c6bSjp151216 		case IDMAP_MAP_TYPE_DS_AD:
49748258c6bSjp151216 			how->idmap_how_u.ad.dn =
49848258c6bSjp151216 			    strdup(argv[12]);
49948258c6bSjp151216 			how->idmap_how_u.ad.attr =
50048258c6bSjp151216 			    strdup(argv[13]);
50148258c6bSjp151216 			how->idmap_how_u.ad.value =
50248258c6bSjp151216 			    strdup(argv[14]);
50348258c6bSjp151216 			break;
50448258c6bSjp151216 
50548258c6bSjp151216 		case IDMAP_MAP_TYPE_DS_NLDAP:
50648258c6bSjp151216 			how->idmap_how_u.nldap.dn =
50748258c6bSjp151216 			    strdup(argv[12]);
50848258c6bSjp151216 			how->idmap_how_u.nldap.attr =
50948258c6bSjp151216 			    strdup(argv[13]);
51048258c6bSjp151216 			how->idmap_how_u.nldap.value =
51148258c6bSjp151216 			    strdup(argv[14]);
51248258c6bSjp151216 			break;
51348258c6bSjp151216 
51448258c6bSjp151216 		case IDMAP_MAP_TYPE_RULE_BASED:
51548258c6bSjp151216 			how->idmap_how_u.rule.windomain =
51648258c6bSjp151216 			    strdup(argv[15]);
51748258c6bSjp151216 			how->idmap_how_u.rule.winname =
51848258c6bSjp151216 			    strdup(argv[16]);
51948258c6bSjp151216 			how->idmap_how_u.rule.unixname =
52048258c6bSjp151216 			    strdup(argv[17]);
52148258c6bSjp151216 			how->idmap_how_u.rule.is_nt4 =
52248258c6bSjp151216 			    strtoul(argv[18], &end, 10);
52348258c6bSjp151216 			how->idmap_how_u.rule.is_user =
52448258c6bSjp151216 			    strtol(argv[9], &end, 10);
52548258c6bSjp151216 			how->idmap_how_u.rule.is_wuser =
52648258c6bSjp151216 			    strtol(argv[10], &end, 10);
52748258c6bSjp151216 			break;
52848258c6bSjp151216 
52948258c6bSjp151216 		case IDMAP_MAP_TYPE_EPHEMERAL:
53048258c6bSjp151216 			break;
53148258c6bSjp151216 
53248258c6bSjp151216 		case IDMAP_MAP_TYPE_LOCAL_SID:
53348258c6bSjp151216 			break;
53448258c6bSjp151216 
535e3f2c991SKeyur Desai 		case IDMAP_MAP_TYPE_IDMU:
536e3f2c991SKeyur Desai 			how->idmap_how_u.idmu.dn =
537e3f2c991SKeyur Desai 			    strdup(argv[12]);
538e3f2c991SKeyur Desai 			how->idmap_how_u.idmu.attr =
539e3f2c991SKeyur Desai 			    strdup(argv[13]);
540e3f2c991SKeyur Desai 			how->idmap_how_u.idmu.value =
541e3f2c991SKeyur Desai 			    strdup(argv[14]);
542e3f2c991SKeyur Desai 			break;
543e3f2c991SKeyur Desai 
54448258c6bSjp151216 		default:
545e3f2c991SKeyur Desai 			/* Unknown mapping type */
54648258c6bSjp151216 			assert(FALSE);
54748258c6bSjp151216 		}
54848258c6bSjp151216 
54948258c6bSjp151216 	}
550c5c4113dSnw141292 
551c5c4113dSnw141292 	result->lastrowid = strtoll(argv[0], &end, 10);
552c5c4113dSnw141292 	cb_data->next++;
553c5c4113dSnw141292 	result->retcode = IDMAP_SUCCESS;
554c5c4113dSnw141292 	return (0);
555c5c4113dSnw141292 }
556c5c4113dSnw141292 
557c5c4113dSnw141292 
558c5c4113dSnw141292 /* ARGSUSED */
559c5c4113dSnw141292 bool_t
56048258c6bSjp151216 idmap_list_mappings_1_svc(int64_t lastrowid, uint64_t limit, int32_t flag,
561cd37da74Snw141292     idmap_mappings_res *result, struct svc_req *rqstp)
562cd37da74Snw141292 {
563c5c4113dSnw141292 	sqlite		*cache = NULL;
564c5c4113dSnw141292 	char		lbuf[30], rbuf[30];
565c5c4113dSnw141292 	uint64_t	maxlimit;
566c5c4113dSnw141292 	idmap_retcode	retcode;
567c5c4113dSnw141292 	char		*sql = NULL;
56848258c6bSjp151216 	time_t		curtime;
569c5c4113dSnw141292 
570c5c4113dSnw141292 	(void) memset(result, 0, sizeof (*result));
571c5c4113dSnw141292 
57248258c6bSjp151216 	/* Current time */
57348258c6bSjp151216 	errno = 0;
57448258c6bSjp151216 	if ((curtime = time(NULL)) == (time_t)-1) {
57548258c6bSjp151216 		idmapdlog(LOG_ERR, "Failed to get current time (%s)",
57648258c6bSjp151216 		    strerror(errno));
57748258c6bSjp151216 		retcode = IDMAP_ERR_INTERNAL;
57848258c6bSjp151216 		goto out;
57948258c6bSjp151216 	}
58048258c6bSjp151216 
581c5c4113dSnw141292 	RDLOCK_CONFIG();
582c5c4113dSnw141292 	maxlimit = _idmapdstate.cfg->pgcfg.list_size_limit;
583c5c4113dSnw141292 	UNLOCK_CONFIG();
584c5c4113dSnw141292 
585c5c4113dSnw141292 	/* Get cache handle */
586c5c4113dSnw141292 	result->retcode = get_cache_handle(&cache);
587c5c4113dSnw141292 	if (result->retcode != IDMAP_SUCCESS)
588c5c4113dSnw141292 		goto out;
589c5c4113dSnw141292 
590c5c4113dSnw141292 	result->retcode = IDMAP_ERR_INTERNAL;
591c5c4113dSnw141292 
592c5c4113dSnw141292 	/* Create LIMIT expression. */
593c5c4113dSnw141292 	if (limit == 0 || (maxlimit > 0 && maxlimit < limit))
594c5c4113dSnw141292 		limit = maxlimit;
595c5c4113dSnw141292 	if (limit > 0)
596c5c4113dSnw141292 		(void) snprintf(lbuf, sizeof (lbuf),
597c5c4113dSnw141292 		    "LIMIT %" PRIu64, limit + 1ULL);
598bbf6f00cSJordan Brown 	else
599bbf6f00cSJordan Brown 		lbuf[0] = '\0';
600c5c4113dSnw141292 
601c5c4113dSnw141292 	(void) snprintf(rbuf, sizeof (rbuf), "rowid > %" PRIu64, lastrowid);
602c5c4113dSnw141292 
603c5c4113dSnw141292 	/*
604c5c4113dSnw141292 	 * Combine all the above into a giant SELECT statement that
605c5c4113dSnw141292 	 * will return the requested mappings
606c5c4113dSnw141292 	 */
60748258c6bSjp151216 
60848258c6bSjp151216 	sql = sqlite_mprintf("SELECT rowid, sidprefix, rid, pid, w2u, "
60948258c6bSjp151216 	    "u2w, windomain, canon_winname, unixname, is_user, is_wuser, "
61048258c6bSjp151216 	    "map_type, map_dn, map_attr, map_value, map_windomain, "
61148258c6bSjp151216 	    "map_winname, map_unixname, map_is_nt4 "
61248258c6bSjp151216 	    "FROM idmap_cache WHERE %s AND "
61348258c6bSjp151216 	    "(pid >= 2147483648 OR (expiration = 0 OR "
61448258c6bSjp151216 	    "expiration ISNULL  OR expiration > %d)) "
61548258c6bSjp151216 	    "%s;",
61648258c6bSjp151216 	    rbuf, curtime, lbuf);
617c5c4113dSnw141292 	if (sql == NULL) {
618479ac375Sdm199847 		result->retcode = IDMAP_ERR_MEMORY;
619c5c4113dSnw141292 		idmapdlog(LOG_ERR, "Out of memory");
620c5c4113dSnw141292 		goto out;
621c5c4113dSnw141292 	}
622c5c4113dSnw141292 
623c5c4113dSnw141292 	/* Execute the SQL statement and update the return buffer */
62471590c90Snw141292 	PROCESS_LIST_SVC_SQL(retcode, cache, IDMAP_CACHENAME, sql, limit,
62548258c6bSjp151216 	    flag, list_mappings_cb, result, result->mappings.mappings_len);
626c5c4113dSnw141292 
627c5c4113dSnw141292 out:
628c5c4113dSnw141292 	if (sql)
629c5c4113dSnw141292 		sqlite_freemem(sql);
630c5c4113dSnw141292 	if (IDMAP_ERROR(result->retcode))
631c5c4113dSnw141292 		(void) xdr_free(xdr_idmap_mappings_res, (caddr_t)result);
632c5c4113dSnw141292 	result->retcode = idmap_stat4prot(result->retcode);
633c5c4113dSnw141292 	return (TRUE);
634c5c4113dSnw141292 }
635c5c4113dSnw141292 
636c5c4113dSnw141292 
637c5c4113dSnw141292 /* ARGSUSED */
638cd37da74Snw141292 static
639cd37da74Snw141292 int
640cd37da74Snw141292 list_namerules_cb(void *parg, int argc, char **argv, char **colnames)
641cd37da74Snw141292 {
642c5c4113dSnw141292 	list_cb_data_t		*cb_data;
643c5c4113dSnw141292 	idmap_namerules_res	*result;
644c5c4113dSnw141292 	idmap_retcode		retcode;
645c5c4113dSnw141292 	int			w2u_order, u2w_order;
646c5c4113dSnw141292 	char			*end;
647cd37da74Snw141292 	static int		validated_column_names = 0;
648cd37da74Snw141292 
649cd37da74Snw141292 	if (!validated_column_names) {
650cd37da74Snw141292 		assert(strcmp(colnames[0], "rowid") == 0);
651cd37da74Snw141292 		assert(strcmp(colnames[1], "is_user") == 0);
652cd37da74Snw141292 		assert(strcmp(colnames[2], "is_wuser") == 0);
653cd37da74Snw141292 		assert(strcmp(colnames[3], "windomain") == 0);
654cd37da74Snw141292 		assert(strcmp(colnames[4], "winname_display") == 0);
655cd37da74Snw141292 		assert(strcmp(colnames[5], "is_nt4") == 0);
656cd37da74Snw141292 		assert(strcmp(colnames[6], "unixname") == 0);
657cd37da74Snw141292 		assert(strcmp(colnames[7], "w2u_order") == 0);
658cd37da74Snw141292 		assert(strcmp(colnames[8], "u2w_order") == 0);
659cd37da74Snw141292 		validated_column_names = 1;
660cd37da74Snw141292 	}
661c5c4113dSnw141292 
662c5c4113dSnw141292 	cb_data = (list_cb_data_t *)parg;
663c5c4113dSnw141292 	result = (idmap_namerules_res *)cb_data->result;
664c5c4113dSnw141292 
665cd37da74Snw141292 	_VALIDATE_LIST_CB_DATA(9, &result->rules.rules_val,
666c5c4113dSnw141292 	    sizeof (idmap_namerule));
667c5c4113dSnw141292 
668c5c4113dSnw141292 	result->rules.rules_len++;
669c5c4113dSnw141292 
670c5c4113dSnw141292 	result->rules.rules_val[cb_data->next].is_user =
671c5c4113dSnw141292 	    strtol(argv[1], &end, 10);
672c5c4113dSnw141292 
673cd37da74Snw141292 	result->rules.rules_val[cb_data->next].is_wuser =
674cd37da74Snw141292 	    strtol(argv[2], &end, 10);
675c5c4113dSnw141292 
676cd37da74Snw141292 	STRDUP_OR_FAIL(result->rules.rules_val[cb_data->next].windomain,
6778e228215Sdm199847 	    argv[3]);
678c5c4113dSnw141292 
679cd37da74Snw141292 	STRDUP_OR_FAIL(result->rules.rules_val[cb_data->next].winname,
680cd37da74Snw141292 	    argv[4]);
681cd37da74Snw141292 
682c5c4113dSnw141292 	result->rules.rules_val[cb_data->next].is_nt4 =
683cd37da74Snw141292 	    strtol(argv[5], &end, 10);
684c5c4113dSnw141292 
6858e228215Sdm199847 	STRDUP_OR_FAIL(result->rules.rules_val[cb_data->next].unixname,
686cd37da74Snw141292 	    argv[6]);
687c5c4113dSnw141292 
688cd37da74Snw141292 	w2u_order = argv[7] ? strtol(argv[7], &end, 10) : 0;
689cd37da74Snw141292 	u2w_order = argv[8] ? strtol(argv[8], &end, 10) : 0;
690c5c4113dSnw141292 
691c5c4113dSnw141292 	if (w2u_order > 0 && u2w_order == 0)
692651c0131Sbaban 		result->rules.rules_val[cb_data->next].direction =
693651c0131Sbaban 		    IDMAP_DIRECTION_W2U;
694c5c4113dSnw141292 	else if (w2u_order == 0 && u2w_order > 0)
695651c0131Sbaban 		result->rules.rules_val[cb_data->next].direction =
696651c0131Sbaban 		    IDMAP_DIRECTION_U2W;
697c5c4113dSnw141292 	else
698651c0131Sbaban 		result->rules.rules_val[cb_data->next].direction =
699651c0131Sbaban 		    IDMAP_DIRECTION_BI;
700c5c4113dSnw141292 
701c5c4113dSnw141292 	result->lastrowid = strtoll(argv[0], &end, 10);
702c5c4113dSnw141292 	cb_data->next++;
703c5c4113dSnw141292 	result->retcode = IDMAP_SUCCESS;
704c5c4113dSnw141292 	return (0);
705c5c4113dSnw141292 }
706c5c4113dSnw141292 
707c5c4113dSnw141292 
708c5c4113dSnw141292 /* ARGSUSED */
709c5c4113dSnw141292 bool_t
710c5c4113dSnw141292 idmap_list_namerules_1_svc(idmap_namerule rule, uint64_t lastrowid,
711c5c4113dSnw141292 		uint64_t limit, idmap_namerules_res *result,
712cd37da74Snw141292 		struct svc_req *rqstp)
713cd37da74Snw141292 {
714c5c4113dSnw141292 
715c5c4113dSnw141292 	sqlite		*db = NULL;
716c5c4113dSnw141292 	char		lbuf[30], rbuf[30];
717c5c4113dSnw141292 	char		*sql = NULL;
718cd37da74Snw141292 	char		*expr = NULL;
719c5c4113dSnw141292 	uint64_t	maxlimit;
720c5c4113dSnw141292 	idmap_retcode	retcode;
721c5c4113dSnw141292 
722c5c4113dSnw141292 	(void) memset(result, 0, sizeof (*result));
723c5c4113dSnw141292 
7240dcc7149Snw141292 	result->retcode = validate_rule(&rule);
7250dcc7149Snw141292 	if (result->retcode != IDMAP_SUCCESS)
7260dcc7149Snw141292 		goto out;
7270dcc7149Snw141292 
728c5c4113dSnw141292 	RDLOCK_CONFIG();
729c5c4113dSnw141292 	maxlimit = _idmapdstate.cfg->pgcfg.list_size_limit;
730c5c4113dSnw141292 	UNLOCK_CONFIG();
731c5c4113dSnw141292 
732c5c4113dSnw141292 	/* Get db handle */
733c5c4113dSnw141292 	result->retcode = get_db_handle(&db);
734c5c4113dSnw141292 	if (result->retcode != IDMAP_SUCCESS)
735c5c4113dSnw141292 		goto out;
736c5c4113dSnw141292 
7370dcc7149Snw141292 	result->retcode = gen_sql_expr_from_rule(&rule, &expr);
7380dcc7149Snw141292 	if (result->retcode != IDMAP_SUCCESS)
739c5c4113dSnw141292 		goto out;
740c5c4113dSnw141292 
741c5c4113dSnw141292 	/* Create LIMIT expression. */
742c5c4113dSnw141292 	if (limit == 0 || (maxlimit > 0 && maxlimit < limit))
743c5c4113dSnw141292 		limit = maxlimit;
744c5c4113dSnw141292 	if (limit > 0)
745c5c4113dSnw141292 		(void) snprintf(lbuf, sizeof (lbuf),
746c5c4113dSnw141292 		    "LIMIT %" PRIu64, limit + 1ULL);
747bbf6f00cSJordan Brown 	else
748bbf6f00cSJordan Brown 		lbuf[0] = '\0';
749c5c4113dSnw141292 
750c5c4113dSnw141292 	(void) snprintf(rbuf, sizeof (rbuf), "rowid > %" PRIu64, lastrowid);
751c5c4113dSnw141292 
752c5c4113dSnw141292 	/*
753c5c4113dSnw141292 	 * Combine all the above into a giant SELECT statement that
754c5c4113dSnw141292 	 * will return the requested rules
755c5c4113dSnw141292 	 */
756cd37da74Snw141292 	sql = sqlite_mprintf("SELECT rowid, is_user, is_wuser, windomain, "
757cd37da74Snw141292 	    "winname_display, is_nt4, unixname, w2u_order, u2w_order "
758c5c4113dSnw141292 	    "FROM namerules WHERE "
759bbf6f00cSJordan Brown 	    " %s %s %s;",
760bbf6f00cSJordan Brown 	    rbuf, expr, lbuf);
761cd37da74Snw141292 
762c5c4113dSnw141292 	if (sql == NULL) {
763479ac375Sdm199847 		result->retcode = IDMAP_ERR_MEMORY;
764c5c4113dSnw141292 		idmapdlog(LOG_ERR, "Out of memory");
765c5c4113dSnw141292 		goto out;
766c5c4113dSnw141292 	}
767c5c4113dSnw141292 
768c5c4113dSnw141292 	/* Execute the SQL statement and update the return buffer */
76971590c90Snw141292 	PROCESS_LIST_SVC_SQL(retcode, db, IDMAP_DBNAME, sql, limit,
77048258c6bSjp151216 	    0, list_namerules_cb, result, result->rules.rules_len);
771c5c4113dSnw141292 
772c5c4113dSnw141292 out:
773cd37da74Snw141292 	if (expr)
774cd37da74Snw141292 		sqlite_freemem(expr);
775c5c4113dSnw141292 	if (sql)
776c5c4113dSnw141292 		sqlite_freemem(sql);
777c5c4113dSnw141292 	if (IDMAP_ERROR(result->retcode))
778c5c4113dSnw141292 		(void) xdr_free(xdr_idmap_namerules_res, (caddr_t)result);
779c5c4113dSnw141292 	result->retcode = idmap_stat4prot(result->retcode);
780c5c4113dSnw141292 	return (TRUE);
781c5c4113dSnw141292 }
782c5c4113dSnw141292 
783c5c4113dSnw141292 #define	IDMAP_RULES_AUTH	"solaris.admin.idmap.rules"
784c5c4113dSnw141292 static int
785cd37da74Snw141292 verify_rules_auth(struct svc_req *rqstp)
786cd37da74Snw141292 {
787c5c4113dSnw141292 	ucred_t		*uc = NULL;
788c5c4113dSnw141292 	uid_t		uid;
789c5c4113dSnw141292 	char		buf[1024];
790c5c4113dSnw141292 	struct passwd	pwd;
791c5c4113dSnw141292 
792c5c4113dSnw141292 	if (svc_getcallerucred(rqstp->rq_xprt, &uc) != 0) {
79371590c90Snw141292 		idmapdlog(LOG_ERR, "svc_getcallerucred failed during "
79471590c90Snw141292 		    "authorization (%s)", strerror(errno));
795c5c4113dSnw141292 		return (-1);
796c5c4113dSnw141292 	}
797c5c4113dSnw141292 
798c5c4113dSnw141292 	uid = ucred_geteuid(uc);
799c5c4113dSnw141292 	if (uid == (uid_t)-1) {
80071590c90Snw141292 		idmapdlog(LOG_ERR, "ucred_geteuid failed during "
80171590c90Snw141292 		    "authorization (%s)", strerror(errno));
802c5c4113dSnw141292 		ucred_free(uc);
803c5c4113dSnw141292 		return (-1);
804c5c4113dSnw141292 	}
805c5c4113dSnw141292 
806c5c4113dSnw141292 	if (getpwuid_r(uid, &pwd, buf, sizeof (buf)) == NULL) {
80771590c90Snw141292 		idmapdlog(LOG_ERR, "getpwuid_r(%u) failed during "
80871590c90Snw141292 		    "authorization (%s)", uid, strerror(errno));
809c5c4113dSnw141292 		ucred_free(uc);
810c5c4113dSnw141292 		return (-1);
811c5c4113dSnw141292 	}
812c5c4113dSnw141292 
813c5c4113dSnw141292 	if (chkauthattr(IDMAP_RULES_AUTH, pwd.pw_name) != 1) {
81471590c90Snw141292 		idmapdlog(LOG_INFO, "%s is not authorized (%s)",
81571590c90Snw141292 		    pwd.pw_name, IDMAP_RULES_AUTH);
816c5c4113dSnw141292 		ucred_free(uc);
817c5c4113dSnw141292 		return (-1);
818c5c4113dSnw141292 	}
819c5c4113dSnw141292 
820c5c4113dSnw141292 	ucred_free(uc);
821c5c4113dSnw141292 	return (1);
822c5c4113dSnw141292 }
823c5c4113dSnw141292 
8248e228215Sdm199847 /*
8258e228215Sdm199847  * Meaning of the return values is the following: For retcode ==
8268e228215Sdm199847  * IDMAP_SUCCESS, everything went OK and error_index is
8278e228215Sdm199847  * undefined. Otherwise, error_index >=0 shows the failed batch
8288e228215Sdm199847  * element. errro_index == -1 indicates failure at the beginning,
8298e228215Sdm199847  * error_index == -2 at the end.
8308e228215Sdm199847  */
8318e228215Sdm199847 
832c5c4113dSnw141292 /* ARGSUSED */
833c5c4113dSnw141292 bool_t
8348e228215Sdm199847 idmap_update_1_svc(idmap_update_batch batch, idmap_update_res *res,
835cd37da74Snw141292 		struct svc_req *rqstp)
836cd37da74Snw141292 {
837c5c4113dSnw141292 	sqlite		*db = NULL;
838c5c4113dSnw141292 	idmap_update_op	*up;
839c5c4113dSnw141292 	int		i;
84084decf41Sjp151216 	int		trans = FALSE;
841c5c4113dSnw141292 
8428e228215Sdm199847 	res->error_index = -1;
8438e228215Sdm199847 	(void) memset(&res->error_rule, 0, sizeof (res->error_rule));
8448e228215Sdm199847 	(void) memset(&res->conflict_rule, 0, sizeof (res->conflict_rule));
8458e228215Sdm199847 
846c5c4113dSnw141292 	if (verify_rules_auth(rqstp) < 0) {
8478e228215Sdm199847 		res->retcode = IDMAP_ERR_PERMISSION_DENIED;
848c5c4113dSnw141292 		goto out;
849c5c4113dSnw141292 	}
850c5c4113dSnw141292 
851c5c4113dSnw141292 	if (batch.idmap_update_batch_len == 0 ||
852c5c4113dSnw141292 	    batch.idmap_update_batch_val == NULL) {
8538e228215Sdm199847 		res->retcode = IDMAP_SUCCESS;
854c5c4113dSnw141292 		goto out;
855c5c4113dSnw141292 	}
856c5c4113dSnw141292 
8570dcc7149Snw141292 	res->retcode = validate_rules(&batch);
8580dcc7149Snw141292 	if (res->retcode != IDMAP_SUCCESS)
8590dcc7149Snw141292 		goto out;
8600dcc7149Snw141292 
861c5c4113dSnw141292 	/* Get db handle */
8628e228215Sdm199847 	res->retcode = get_db_handle(&db);
8638e228215Sdm199847 	if (res->retcode != IDMAP_SUCCESS)
864c5c4113dSnw141292 		goto out;
865c5c4113dSnw141292 
86671590c90Snw141292 	res->retcode = sql_exec_no_cb(db, IDMAP_DBNAME, "BEGIN TRANSACTION;");
8678e228215Sdm199847 	if (res->retcode != IDMAP_SUCCESS)
868c5c4113dSnw141292 		goto out;
86984decf41Sjp151216 	trans = TRUE;
870c5c4113dSnw141292 
871c5c4113dSnw141292 	for (i = 0; i < batch.idmap_update_batch_len; i++) {
872c5c4113dSnw141292 		up = &batch.idmap_update_batch_val[i];
873c5c4113dSnw141292 		switch (up->opnum) {
874c5c4113dSnw141292 		case OP_NONE:
8758e228215Sdm199847 			res->retcode = IDMAP_SUCCESS;
876c5c4113dSnw141292 			break;
877c5c4113dSnw141292 		case OP_ADD_NAMERULE:
8788e228215Sdm199847 			res->retcode = add_namerule(db,
879c5c4113dSnw141292 			    &up->idmap_update_op_u.rule);
880c5c4113dSnw141292 			break;
881c5c4113dSnw141292 		case OP_RM_NAMERULE:
8828e228215Sdm199847 			res->retcode = rm_namerule(db,
883c5c4113dSnw141292 			    &up->idmap_update_op_u.rule);
884c5c4113dSnw141292 			break;
885c5c4113dSnw141292 		case OP_FLUSH_NAMERULES:
886cd37da74Snw141292 			res->retcode = flush_namerules(db);
887c5c4113dSnw141292 			break;
888c5c4113dSnw141292 		default:
8898e228215Sdm199847 			res->retcode = IDMAP_ERR_NOTSUPPORTED;
8908e228215Sdm199847 			break;
891c5c4113dSnw141292 		};
892c5c4113dSnw141292 
8938e228215Sdm199847 		if (res->retcode != IDMAP_SUCCESS) {
8948e228215Sdm199847 			res->error_index = i;
8958e228215Sdm199847 			if (up->opnum == OP_ADD_NAMERULE ||
8968e228215Sdm199847 			    up->opnum == OP_RM_NAMERULE) {
8978e228215Sdm199847 				idmap_stat r2 =
8988e228215Sdm199847 				    idmap_namerule_cpy(&res->error_rule,
8998e228215Sdm199847 				    &up->idmap_update_op_u.rule);
9008e228215Sdm199847 				if (r2 != IDMAP_SUCCESS)
9018e228215Sdm199847 					res->retcode = r2;
9028e228215Sdm199847 			}
903c5c4113dSnw141292 			goto out;
904c5c4113dSnw141292 		}
9058e228215Sdm199847 	}
906c5c4113dSnw141292 
907c5c4113dSnw141292 out:
90884decf41Sjp151216 	if (trans) {
9098e228215Sdm199847 		if (res->retcode == IDMAP_SUCCESS) {
9108e228215Sdm199847 			res->retcode =
91171590c90Snw141292 			    sql_exec_no_cb(db, IDMAP_DBNAME,
91271590c90Snw141292 			    "COMMIT TRANSACTION;");
9138e228215Sdm199847 			if (res->retcode !=  IDMAP_SUCCESS)
9148e228215Sdm199847 				res->error_index = -2;
9158e228215Sdm199847 		}
91684decf41Sjp151216 		else
91771590c90Snw141292 			(void) sql_exec_no_cb(db, IDMAP_DBNAME,
91871590c90Snw141292 			    "ROLLBACK TRANSACTION;");
919c5c4113dSnw141292 	}
9208e228215Sdm199847 
9218e228215Sdm199847 	res->retcode = idmap_stat4prot(res->retcode);
9228e228215Sdm199847 
923c5c4113dSnw141292 	return (TRUE);
924c5c4113dSnw141292 }
925c5c4113dSnw141292 
926*fe1c642dSBill Krier static
927*fe1c642dSBill Krier int
928*fe1c642dSBill Krier copy_string(char **to, char *from)
929*fe1c642dSBill Krier {
930*fe1c642dSBill Krier 	if (EMPTY_STRING(from)) {
931*fe1c642dSBill Krier 		*to = NULL;
932*fe1c642dSBill Krier 	} else {
933*fe1c642dSBill Krier 		*to = strdup(from);
934*fe1c642dSBill Krier 		if (*to == NULL) {
935*fe1c642dSBill Krier 			idmapdlog(LOG_ERR, "Out of memory");
936*fe1c642dSBill Krier 			return (IDMAP_ERR_MEMORY);
937*fe1c642dSBill Krier 		}
938*fe1c642dSBill Krier 	}
939*fe1c642dSBill Krier 	return (IDMAP_SUCCESS);
940*fe1c642dSBill Krier }
941*fe1c642dSBill Krier 
942*fe1c642dSBill Krier static
943*fe1c642dSBill Krier int
944*fe1c642dSBill Krier copy_id(idmap_id *to, idmap_id *from)
945*fe1c642dSBill Krier {
946*fe1c642dSBill Krier 	(void) memset(to, 0, sizeof (*to));
947*fe1c642dSBill Krier 
948*fe1c642dSBill Krier 	to->idtype = from->idtype;
949*fe1c642dSBill Krier 	if (IS_ID_SID(*from)) {
950*fe1c642dSBill Krier 		idmap_retcode retcode;
951*fe1c642dSBill Krier 
952*fe1c642dSBill Krier 		to->idmap_id_u.sid.rid = from->idmap_id_u.sid.rid;
953*fe1c642dSBill Krier 		retcode = copy_string(&to->idmap_id_u.sid.prefix,
954*fe1c642dSBill Krier 		    from->idmap_id_u.sid.prefix);
955*fe1c642dSBill Krier 
956*fe1c642dSBill Krier 		return (retcode);
957*fe1c642dSBill Krier 	} else {
958*fe1c642dSBill Krier 		to->idmap_id_u.uid = from->idmap_id_u.uid;
959*fe1c642dSBill Krier 		return (IDMAP_SUCCESS);
960*fe1c642dSBill Krier 	}
961*fe1c642dSBill Krier }
962*fe1c642dSBill Krier 
963*fe1c642dSBill Krier static
964*fe1c642dSBill Krier int
965*fe1c642dSBill Krier copy_mapping(idmap_mapping *mapping, idmap_mapping *request)
966*fe1c642dSBill Krier {
967*fe1c642dSBill Krier 	idmap_retcode retcode;
968*fe1c642dSBill Krier 
969*fe1c642dSBill Krier 	(void) memset(mapping, 0, sizeof (*mapping));
970*fe1c642dSBill Krier 
971*fe1c642dSBill Krier 	mapping->flag = request->flag;
972*fe1c642dSBill Krier 	mapping->direction = _IDMAP_F_DONE;
973*fe1c642dSBill Krier 
974*fe1c642dSBill Krier 	retcode = copy_id(&mapping->id1, &request->id1);
975*fe1c642dSBill Krier 	if (retcode != IDMAP_SUCCESS)
976*fe1c642dSBill Krier 		goto errout;
977*fe1c642dSBill Krier 
978*fe1c642dSBill Krier 	retcode = copy_string(&mapping->id1domain, request->id1domain);
979*fe1c642dSBill Krier 	if (retcode != IDMAP_SUCCESS)
980*fe1c642dSBill Krier 		goto errout;
981*fe1c642dSBill Krier 
982*fe1c642dSBill Krier 	retcode = copy_string(&mapping->id1name, request->id1name);
983*fe1c642dSBill Krier 	if (retcode != IDMAP_SUCCESS)
984*fe1c642dSBill Krier 		goto errout;
985*fe1c642dSBill Krier 
986*fe1c642dSBill Krier 	retcode = copy_id(&mapping->id2, &request->id2);
987*fe1c642dSBill Krier 	if (retcode != IDMAP_SUCCESS)
988*fe1c642dSBill Krier 		goto errout;
989*fe1c642dSBill Krier 
990*fe1c642dSBill Krier 	retcode = copy_string(&mapping->id2domain, request->id2domain);
991*fe1c642dSBill Krier 	if (retcode != IDMAP_SUCCESS)
992*fe1c642dSBill Krier 		goto errout;
993*fe1c642dSBill Krier 	retcode = copy_string(&mapping->id2name, request->id2name);
994*fe1c642dSBill Krier 	if (retcode != IDMAP_SUCCESS)
995*fe1c642dSBill Krier 		goto errout;
996*fe1c642dSBill Krier 
997*fe1c642dSBill Krier 	return (IDMAP_SUCCESS);
998*fe1c642dSBill Krier 
999*fe1c642dSBill Krier errout:
1000*fe1c642dSBill Krier 	if (IS_ID_SID(mapping->id1))
1001*fe1c642dSBill Krier 		free(mapping->id1.idmap_id_u.sid.prefix);
1002*fe1c642dSBill Krier 	free(mapping->id1domain);
1003*fe1c642dSBill Krier 	free(mapping->id1name);
1004*fe1c642dSBill Krier 	if (IS_ID_SID(mapping->id2))
1005*fe1c642dSBill Krier 		free(mapping->id2.idmap_id_u.sid.prefix);
1006*fe1c642dSBill Krier 	free(mapping->id2domain);
1007*fe1c642dSBill Krier 	free(mapping->id2name);
1008*fe1c642dSBill Krier 
1009*fe1c642dSBill Krier 	(void) memset(mapping, 0, sizeof (*mapping));
1010*fe1c642dSBill Krier 	return (retcode);
1011*fe1c642dSBill Krier }
1012*fe1c642dSBill Krier 
1013c5c4113dSnw141292 
1014c5c4113dSnw141292 /* ARGSUSED */
1015c5c4113dSnw141292 bool_t
1016c5c4113dSnw141292 idmap_get_mapped_id_by_name_1_svc(idmap_mapping request,
1017cd37da74Snw141292 		idmap_mappings_res *result, struct svc_req *rqstp)
1018cd37da74Snw141292 {
1019*fe1c642dSBill Krier 	idmap_mapping_batch batch_request;
1020*fe1c642dSBill Krier 	idmap_ids_res batch_result;
1021*fe1c642dSBill Krier 	idmap_mapping *map;
1022c5c4113dSnw141292 
1023*fe1c642dSBill Krier 	/* Clear out things we might want to xdr_free on error */
1024*fe1c642dSBill Krier 	(void) memset(&batch_result, 0, sizeof (batch_result));
1025c5c4113dSnw141292 	(void) memset(result, 0, sizeof (*result));
1026c5c4113dSnw141292 
10270dcc7149Snw141292 	result->retcode = validate_mapped_id_by_name_req(&request);
10280dcc7149Snw141292 	if (result->retcode != IDMAP_SUCCESS)
10290dcc7149Snw141292 		goto out;
10300dcc7149Snw141292 
1031*fe1c642dSBill Krier 	/*
1032*fe1c642dSBill Krier 	 * Copy the request.  We need to modify it, and
1033*fe1c642dSBill Krier 	 * what we have is a shallow copy.  Freeing pointers from
1034*fe1c642dSBill Krier 	 * our copy will lead to problems, since the RPC framework
1035*fe1c642dSBill Krier 	 * has its own copy of those pointers.  Besides, we need
1036*fe1c642dSBill Krier 	 * a copy to return.
1037*fe1c642dSBill Krier 	 */
1038*fe1c642dSBill Krier 	map = calloc(1, sizeof (idmap_mapping));
1039*fe1c642dSBill Krier 	if (map == NULL) {
1040c5c4113dSnw141292 		idmapdlog(LOG_ERR, "Out of memory");
1041c5c4113dSnw141292 		result->retcode = IDMAP_ERR_MEMORY;
1042c5c4113dSnw141292 		goto out;
1043c5c4113dSnw141292 	}
1044*fe1c642dSBill Krier 
1045*fe1c642dSBill Krier 	/*
1046*fe1c642dSBill Krier 	 * Set up to return the filled-in mapping structure.
1047*fe1c642dSBill Krier 	 * Note that we xdr_free result on error, and that'll take
1048*fe1c642dSBill Krier 	 * care of freeing the mapping structure.
1049*fe1c642dSBill Krier 	 */
1050*fe1c642dSBill Krier 	result->mappings.mappings_val = map;
1051c5c4113dSnw141292 	result->mappings.mappings_len = 1;
1052c5c4113dSnw141292 
1053*fe1c642dSBill Krier 	result->retcode = copy_mapping(map, &request);
1054*fe1c642dSBill Krier 	if (result->retcode != IDMAP_SUCCESS)
1055*fe1c642dSBill Krier 		goto out;
1056cd37da74Snw141292 
1057*fe1c642dSBill Krier 	/* Set up for the request to the batch API */
1058*fe1c642dSBill Krier 	batch_request.idmap_mapping_batch_val = map;
1059*fe1c642dSBill Krier 	batch_request.idmap_mapping_batch_len = 1;
1060*fe1c642dSBill Krier 
1061*fe1c642dSBill Krier 	/* Do the real work. */
1062*fe1c642dSBill Krier 	(void) idmap_get_mapped_ids_1_svc(batch_request,
1063*fe1c642dSBill Krier 	    &batch_result, rqstp);
1064*fe1c642dSBill Krier 
1065*fe1c642dSBill Krier 	/* Copy what we need out of the batch response */
1066*fe1c642dSBill Krier 
1067*fe1c642dSBill Krier 	if (batch_result.retcode != IDMAP_SUCCESS) {
1068*fe1c642dSBill Krier 		result->retcode = batch_result.retcode;
1069*fe1c642dSBill Krier 		goto out;
1070*fe1c642dSBill Krier 	}
1071*fe1c642dSBill Krier 
1072*fe1c642dSBill Krier 	result->retcode = copy_id(&map->id2, &batch_result.ids.ids_val[0].id);
1073*fe1c642dSBill Krier 	if (result->retcode != IDMAP_SUCCESS)
1074*fe1c642dSBill Krier 		goto out;
1075*fe1c642dSBill Krier 
1076*fe1c642dSBill Krier 	map->direction = batch_result.ids.ids_val[0].direction;
1077*fe1c642dSBill Krier 
1078*fe1c642dSBill Krier 	result->retcode = batch_result.ids.ids_val[0].retcode;
1079*fe1c642dSBill Krier 
1080*fe1c642dSBill Krier 	if (map->flag & IDMAP_REQ_FLG_MAPPING_INFO ||
1081*fe1c642dSBill Krier 	    result->retcode != IDMAP_SUCCESS) {
1082*fe1c642dSBill Krier 		(void) idmap_info_mov(&map->info,
1083*fe1c642dSBill Krier 		    &batch_result.ids.ids_val[0].info);
1084c5c4113dSnw141292 	}
1085c5c4113dSnw141292 
1086c5c4113dSnw141292 out:
1087c5c4113dSnw141292 	if (IDMAP_FATAL_ERROR(result->retcode)) {
1088c5c4113dSnw141292 		xdr_free(xdr_idmap_mappings_res, (caddr_t)result);
1089c5c4113dSnw141292 		result->mappings.mappings_len = 0;
1090c5c4113dSnw141292 		result->mappings.mappings_val = NULL;
1091c5c4113dSnw141292 	}
1092c5c4113dSnw141292 	result->retcode = idmap_stat4prot(result->retcode);
1093*fe1c642dSBill Krier 
1094*fe1c642dSBill Krier 	xdr_free(xdr_idmap_ids_res, (char *)&batch_result);
1095*fe1c642dSBill Krier 
1096c5c4113dSnw141292 	return (TRUE);
1097c5c4113dSnw141292 }
1098c5c4113dSnw141292 
1099479ac375Sdm199847 /* ARGSUSED */
1100479ac375Sdm199847 bool_t
1101479ac375Sdm199847 idmap_get_prop_1_svc(idmap_prop_type request,
1102479ac375Sdm199847 		idmap_prop_res *result, struct svc_req *rqstp)
1103479ac375Sdm199847 {
1104479ac375Sdm199847 	idmap_pg_config_t *pgcfg;
1105479ac375Sdm199847 
1106479ac375Sdm199847 	/* Init */
1107479ac375Sdm199847 	(void) memset(result, 0, sizeof (*result));
1108479ac375Sdm199847 	result->retcode = IDMAP_SUCCESS;
1109479ac375Sdm199847 	result->value.prop = request;
1110479ac375Sdm199847 
1111479ac375Sdm199847 	RDLOCK_CONFIG();
1112479ac375Sdm199847 
1113479ac375Sdm199847 	/* Just shortcuts: */
1114479ac375Sdm199847 	pgcfg = &_idmapdstate.cfg->pgcfg;
11154d61c878SJulian Pullen 
1116479ac375Sdm199847 
1117479ac375Sdm199847 	switch (request) {
1118479ac375Sdm199847 	case PROP_LIST_SIZE_LIMIT:
1119479ac375Sdm199847 		result->value.idmap_prop_val_u.intval = pgcfg->list_size_limit;
1120479ac375Sdm199847 		result->auto_discovered = FALSE;
1121479ac375Sdm199847 		break;
1122479ac375Sdm199847 	case PROP_DEFAULT_DOMAIN:
1123479ac375Sdm199847 		result->auto_discovered = FALSE;
1124479ac375Sdm199847 		STRDUP_CHECK(result->value.idmap_prop_val_u.utf8val,
1125479ac375Sdm199847 		    pgcfg->default_domain);
1126479ac375Sdm199847 		break;
1127479ac375Sdm199847 	case PROP_DOMAIN_NAME:
1128479ac375Sdm199847 		STRDUP_CHECK(result->value.idmap_prop_val_u.utf8val,
1129479ac375Sdm199847 		    pgcfg->domain_name);
1130479ac375Sdm199847 		result->auto_discovered =
11314d61c878SJulian Pullen 		    pgcfg->domain_name_auto_disc;
1132479ac375Sdm199847 		break;
1133479ac375Sdm199847 	case PROP_MACHINE_SID:
1134479ac375Sdm199847 		result->auto_discovered = FALSE;
1135479ac375Sdm199847 		STRDUP_CHECK(result->value.idmap_prop_val_u.utf8val,
1136479ac375Sdm199847 		    pgcfg->machine_sid);
1137479ac375Sdm199847 		break;
1138479ac375Sdm199847 	case PROP_DOMAIN_CONTROLLER:
1139479ac375Sdm199847 		if (pgcfg->domain_controller != NULL) {
1140479ac375Sdm199847 			(void) memcpy(&result->value.idmap_prop_val_u.dsval,
1141479ac375Sdm199847 			    pgcfg->domain_controller,
1142479ac375Sdm199847 			    sizeof (idmap_ad_disc_ds_t));
1143479ac375Sdm199847 		}
11444d61c878SJulian Pullen 		result->auto_discovered = pgcfg->domain_controller_auto_disc;
1145479ac375Sdm199847 		break;
1146479ac375Sdm199847 	case PROP_FOREST_NAME:
1147479ac375Sdm199847 		STRDUP_CHECK(result->value.idmap_prop_val_u.utf8val,
1148479ac375Sdm199847 		    pgcfg->forest_name);
11494d61c878SJulian Pullen 		result->auto_discovered = pgcfg->forest_name_auto_disc;
1150479ac375Sdm199847 		break;
1151479ac375Sdm199847 	case PROP_SITE_NAME:
1152479ac375Sdm199847 		STRDUP_CHECK(result->value.idmap_prop_val_u.utf8val,
1153479ac375Sdm199847 		    pgcfg->site_name);
11544d61c878SJulian Pullen 		result->auto_discovered = pgcfg->site_name_auto_disc;
1155479ac375Sdm199847 		break;
1156479ac375Sdm199847 	case PROP_GLOBAL_CATALOG:
1157479ac375Sdm199847 		if (pgcfg->global_catalog != NULL) {
1158479ac375Sdm199847 			(void) memcpy(&result->value.idmap_prop_val_u.dsval,
1159479ac375Sdm199847 			    pgcfg->global_catalog, sizeof (idmap_ad_disc_ds_t));
1160479ac375Sdm199847 		}
11614d61c878SJulian Pullen 		result->auto_discovered = pgcfg->global_catalog_auto_disc;
1162479ac375Sdm199847 		break;
1163479ac375Sdm199847 	case PROP_AD_UNIXUSER_ATTR:
1164479ac375Sdm199847 		STRDUP_CHECK(result->value.idmap_prop_val_u.utf8val,
1165479ac375Sdm199847 		    pgcfg->ad_unixuser_attr);
1166479ac375Sdm199847 		result->auto_discovered = FALSE;
1167479ac375Sdm199847 		break;
1168479ac375Sdm199847 	case PROP_AD_UNIXGROUP_ATTR:
1169479ac375Sdm199847 		STRDUP_CHECK(result->value.idmap_prop_val_u.utf8val,
1170479ac375Sdm199847 		    pgcfg->ad_unixgroup_attr);
1171479ac375Sdm199847 		result->auto_discovered = FALSE;
1172479ac375Sdm199847 		break;
1173479ac375Sdm199847 	case PROP_NLDAP_WINNAME_ATTR:
1174479ac375Sdm199847 		STRDUP_CHECK(result->value.idmap_prop_val_u.utf8val,
1175479ac375Sdm199847 		    pgcfg->nldap_winname_attr);
1176479ac375Sdm199847 		result->auto_discovered = FALSE;
1177479ac375Sdm199847 		break;
1178e3f2c991SKeyur Desai 	case PROP_DIRECTORY_BASED_MAPPING:
1179e3f2c991SKeyur Desai 		STRDUP_CHECK(result->value.idmap_prop_val_u.utf8val,
1180e3f2c991SKeyur Desai 		    enum_lookup(pgcfg->directory_based_mapping,
1181e3f2c991SKeyur Desai 		    directory_mapping_map));
1182479ac375Sdm199847 		result->auto_discovered = FALSE;
1183479ac375Sdm199847 		break;
1184479ac375Sdm199847 	default:
1185479ac375Sdm199847 		result->retcode = IDMAP_ERR_PROP_UNKNOWN;
1186479ac375Sdm199847 		break;
1187479ac375Sdm199847 	}
1188479ac375Sdm199847 
1189479ac375Sdm199847 out:
1190479ac375Sdm199847 	UNLOCK_CONFIG();
1191479ac375Sdm199847 	if (IDMAP_FATAL_ERROR(result->retcode)) {
1192479ac375Sdm199847 		xdr_free(xdr_idmap_prop_res, (caddr_t)result);
1193479ac375Sdm199847 		result->value.prop = PROP_UNKNOWN;
1194479ac375Sdm199847 	}
1195479ac375Sdm199847 	result->retcode = idmap_stat4prot(result->retcode);
1196479ac375Sdm199847 	return (TRUE);
1197479ac375Sdm199847 }
1198479ac375Sdm199847 
1199c5c4113dSnw141292 
1200c5c4113dSnw141292 /* ARGSUSED */
1201c5c4113dSnw141292 int
1202c5c4113dSnw141292 idmap_prog_1_freeresult(SVCXPRT *transp, xdrproc_t xdr_result,
1203cd37da74Snw141292 		caddr_t result)
1204cd37da74Snw141292 {
1205c5c4113dSnw141292 	(void) xdr_free(xdr_result, result);
1206c5c4113dSnw141292 	return (TRUE);
1207c5c4113dSnw141292 }
12081fcced4cSJordan Brown 
12091fcced4cSJordan Brown /*
12101fcced4cSJordan Brown  * This function is called by rpc_svc.c when it encounters an error.
12111fcced4cSJordan Brown  */
12121fcced4cSJordan Brown NOTE(PRINTFLIKE(1))
12131fcced4cSJordan Brown void
12141fcced4cSJordan Brown idmap_rpc_msgout(const char *fmt, ...)
12151fcced4cSJordan Brown {
12161fcced4cSJordan Brown 	va_list va;
12171fcced4cSJordan Brown 	char buf[1000];
12181fcced4cSJordan Brown 
12191fcced4cSJordan Brown 	va_start(va, fmt);
12201fcced4cSJordan Brown 	(void) vsnprintf(buf, sizeof (buf), fmt, va);
12211fcced4cSJordan Brown 	va_end(va);
12221fcced4cSJordan Brown 
12231fcced4cSJordan Brown 	idmapdlog(LOG_ERR, "idmap RPC:  %s", buf);
12241fcced4cSJordan Brown }
1225