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 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 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 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 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 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 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 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 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 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