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]
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
27 #include <smbsrv/libsmb.h>
29 static int smb_idmap_batch_binsid(smb_idmap_batch_t
*sib
);
32 * Report an idmap error.
35 smb_idmap_check(const char *s
, idmap_stat stat
)
37 if (stat
!= IDMAP_SUCCESS
) {
39 s
= "smb_idmap_check";
41 syslog(LOG_ERR
, "%s: %s", s
, idmap_stat2string(stat
));
48 * Tries to get a mapping for the given uid/gid
51 smb_idmap_getsid(uid_t id
, int idtype
, smb_sid_t
**sid
)
53 smb_idmap_batch_t sib
;
56 stat
= smb_idmap_batch_create(&sib
, 1, SMB_IDMAP_ID2SID
);
57 if (stat
!= IDMAP_SUCCESS
)
60 stat
= smb_idmap_batch_getsid(sib
.sib_idmaph
, &sib
.sib_maps
[0],
63 if (stat
!= IDMAP_SUCCESS
) {
64 smb_idmap_batch_destroy(&sib
);
68 stat
= smb_idmap_batch_getmappings(&sib
);
70 if (stat
!= IDMAP_SUCCESS
) {
71 smb_idmap_batch_destroy(&sib
);
75 *sid
= smb_sid_dup(sib
.sib_maps
[0].sim_sid
);
77 smb_idmap_batch_destroy(&sib
);
79 return (IDMAP_SUCCESS
);
85 * Tries to get a mapping for the given SID
88 smb_idmap_getid(smb_sid_t
*sid
, uid_t
*id
, int *id_type
)
90 smb_idmap_batch_t sib
;
94 stat
= smb_idmap_batch_create(&sib
, 1, SMB_IDMAP_SID2ID
);
95 if (stat
!= IDMAP_SUCCESS
)
98 sim
= &sib
.sib_maps
[0];
100 stat
= smb_idmap_batch_getid(sib
.sib_idmaph
, sim
, sid
, *id_type
);
101 if (stat
!= IDMAP_SUCCESS
) {
102 smb_idmap_batch_destroy(&sib
);
106 stat
= smb_idmap_batch_getmappings(&sib
);
108 if (stat
!= IDMAP_SUCCESS
) {
109 smb_idmap_batch_destroy(&sib
);
113 *id_type
= sim
->sim_idtype
;
114 smb_idmap_batch_destroy(&sib
);
116 return (IDMAP_SUCCESS
);
120 * smb_idmap_batch_create
122 * Creates and initializes the context for batch ID mapping.
125 smb_idmap_batch_create(smb_idmap_batch_t
*sib
, uint16_t nmap
, int flags
)
130 return (IDMAP_ERR_ARG
);
132 bzero(sib
, sizeof (smb_idmap_batch_t
));
133 stat
= idmap_get_create(&sib
->sib_idmaph
);
135 if (stat
!= IDMAP_SUCCESS
) {
136 smb_idmap_check("idmap_get_create", stat
);
140 sib
->sib_flags
= flags
;
141 sib
->sib_nmap
= nmap
;
142 sib
->sib_size
= nmap
* sizeof (smb_idmap_t
);
143 sib
->sib_maps
= malloc(sib
->sib_size
);
145 return (IDMAP_ERR_MEMORY
);
147 bzero(sib
->sib_maps
, sib
->sib_size
);
148 return (IDMAP_SUCCESS
);
152 * smb_idmap_batch_destroy
154 * Frees the batch ID mapping context.
157 smb_idmap_batch_destroy(smb_idmap_batch_t
*sib
)
164 if (sib
->sib_idmaph
) {
165 idmap_get_destroy(sib
->sib_idmaph
);
166 sib
->sib_idmaph
= NULL
;
169 if (sib
->sib_maps
== NULL
)
172 if (sib
->sib_flags
& SMB_IDMAP_ID2SID
) {
174 * SIDs are allocated only when mapping
177 for (i
= 0; i
< sib
->sib_nmap
; i
++)
178 smb_sid_free(sib
->sib_maps
[i
].sim_sid
);
181 if (sib
->sib_size
&& sib
->sib_maps
) {
183 sib
->sib_maps
= NULL
;
188 * smb_idmap_batch_getid
190 * Queue a request to map the given SID to a UID or GID.
192 * sim->sim_id should point to variable that's supposed to
193 * hold the returned UID/GID. This needs to be setup by caller
195 * If requested ID type is known, it's passed as 'idtype',
196 * if it's unknown it'll be returned in sim->sim_idtype.
199 smb_idmap_batch_getid(idmap_get_handle_t
*idmaph
, smb_idmap_t
*sim
,
200 smb_sid_t
*sid
, int idtype
)
202 char sidstr
[SMB_SID_STRSZ
];
207 if (idmaph
== NULL
|| sim
== NULL
|| sid
== NULL
)
208 return (IDMAP_ERR_ARG
);
210 if ((tmpsid
= smb_sid_split(sid
, &sim
->sim_rid
)) == NULL
)
211 return (IDMAP_ERR_MEMORY
);
213 smb_sid_tostr(tmpsid
, sidstr
);
214 sim
->sim_domsid
= sidstr
;
215 sim
->sim_idtype
= idtype
;
216 smb_sid_free(tmpsid
);
220 stat
= idmap_get_uidbysid(idmaph
, sim
->sim_domsid
,
221 sim
->sim_rid
, flag
, sim
->sim_id
, &sim
->sim_stat
);
222 smb_idmap_check("idmap_get_uidbysid", stat
);
225 case SMB_IDMAP_GROUP
:
226 stat
= idmap_get_gidbysid(idmaph
, sim
->sim_domsid
,
227 sim
->sim_rid
, flag
, sim
->sim_id
, &sim
->sim_stat
);
228 smb_idmap_check("idmap_get_gidbysid", stat
);
231 case SMB_IDMAP_UNKNOWN
:
232 stat
= idmap_get_pidbysid(idmaph
, sim
->sim_domsid
,
233 sim
->sim_rid
, flag
, sim
->sim_id
, &sim
->sim_idtype
,
235 smb_idmap_check("idmap_get_pidbysid", stat
);
239 return (IDMAP_ERR_ARG
);
246 * smb_idmap_batch_getsid
248 * Queue a request to map the given UID/GID to a SID.
250 * sim->sim_domsid and sim->sim_rid will contain the mapping
251 * result upon successful process of the batched request.
254 smb_idmap_batch_getsid(idmap_get_handle_t
*idmaph
, smb_idmap_t
*sim
,
255 uid_t id
, int idtype
)
261 return (IDMAP_ERR_ARG
);
265 stat
= idmap_get_sidbyuid(idmaph
, id
, flag
,
266 &sim
->sim_domsid
, &sim
->sim_rid
, &sim
->sim_stat
);
267 smb_idmap_check("idmap_get_sidbyuid", stat
);
270 case SMB_IDMAP_GROUP
:
271 stat
= idmap_get_sidbygid(idmaph
, id
, flag
,
272 &sim
->sim_domsid
, &sim
->sim_rid
, &sim
->sim_stat
);
273 smb_idmap_check("idmap_get_sidbygid", stat
);
276 case SMB_IDMAP_OWNERAT
:
277 /* Current Owner S-1-5-32-766 */
278 sim
->sim_domsid
= strdup(NT_BUILTIN_DOMAIN_SIDSTR
);
279 sim
->sim_rid
= SECURITY_CURRENT_OWNER_RID
;
280 sim
->sim_stat
= IDMAP_SUCCESS
;
281 stat
= IDMAP_SUCCESS
;
284 case SMB_IDMAP_GROUPAT
:
285 /* Current Group S-1-5-32-767 */
286 sim
->sim_domsid
= strdup(NT_BUILTIN_DOMAIN_SIDSTR
);
287 sim
->sim_rid
= SECURITY_CURRENT_GROUP_RID
;
288 sim
->sim_stat
= IDMAP_SUCCESS
;
289 stat
= IDMAP_SUCCESS
;
292 case SMB_IDMAP_EVERYONE
:
293 /* Everyone S-1-1-0 */
294 sim
->sim_domsid
= strdup(NT_WORLD_AUTH_SIDSTR
);
296 sim
->sim_stat
= IDMAP_SUCCESS
;
297 stat
= IDMAP_SUCCESS
;
301 return (IDMAP_ERR_ARG
);
308 * smb_idmap_batch_getmappings
310 * trigger ID mapping service to get the mappings for queued
313 * Checks the result of all the queued requests.
316 smb_idmap_batch_getmappings(smb_idmap_batch_t
*sib
)
318 idmap_stat stat
= IDMAP_SUCCESS
;
322 if ((stat
= idmap_get_mappings(sib
->sib_idmaph
)) != IDMAP_SUCCESS
) {
323 smb_idmap_check("idmap_get_mappings", stat
);
328 * Check the status for all the queued requests
330 for (i
= 0, sim
= sib
->sib_maps
; i
< sib
->sib_nmap
; i
++, sim
++) {
331 if (sim
->sim_stat
!= IDMAP_SUCCESS
) {
332 if (sib
->sib_flags
== SMB_IDMAP_SID2ID
) {
333 smb_tracef("[%d] %d (%d)", sim
->sim_idtype
,
334 sim
->sim_rid
, sim
->sim_stat
);
336 return (sim
->sim_stat
);
340 if (smb_idmap_batch_binsid(sib
) != 0)
341 stat
= IDMAP_ERR_OTHER
;
347 * smb_idmap_batch_binsid
349 * Convert sidrids to binary sids
351 * Returns 0 if successful and non-zero upon failure.
354 smb_idmap_batch_binsid(smb_idmap_batch_t
*sib
)
360 if (sib
->sib_flags
& SMB_IDMAP_SID2ID
)
361 /* This operation is not required */
365 for (i
= 0; i
< sib
->sib_nmap
; sim
++, i
++) {
366 if (sim
->sim_domsid
== NULL
)
369 sid
= smb_sid_fromstr(sim
->sim_domsid
);
370 free(sim
->sim_domsid
);
374 sim
->sim_sid
= smb_sid_splice(sid
, sim
->sim_rid
);