3  *
   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.
   7  *
   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.
  12  *
  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]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 
  26 /*
  27  * SMB server interface to idmap
  28  * (smb_idmap_get..., smb_idmap_batch_...)
  29  *
  30  * There are three implementations of this interface:
  31  *      uts/common/fs/smbsrv/smb_idmap.c (smbsrv kmod)
  32  *      lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c (libfksmbsrv)
  33  *      lib/smbsrv/libsmb/common/smb_idmap.c (libsmb)
  34  *
  35  * There are enough differences (relative to the code size)
  36  * that it's more trouble than it's worth to merge them.
  37  *
  38  * This one differs from the others in that it:
  39  *      calls kernel (kidmap_...) interfaces
  40  *      domain SIDs are shared, not strdup'ed
  41  */
  42 
  43 /*
  44  * SMB ID mapping
  45  *
  46  * Solaris ID mapping service (aka Winchester) works with domain SIDs
  47  * and RIDs where domain SIDs are in string format. CIFS service works
  48  * with binary SIDs understandable by CIFS clients. A layer of SMB ID
  49  * mapping functions are implemeted to hide the SID conversion details
  50  * and also hide the handling of array of batch mapping requests.
  51  */
  52 
  53 #include <sys/param.h>
  54 #include <sys/types.h>
  55 #include <sys/tzfile.h>
  56 #include <sys/atomic.h>
  57 #include <sys/kidmap.h>
  58 #include <sys/time.h>
  59 #include <sys/spl.h>
  60 #include <sys/random.h>
 
 
  87                     (const char **)&sim.sim_domsid, &sim.sim_rid);
  88                 break;
  89 
  90         case SMB_IDMAP_GROUP:
  91                 sim.sim_stat = kidmap_getsidbygid(global_zone, id,
  92                     (const char **)&sim.sim_domsid, &sim.sim_rid);
  93                 break;
  94 
  95         case SMB_IDMAP_EVERYONE:
  96                 /* Everyone S-1-1-0 */
  97                 sim.sim_domsid = "S-1-1";
  98                 sim.sim_rid = 0;
  99                 sim.sim_stat = IDMAP_SUCCESS;
 100                 break;
 101 
 102         default:
 103                 ASSERT(0);
 104                 return (IDMAP_ERR_ARG);
 105         }
 106 
 107         if (sim.sim_stat != IDMAP_SUCCESS)
 108                 return (sim.sim_stat);
 109 
 110         if (sim.sim_domsid == NULL)
 111                 return (IDMAP_ERR_NOMAPPING);
 112 
 113         sim.sim_sid = smb_sid_fromstr(sim.sim_domsid);
 114         if (sim.sim_sid == NULL)
 115                 return (IDMAP_ERR_INTERNAL);
 116 
 117         *sid = smb_sid_splice(sim.sim_sid, sim.sim_rid);
 118         smb_sid_free(sim.sim_sid);
 119         if (*sid == NULL)
 120                 sim.sim_stat = IDMAP_ERR_INTERNAL;
 121 
 122         return (sim.sim_stat);
 123 }
 124 
 125 /*
 126  * smb_idmap_getid
 
 
 157                 break;
 158 
 159         default:
 160                 ASSERT(0);
 161                 return (IDMAP_ERR_ARG);
 162         }
 163 
 164         *idtype = sim.sim_idtype;
 165 
 166         return (sim.sim_stat);
 167 }
 168 
 169 /*
 170  * smb_idmap_batch_create
 171  *
 172  * Creates and initializes the context for batch ID mapping.
 173  */
 174 idmap_stat
 175 smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags)
 176 {
 177         ASSERT(sib);
 178 
 179         bzero(sib, sizeof (smb_idmap_batch_t));
 180 
 181         sib->sib_idmaph = kidmap_get_create(global_zone);
 182 
 183         sib->sib_flags = flags;
 184         sib->sib_nmap = nmap;
 185         sib->sib_size = nmap * sizeof (smb_idmap_t);
 186         sib->sib_maps = kmem_zalloc(sib->sib_size, KM_SLEEP);
 187 
 188         return (IDMAP_SUCCESS);
 189 }
 190 
 191 /*
 192  * smb_idmap_batch_destroy
 193  *
 194  * Frees the batch ID mapping context.
 195  * If ID mapping is Solaris -> Windows it frees memories
 196  * allocated for binary SIDs.
 197  */
 198 void
 199 smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
 200 {
 201         char *domsid;
 202         int i;
 203 
 204         ASSERT(sib);
 205         ASSERT(sib->sib_maps);
 206 
 207         if (sib->sib_idmaph)
 208                 kidmap_get_destroy(sib->sib_idmaph);
 209 
 210         if (sib->sib_flags & SMB_IDMAP_ID2SID) {
 211                 /*
 212                  * SIDs are allocated only when mapping
 213                  * UID/GID to SIDs
 214                  */
 215                 for (i = 0; i < sib->sib_nmap; i++)
 216                         smb_sid_free(sib->sib_maps[i].sim_sid);
 217         } else if (sib->sib_flags & SMB_IDMAP_SID2ID) {
 218                 /*
 219                  * SID prefixes are allocated only when mapping
 220                  * SIDs to UID/GID
 221                  */
 222                 for (i = 0; i < sib->sib_nmap; i++) {
 223                         domsid = sib->sib_maps[i].sim_domsid;
 224                         if (domsid)
 225                                 smb_mem_free(domsid);
 226                 }
 227         }
 228 
 229         if (sib->sib_size && sib->sib_maps)
 230                 kmem_free(sib->sib_maps, sib->sib_size);
 231 }
 232 
 233 /*
 234  * smb_idmap_batch_getid
 235  *
 236  * Queue a request to map the given SID to a UID or GID.
 237  *
 238  * sim->sim_id should point to variable that's supposed to
 239  * hold the returned UID/GID. This needs to be setup by caller
 240  * of this function.
 241  *
 242  * If requested ID type is known, it's passed as 'idtype',
 243  * if it's unknown it'll be returned in sim->sim_idtype.
 244  */
 245 idmap_stat
 246 smb_idmap_batch_getid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
 247     smb_sid_t *sid, int idtype)
 248 {
 249         char strsid[SMB_SID_STRSZ];
 250         idmap_stat idm_stat;
 251 
 252         ASSERT(idmaph);
 253         ASSERT(sim);
 254         ASSERT(sid);
 255 
 256         smb_sid_tostr(sid, strsid);
 257         if (smb_sid_splitstr(strsid, &sim->sim_rid) != 0)
 258                 return (IDMAP_ERR_SID);
 259         sim->sim_domsid = smb_mem_strdup(strsid);
 260 
 261         switch (idtype) {
 262         case SMB_IDMAP_USER:
 263                 idm_stat = kidmap_batch_getuidbysid(idmaph, sim->sim_domsid,
 264                     sim->sim_rid, sim->sim_id, &sim->sim_stat);
 265                 break;
 266 
 267         case SMB_IDMAP_GROUP:
 268                 idm_stat = kidmap_batch_getgidbysid(idmaph, sim->sim_domsid,
 269                     sim->sim_rid, sim->sim_id, &sim->sim_stat);
 270                 break;
 271 
 272         case SMB_IDMAP_UNKNOWN:
 273                 idm_stat = kidmap_batch_getpidbysid(idmaph, sim->sim_domsid,
 274                     sim->sim_rid, sim->sim_id, &sim->sim_idtype,
 275                     &sim->sim_stat);
 276                 break;
 277 
 278         default:
 279                 ASSERT(0);
 280                 return (IDMAP_ERR_ARG);
 281         }
 282 
 283         return (idm_stat);
 284 }
 285 
 286 /*
 287  * smb_idmap_batch_getsid
 288  *
 289  * Queue a request to map the given UID/GID to a SID.
 290  *
 291  * sim->sim_domsid and sim->sim_rid will contain the mapping
 292  * result upon successful process of the batched request.
 293  */
 294 idmap_stat
 295 smb_idmap_batch_getsid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
 296     uid_t id, int idtype)
 297 {
 298         idmap_stat idm_stat;
 299 
 300         switch (idtype) {
 301         case SMB_IDMAP_USER:
 302                 idm_stat = kidmap_batch_getsidbyuid(idmaph, id,
 303                     (const char **)&sim->sim_domsid, &sim->sim_rid,
 304                     &sim->sim_stat);
 305                 break;
 306 
 307         case SMB_IDMAP_GROUP:
 308                 idm_stat = kidmap_batch_getsidbygid(idmaph, id,
 309                     (const char **)&sim->sim_domsid, &sim->sim_rid,
 310                     &sim->sim_stat);
 311                 break;
 312 
 313         case SMB_IDMAP_OWNERAT:
 314                 /* Current Owner S-1-5-32-766 */
 315                 sim->sim_domsid = NT_BUILTIN_DOMAIN_SIDSTR;
 316                 sim->sim_rid = SECURITY_CURRENT_OWNER_RID;
 317                 sim->sim_stat = IDMAP_SUCCESS;
 318                 idm_stat = IDMAP_SUCCESS;
 319                 break;
 
 325                 sim->sim_stat = IDMAP_SUCCESS;
 326                 idm_stat = IDMAP_SUCCESS;
 327                 break;
 328 
 329         case SMB_IDMAP_EVERYONE:
 330                 /* Everyone S-1-1-0 */
 331                 sim->sim_domsid = NT_WORLD_AUTH_SIDSTR;
 332                 sim->sim_rid = 0;
 333                 sim->sim_stat = IDMAP_SUCCESS;
 334                 idm_stat = IDMAP_SUCCESS;
 335                 break;
 336 
 337         default:
 338                 ASSERT(0);
 339                 return (IDMAP_ERR_ARG);
 340         }
 341 
 342         return (idm_stat);
 343 }
 344 
 345 /*
 346  * smb_idmap_batch_getmappings
 347  *
 348  * trigger ID mapping service to get the mappings for queued
 349  * requests.
 350  *
 351  * Checks the result of all the queued requests.
 352  * If this is a Solaris -> Windows mapping it generates
 353  * binary SIDs from returned (domsid, rid) pairs.
 354  */
 355 idmap_stat
 356 smb_idmap_batch_getmappings(smb_idmap_batch_t *sib)
 357 {
 358         idmap_stat idm_stat = IDMAP_SUCCESS;
 359         int i;
 360 
 361         idm_stat = kidmap_get_mappings(sib->sib_idmaph);
 362         if (idm_stat != IDMAP_SUCCESS)
 363                 return (idm_stat);
 364 
 365         /*
 366          * Check the status for all the queued requests
 367          */
 368         for (i = 0; i < sib->sib_nmap; i++) {
 369                 if (sib->sib_maps[i].sim_stat != IDMAP_SUCCESS)
 370                         return (sib->sib_maps[i].sim_stat);
 371         }
 372 
 373         if (smb_idmap_batch_binsid(sib) != 0)
 374                 idm_stat = IDMAP_ERR_OTHER;
 375 
 376         return (idm_stat);
 377 }
 378 
 379 /*
 380  * smb_idmap_batch_binsid
 381  *
 382  * Convert sidrids to binary sids
 383  *
 384  * Returns 0 if successful and non-zero upon failure.
 385  */
 386 static int
 387 smb_idmap_batch_binsid(smb_idmap_batch_t *sib)
 388 {
 389         smb_sid_t *sid;
 390         smb_idmap_t *sim;
 391         int i;
 392 
 393         if (sib->sib_flags & SMB_IDMAP_SID2ID)
 394                 /* This operation is not required */
 395                 return (0);
 396 
 397         sim = sib->sib_maps;
 398         for (i = 0; i < sib->sib_nmap; sim++, i++) {
 399                 ASSERT(sim->sim_domsid);
 400                 if (sim->sim_domsid == NULL)
 401                         return (1);
 402 
 403                 if ((sid = smb_sid_fromstr(sim->sim_domsid)) == NULL)
 404                         return (1);
 405 
 406                 sim->sim_sid = smb_sid_splice(sid, sim->sim_rid);
 407                 smb_sid_free(sid);
 408         }
 409 
 410         return (0);
 411 }
 | 
 
 
   3  *
   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.
   7  *
   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.
  12  *
  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]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  24  */
  25 
  26 /*
  27  * SMB server interface to idmap
  28  * (smb_idmap_get..., smb_idmap_batch_...)
  29  *
  30  * There are three implementations of this interface.
  31  * This is the kernel version of these routines.  See also:
  32  * $SRC/lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c
  33  * $SRC/lib/smbsrv/libsmb/common/smb_idmap.c
  34  *
  35  * There are enough differences (relative to the code size)
  36  * that it's more trouble than it's worth to merge them.
  37  *
  38  * This one differs from the others in that it:
  39  *      calls kernel (kidmap_...) interfaces
  40  *      returned domain SIDs are shared, not strdup'ed
  41  */
  42 
  43 /*
  44  * SMB ID mapping
  45  *
  46  * Solaris ID mapping service (aka Winchester) works with domain SIDs
  47  * and RIDs where domain SIDs are in string format. CIFS service works
  48  * with binary SIDs understandable by CIFS clients. A layer of SMB ID
  49  * mapping functions are implemeted to hide the SID conversion details
  50  * and also hide the handling of array of batch mapping requests.
  51  */
  52 
  53 #include <sys/param.h>
  54 #include <sys/types.h>
  55 #include <sys/tzfile.h>
  56 #include <sys/atomic.h>
  57 #include <sys/kidmap.h>
  58 #include <sys/time.h>
  59 #include <sys/spl.h>
  60 #include <sys/random.h>
 
 
  87                     (const char **)&sim.sim_domsid, &sim.sim_rid);
  88                 break;
  89 
  90         case SMB_IDMAP_GROUP:
  91                 sim.sim_stat = kidmap_getsidbygid(global_zone, id,
  92                     (const char **)&sim.sim_domsid, &sim.sim_rid);
  93                 break;
  94 
  95         case SMB_IDMAP_EVERYONE:
  96                 /* Everyone S-1-1-0 */
  97                 sim.sim_domsid = "S-1-1";
  98                 sim.sim_rid = 0;
  99                 sim.sim_stat = IDMAP_SUCCESS;
 100                 break;
 101 
 102         default:
 103                 ASSERT(0);
 104                 return (IDMAP_ERR_ARG);
 105         }
 106 
 107         /*
 108          * IDMAP_ERR_NOTFOUND is an advisory error
 109          * and idmap will generate a local sid.
 110          */
 111         if (sim.sim_stat == IDMAP_ERR_NOTFOUND &&
 112             sim.sim_domsid != NULL)
 113                 sim.sim_stat = IDMAP_SUCCESS;
 114 
 115         if (sim.sim_stat != IDMAP_SUCCESS)
 116                 return (sim.sim_stat);
 117 
 118         if (sim.sim_domsid == NULL)
 119                 return (IDMAP_ERR_NOMAPPING);
 120 
 121         sim.sim_sid = smb_sid_fromstr(sim.sim_domsid);
 122         if (sim.sim_sid == NULL)
 123                 return (IDMAP_ERR_INTERNAL);
 124 
 125         *sid = smb_sid_splice(sim.sim_sid, sim.sim_rid);
 126         smb_sid_free(sim.sim_sid);
 127         if (*sid == NULL)
 128                 sim.sim_stat = IDMAP_ERR_INTERNAL;
 129 
 130         return (sim.sim_stat);
 131 }
 132 
 133 /*
 134  * smb_idmap_getid
 
 
 165                 break;
 166 
 167         default:
 168                 ASSERT(0);
 169                 return (IDMAP_ERR_ARG);
 170         }
 171 
 172         *idtype = sim.sim_idtype;
 173 
 174         return (sim.sim_stat);
 175 }
 176 
 177 /*
 178  * smb_idmap_batch_create
 179  *
 180  * Creates and initializes the context for batch ID mapping.
 181  */
 182 idmap_stat
 183 smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags)
 184 {
 185         ASSERT(sib != NULL);
 186 
 187         bzero(sib, sizeof (smb_idmap_batch_t));
 188 
 189         sib->sib_idmaph = kidmap_get_create(global_zone);
 190 
 191         sib->sib_flags = flags;
 192         sib->sib_nmap = nmap;
 193         sib->sib_size = nmap * sizeof (smb_idmap_t);
 194         sib->sib_maps = kmem_zalloc(sib->sib_size, KM_SLEEP);
 195 
 196         return (IDMAP_SUCCESS);
 197 }
 198 
 199 /*
 200  * smb_idmap_batch_destroy
 201  *
 202  * Frees the batch ID mapping context.
 203  * If ID mapping is Solaris -> Windows it frees memories
 204  * allocated for binary SIDs.
 205  */
 206 void
 207 smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
 208 {
 209         char *domsid;
 210         int i;
 211 
 212         ASSERT(sib != NULL);
 213         ASSERT(sib->sib_maps != NULL);
 214 
 215         if (sib->sib_idmaph) {
 216                 kidmap_get_destroy(sib->sib_idmaph);
 217                 sib->sib_idmaph = NULL;
 218         }
 219 
 220         if (sib->sib_flags & SMB_IDMAP_ID2SID) {
 221                 /*
 222                  * SIDs are allocated only when mapping
 223                  * UID/GID to SIDs
 224                  */
 225                 for (i = 0; i < sib->sib_nmap; i++)
 226                         smb_sid_free(sib->sib_maps[i].sim_sid);
 227         } else if (sib->sib_flags & SMB_IDMAP_SID2ID) {
 228                 /*
 229                  * SID prefixes are allocated only when mapping
 230                  * SIDs to UID/GID
 231                  */
 232                 for (i = 0; i < sib->sib_nmap; i++) {
 233                         domsid = sib->sib_maps[i].sim_domsid;
 234                         if (domsid)
 235                                 smb_mem_free(domsid);
 236                 }
 237         }
 238 
 239         if (sib->sib_size && sib->sib_maps) {
 240                 kmem_free(sib->sib_maps, sib->sib_size);
 241                 sib->sib_maps = NULL;
 242         }
 243 }
 244 
 245 /*
 246  * smb_idmap_batch_getid
 247  *
 248  * Queue a request to map the given SID to a UID or GID.
 249  *
 250  * sim->sim_id should point to variable that's supposed to
 251  * hold the returned UID/GID. This needs to be setup by caller
 252  * of this function.
 253  *
 254  * If requested ID type is known, it's passed as 'idtype',
 255  * if it's unknown it'll be returned in sim->sim_idtype.
 256  */
 257 idmap_stat
 258 smb_idmap_batch_getid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
 259     smb_sid_t *sid, int idtype)
 260 {
 261         char strsid[SMB_SID_STRSZ];
 262         idmap_stat idm_stat;
 263 
 264         ASSERT(idmaph != NULL);
 265         ASSERT(sim != NULL);
 266         ASSERT(sid != NULL);
 267 
 268         smb_sid_tostr(sid, strsid);
 269         if (smb_sid_splitstr(strsid, &sim->sim_rid) != 0)
 270                 return (IDMAP_ERR_SID);
 271         /* Note: Free sim_domsid in smb_idmap_batch_destroy */
 272         sim->sim_domsid = smb_mem_strdup(strsid);
 273         sim->sim_idtype = idtype;
 274 
 275         switch (idtype) {
 276         case SMB_IDMAP_USER:
 277                 idm_stat = kidmap_batch_getuidbysid(idmaph, sim->sim_domsid,
 278                     sim->sim_rid, sim->sim_id, &sim->sim_stat);
 279                 break;
 280 
 281         case SMB_IDMAP_GROUP:
 282                 idm_stat = kidmap_batch_getgidbysid(idmaph, sim->sim_domsid,
 283                     sim->sim_rid, sim->sim_id, &sim->sim_stat);
 284                 break;
 285 
 286         case SMB_IDMAP_UNKNOWN:
 287                 idm_stat = kidmap_batch_getpidbysid(idmaph, sim->sim_domsid,
 288                     sim->sim_rid, sim->sim_id, &sim->sim_idtype,
 289                     &sim->sim_stat);
 290                 break;
 291 
 292         default:
 293                 ASSERT(0);
 294                 return (IDMAP_ERR_ARG);
 295         }
 296 
 297         return (idm_stat);
 298 }
 299 
 300 /*
 301  * smb_idmap_batch_getsid
 302  *
 303  * Queue a request to map the given UID/GID to a SID.
 304  *
 305  * sim->sim_domsid and sim->sim_rid will contain the mapping
 306  * result upon successful process of the batched request.
 307  * Stash the type for error reporting (caller saves the ID).
 308  */
 309 idmap_stat
 310 smb_idmap_batch_getsid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
 311     uid_t id, int idtype)
 312 {
 313         idmap_stat idm_stat;
 314 
 315         sim->sim_idtype = idtype;
 316         switch (idtype) {
 317         case SMB_IDMAP_USER:
 318                 idm_stat = kidmap_batch_getsidbyuid(idmaph, id,
 319                     (const char **)&sim->sim_domsid, &sim->sim_rid,
 320                     &sim->sim_stat);
 321                 break;
 322 
 323         case SMB_IDMAP_GROUP:
 324                 idm_stat = kidmap_batch_getsidbygid(idmaph, id,
 325                     (const char **)&sim->sim_domsid, &sim->sim_rid,
 326                     &sim->sim_stat);
 327                 break;
 328 
 329         case SMB_IDMAP_OWNERAT:
 330                 /* Current Owner S-1-5-32-766 */
 331                 sim->sim_domsid = NT_BUILTIN_DOMAIN_SIDSTR;
 332                 sim->sim_rid = SECURITY_CURRENT_OWNER_RID;
 333                 sim->sim_stat = IDMAP_SUCCESS;
 334                 idm_stat = IDMAP_SUCCESS;
 335                 break;
 
 341                 sim->sim_stat = IDMAP_SUCCESS;
 342                 idm_stat = IDMAP_SUCCESS;
 343                 break;
 344 
 345         case SMB_IDMAP_EVERYONE:
 346                 /* Everyone S-1-1-0 */
 347                 sim->sim_domsid = NT_WORLD_AUTH_SIDSTR;
 348                 sim->sim_rid = 0;
 349                 sim->sim_stat = IDMAP_SUCCESS;
 350                 idm_stat = IDMAP_SUCCESS;
 351                 break;
 352 
 353         default:
 354                 ASSERT(0);
 355                 return (IDMAP_ERR_ARG);
 356         }
 357 
 358         return (idm_stat);
 359 }
 360 
 361 static void
 362 smb_idmap_bgm_report(smb_idmap_batch_t *sib, smb_idmap_t *sim)
 363 {
 364 
 365         if ((sib->sib_flags & SMB_IDMAP_ID2SID) != 0) {
 366                 /*
 367                  * Note: The ID and type we asked idmap to map
 368                  * were saved in *sim_id and sim_idtype.
 369                  */
 370                 uint_t id = (sim->sim_id == NULL) ?
 371                     0 : (uint_t)*sim->sim_id;
 372                 cmn_err(CE_WARN, "Can't get SID for "
 373                     "ID=%u type=%d, status=%d",
 374                     id, sim->sim_idtype, sim->sim_stat);
 375         }
 376 
 377         if ((sib->sib_flags & SMB_IDMAP_SID2ID) != 0) {
 378                 cmn_err(CE_WARN, "Can't get ID for SID %s-%u, status=%d",
 379                     sim->sim_domsid, sim->sim_rid, sim->sim_stat);
 380         }
 381 }
 382 
 383 /*
 384  * smb_idmap_batch_getmappings
 385  *
 386  * trigger ID mapping service to get the mappings for queued
 387  * requests.
 388  *
 389  * Checks the result of all the queued requests.
 390  * If this is a Solaris -> Windows mapping it generates
 391  * binary SIDs from returned (domsid, rid) pairs.
 392  */
 393 idmap_stat
 394 smb_idmap_batch_getmappings(smb_idmap_batch_t *sib)
 395 {
 396         idmap_stat idm_stat = IDMAP_SUCCESS;
 397         smb_idmap_t *sim;
 398         int i;
 399 
 400         idm_stat = kidmap_get_mappings(sib->sib_idmaph);
 401         if (idm_stat != IDMAP_SUCCESS)
 402                 return (idm_stat);
 403 
 404         /*
 405          * Check the status for all the queued requests
 406          */
 407         for (i = 0, sim = sib->sib_maps; i < sib->sib_nmap; i++, sim++) {
 408                 if (sim->sim_stat != IDMAP_SUCCESS) {
 409                         smb_idmap_bgm_report(sib, sim);
 410                         if ((sib->sib_flags & SMB_IDMAP_SKIP_ERRS) == 0) {
 411                                 return (sim->sim_stat);
 412                         }
 413                 }
 414         }
 415 
 416         if (smb_idmap_batch_binsid(sib) != 0)
 417                 idm_stat = IDMAP_ERR_OTHER;
 418 
 419         return (idm_stat);
 420 }
 421 
 422 /*
 423  * smb_idmap_batch_binsid
 424  *
 425  * Convert sidrids to binary sids
 426  *
 427  * Returns 0 if successful and non-zero upon failure.
 428  */
 429 static int
 430 smb_idmap_batch_binsid(smb_idmap_batch_t *sib)
 431 {
 432         smb_sid_t *sid;
 433         smb_idmap_t *sim;
 434         int i;
 435 
 436         if (sib->sib_flags & SMB_IDMAP_SID2ID)
 437                 /* This operation is not required */
 438                 return (0);
 439 
 440         sim = sib->sib_maps;
 441         for (i = 0; i < sib->sib_nmap; sim++, i++) {
 442                 ASSERT(sim->sim_domsid != NULL);
 443                 if (sim->sim_domsid == NULL)
 444                         return (1);
 445 
 446                 if ((sid = smb_sid_fromstr(sim->sim_domsid)) == NULL)
 447                         return (1);
 448 
 449                 sim->sim_sid = smb_sid_splice(sid, sim->sim_rid);
 450                 smb_sid_free(sid);
 451         }
 452 
 453         return (0);
 454 }
 |