1b819cea2SGordon Ross /*
2b819cea2SGordon Ross  * CDDL HEADER START
3b819cea2SGordon Ross  *
4b819cea2SGordon Ross  * The contents of this file are subject to the terms of the
5b819cea2SGordon Ross  * Common Development and Distribution License (the "License").
6b819cea2SGordon Ross  * You may not use this file except in compliance with the License.
7b819cea2SGordon Ross  *
8b819cea2SGordon Ross  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9b819cea2SGordon Ross  * or http://www.opensolaris.org/os/licensing.
10b819cea2SGordon Ross  * See the License for the specific language governing permissions
11b819cea2SGordon Ross  * and limitations under the License.
12b819cea2SGordon Ross  *
13b819cea2SGordon Ross  * When distributing Covered Code, include this CDDL HEADER in each
14b819cea2SGordon Ross  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15b819cea2SGordon Ross  * If applicable, add the following below this CDDL HEADER, with the
16b819cea2SGordon Ross  * fields enclosed by brackets "[]" replaced with your own identifying
17b819cea2SGordon Ross  * information: Portions Copyright [yyyy] [name of copyright owner]
18b819cea2SGordon Ross  *
19b819cea2SGordon Ross  * CDDL HEADER END
20b819cea2SGordon Ross  */
21b819cea2SGordon Ross /*
22b819cea2SGordon Ross  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23526073d8SMatt Barden  * Copyright 2020 Nexenta by DDN, Inc. All rights reserved.
24*f920d1d1SGordon Ross  * Copyright 2023 RackTop Systems, Inc.
25b819cea2SGordon Ross  */
26b819cea2SGordon Ross 
27b819cea2SGordon Ross /*
28b819cea2SGordon Ross  * SMB server interface to idmap
29b819cea2SGordon Ross  * (smb_idmap_get..., smb_idmap_batch_...)
30b819cea2SGordon Ross  *
31a73d9d5eSGordon Ross  * There are three implementations of this interface.
32a73d9d5eSGordon Ross  * This is the kernel version of these routines.  See also:
33a73d9d5eSGordon Ross  * $SRC/lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c
34a73d9d5eSGordon Ross  * $SRC/lib/smbsrv/libsmb/common/smb_idmap.c
35b819cea2SGordon Ross  *
36b819cea2SGordon Ross  * There are enough differences (relative to the code size)
37b819cea2SGordon Ross  * that it's more trouble than it's worth to merge them.
38b819cea2SGordon Ross  *
39b819cea2SGordon Ross  * This one differs from the others in that it:
40b819cea2SGordon Ross  *	calls kernel (kidmap_...) interfaces
41a73d9d5eSGordon Ross  *	returned domain SIDs are shared, not strdup'ed
42b819cea2SGordon Ross  */
43b819cea2SGordon Ross 
44b819cea2SGordon Ross /*
45b819cea2SGordon Ross  * SMB ID mapping
46b819cea2SGordon Ross  *
47b819cea2SGordon Ross  * Solaris ID mapping service (aka Winchester) works with domain SIDs
48b819cea2SGordon Ross  * and RIDs where domain SIDs are in string format. CIFS service works
49b819cea2SGordon Ross  * with binary SIDs understandable by CIFS clients. A layer of SMB ID
50b819cea2SGordon Ross  * mapping functions are implemeted to hide the SID conversion details
51b819cea2SGordon Ross  * and also hide the handling of array of batch mapping requests.
52b819cea2SGordon Ross  */
53b819cea2SGordon Ross 
54b819cea2SGordon Ross #include <sys/param.h>
55b819cea2SGordon Ross #include <sys/types.h>
56b819cea2SGordon Ross #include <sys/tzfile.h>
57b819cea2SGordon Ross #include <sys/atomic.h>
58b819cea2SGordon Ross #include <sys/kidmap.h>
59b819cea2SGordon Ross #include <sys/time.h>
60b819cea2SGordon Ross #include <sys/spl.h>
61b819cea2SGordon Ross #include <sys/random.h>
62b819cea2SGordon Ross #include <smbsrv/smb_kproto.h>
63b819cea2SGordon Ross #include <smbsrv/smb_fsops.h>
64b819cea2SGordon Ross #include <smbsrv/smbinfo.h>
65b819cea2SGordon Ross #include <smbsrv/smb_xdr.h>
66b819cea2SGordon Ross #include <smbsrv/smb_vops.h>
67b819cea2SGordon Ross #include <smbsrv/smb_idmap.h>
68b819cea2SGordon Ross 
69b819cea2SGordon Ross #include <sys/sid.h>
70b819cea2SGordon Ross #include <sys/priv_names.h>
71b819cea2SGordon Ross 
72b819cea2SGordon Ross static int smb_idmap_batch_binsid(smb_idmap_batch_t *sib);
73b819cea2SGordon Ross 
74b819cea2SGordon Ross /*
75b819cea2SGordon Ross  * smb_idmap_getsid
76b819cea2SGordon Ross  *
77b819cea2SGordon Ross  * Maps the given Solaris ID to a Windows SID using the
78b819cea2SGordon Ross  * simple mapping API.
79b819cea2SGordon Ross  */
80b819cea2SGordon Ross idmap_stat
smb_idmap_getsid(uid_t id,int idtype,smb_sid_t ** sid)81b819cea2SGordon Ross smb_idmap_getsid(uid_t id, int idtype, smb_sid_t **sid)
82b819cea2SGordon Ross {
83b819cea2SGordon Ross 	smb_idmap_t sim;
84b819cea2SGordon Ross 
85b819cea2SGordon Ross 	switch (idtype) {
86b819cea2SGordon Ross 	case SMB_IDMAP_USER:
87526073d8SMatt Barden 		sim.sim_stat = kidmap_getsidbyuid(curzone, id,
88b819cea2SGordon Ross 		    (const char **)&sim.sim_domsid, &sim.sim_rid);
89b819cea2SGordon Ross 		break;
90b819cea2SGordon Ross 
91b819cea2SGordon Ross 	case SMB_IDMAP_GROUP:
92526073d8SMatt Barden 		sim.sim_stat = kidmap_getsidbygid(curzone, id,
93b819cea2SGordon Ross 		    (const char **)&sim.sim_domsid, &sim.sim_rid);
94b819cea2SGordon Ross 		break;
95b819cea2SGordon Ross 
96b819cea2SGordon Ross 	case SMB_IDMAP_EVERYONE:
97b819cea2SGordon Ross 		/* Everyone S-1-1-0 */
98b819cea2SGordon Ross 		sim.sim_domsid = "S-1-1";
99b819cea2SGordon Ross 		sim.sim_rid = 0;
100b819cea2SGordon Ross 		sim.sim_stat = IDMAP_SUCCESS;
101b819cea2SGordon Ross 		break;
102b819cea2SGordon Ross 
103b819cea2SGordon Ross 	default:
104b819cea2SGordon Ross 		ASSERT(0);
105b819cea2SGordon Ross 		return (IDMAP_ERR_ARG);
106b819cea2SGordon Ross 	}
107b819cea2SGordon Ross 
108a88046d1SMatt Barden 	/*
109a88046d1SMatt Barden 	 * IDMAP_ERR_NOTFOUND is an advisory error
110a88046d1SMatt Barden 	 * and idmap will generate a local sid.
111a88046d1SMatt Barden 	 */
112a88046d1SMatt Barden 	if (sim.sim_stat == IDMAP_ERR_NOTFOUND &&
113a88046d1SMatt Barden 	    sim.sim_domsid != NULL)
114a88046d1SMatt Barden 		sim.sim_stat = IDMAP_SUCCESS;
115a88046d1SMatt Barden 
116b819cea2SGordon Ross 	if (sim.sim_stat != IDMAP_SUCCESS)
117b819cea2SGordon Ross 		return (sim.sim_stat);
118b819cea2SGordon Ross 
119b819cea2SGordon Ross 	if (sim.sim_domsid == NULL)
120b819cea2SGordon Ross 		return (IDMAP_ERR_NOMAPPING);
121b819cea2SGordon Ross 
122b819cea2SGordon Ross 	sim.sim_sid = smb_sid_fromstr(sim.sim_domsid);
123b819cea2SGordon Ross 	if (sim.sim_sid == NULL)
124b819cea2SGordon Ross 		return (IDMAP_ERR_INTERNAL);
125b819cea2SGordon Ross 
126b819cea2SGordon Ross 	*sid = smb_sid_splice(sim.sim_sid, sim.sim_rid);
127b819cea2SGordon Ross 	smb_sid_free(sim.sim_sid);
128b819cea2SGordon Ross 	if (*sid == NULL)
129b819cea2SGordon Ross 		sim.sim_stat = IDMAP_ERR_INTERNAL;
130b819cea2SGordon Ross 
131b819cea2SGordon Ross 	return (sim.sim_stat);
132b819cea2SGordon Ross }
133b819cea2SGordon Ross 
134b819cea2SGordon Ross /*
135b819cea2SGordon Ross  * smb_idmap_getid
136b819cea2SGordon Ross  *
137b819cea2SGordon Ross  * Maps the given Windows SID to a Unix ID using the
138b819cea2SGordon Ross  * simple mapping API.
139b819cea2SGordon Ross  */
140b819cea2SGordon Ross idmap_stat
smb_idmap_getid(smb_sid_t * sid,uid_t * id,int * idtype)141b819cea2SGordon Ross smb_idmap_getid(smb_sid_t *sid, uid_t *id, int *idtype)
142b819cea2SGordon Ross {
143b819cea2SGordon Ross 	smb_idmap_t sim;
144b819cea2SGordon Ross 	char sidstr[SMB_SID_STRSZ];
145b819cea2SGordon Ross 
146b819cea2SGordon Ross 	smb_sid_tostr(sid, sidstr);
147b819cea2SGordon Ross 	if (smb_sid_splitstr(sidstr, &sim.sim_rid) != 0)
148b819cea2SGordon Ross 		return (IDMAP_ERR_SID);
149b819cea2SGordon Ross 	sim.sim_domsid = sidstr;
150b819cea2SGordon Ross 	sim.sim_id = id;
151b819cea2SGordon Ross 
152b819cea2SGordon Ross 	switch (*idtype) {
153b819cea2SGordon Ross 	case SMB_IDMAP_USER:
154526073d8SMatt Barden 		sim.sim_stat = kidmap_getuidbysid(curzone, sim.sim_domsid,
155b819cea2SGordon Ross 		    sim.sim_rid, sim.sim_id);
156b819cea2SGordon Ross 		break;
157b819cea2SGordon Ross 
158b819cea2SGordon Ross 	case SMB_IDMAP_GROUP:
159526073d8SMatt Barden 		sim.sim_stat = kidmap_getgidbysid(curzone, sim.sim_domsid,
160b819cea2SGordon Ross 		    sim.sim_rid, sim.sim_id);
161b819cea2SGordon Ross 		break;
162b819cea2SGordon Ross 
163b819cea2SGordon Ross 	case SMB_IDMAP_UNKNOWN:
164526073d8SMatt Barden 		sim.sim_stat = kidmap_getpidbysid(curzone, sim.sim_domsid,
165b819cea2SGordon Ross 		    sim.sim_rid, sim.sim_id, &sim.sim_idtype);
166b819cea2SGordon Ross 		break;
167b819cea2SGordon Ross 
168b819cea2SGordon Ross 	default:
169b819cea2SGordon Ross 		ASSERT(0);
170b819cea2SGordon Ross 		return (IDMAP_ERR_ARG);
171b819cea2SGordon Ross 	}
172b819cea2SGordon Ross 
173b819cea2SGordon Ross 	*idtype = sim.sim_idtype;
174b819cea2SGordon Ross 
175b819cea2SGordon Ross 	return (sim.sim_stat);
176b819cea2SGordon Ross }
177b819cea2SGordon Ross 
178b819cea2SGordon Ross /*
179b819cea2SGordon Ross  * smb_idmap_batch_create
180b819cea2SGordon Ross  *
181b819cea2SGordon Ross  * Creates and initializes the context for batch ID mapping.
182b819cea2SGordon Ross  */
183b819cea2SGordon Ross idmap_stat
smb_idmap_batch_create(smb_idmap_batch_t * sib,uint16_t nmap,int flags)184b819cea2SGordon Ross smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags)
185b819cea2SGordon Ross {
186a73d9d5eSGordon Ross 	ASSERT(sib != NULL);
187b819cea2SGordon Ross 
188b819cea2SGordon Ross 	bzero(sib, sizeof (smb_idmap_batch_t));
189b819cea2SGordon Ross 
190526073d8SMatt Barden 	sib->sib_idmaph = kidmap_get_create(curzone);
191b819cea2SGordon Ross 
192b819cea2SGordon Ross 	sib->sib_flags = flags;
193b819cea2SGordon Ross 	sib->sib_nmap = nmap;
194b819cea2SGordon Ross 	sib->sib_size = nmap * sizeof (smb_idmap_t);
195b819cea2SGordon Ross 	sib->sib_maps = kmem_zalloc(sib->sib_size, KM_SLEEP);
196b819cea2SGordon Ross 
197b819cea2SGordon Ross 	return (IDMAP_SUCCESS);
198b819cea2SGordon Ross }
199b819cea2SGordon Ross 
200b819cea2SGordon Ross /*
201b819cea2SGordon Ross  * smb_idmap_batch_destroy
202b819cea2SGordon Ross  *
203b819cea2SGordon Ross  * Frees the batch ID mapping context.
204b819cea2SGordon Ross  * If ID mapping is Solaris -> Windows it frees memories
205b819cea2SGordon Ross  * allocated for binary SIDs.
206b819cea2SGordon Ross  */
207b819cea2SGordon Ross void
smb_idmap_batch_destroy(smb_idmap_batch_t * sib)208b819cea2SGordon Ross smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
209b819cea2SGordon Ross {
210b819cea2SGordon Ross 	char *domsid;
211b819cea2SGordon Ross 	int i;
212b819cea2SGordon Ross 
213a73d9d5eSGordon Ross 	ASSERT(sib != NULL);
214a73d9d5eSGordon Ross 	ASSERT(sib->sib_maps != NULL);
215b819cea2SGordon Ross 
216a73d9d5eSGordon Ross 	if (sib->sib_idmaph) {
217b819cea2SGordon Ross 		kidmap_get_destroy(sib->sib_idmaph);
218a73d9d5eSGordon Ross 		sib->sib_idmaph = NULL;
219a73d9d5eSGordon Ross 	}
220b819cea2SGordon Ross 
221b819cea2SGordon Ross 	if (sib->sib_flags & SMB_IDMAP_ID2SID) {
222b819cea2SGordon Ross 		/*
223b819cea2SGordon Ross 		 * SIDs are allocated only when mapping
224b819cea2SGordon Ross 		 * UID/GID to SIDs
225b819cea2SGordon Ross 		 */
226b819cea2SGordon Ross 		for (i = 0; i < sib->sib_nmap; i++)
227b819cea2SGordon Ross 			smb_sid_free(sib->sib_maps[i].sim_sid);
228b819cea2SGordon Ross 	} else if (sib->sib_flags & SMB_IDMAP_SID2ID) {
229b819cea2SGordon Ross 		/*
230b819cea2SGordon Ross 		 * SID prefixes are allocated only when mapping
231b819cea2SGordon Ross 		 * SIDs to UID/GID
232b819cea2SGordon Ross 		 */
233b819cea2SGordon Ross 		for (i = 0; i < sib->sib_nmap; i++) {
234b819cea2SGordon Ross 			domsid = sib->sib_maps[i].sim_domsid;
235b819cea2SGordon Ross 			if (domsid)
236b819cea2SGordon Ross 				smb_mem_free(domsid);
237b819cea2SGordon Ross 		}
238b819cea2SGordon Ross 	}
239b819cea2SGordon Ross 
240a73d9d5eSGordon Ross 	if (sib->sib_size && sib->sib_maps) {
241b819cea2SGordon Ross 		kmem_free(sib->sib_maps, sib->sib_size);
242a73d9d5eSGordon Ross 		sib->sib_maps = NULL;
243a73d9d5eSGordon Ross 	}
244b819cea2SGordon Ross }
245b819cea2SGordon Ross 
246b819cea2SGordon Ross /*
247b819cea2SGordon Ross  * smb_idmap_batch_getid
248b819cea2SGordon Ross  *
249b819cea2SGordon Ross  * Queue a request to map the given SID to a UID or GID.
250b819cea2SGordon Ross  *
251b819cea2SGordon Ross  * sim->sim_id should point to variable that's supposed to
252b819cea2SGordon Ross  * hold the returned UID/GID. This needs to be setup by caller
253b819cea2SGordon Ross  * of this function.
254b819cea2SGordon Ross  *
255b819cea2SGordon Ross  * If requested ID type is known, it's passed as 'idtype',
256b819cea2SGordon Ross  * if it's unknown it'll be returned in sim->sim_idtype.
257b819cea2SGordon Ross  */
258b819cea2SGordon Ross idmap_stat
smb_idmap_batch_getid(idmap_get_handle_t * idmaph,smb_idmap_t * sim,smb_sid_t * sid,int idtype)259b819cea2SGordon Ross smb_idmap_batch_getid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
260b819cea2SGordon Ross     smb_sid_t *sid, int idtype)
261b819cea2SGordon Ross {
262b819cea2SGordon Ross 	char strsid[SMB_SID_STRSZ];
263b819cea2SGordon Ross 	idmap_stat idm_stat;
264b819cea2SGordon Ross 
265a73d9d5eSGordon Ross 	ASSERT(idmaph != NULL);
266a73d9d5eSGordon Ross 	ASSERT(sim != NULL);
267a73d9d5eSGordon Ross 	ASSERT(sid != NULL);
268b819cea2SGordon Ross 
269b819cea2SGordon Ross 	smb_sid_tostr(sid, strsid);
270b819cea2SGordon Ross 	if (smb_sid_splitstr(strsid, &sim->sim_rid) != 0)
271b819cea2SGordon Ross 		return (IDMAP_ERR_SID);
272a73d9d5eSGordon Ross 	/* Note: Free sim_domsid in smb_idmap_batch_destroy */
273b819cea2SGordon Ross 	sim->sim_domsid = smb_mem_strdup(strsid);
274a73d9d5eSGordon Ross 	sim->sim_idtype = idtype;
275b819cea2SGordon Ross 
276b819cea2SGordon Ross 	switch (idtype) {
277b819cea2SGordon Ross 	case SMB_IDMAP_USER:
278b819cea2SGordon Ross 		idm_stat = kidmap_batch_getuidbysid(idmaph, sim->sim_domsid,
279b819cea2SGordon Ross 		    sim->sim_rid, sim->sim_id, &sim->sim_stat);
280b819cea2SGordon Ross 		break;
281b819cea2SGordon Ross 
282b819cea2SGordon Ross 	case SMB_IDMAP_GROUP:
283b819cea2SGordon Ross 		idm_stat = kidmap_batch_getgidbysid(idmaph, sim->sim_domsid,
284b819cea2SGordon Ross 		    sim->sim_rid, sim->sim_id, &sim->sim_stat);
285b819cea2SGordon Ross 		break;
286b819cea2SGordon Ross 
287b819cea2SGordon Ross 	case SMB_IDMAP_UNKNOWN:
288b819cea2SGordon Ross 		idm_stat = kidmap_batch_getpidbysid(idmaph, sim->sim_domsid,
289b819cea2SGordon Ross 		    sim->sim_rid, sim->sim_id, &sim->sim_idtype,
290b819cea2SGordon Ross 		    &sim->sim_stat);
291b819cea2SGordon Ross 		break;
292b819cea2SGordon Ross 
293b819cea2SGordon Ross 	default:
294b819cea2SGordon Ross 		ASSERT(0);
295b819cea2SGordon Ross 		return (IDMAP_ERR_ARG);
296b819cea2SGordon Ross 	}
297b819cea2SGordon Ross 
298b819cea2SGordon Ross 	return (idm_stat);
299b819cea2SGordon Ross }
300b819cea2SGordon Ross 
301b819cea2SGordon Ross /*
302b819cea2SGordon Ross  * smb_idmap_batch_getsid
303b819cea2SGordon Ross  *
304b819cea2SGordon Ross  * Queue a request to map the given UID/GID to a SID.
305b819cea2SGordon Ross  *
306b819cea2SGordon Ross  * sim->sim_domsid and sim->sim_rid will contain the mapping
307b819cea2SGordon Ross  * result upon successful process of the batched request.
308a73d9d5eSGordon Ross  * Stash the type for error reporting (caller saves the ID).
309b819cea2SGordon Ross  */
310b819cea2SGordon Ross idmap_stat
smb_idmap_batch_getsid(idmap_get_handle_t * idmaph,smb_idmap_t * sim,uid_t id,int idtype)311b819cea2SGordon Ross smb_idmap_batch_getsid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
312b819cea2SGordon Ross     uid_t id, int idtype)
313b819cea2SGordon Ross {
314b819cea2SGordon Ross 	idmap_stat idm_stat;
315b819cea2SGordon Ross 
316a73d9d5eSGordon Ross 	sim->sim_idtype = idtype;
317b819cea2SGordon Ross 	switch (idtype) {
318b819cea2SGordon Ross 	case SMB_IDMAP_USER:
319b819cea2SGordon Ross 		idm_stat = kidmap_batch_getsidbyuid(idmaph, id,
320b819cea2SGordon Ross 		    (const char **)&sim->sim_domsid, &sim->sim_rid,
321b819cea2SGordon Ross 		    &sim->sim_stat);
322b819cea2SGordon Ross 		break;
323b819cea2SGordon Ross 
324b819cea2SGordon Ross 	case SMB_IDMAP_GROUP:
325b819cea2SGordon Ross 		idm_stat = kidmap_batch_getsidbygid(idmaph, id,
326b819cea2SGordon Ross 		    (const char **)&sim->sim_domsid, &sim->sim_rid,
327b819cea2SGordon Ross 		    &sim->sim_stat);
328b819cea2SGordon Ross 		break;
329b819cea2SGordon Ross 
330b819cea2SGordon Ross 	case SMB_IDMAP_OWNERAT:
331b819cea2SGordon Ross 		/* Current Owner S-1-5-32-766 */
332b819cea2SGordon Ross 		sim->sim_domsid = NT_BUILTIN_DOMAIN_SIDSTR;
333b819cea2SGordon Ross 		sim->sim_rid = SECURITY_CURRENT_OWNER_RID;
334b819cea2SGordon Ross 		sim->sim_stat = IDMAP_SUCCESS;
335b819cea2SGordon Ross 		idm_stat = IDMAP_SUCCESS;
336b819cea2SGordon Ross 		break;
337b819cea2SGordon Ross 
338b819cea2SGordon Ross 	case SMB_IDMAP_GROUPAT:
339b819cea2SGordon Ross 		/* Current Group S-1-5-32-767 */
340b819cea2SGordon Ross 		sim->sim_domsid = NT_BUILTIN_DOMAIN_SIDSTR;
341b819cea2SGordon Ross 		sim->sim_rid = SECURITY_CURRENT_GROUP_RID;
342b819cea2SGordon Ross 		sim->sim_stat = IDMAP_SUCCESS;
343b819cea2SGordon Ross 		idm_stat = IDMAP_SUCCESS;
344b819cea2SGordon Ross 		break;
345b819cea2SGordon Ross 
346b819cea2SGordon Ross 	case SMB_IDMAP_EVERYONE:
347b819cea2SGordon Ross 		/* Everyone S-1-1-0 */
348b819cea2SGordon Ross 		sim->sim_domsid = NT_WORLD_AUTH_SIDSTR;
349b819cea2SGordon Ross 		sim->sim_rid = 0;
350b819cea2SGordon Ross 		sim->sim_stat = IDMAP_SUCCESS;
351b819cea2SGordon Ross 		idm_stat = IDMAP_SUCCESS;
352b819cea2SGordon Ross 		break;
353b819cea2SGordon Ross 
354b819cea2SGordon Ross 	default:
355b819cea2SGordon Ross 		ASSERT(0);
356b819cea2SGordon Ross 		return (IDMAP_ERR_ARG);
357b819cea2SGordon Ross 	}
358b819cea2SGordon Ross 
359b819cea2SGordon Ross 	return (idm_stat);
360b819cea2SGordon Ross }
361b819cea2SGordon Ross 
362b819cea2SGordon Ross /*
363b819cea2SGordon Ross  * smb_idmap_batch_getmappings
364b819cea2SGordon Ross  *
365b819cea2SGordon Ross  * trigger ID mapping service to get the mappings for queued
366b819cea2SGordon Ross  * requests.
367b819cea2SGordon Ross  *
368b819cea2SGordon Ross  * Checks the result of all the queued requests.
369b819cea2SGordon Ross  * If this is a Solaris -> Windows mapping it generates
370b819cea2SGordon Ross  * binary SIDs from returned (domsid, rid) pairs.
371b819cea2SGordon Ross  */
372b819cea2SGordon Ross idmap_stat
smb_idmap_batch_getmappings(smb_idmap_batch_t * sib,smb_idmap_batch_errcb_t errcb)373*f920d1d1SGordon Ross smb_idmap_batch_getmappings(smb_idmap_batch_t *sib,
374*f920d1d1SGordon Ross     smb_idmap_batch_errcb_t errcb)
375b819cea2SGordon Ross {
376b819cea2SGordon Ross 	idmap_stat idm_stat = IDMAP_SUCCESS;
377a73d9d5eSGordon Ross 	smb_idmap_t *sim;
378b819cea2SGordon Ross 	int i;
379b819cea2SGordon Ross 
380b819cea2SGordon Ross 	idm_stat = kidmap_get_mappings(sib->sib_idmaph);
381b819cea2SGordon Ross 	if (idm_stat != IDMAP_SUCCESS)
382b819cea2SGordon Ross 		return (idm_stat);
383b819cea2SGordon Ross 
384b819cea2SGordon Ross 	/*
385b819cea2SGordon Ross 	 * Check the status for all the queued requests
386b819cea2SGordon Ross 	 */
387a73d9d5eSGordon Ross 	for (i = 0, sim = sib->sib_maps; i < sib->sib_nmap; i++, sim++) {
388a73d9d5eSGordon Ross 		if (sim->sim_stat != IDMAP_SUCCESS) {
389*f920d1d1SGordon Ross 			sib->sib_nerr++;
390*f920d1d1SGordon Ross 			if (errcb != NULL)
391*f920d1d1SGordon Ross 				errcb(sib, sim);
392a73d9d5eSGordon Ross 			if ((sib->sib_flags & SMB_IDMAP_SKIP_ERRS) == 0) {
393a73d9d5eSGordon Ross 				return (sim->sim_stat);
394a73d9d5eSGordon Ross 			}
395a73d9d5eSGordon Ross 		}
396b819cea2SGordon Ross 	}
397b819cea2SGordon Ross 
398b819cea2SGordon Ross 	if (smb_idmap_batch_binsid(sib) != 0)
399b819cea2SGordon Ross 		idm_stat = IDMAP_ERR_OTHER;
400b819cea2SGordon Ross 
401b819cea2SGordon Ross 	return (idm_stat);
402b819cea2SGordon Ross }
403b819cea2SGordon Ross 
404b819cea2SGordon Ross /*
405b819cea2SGordon Ross  * smb_idmap_batch_binsid
406b819cea2SGordon Ross  *
407b819cea2SGordon Ross  * Convert sidrids to binary sids
408b819cea2SGordon Ross  *
409b819cea2SGordon Ross  * Returns 0 if successful and non-zero upon failure.
410b819cea2SGordon Ross  */
411b819cea2SGordon Ross static int
smb_idmap_batch_binsid(smb_idmap_batch_t * sib)412b819cea2SGordon Ross smb_idmap_batch_binsid(smb_idmap_batch_t *sib)
413b819cea2SGordon Ross {
414b819cea2SGordon Ross 	smb_sid_t *sid;
415b819cea2SGordon Ross 	smb_idmap_t *sim;
416b819cea2SGordon Ross 	int i;
417b819cea2SGordon Ross 
418b819cea2SGordon Ross 	if (sib->sib_flags & SMB_IDMAP_SID2ID)
419b819cea2SGordon Ross 		/* This operation is not required */
420b819cea2SGordon Ross 		return (0);
421b819cea2SGordon Ross 
422b819cea2SGordon Ross 	sim = sib->sib_maps;
423b819cea2SGordon Ross 	for (i = 0; i < sib->sib_nmap; sim++, i++) {
424a73d9d5eSGordon Ross 		ASSERT(sim->sim_domsid != NULL);
425b819cea2SGordon Ross 		if (sim->sim_domsid == NULL)
426b819cea2SGordon Ross 			return (1);
427b819cea2SGordon Ross 
428b819cea2SGordon Ross 		if ((sid = smb_sid_fromstr(sim->sim_domsid)) == NULL)
429b819cea2SGordon Ross 			return (1);
430b819cea2SGordon Ross 
431b819cea2SGordon Ross 		sim->sim_sid = smb_sid_splice(sid, sim->sim_rid);
432b819cea2SGordon Ross 		smb_sid_free(sid);
433b819cea2SGordon Ross 	}
434b819cea2SGordon Ross 
435b819cea2SGordon Ross 	return (0);
436b819cea2SGordon Ross }
437