dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / smbsrv / libsmb / common / smb_idmap.c
blob232ddaba65099340106316c7fb75d77dd4a3dffc
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
27 * SMB server interface to idmap
28 * (smb_idmap_get..., smb_idmap_batch_...)
30 * There are two implementations of this interface:
31 * uts/common/fs/smbsrv/smb_idmap.c (smbsrv kmod)
32 * lib/smbsrv/libsmb/common/smb_idmap.c (libsmb)
34 * There are enough differences (relative to the code size)
35 * that it's more trouble than it's worth to merge them.
37 * This one differs from the others in that it:
38 * calls idmap interfaces (libidmap)
39 * domain SIDs returned are allocated
42 #include <syslog.h>
43 #include <strings.h>
44 #include <smbsrv/libsmb.h>
46 static int smb_idmap_batch_binsid(smb_idmap_batch_t *sib);
49 * Report an idmap error.
51 void
52 smb_idmap_check(const char *s, idmap_stat stat)
54 if (stat != IDMAP_SUCCESS) {
55 if (s == NULL)
56 s = "smb_idmap_check";
58 syslog(LOG_ERR, "%s: %s", s, idmap_stat2string(stat));
63 * smb_idmap_getsid
65 * Tries to get a mapping for the given uid/gid
66 * Allocates ->sim_domsid
68 idmap_stat
69 smb_idmap_getsid(uid_t id, int idtype, smb_sid_t **sid)
71 smb_idmap_batch_t sib;
72 idmap_stat stat;
74 stat = smb_idmap_batch_create(&sib, 1, SMB_IDMAP_ID2SID);
75 if (stat != IDMAP_SUCCESS)
76 return (stat);
78 stat = smb_idmap_batch_getsid(sib.sib_idmaph, &sib.sib_maps[0],
79 id, idtype);
81 if (stat != IDMAP_SUCCESS) {
82 smb_idmap_batch_destroy(&sib);
83 return (stat);
86 stat = smb_idmap_batch_getmappings(&sib);
88 if (stat != IDMAP_SUCCESS) {
89 smb_idmap_batch_destroy(&sib);
90 return (stat);
93 *sid = smb_sid_dup(sib.sib_maps[0].sim_sid);
95 smb_idmap_batch_destroy(&sib);
97 return (IDMAP_SUCCESS);
101 * smb_idmap_getid
103 * Tries to get a mapping for the given SID
105 idmap_stat
106 smb_idmap_getid(smb_sid_t *sid, uid_t *id, int *id_type)
108 smb_idmap_batch_t sib;
109 smb_idmap_t *sim;
110 idmap_stat stat;
112 stat = smb_idmap_batch_create(&sib, 1, SMB_IDMAP_SID2ID);
113 if (stat != IDMAP_SUCCESS)
114 return (stat);
116 sim = &sib.sib_maps[0];
117 sim->sim_id = id;
118 stat = smb_idmap_batch_getid(sib.sib_idmaph, sim, sid, *id_type);
119 if (stat != IDMAP_SUCCESS) {
120 smb_idmap_batch_destroy(&sib);
121 return (stat);
124 stat = smb_idmap_batch_getmappings(&sib);
126 if (stat != IDMAP_SUCCESS) {
127 smb_idmap_batch_destroy(&sib);
128 return (stat);
131 *id_type = sim->sim_idtype;
132 smb_idmap_batch_destroy(&sib);
134 return (IDMAP_SUCCESS);
138 * smb_idmap_batch_create
140 * Creates and initializes the context for batch ID mapping.
142 idmap_stat
143 smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags)
145 idmap_stat stat;
147 if (!sib)
148 return (IDMAP_ERR_ARG);
150 bzero(sib, sizeof (smb_idmap_batch_t));
151 stat = idmap_get_create(&sib->sib_idmaph);
153 if (stat != IDMAP_SUCCESS) {
154 smb_idmap_check("idmap_get_create", stat);
155 return (stat);
158 sib->sib_flags = flags;
159 sib->sib_nmap = nmap;
160 sib->sib_size = nmap * sizeof (smb_idmap_t);
161 sib->sib_maps = malloc(sib->sib_size);
162 if (!sib->sib_maps)
163 return (IDMAP_ERR_MEMORY);
165 bzero(sib->sib_maps, sib->sib_size);
166 return (IDMAP_SUCCESS);
170 * smb_idmap_batch_destroy
172 * Frees the batch ID mapping context.
174 void
175 smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
177 int i;
179 if (sib == NULL)
180 return;
182 if (sib->sib_idmaph) {
183 idmap_get_destroy(sib->sib_idmaph);
184 sib->sib_idmaph = NULL;
187 if (sib->sib_maps == NULL)
188 return;
190 if (sib->sib_flags & SMB_IDMAP_ID2SID) {
192 * SIDs are allocated only when mapping
193 * UID/GID to SIDs
195 for (i = 0; i < sib->sib_nmap; i++) {
196 smb_sid_free(sib->sib_maps[i].sim_sid);
197 free(sib->sib_maps[i].sim_domsid);
201 if (sib->sib_size && sib->sib_maps) {
202 free(sib->sib_maps);
203 sib->sib_maps = NULL;
208 * smb_idmap_batch_getid
210 * Queue a request to map the given SID to a UID or GID.
212 * sim->sim_id should point to variable that's supposed to
213 * hold the returned UID/GID. This needs to be setup by caller
214 * of this function.
215 * If requested ID type is known, it's passed as 'idtype',
216 * if it's unknown it'll be returned in sim->sim_idtype.
218 idmap_stat
219 smb_idmap_batch_getid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
220 smb_sid_t *sid, int idtype)
222 char sidstr[SMB_SID_STRSZ];
223 idmap_stat stat;
224 int flag = 0;
226 if (idmaph == NULL || sim == NULL || sid == NULL)
227 return (IDMAP_ERR_ARG);
229 smb_sid_tostr(sid, sidstr);
230 if (smb_sid_splitstr(sidstr, &sim->sim_rid) != 0)
231 return (IDMAP_ERR_SID);
232 sim->sim_domsid = sidstr;
233 sim->sim_idtype = idtype;
235 switch (idtype) {
236 case SMB_IDMAP_USER:
237 stat = idmap_get_uidbysid(idmaph, sim->sim_domsid,
238 sim->sim_rid, flag, sim->sim_id, &sim->sim_stat);
239 smb_idmap_check("idmap_get_uidbysid", stat);
240 break;
242 case SMB_IDMAP_GROUP:
243 stat = idmap_get_gidbysid(idmaph, sim->sim_domsid,
244 sim->sim_rid, flag, sim->sim_id, &sim->sim_stat);
245 smb_idmap_check("idmap_get_gidbysid", stat);
246 break;
248 case SMB_IDMAP_UNKNOWN:
249 stat = idmap_get_pidbysid(idmaph, sim->sim_domsid,
250 sim->sim_rid, flag, sim->sim_id, &sim->sim_idtype,
251 &sim->sim_stat);
252 smb_idmap_check("idmap_get_pidbysid", stat);
253 break;
255 default:
256 stat = IDMAP_ERR_ARG;
257 break;
260 /* This was copied by idmap_get_Xbysid. */
261 sim->sim_domsid = NULL;
263 return (stat);
267 * smb_idmap_batch_getsid
269 * Queue a request to map the given UID/GID to a SID.
271 * sim->sim_domsid and sim->sim_rid will contain the mapping
272 * result upon successful process of the batched request.
273 * NB: sim_domsid allocated by strdup, here or in libidmap
275 idmap_stat
276 smb_idmap_batch_getsid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
277 uid_t id, int idtype)
279 idmap_stat stat;
280 int flag = 0;
282 if (!idmaph || !sim)
283 return (IDMAP_ERR_ARG);
285 switch (idtype) {
286 case SMB_IDMAP_USER:
287 stat = idmap_get_sidbyuid(idmaph, id, flag,
288 &sim->sim_domsid, &sim->sim_rid, &sim->sim_stat);
289 smb_idmap_check("idmap_get_sidbyuid", stat);
290 break;
292 case SMB_IDMAP_GROUP:
293 stat = idmap_get_sidbygid(idmaph, id, flag,
294 &sim->sim_domsid, &sim->sim_rid, &sim->sim_stat);
295 smb_idmap_check("idmap_get_sidbygid", stat);
296 break;
298 case SMB_IDMAP_OWNERAT:
299 /* Current Owner S-1-5-32-766 */
300 sim->sim_domsid = strdup(NT_BUILTIN_DOMAIN_SIDSTR);
301 sim->sim_rid = SECURITY_CURRENT_OWNER_RID;
302 sim->sim_stat = IDMAP_SUCCESS;
303 stat = IDMAP_SUCCESS;
304 break;
306 case SMB_IDMAP_GROUPAT:
307 /* Current Group S-1-5-32-767 */
308 sim->sim_domsid = strdup(NT_BUILTIN_DOMAIN_SIDSTR);
309 sim->sim_rid = SECURITY_CURRENT_GROUP_RID;
310 sim->sim_stat = IDMAP_SUCCESS;
311 stat = IDMAP_SUCCESS;
312 break;
314 case SMB_IDMAP_EVERYONE:
315 /* Everyone S-1-1-0 */
316 sim->sim_domsid = strdup(NT_WORLD_AUTH_SIDSTR);
317 sim->sim_rid = 0;
318 sim->sim_stat = IDMAP_SUCCESS;
319 stat = IDMAP_SUCCESS;
320 break;
322 default:
323 return (IDMAP_ERR_ARG);
326 return (stat);
330 * smb_idmap_batch_getmappings
332 * trigger ID mapping service to get the mappings for queued
333 * requests.
335 * Checks the result of all the queued requests.
337 idmap_stat
338 smb_idmap_batch_getmappings(smb_idmap_batch_t *sib)
340 idmap_stat stat = IDMAP_SUCCESS;
341 smb_idmap_t *sim;
342 int i;
344 if ((stat = idmap_get_mappings(sib->sib_idmaph)) != IDMAP_SUCCESS) {
345 smb_idmap_check("idmap_get_mappings", stat);
346 return (stat);
350 * Check the status for all the queued requests
352 for (i = 0, sim = sib->sib_maps; i < sib->sib_nmap; i++, sim++) {
353 if (sim->sim_stat != IDMAP_SUCCESS) {
354 if (sib->sib_flags == SMB_IDMAP_SID2ID) {
355 smb_tracef("[%d] %d (%d)", sim->sim_idtype,
356 sim->sim_rid, sim->sim_stat);
358 return (sim->sim_stat);
362 if (smb_idmap_batch_binsid(sib) != 0)
363 stat = IDMAP_ERR_OTHER;
365 return (stat);
369 * smb_idmap_batch_binsid
371 * Convert sidrids to binary sids
373 * Returns 0 if successful and non-zero upon failure.
375 static int
376 smb_idmap_batch_binsid(smb_idmap_batch_t *sib)
378 smb_sid_t *sid;
379 smb_idmap_t *sim;
380 int i;
382 if (sib->sib_flags & SMB_IDMAP_SID2ID)
383 /* This operation is not required */
384 return (0);
386 sim = sib->sib_maps;
387 for (i = 0; i < sib->sib_nmap; sim++, i++) {
388 if (sim->sim_domsid == NULL)
389 return (-1);
391 sid = smb_sid_fromstr(sim->sim_domsid);
392 if (sid == NULL)
393 return (-1);
395 sim->sim_sid = smb_sid_splice(sid, sim->sim_rid);
396 smb_sid_free(sid);
399 return (0);