1da6c28aaSamw /*
2da6c28aaSamw * CDDL HEADER START
3da6c28aaSamw *
4da6c28aaSamw * The contents of this file are subject to the terms of the
5da6c28aaSamw * Common Development and Distribution License (the "License").
6da6c28aaSamw * You may not use this file except in compliance with the License.
7da6c28aaSamw *
8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw * See the License for the specific language governing permissions
11da6c28aaSamw * and limitations under the License.
12da6c28aaSamw *
13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw *
19da6c28aaSamw * CDDL HEADER END
20da6c28aaSamw */
21da6c28aaSamw /*
221fdeec65Sjoyce mcintosh * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23*b819cea2SGordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
24*b819cea2SGordon Ross */
25*b819cea2SGordon Ross
26*b819cea2SGordon Ross /*
27*b819cea2SGordon Ross * SMB server interface to idmap
28*b819cea2SGordon Ross * (smb_idmap_get..., smb_idmap_batch_...)
29*b819cea2SGordon Ross *
30*b819cea2SGordon Ross * There are three implementations of this interface:
31*b819cea2SGordon Ross * uts/common/fs/smbsrv/smb_idmap.c (smbsrv kmod)
32*b819cea2SGordon Ross * lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c (libfksmbsrv)
33*b819cea2SGordon Ross * lib/smbsrv/libsmb/common/smb_idmap.c (libsmb)
34*b819cea2SGordon Ross *
35*b819cea2SGordon Ross * There are enough differences (relative to the code size)
36*b819cea2SGordon Ross * that it's more trouble than it's worth to merge them.
37*b819cea2SGordon Ross *
38*b819cea2SGordon Ross * This one differs from the others in that it:
39*b819cea2SGordon Ross * calls idmap interfaces (libidmap)
40*b819cea2SGordon Ross * domain SIDs returned are allocated
41da6c28aaSamw */
42da6c28aaSamw
439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <syslog.h>
44da6c28aaSamw #include <strings.h>
45da6c28aaSamw #include <smbsrv/libsmb.h>
46da6c28aaSamw
47da6c28aaSamw static int smb_idmap_batch_binsid(smb_idmap_batch_t *sib);
48da6c28aaSamw
49da6c28aaSamw /*
501fdeec65Sjoyce mcintosh * Report an idmap error.
51da6c28aaSamw */
52da6c28aaSamw void
smb_idmap_check(const char * s,idmap_stat stat)539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_check(const char *s, idmap_stat stat)
54da6c28aaSamw {
559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (stat != IDMAP_SUCCESS) {
569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (s == NULL)
579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States s = "smb_idmap_check";
589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
591fdeec65Sjoyce mcintosh syslog(LOG_ERR, "%s: %s", s, idmap_stat2string(stat));
60da6c28aaSamw }
619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
62da6c28aaSamw
63da6c28aaSamw /*
64da6c28aaSamw * smb_idmap_getsid
65da6c28aaSamw *
66da6c28aaSamw * Tries to get a mapping for the given uid/gid
67*b819cea2SGordon Ross * Allocates ->sim_domsid
68da6c28aaSamw */
69da6c28aaSamw idmap_stat
smb_idmap_getsid(uid_t id,int idtype,smb_sid_t ** sid)706537f381Sas200622 smb_idmap_getsid(uid_t id, int idtype, smb_sid_t **sid)
71da6c28aaSamw {
72da6c28aaSamw smb_idmap_batch_t sib;
73da6c28aaSamw idmap_stat stat;
74da6c28aaSamw
75da6c28aaSamw stat = smb_idmap_batch_create(&sib, 1, SMB_IDMAP_ID2SID);
76da6c28aaSamw if (stat != IDMAP_SUCCESS)
77da6c28aaSamw return (stat);
78da6c28aaSamw
79da6c28aaSamw stat = smb_idmap_batch_getsid(sib.sib_idmaph, &sib.sib_maps[0],
80da6c28aaSamw id, idtype);
81da6c28aaSamw
82da6c28aaSamw if (stat != IDMAP_SUCCESS) {
83da6c28aaSamw smb_idmap_batch_destroy(&sib);
84da6c28aaSamw return (stat);
85da6c28aaSamw }
86da6c28aaSamw
87da6c28aaSamw stat = smb_idmap_batch_getmappings(&sib);
88da6c28aaSamw
89da6c28aaSamw if (stat != IDMAP_SUCCESS) {
90da6c28aaSamw smb_idmap_batch_destroy(&sib);
91da6c28aaSamw return (stat);
92da6c28aaSamw }
93da6c28aaSamw
946537f381Sas200622 *sid = smb_sid_dup(sib.sib_maps[0].sim_sid);
95da6c28aaSamw
96da6c28aaSamw smb_idmap_batch_destroy(&sib);
97da6c28aaSamw
98da6c28aaSamw return (IDMAP_SUCCESS);
99da6c28aaSamw }
100da6c28aaSamw
101da6c28aaSamw /*
102dc20a302Sas200622 * smb_idmap_getid
103dc20a302Sas200622 *
104dc20a302Sas200622 * Tries to get a mapping for the given SID
105dc20a302Sas200622 */
106dc20a302Sas200622 idmap_stat
smb_idmap_getid(smb_sid_t * sid,uid_t * id,int * id_type)1076537f381Sas200622 smb_idmap_getid(smb_sid_t *sid, uid_t *id, int *id_type)
108dc20a302Sas200622 {
109dc20a302Sas200622 smb_idmap_batch_t sib;
110dc20a302Sas200622 smb_idmap_t *sim;
111dc20a302Sas200622 idmap_stat stat;
112dc20a302Sas200622
113dc20a302Sas200622 stat = smb_idmap_batch_create(&sib, 1, SMB_IDMAP_SID2ID);
114dc20a302Sas200622 if (stat != IDMAP_SUCCESS)
115dc20a302Sas200622 return (stat);
116dc20a302Sas200622
117dc20a302Sas200622 sim = &sib.sib_maps[0];
118dc20a302Sas200622 sim->sim_id = id;
119dc20a302Sas200622 stat = smb_idmap_batch_getid(sib.sib_idmaph, sim, sid, *id_type);
120dc20a302Sas200622 if (stat != IDMAP_SUCCESS) {
121dc20a302Sas200622 smb_idmap_batch_destroy(&sib);
122dc20a302Sas200622 return (stat);
123dc20a302Sas200622 }
124dc20a302Sas200622
125dc20a302Sas200622 stat = smb_idmap_batch_getmappings(&sib);
126dc20a302Sas200622
127dc20a302Sas200622 if (stat != IDMAP_SUCCESS) {
128dc20a302Sas200622 smb_idmap_batch_destroy(&sib);
129dc20a302Sas200622 return (stat);
130dc20a302Sas200622 }
131dc20a302Sas200622
132dc20a302Sas200622 *id_type = sim->sim_idtype;
133dc20a302Sas200622 smb_idmap_batch_destroy(&sib);
134dc20a302Sas200622
135dc20a302Sas200622 return (IDMAP_SUCCESS);
136dc20a302Sas200622 }
137dc20a302Sas200622
138dc20a302Sas200622 /*
139da6c28aaSamw * smb_idmap_batch_create
140da6c28aaSamw *
141da6c28aaSamw * Creates and initializes the context for batch ID mapping.
142da6c28aaSamw */
143da6c28aaSamw idmap_stat
smb_idmap_batch_create(smb_idmap_batch_t * sib,uint16_t nmap,int flags)144da6c28aaSamw smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags)
145da6c28aaSamw {
146da6c28aaSamw idmap_stat stat;
147da6c28aaSamw
148da6c28aaSamw if (!sib)
149da6c28aaSamw return (IDMAP_ERR_ARG);
150da6c28aaSamw
151da6c28aaSamw bzero(sib, sizeof (smb_idmap_batch_t));
1521fdeec65Sjoyce mcintosh stat = idmap_get_create(&sib->sib_idmaph);
1538d7e4166Sjose borrego
1549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (stat != IDMAP_SUCCESS) {
1559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_check("idmap_get_create", stat);
156da6c28aaSamw return (stat);
1579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
158da6c28aaSamw
159da6c28aaSamw sib->sib_flags = flags;
160da6c28aaSamw sib->sib_nmap = nmap;
161da6c28aaSamw sib->sib_size = nmap * sizeof (smb_idmap_t);
162da6c28aaSamw sib->sib_maps = malloc(sib->sib_size);
163da6c28aaSamw if (!sib->sib_maps)
164da6c28aaSamw return (IDMAP_ERR_MEMORY);
165da6c28aaSamw
166da6c28aaSamw bzero(sib->sib_maps, sib->sib_size);
167da6c28aaSamw return (IDMAP_SUCCESS);
168da6c28aaSamw }
169da6c28aaSamw
170da6c28aaSamw /*
171da6c28aaSamw * smb_idmap_batch_destroy
172da6c28aaSamw *
173da6c28aaSamw * Frees the batch ID mapping context.
174da6c28aaSamw */
175da6c28aaSamw void
smb_idmap_batch_destroy(smb_idmap_batch_t * sib)176da6c28aaSamw smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
177da6c28aaSamw {
178da6c28aaSamw int i;
179da6c28aaSamw
1806537f381Sas200622 if (sib == NULL)
181da6c28aaSamw return;
182da6c28aaSamw
183da6c28aaSamw if (sib->sib_idmaph) {
184da6c28aaSamw idmap_get_destroy(sib->sib_idmaph);
185da6c28aaSamw sib->sib_idmaph = NULL;
186da6c28aaSamw }
187da6c28aaSamw
1886537f381Sas200622 if (sib->sib_maps == NULL)
189da6c28aaSamw return;
190da6c28aaSamw
191dc20a302Sas200622 if (sib->sib_flags & SMB_IDMAP_ID2SID) {
192da6c28aaSamw /*
193da6c28aaSamw * SIDs are allocated only when mapping
194da6c28aaSamw * UID/GID to SIDs
195da6c28aaSamw */
196330db02cSGordon Ross for (i = 0; i < sib->sib_nmap; i++) {
1976537f381Sas200622 smb_sid_free(sib->sib_maps[i].sim_sid);
198330db02cSGordon Ross free(sib->sib_maps[i].sim_domsid);
199330db02cSGordon Ross }
200da6c28aaSamw }
201da6c28aaSamw
202da6c28aaSamw if (sib->sib_size && sib->sib_maps) {
203da6c28aaSamw free(sib->sib_maps);
204da6c28aaSamw sib->sib_maps = NULL;
205da6c28aaSamw }
206da6c28aaSamw }
207da6c28aaSamw
208da6c28aaSamw /*
209da6c28aaSamw * smb_idmap_batch_getid
210da6c28aaSamw *
211da6c28aaSamw * Queue a request to map the given SID to a UID or GID.
212da6c28aaSamw *
213da6c28aaSamw * sim->sim_id should point to variable that's supposed to
214da6c28aaSamw * hold the returned UID/GID. This needs to be setup by caller
215da6c28aaSamw * of this function.
216da6c28aaSamw * If requested ID type is known, it's passed as 'idtype',
217da6c28aaSamw * if it's unknown it'll be returned in sim->sim_idtype.
218da6c28aaSamw */
219da6c28aaSamw idmap_stat
smb_idmap_batch_getid(idmap_get_handle_t * idmaph,smb_idmap_t * sim,smb_sid_t * sid,int idtype)220da6c28aaSamw smb_idmap_batch_getid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
2216537f381Sas200622 smb_sid_t *sid, int idtype)
222da6c28aaSamw {
2236537f381Sas200622 char sidstr[SMB_SID_STRSZ];
224da6c28aaSamw idmap_stat stat;
225da6c28aaSamw int flag = 0;
226da6c28aaSamw
2277f667e74Sjose borrego if (idmaph == NULL || sim == NULL || sid == NULL)
228da6c28aaSamw return (IDMAP_ERR_ARG);
229da6c28aaSamw
230*b819cea2SGordon Ross smb_sid_tostr(sid, sidstr);
231*b819cea2SGordon Ross if (smb_sid_splitstr(sidstr, &sim->sim_rid) != 0)
232*b819cea2SGordon Ross return (IDMAP_ERR_SID);
2336537f381Sas200622 sim->sim_domsid = sidstr;
2349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States sim->sim_idtype = idtype;
235da6c28aaSamw
236da6c28aaSamw switch (idtype) {
237da6c28aaSamw case SMB_IDMAP_USER:
238da6c28aaSamw stat = idmap_get_uidbysid(idmaph, sim->sim_domsid,
239da6c28aaSamw sim->sim_rid, flag, sim->sim_id, &sim->sim_stat);
2409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_check("idmap_get_uidbysid", stat);
241da6c28aaSamw break;
242da6c28aaSamw
243da6c28aaSamw case SMB_IDMAP_GROUP:
244da6c28aaSamw stat = idmap_get_gidbysid(idmaph, sim->sim_domsid,
245da6c28aaSamw sim->sim_rid, flag, sim->sim_id, &sim->sim_stat);
2469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_check("idmap_get_gidbysid", stat);
247da6c28aaSamw break;
248da6c28aaSamw
249da6c28aaSamw case SMB_IDMAP_UNKNOWN:
250da6c28aaSamw stat = idmap_get_pidbysid(idmaph, sim->sim_domsid,
251da6c28aaSamw sim->sim_rid, flag, sim->sim_id, &sim->sim_idtype,
252da6c28aaSamw &sim->sim_stat);
2539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_check("idmap_get_pidbysid", stat);
254da6c28aaSamw break;
255da6c28aaSamw
256da6c28aaSamw default:
257*b819cea2SGordon Ross stat = IDMAP_ERR_ARG;
258*b819cea2SGordon Ross break;
259da6c28aaSamw }
260da6c28aaSamw
261*b819cea2SGordon Ross /* This was copied by idmap_get_Xbysid. */
262*b819cea2SGordon Ross sim->sim_domsid = NULL;
263*b819cea2SGordon Ross
264da6c28aaSamw return (stat);
265da6c28aaSamw }
266da6c28aaSamw
267da6c28aaSamw /*
268da6c28aaSamw * smb_idmap_batch_getsid
269da6c28aaSamw *
270da6c28aaSamw * Queue a request to map the given UID/GID to a SID.
271da6c28aaSamw *
272da6c28aaSamw * sim->sim_domsid and sim->sim_rid will contain the mapping
273da6c28aaSamw * result upon successful process of the batched request.
274*b819cea2SGordon Ross * NB: sim_domsid allocated by strdup, here or in libidmap
275da6c28aaSamw */
276da6c28aaSamw idmap_stat
smb_idmap_batch_getsid(idmap_get_handle_t * idmaph,smb_idmap_t * sim,uid_t id,int idtype)277da6c28aaSamw smb_idmap_batch_getsid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
278da6c28aaSamw uid_t id, int idtype)
279da6c28aaSamw {
280da6c28aaSamw idmap_stat stat;
281da6c28aaSamw int flag = 0;
282da6c28aaSamw
283da6c28aaSamw if (!idmaph || !sim)
284da6c28aaSamw return (IDMAP_ERR_ARG);
285da6c28aaSamw
286da6c28aaSamw switch (idtype) {
287da6c28aaSamw case SMB_IDMAP_USER:
288da6c28aaSamw stat = idmap_get_sidbyuid(idmaph, id, flag,
289da6c28aaSamw &sim->sim_domsid, &sim->sim_rid, &sim->sim_stat);
2909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_check("idmap_get_sidbyuid", stat);
291da6c28aaSamw break;
292da6c28aaSamw
293da6c28aaSamw case SMB_IDMAP_GROUP:
294da6c28aaSamw stat = idmap_get_sidbygid(idmaph, id, flag,
295da6c28aaSamw &sim->sim_domsid, &sim->sim_rid, &sim->sim_stat);
2969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_check("idmap_get_sidbygid", stat);
297da6c28aaSamw break;
298da6c28aaSamw
299f96bd5c8SAlan Wright case SMB_IDMAP_OWNERAT:
300f96bd5c8SAlan Wright /* Current Owner S-1-5-32-766 */
301f96bd5c8SAlan Wright sim->sim_domsid = strdup(NT_BUILTIN_DOMAIN_SIDSTR);
302f96bd5c8SAlan Wright sim->sim_rid = SECURITY_CURRENT_OWNER_RID;
303f96bd5c8SAlan Wright sim->sim_stat = IDMAP_SUCCESS;
304f96bd5c8SAlan Wright stat = IDMAP_SUCCESS;
305f96bd5c8SAlan Wright break;
306f96bd5c8SAlan Wright
307f96bd5c8SAlan Wright case SMB_IDMAP_GROUPAT:
308f96bd5c8SAlan Wright /* Current Group S-1-5-32-767 */
309f96bd5c8SAlan Wright sim->sim_domsid = strdup(NT_BUILTIN_DOMAIN_SIDSTR);
310f96bd5c8SAlan Wright sim->sim_rid = SECURITY_CURRENT_GROUP_RID;
311f96bd5c8SAlan Wright sim->sim_stat = IDMAP_SUCCESS;
312f96bd5c8SAlan Wright stat = IDMAP_SUCCESS;
313f96bd5c8SAlan Wright break;
314f96bd5c8SAlan Wright
315da6c28aaSamw case SMB_IDMAP_EVERYONE:
316da6c28aaSamw /* Everyone S-1-1-0 */
317f96bd5c8SAlan Wright sim->sim_domsid = strdup(NT_WORLD_AUTH_SIDSTR);
318da6c28aaSamw sim->sim_rid = 0;
319da6c28aaSamw sim->sim_stat = IDMAP_SUCCESS;
320da6c28aaSamw stat = IDMAP_SUCCESS;
321da6c28aaSamw break;
322da6c28aaSamw
323da6c28aaSamw default:
324da6c28aaSamw return (IDMAP_ERR_ARG);
325da6c28aaSamw }
326da6c28aaSamw
327da6c28aaSamw return (stat);
328da6c28aaSamw }
329da6c28aaSamw
330da6c28aaSamw /*
331da6c28aaSamw * smb_idmap_batch_getmappings
332da6c28aaSamw *
333da6c28aaSamw * trigger ID mapping service to get the mappings for queued
334da6c28aaSamw * requests.
335da6c28aaSamw *
336da6c28aaSamw * Checks the result of all the queued requests.
337da6c28aaSamw */
338da6c28aaSamw idmap_stat
smb_idmap_batch_getmappings(smb_idmap_batch_t * sib)339da6c28aaSamw smb_idmap_batch_getmappings(smb_idmap_batch_t *sib)
340da6c28aaSamw {
341da6c28aaSamw idmap_stat stat = IDMAP_SUCCESS;
3422c1b14e5Sjose borrego smb_idmap_t *sim;
343da6c28aaSamw int i;
344da6c28aaSamw
3459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((stat = idmap_get_mappings(sib->sib_idmaph)) != IDMAP_SUCCESS) {
3469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_idmap_check("idmap_get_mappings", stat);
347da6c28aaSamw return (stat);
3489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
349da6c28aaSamw
350da6c28aaSamw /*
351da6c28aaSamw * Check the status for all the queued requests
352da6c28aaSamw */
3532c1b14e5Sjose borrego for (i = 0, sim = sib->sib_maps; i < sib->sib_nmap; i++, sim++) {
3542c1b14e5Sjose borrego if (sim->sim_stat != IDMAP_SUCCESS) {
3552c1b14e5Sjose borrego if (sib->sib_flags == SMB_IDMAP_SID2ID) {
35629bd2886SAlan Wright smb_tracef("[%d] %d (%d)", sim->sim_idtype,
3572c1b14e5Sjose borrego sim->sim_rid, sim->sim_stat);
3582c1b14e5Sjose borrego }
3592c1b14e5Sjose borrego return (sim->sim_stat);
360da6c28aaSamw }
361da6c28aaSamw }
362da6c28aaSamw
3632c1b14e5Sjose borrego if (smb_idmap_batch_binsid(sib) != 0)
364da6c28aaSamw stat = IDMAP_ERR_OTHER;
365da6c28aaSamw
366da6c28aaSamw return (stat);
367da6c28aaSamw }
368da6c28aaSamw
369da6c28aaSamw /*
370da6c28aaSamw * smb_idmap_batch_binsid
371da6c28aaSamw *
372da6c28aaSamw * Convert sidrids to binary sids
373da6c28aaSamw *
374da6c28aaSamw * Returns 0 if successful and non-zero upon failure.
375da6c28aaSamw */
376da6c28aaSamw static int
smb_idmap_batch_binsid(smb_idmap_batch_t * sib)377da6c28aaSamw smb_idmap_batch_binsid(smb_idmap_batch_t *sib)
378da6c28aaSamw {
3796537f381Sas200622 smb_sid_t *sid;
380da6c28aaSamw smb_idmap_t *sim;
381da6c28aaSamw int i;
382da6c28aaSamw
383da6c28aaSamw if (sib->sib_flags & SMB_IDMAP_SID2ID)
384da6c28aaSamw /* This operation is not required */
385da6c28aaSamw return (0);
386da6c28aaSamw
387da6c28aaSamw sim = sib->sib_maps;
388da6c28aaSamw for (i = 0; i < sib->sib_nmap; sim++, i++) {
389da6c28aaSamw if (sim->sim_domsid == NULL)
390da6c28aaSamw return (-1);
391da6c28aaSamw
3926537f381Sas200622 sid = smb_sid_fromstr(sim->sim_domsid);
393da6c28aaSamw if (sid == NULL)
394da6c28aaSamw return (-1);
395da6c28aaSamw
3966537f381Sas200622 sim->sim_sid = smb_sid_splice(sid, sim->sim_rid);
397*b819cea2SGordon Ross smb_sid_free(sid);
398da6c28aaSamw }
399da6c28aaSamw
400da6c28aaSamw return (0);
401da6c28aaSamw }
402