1c5c4113dSnw141292 /* 2c5c4113dSnw141292 * CDDL HEADER START 3c5c4113dSnw141292 * 4c5c4113dSnw141292 * The contents of this file are subject to the terms of the 5c5c4113dSnw141292 * Common Development and Distribution License (the "License"). 6c5c4113dSnw141292 * You may not use this file except in compliance with the License. 7c5c4113dSnw141292 * 8c5c4113dSnw141292 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9c5c4113dSnw141292 * or http://www.opensolaris.org/os/licensing. 10c5c4113dSnw141292 * See the License for the specific language governing permissions 11c5c4113dSnw141292 * and limitations under the License. 12c5c4113dSnw141292 * 13c5c4113dSnw141292 * When distributing Covered Code, include this CDDL HEADER in each 14c5c4113dSnw141292 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15c5c4113dSnw141292 * If applicable, add the following below this CDDL HEADER, with the 16c5c4113dSnw141292 * fields enclosed by brackets "[]" replaced with your own identifying 17c5c4113dSnw141292 * information: Portions Copyright [yyyy] [name of copyright owner] 18c5c4113dSnw141292 * 19c5c4113dSnw141292 * CDDL HEADER END 20c5c4113dSnw141292 */ 21c5c4113dSnw141292 22c5c4113dSnw141292 /* 239b214d32SJordan Brown * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24c5c4113dSnw141292 * Use is subject to license terms. 25c5c4113dSnw141292 */ 26c5c4113dSnw141292 27c5c4113dSnw141292 /* 28c5c4113dSnw141292 * Windows to Solaris Identity Mapping kernel API 29c5c4113dSnw141292 * This module provides an API to map Windows SIDs to 30c5c4113dSnw141292 * Solaris UID and GIDs. 31c5c4113dSnw141292 */ 32c5c4113dSnw141292 33c5c4113dSnw141292 34c5c4113dSnw141292 #include <sys/types.h> 35c5c4113dSnw141292 #include <sys/ksynch.h> 36c5c4113dSnw141292 #include <sys/door.h> 37c5c4113dSnw141292 #include <rpc/rpc_msg.h> 38c5c4113dSnw141292 #include <rpc/xdr.h> 39c5c4113dSnw141292 #include <rpc/auth.h> 40c5c4113dSnw141292 #include <rpc/rpc_sztypes.h> 41c5c4113dSnw141292 #ifdef DEBUG 42c5c4113dSnw141292 #include <sys/cmn_err.h> 43c5c4113dSnw141292 #endif /* DEBUG */ 44c5c4113dSnw141292 #include <sys/proc.h> 45c5c4113dSnw141292 #include <sys/sunddi.h> 46c5c4113dSnw141292 #include <sys/param.h> 47c5c4113dSnw141292 #include <sys/atomic.h> 48c5c4113dSnw141292 #include <sys/sysmacros.h> 49c5c4113dSnw141292 #include <sys/disp.h> 50c5c4113dSnw141292 #include <sys/kidmap.h> 51bda89588Sjp151216 #include <sys/zone.h> 529b214d32SJordan Brown #include <rpcsvc/idmap_prot.h> 53c5c4113dSnw141292 #include "kidmap_priv.h" 54c5c4113dSnw141292 55c5c4113dSnw141292 56bda89588Sjp151216 /* 57bda89588Sjp151216 * Defined types 58bda89588Sjp151216 */ 59bda89588Sjp151216 60c5c4113dSnw141292 61c5c4113dSnw141292 /* 62bda89588Sjp151216 * This structure holds pointers for the 63bda89588Sjp151216 * batch mapping results. 64c5c4113dSnw141292 */ 65c5c4113dSnw141292 typedef struct idmap_get_res { 66c5c4113dSnw141292 idmap_id_type idtype; 67c5c4113dSnw141292 uid_t *uid; 68c5c4113dSnw141292 gid_t *gid; 690b10de9fSjp151216 uid_t *pid; 70c5c4113dSnw141292 int *is_user; 71c5c4113dSnw141292 const char **sid_prefix; 72c5c4113dSnw141292 uint32_t *rid; 73c5c4113dSnw141292 idmap_stat *stat; 74c5c4113dSnw141292 } idmap_get_res; 75c5c4113dSnw141292 76c5c4113dSnw141292 /* Batch mapping handle structure */ 77c5c4113dSnw141292 struct idmap_get_handle { 78bda89588Sjp151216 struct idmap_zone_specific *zs; 79c5c4113dSnw141292 int mapping_num; 80c5c4113dSnw141292 int mapping_size; 81c5c4113dSnw141292 idmap_mapping *mapping; 82c5c4113dSnw141292 idmap_get_res *result; 83c5c4113dSnw141292 }; 84c5c4113dSnw141292 85c5c4113dSnw141292 86bda89588Sjp151216 /* Zone specific data */ 87bda89588Sjp151216 typedef struct idmap_zone_specific { 88f7b4b2feSjp151216 zoneid_t zone_id; 89bda89588Sjp151216 kmutex_t zone_mutex; 90bda89588Sjp151216 idmap_cache_t cache; 91bda89588Sjp151216 door_handle_t door_handle; 92bda89588Sjp151216 int door_valid; 938d059b82SJulian Pullen int door_retried; 94bda89588Sjp151216 uint32_t message_id; 95bda89588Sjp151216 } idmap_zone_specific_t; 96c5c4113dSnw141292 97bda89588Sjp151216 98bda89588Sjp151216 99bda89588Sjp151216 /* 100bda89588Sjp151216 * Module global data 101bda89588Sjp151216 */ 102bda89588Sjp151216 103bda89588Sjp151216 static kmutex_t idmap_zone_mutex; 104bda89588Sjp151216 static zone_key_t idmap_zone_key; 105bda89588Sjp151216 106bda89588Sjp151216 107bda89588Sjp151216 /* 108bda89588Sjp151216 * Local function definitions 109bda89588Sjp151216 */ 110c5c4113dSnw141292 111c5c4113dSnw141292 112c5c4113dSnw141292 static int 113bda89588Sjp151216 kidmap_rpc_call(idmap_zone_specific_t *zs, uint32_t op, 114bda89588Sjp151216 xdrproc_t xdr_args, caddr_t args, 115c5c4113dSnw141292 xdrproc_t xdr_res, caddr_t res); 116c5c4113dSnw141292 117bda89588Sjp151216 static int 118bda89588Sjp151216 kidmap_call_door(idmap_zone_specific_t *zs, door_arg_t *arg); 119c5c4113dSnw141292 120bda89588Sjp151216 static idmap_zone_specific_t * 121bda89588Sjp151216 idmap_get_zone_specific(zone_t *zone); 122c5c4113dSnw141292 123c5c4113dSnw141292 124c5c4113dSnw141292 125c5c4113dSnw141292 int 126bda89588Sjp151216 idmap_reg_dh(zone_t *zone, door_handle_t dh) 127c5c4113dSnw141292 { 128bda89588Sjp151216 idmap_zone_specific_t *zs; 129c5c4113dSnw141292 130bda89588Sjp151216 zs = idmap_get_zone_specific(zone); 131c5c4113dSnw141292 132bda89588Sjp151216 mutex_enter(&zs->zone_mutex); 133c5c4113dSnw141292 134bda89588Sjp151216 if (zs->door_valid) 135bda89588Sjp151216 door_ki_rele(zs->door_handle); 136c5c4113dSnw141292 137bda89588Sjp151216 zs->door_handle = dh; 138bda89588Sjp151216 zs->door_valid = 1; 139c5c4113dSnw141292 140bda89588Sjp151216 mutex_exit(&zs->zone_mutex); 141c5c4113dSnw141292 142c5c4113dSnw141292 return (0); 143c5c4113dSnw141292 } 144c5c4113dSnw141292 145bda89588Sjp151216 /* 146bda89588Sjp151216 * idmap_unreg_dh 147bda89588Sjp151216 * 148bda89588Sjp151216 * This routine is called by system call idmap_unreg(). 149bda89588Sjp151216 * idmap_unreg() calls door_ki_rele() on the supplied 150bda89588Sjp151216 * door handle after this routine returns. We only 151bda89588Sjp151216 * need to perform one door release on zs->door_handle 152bda89588Sjp151216 */ 153c5c4113dSnw141292 int 154bda89588Sjp151216 idmap_unreg_dh(zone_t *zone, door_handle_t dh) 155c5c4113dSnw141292 { 156bda89588Sjp151216 idmap_zone_specific_t *zs; 1570b10de9fSjp151216 158bda89588Sjp151216 zs = idmap_get_zone_specific(zone); 159bda89588Sjp151216 160bda89588Sjp151216 kidmap_cache_purge(&zs->cache); 161bda89588Sjp151216 162bda89588Sjp151216 mutex_enter(&zs->zone_mutex); 163bda89588Sjp151216 164f7b4b2feSjp151216 if (!zs->door_valid || zs->door_handle != dh) { 165bda89588Sjp151216 mutex_exit(&zs->zone_mutex); 166c5c4113dSnw141292 return (EINVAL); 167c5c4113dSnw141292 } 168bda89588Sjp151216 169bda89588Sjp151216 door_ki_rele(zs->door_handle); 170bda89588Sjp151216 171bda89588Sjp151216 zs->door_valid = 0; 1728d059b82SJulian Pullen zs->door_retried = 0; 173bda89588Sjp151216 mutex_exit(&zs->zone_mutex); 174bda89588Sjp151216 175c5c4113dSnw141292 return (0); 176c5c4113dSnw141292 } 177c5c4113dSnw141292 178c5c4113dSnw141292 179f7b4b2feSjp151216 /* 180f7b4b2feSjp151216 * IMPORTANT. This function idmap_get_cache_data() is project 181f7b4b2feSjp151216 * private and is for use of the test system only and should 182f7b4b2feSjp151216 * not be used for other purposes. 183f7b4b2feSjp151216 */ 184f7b4b2feSjp151216 void 185f7b4b2feSjp151216 idmap_get_cache_data(zone_t *zone, size_t *uidbysid, size_t *gidbysid, 186f7b4b2feSjp151216 size_t *pidbysid, size_t *sidbyuid, size_t *sidbygid) 187f7b4b2feSjp151216 { 188f7b4b2feSjp151216 idmap_zone_specific_t *zs; 189f7b4b2feSjp151216 190f7b4b2feSjp151216 zs = idmap_get_zone_specific(zone); 191f7b4b2feSjp151216 192f7b4b2feSjp151216 kidmap_cache_get_data(&zs->cache, uidbysid, gidbysid, 193f7b4b2feSjp151216 pidbysid, sidbyuid, sidbygid); 194f7b4b2feSjp151216 } 195f7b4b2feSjp151216 196c5c4113dSnw141292 static int 197bda89588Sjp151216 kidmap_call_door(idmap_zone_specific_t *zs, door_arg_t *arg) 198c5c4113dSnw141292 { 199c5c4113dSnw141292 door_handle_t dh; 200f7b4b2feSjp151216 door_info_t di; 201bda89588Sjp151216 int status = 0; 2028d059b82SJulian Pullen int num_retries = 5; 2038d059b82SJulian Pullen int door_retried; 204c5c4113dSnw141292 205f7b4b2feSjp151216 retry: 206bda89588Sjp151216 mutex_enter(&zs->zone_mutex); 207f7b4b2feSjp151216 if (zs->door_valid) { 208bda89588Sjp151216 dh = zs->door_handle; 209bda89588Sjp151216 door_ki_hold(dh); 2108d059b82SJulian Pullen } else { 2118d059b82SJulian Pullen dh = NULL; 2128d059b82SJulian Pullen door_retried = zs->door_retried; 213f7b4b2feSjp151216 } 214bda89588Sjp151216 mutex_exit(&zs->zone_mutex); 215c5c4113dSnw141292 216f7b4b2feSjp151216 if (dh == NULL) { 2178d059b82SJulian Pullen /* The door has been retried before so dont wait */ 2188d059b82SJulian Pullen if (door_retried) 2198d059b82SJulian Pullen return (-1); 2208d059b82SJulian Pullen 221f7b4b2feSjp151216 /* 222f7b4b2feSjp151216 * There is no door handle yet. Give 2238d059b82SJulian Pullen * smf a chance to restart idmapd 224f7b4b2feSjp151216 */ 2258d059b82SJulian Pullen if (num_retries-- > 0) { 226f7b4b2feSjp151216 delay(hz); 227f7b4b2feSjp151216 goto retry; 228f7b4b2feSjp151216 } 2298d059b82SJulian Pullen 230f7b4b2feSjp151216 #ifdef DEBUG 231f7b4b2feSjp151216 zcmn_err(zs->zone_id, CE_WARN, 232f7b4b2feSjp151216 "idmap: Error no registered door to call the " 233f7b4b2feSjp151216 "idmap daemon\n"); 234f7b4b2feSjp151216 #endif 2358d059b82SJulian Pullen mutex_enter(&zs->zone_mutex); 2368d059b82SJulian Pullen if (!zs->door_valid) 2378d059b82SJulian Pullen zs->door_retried = 1; 2388d059b82SJulian Pullen mutex_exit(&zs->zone_mutex); 2398d059b82SJulian Pullen 240f7b4b2feSjp151216 return (-1); 241f7b4b2feSjp151216 } 242f7b4b2feSjp151216 243323a81d9Sjwadams status = door_ki_upcall_limited(dh, arg, NULL, SIZE_MAX, 0); 244c5c4113dSnw141292 245f7b4b2feSjp151216 switch (status) { 246f7b4b2feSjp151216 case 0: /* Success */ 247bda89588Sjp151216 door_ki_rele(dh); 248f7b4b2feSjp151216 return (0); 249bda89588Sjp151216 250f7b4b2feSjp151216 case EINTR: 251f7b4b2feSjp151216 /* If we took an interrupt we have to bail out. */ 252f7b4b2feSjp151216 if (ttolwp(curthread) && ISSIG(curthread, JUSTLOOKING)) { 253f7b4b2feSjp151216 door_ki_rele(dh); 2548d059b82SJulian Pullen #ifdef DEBUG 255f7b4b2feSjp151216 zcmn_err(zs->zone_id, CE_WARN, 256f7b4b2feSjp151216 "idmap: Interrupted\n"); 2578d059b82SJulian Pullen #endif 258f7b4b2feSjp151216 return (-1); 259f7b4b2feSjp151216 } 260bda89588Sjp151216 /* 261f7b4b2feSjp151216 * Just retry and see what happens. 262bda89588Sjp151216 */ 263f7b4b2feSjp151216 /* FALLTHROUGH */ 264f7b4b2feSjp151216 265f7b4b2feSjp151216 case EAGAIN: 266f7b4b2feSjp151216 /* A resouce problem */ 267f7b4b2feSjp151216 door_ki_rele(dh); 268f7b4b2feSjp151216 /* Back off before retrying */ 269f7b4b2feSjp151216 #ifdef DEBUG 270f7b4b2feSjp151216 zcmn_err(zs->zone_id, CE_WARN, 271f7b4b2feSjp151216 "idmap: Door call returned error %d. Retrying\n", status); 272f7b4b2feSjp151216 #endif /* DEBUG */ 273f7b4b2feSjp151216 delay(hz); 274f7b4b2feSjp151216 goto retry; 275f7b4b2feSjp151216 276f7b4b2feSjp151216 case EBADF: 277f7b4b2feSjp151216 /* Stale door handle. See if smf restarts the daemon. */ 278f7b4b2feSjp151216 door_ki_rele(dh); 279bda89588Sjp151216 mutex_enter(&zs->zone_mutex); 280f7b4b2feSjp151216 if (zs->door_valid && dh == zs->door_handle) { 281bda89588Sjp151216 zs->door_valid = 0; 2828d059b82SJulian Pullen zs->door_retried = 0; 283bda89588Sjp151216 door_ki_rele(zs->door_handle); 284bda89588Sjp151216 } 285bda89588Sjp151216 mutex_exit(&zs->zone_mutex); 286f7b4b2feSjp151216 /* Back off before retrying */ 287f7b4b2feSjp151216 #ifdef DEBUG 288f7b4b2feSjp151216 zcmn_err(zs->zone_id, CE_WARN, 289f7b4b2feSjp151216 "idmap: Door call returned error %d. Retrying\n", status); 290f7b4b2feSjp151216 #endif /* DEBUG */ 291f7b4b2feSjp151216 delay(hz); 292f7b4b2feSjp151216 goto retry; 293c5c4113dSnw141292 294f7b4b2feSjp151216 default: 295f7b4b2feSjp151216 /* Unknown error */ 296f7b4b2feSjp151216 #ifdef DEBUG 297f7b4b2feSjp151216 zcmn_err(zs->zone_id, CE_WARN, 298f7b4b2feSjp151216 "idmap: Door call returned error %d.\n", status); 299f7b4b2feSjp151216 #endif /* DEBUG */ 300f7b4b2feSjp151216 door_ki_rele(dh); 301f7b4b2feSjp151216 return (-1); 302f7b4b2feSjp151216 } 303c5c4113dSnw141292 } 304c5c4113dSnw141292 305c5c4113dSnw141292 306bda89588Sjp151216 static idmap_zone_specific_t * 307bda89588Sjp151216 idmap_get_zone_specific(zone_t *zone) 308bda89588Sjp151216 { 309bda89588Sjp151216 idmap_zone_specific_t *zs; 310bda89588Sjp151216 311bda89588Sjp151216 ASSERT(zone != NULL); 312bda89588Sjp151216 313bda89588Sjp151216 zs = zone_getspecific(idmap_zone_key, zone); 314bda89588Sjp151216 if (zs != NULL) 315bda89588Sjp151216 return (zs); 316bda89588Sjp151216 317bda89588Sjp151216 mutex_enter(&idmap_zone_mutex); 318bda89588Sjp151216 zs = zone_getspecific(idmap_zone_key, zone); 319bda89588Sjp151216 if (zs == NULL) { 320bda89588Sjp151216 zs = kmem_zalloc(sizeof (idmap_zone_specific_t), KM_SLEEP); 321bda89588Sjp151216 mutex_init(&zs->zone_mutex, NULL, MUTEX_DEFAULT, NULL); 322bda89588Sjp151216 kidmap_cache_create(&zs->cache); 323f7b4b2feSjp151216 zs->zone_id = zone->zone_id; 324bda89588Sjp151216 (void) zone_setspecific(idmap_zone_key, zone, zs); 325bda89588Sjp151216 mutex_exit(&idmap_zone_mutex); 326bda89588Sjp151216 return (zs); 327bda89588Sjp151216 } 328bda89588Sjp151216 mutex_exit(&idmap_zone_mutex); 329bda89588Sjp151216 330bda89588Sjp151216 return (zs); 331bda89588Sjp151216 } 332bda89588Sjp151216 333bda89588Sjp151216 334bda89588Sjp151216 static void 335bda89588Sjp151216 /* ARGSUSED */ 336bda89588Sjp151216 idmap_zone_destroy(zoneid_t zone_id, void *arg) 337bda89588Sjp151216 { 338bda89588Sjp151216 idmap_zone_specific_t *zs = arg; 339bda89588Sjp151216 if (zs != NULL) { 340bda89588Sjp151216 kidmap_cache_delete(&zs->cache); 341bda89588Sjp151216 if (zs->door_valid) { 342bda89588Sjp151216 door_ki_rele(zs->door_handle); 343bda89588Sjp151216 } 344bda89588Sjp151216 mutex_destroy(&zs->zone_mutex); 345bda89588Sjp151216 kmem_free(zs, sizeof (idmap_zone_specific_t)); 346bda89588Sjp151216 } 347bda89588Sjp151216 } 348bda89588Sjp151216 349bda89588Sjp151216 350c5c4113dSnw141292 int 351c5c4113dSnw141292 kidmap_start(void) 352c5c4113dSnw141292 { 353bda89588Sjp151216 mutex_init(&idmap_zone_mutex, NULL, MUTEX_DEFAULT, NULL); 354bda89588Sjp151216 zone_key_create(&idmap_zone_key, NULL, NULL, idmap_zone_destroy); 355c5c4113dSnw141292 kidmap_sid_prefix_store_init(); 356c5c4113dSnw141292 357c5c4113dSnw141292 return (0); 358c5c4113dSnw141292 } 359c5c4113dSnw141292 360c5c4113dSnw141292 361c5c4113dSnw141292 int 362c5c4113dSnw141292 kidmap_stop(void) 363c5c4113dSnw141292 { 364c5c4113dSnw141292 return (EBUSY); 365c5c4113dSnw141292 } 366c5c4113dSnw141292 367c5c4113dSnw141292 368bda89588Sjp151216 /* 369bda89588Sjp151216 * idmap_get_door 370bda89588Sjp151216 * 371bda89588Sjp151216 * This is called by the system call allocids() to get the door for the 372bda89588Sjp151216 * given zone. 373bda89588Sjp151216 */ 374bda89588Sjp151216 door_handle_t 375bda89588Sjp151216 idmap_get_door(zone_t *zone) 376bda89588Sjp151216 { 377bda89588Sjp151216 door_handle_t dh = NULL; 378bda89588Sjp151216 idmap_zone_specific_t *zs; 379c5c4113dSnw141292 380bda89588Sjp151216 zs = idmap_get_zone_specific(zone); 381c5c4113dSnw141292 382bda89588Sjp151216 mutex_enter(&zs->zone_mutex); 383bda89588Sjp151216 if (zs->door_valid) { 384bda89588Sjp151216 dh = zs->door_handle; 385bda89588Sjp151216 door_ki_hold(dh); 386c5c4113dSnw141292 } 387bda89588Sjp151216 mutex_exit(&zs->zone_mutex); 388bda89588Sjp151216 return (dh); 389bda89588Sjp151216 } 390bda89588Sjp151216 391bda89588Sjp151216 392bda89588Sjp151216 /* 393bda89588Sjp151216 * idmap_purge_cache 394bda89588Sjp151216 * 395bda89588Sjp151216 * This is called by the system call allocids() to purge the cache for the 396bda89588Sjp151216 * given zone. 397bda89588Sjp151216 */ 398bda89588Sjp151216 void 399bda89588Sjp151216 idmap_purge_cache(zone_t *zone) 400bda89588Sjp151216 { 401bda89588Sjp151216 idmap_zone_specific_t *zs; 402bda89588Sjp151216 403bda89588Sjp151216 zs = idmap_get_zone_specific(zone); 404bda89588Sjp151216 405bda89588Sjp151216 kidmap_cache_purge(&zs->cache); 406bda89588Sjp151216 } 407bda89588Sjp151216 408bda89588Sjp151216 409c5c4113dSnw141292 410c5c4113dSnw141292 411c5c4113dSnw141292 /* 412c5c4113dSnw141292 * Given Domain SID and RID, get UID 413c5c4113dSnw141292 * 414c5c4113dSnw141292 * Input: 415c5c4113dSnw141292 * sid_prefix - Domain SID in canonical form 416c5c4113dSnw141292 * rid - RID 417c5c4113dSnw141292 * 418c5c4113dSnw141292 * Output: 419c5c4113dSnw141292 * uid - POSIX UID if return == IDMAP_SUCCESS 420c5c4113dSnw141292 * 421c5c4113dSnw141292 * Return: 422c5c4113dSnw141292 * Success return IDMAP_SUCCESS else IDMAP error 423c5c4113dSnw141292 */ 424c5c4113dSnw141292 idmap_stat 425bda89588Sjp151216 kidmap_getuidbysid(zone_t *zone, const char *sid_prefix, uint32_t rid, 426bda89588Sjp151216 uid_t *uid) 427c5c4113dSnw141292 { 428bda89588Sjp151216 idmap_zone_specific_t *zs; 429c5c4113dSnw141292 idmap_mapping_batch args; 430c5c4113dSnw141292 idmap_mapping mapping; 431c5c4113dSnw141292 idmap_ids_res results; 432c5c4113dSnw141292 uint32_t op = IDMAP_GET_MAPPED_IDS; 433c5c4113dSnw141292 const char *new_sid_prefix; 434c5c4113dSnw141292 idmap_stat status; 435c5c4113dSnw141292 436c5c4113dSnw141292 if (sid_prefix == NULL || uid == NULL) 437c5c4113dSnw141292 return (IDMAP_ERR_ARG); 438c5c4113dSnw141292 439bda89588Sjp151216 zs = idmap_get_zone_specific(zone); 440bda89588Sjp151216 441bda89588Sjp151216 if (kidmap_cache_lookup_uidbysid(&zs->cache, sid_prefix, rid, uid) 4420b10de9fSjp151216 == IDMAP_SUCCESS) 443c5c4113dSnw141292 return (IDMAP_SUCCESS); 444c5c4113dSnw141292 445c5c4113dSnw141292 bzero(&mapping, sizeof (idmap_mapping)); 446c5c4113dSnw141292 mapping.id1.idtype = IDMAP_SID; 447c5c4113dSnw141292 mapping.id1.idmap_id_u.sid.prefix = (char *)sid_prefix; 448c5c4113dSnw141292 mapping.id1.idmap_id_u.sid.rid = rid; 449c5c4113dSnw141292 mapping.id2.idtype = IDMAP_UID; 450c5c4113dSnw141292 451c5c4113dSnw141292 bzero(&results, sizeof (idmap_ids_res)); 452c5c4113dSnw141292 453c5c4113dSnw141292 args.idmap_mapping_batch_len = 1; 454c5c4113dSnw141292 args.idmap_mapping_batch_val = &mapping; 455c5c4113dSnw141292 456bda89588Sjp151216 if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch, 457c5c4113dSnw141292 (caddr_t)&args, xdr_idmap_ids_res, 458c5c4113dSnw141292 (caddr_t)&results) == 0) { 459c5c4113dSnw141292 /* Door call succeded */ 4609d0aba92Sjp151216 if (results.retcode != IDMAP_SUCCESS) { 4619d0aba92Sjp151216 status = results.retcode; 4629d0aba92Sjp151216 *uid = UID_NOBODY; 4639d0aba92Sjp151216 } else if (results.ids.ids_len >= 1 && 464c5c4113dSnw141292 results.ids.ids_val[0].id.idtype == IDMAP_UID) { 465c5c4113dSnw141292 status = results.ids.ids_val[0].retcode; 466c5c4113dSnw141292 *uid = results.ids.ids_val[0].id.idmap_id_u.uid; 467c5c4113dSnw141292 if (status == IDMAP_SUCCESS) { 468c5c4113dSnw141292 new_sid_prefix = kidmap_find_sid_prefix( 469c5c4113dSnw141292 sid_prefix); 470d15447b6Sjp151216 kidmap_cache_add_sid2uid(&zs->cache, 471d15447b6Sjp151216 new_sid_prefix, rid, *uid, 472d15447b6Sjp151216 results.ids.ids_val[0].direction); 473c5c4113dSnw141292 } 474c5c4113dSnw141292 } else { 475c5c4113dSnw141292 status = IDMAP_ERR_NOMAPPING; 476c5c4113dSnw141292 *uid = UID_NOBODY; 477c5c4113dSnw141292 } 478c5c4113dSnw141292 xdr_free(xdr_idmap_ids_res, (char *)&results); 479c5c4113dSnw141292 } else { 480c5c4113dSnw141292 /* Door call failed */ 481c5c4113dSnw141292 status = IDMAP_ERR_NOMAPPING; 482c5c4113dSnw141292 *uid = UID_NOBODY; 483c5c4113dSnw141292 } 484c5c4113dSnw141292 return (status); 485c5c4113dSnw141292 } 486c5c4113dSnw141292 487c5c4113dSnw141292 488c5c4113dSnw141292 /* 489c5c4113dSnw141292 * Given Domain SID and RID, get GID 490c5c4113dSnw141292 * 491c5c4113dSnw141292 * Input: 492c5c4113dSnw141292 * sid_prefix - Domain SID in canonical form 493c5c4113dSnw141292 * rid - RID 494c5c4113dSnw141292 * 495c5c4113dSnw141292 * Output: 496c5c4113dSnw141292 * gid - POSIX UID if return == IDMAP_SUCCESS 497c5c4113dSnw141292 * 498c5c4113dSnw141292 * Return: 499c5c4113dSnw141292 * Success return IDMAP_SUCCESS else IDMAP error 500c5c4113dSnw141292 */ 501c5c4113dSnw141292 idmap_stat 502bda89588Sjp151216 kidmap_getgidbysid(zone_t *zone, const char *sid_prefix, uint32_t rid, 503bda89588Sjp151216 gid_t *gid) 504c5c4113dSnw141292 { 505bda89588Sjp151216 idmap_zone_specific_t *zs; 506c5c4113dSnw141292 idmap_mapping_batch args; 507c5c4113dSnw141292 idmap_mapping mapping; 508c5c4113dSnw141292 idmap_ids_res results; 509c5c4113dSnw141292 uint32_t op = IDMAP_GET_MAPPED_IDS; 510c5c4113dSnw141292 const char *new_sid_prefix; 511c5c4113dSnw141292 idmap_stat status; 512c5c4113dSnw141292 513c5c4113dSnw141292 if (sid_prefix == NULL || gid == NULL) 514c5c4113dSnw141292 return (IDMAP_ERR_ARG); 515c5c4113dSnw141292 516bda89588Sjp151216 zs = idmap_get_zone_specific(zone); 517bda89588Sjp151216 518bda89588Sjp151216 if (kidmap_cache_lookup_gidbysid(&zs->cache, sid_prefix, rid, gid) 519bda89588Sjp151216 == IDMAP_SUCCESS) 520c5c4113dSnw141292 return (IDMAP_SUCCESS); 521c5c4113dSnw141292 522c5c4113dSnw141292 bzero(&mapping, sizeof (idmap_mapping)); 523c5c4113dSnw141292 mapping.id1.idtype = IDMAP_SID; 524c5c4113dSnw141292 mapping.id1.idmap_id_u.sid.prefix = (char *)sid_prefix; 525c5c4113dSnw141292 mapping.id1.idmap_id_u.sid.rid = rid; 526c5c4113dSnw141292 mapping.id2.idtype = IDMAP_GID; 527c5c4113dSnw141292 528c5c4113dSnw141292 bzero(&results, sizeof (idmap_ids_res)); 529c5c4113dSnw141292 530c5c4113dSnw141292 args.idmap_mapping_batch_len = 1; 531c5c4113dSnw141292 args.idmap_mapping_batch_val = &mapping; 532c5c4113dSnw141292 533bda89588Sjp151216 if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch, 534c5c4113dSnw141292 (caddr_t)&args, xdr_idmap_ids_res, 535c5c4113dSnw141292 (caddr_t)&results) == 0) { 536c5c4113dSnw141292 /* Door call succeded */ 5379d0aba92Sjp151216 if (results.retcode != IDMAP_SUCCESS) { 5389d0aba92Sjp151216 status = results.retcode; 5399d0aba92Sjp151216 *gid = GID_NOBODY; 5409d0aba92Sjp151216 } else if (results.ids.ids_len >= 1 && 541c5c4113dSnw141292 results.ids.ids_val[0].id.idtype == IDMAP_GID) { 542c5c4113dSnw141292 status = results.ids.ids_val[0].retcode; 543c5c4113dSnw141292 *gid = results.ids.ids_val[0].id.idmap_id_u.gid; 544c5c4113dSnw141292 if (status == IDMAP_SUCCESS) { 545c5c4113dSnw141292 new_sid_prefix = kidmap_find_sid_prefix( 546c5c4113dSnw141292 sid_prefix); 547d15447b6Sjp151216 kidmap_cache_add_sid2gid(&zs->cache, 548d15447b6Sjp151216 new_sid_prefix, rid, *gid, 549d15447b6Sjp151216 results.ids.ids_val[0].direction); 550c5c4113dSnw141292 } 551c5c4113dSnw141292 } else { 552c5c4113dSnw141292 status = IDMAP_ERR_NOMAPPING; 553c5c4113dSnw141292 *gid = GID_NOBODY; 554c5c4113dSnw141292 } 555c5c4113dSnw141292 xdr_free(xdr_idmap_ids_res, (char *)&results); 556c5c4113dSnw141292 } else { 557c5c4113dSnw141292 /* Door call failed */ 558c5c4113dSnw141292 status = IDMAP_ERR_NOMAPPING; 559c5c4113dSnw141292 *gid = GID_NOBODY; 560c5c4113dSnw141292 } 561c5c4113dSnw141292 return (status); 562c5c4113dSnw141292 } 563c5c4113dSnw141292 564c5c4113dSnw141292 /* 565c5c4113dSnw141292 * Given Domain SID and RID, get Posix ID 566c5c4113dSnw141292 * 567c5c4113dSnw141292 * Input: 568c5c4113dSnw141292 * sid_prefix - Domain SID in canonical form 569c5c4113dSnw141292 * rid - RID 570c5c4113dSnw141292 * 571c5c4113dSnw141292 * Output: 572c5c4113dSnw141292 * pid - POSIX ID if return == IDMAP_SUCCESS 573c5c4113dSnw141292 * is_user - 1 == UID, 0 == GID if return == IDMAP_SUCCESS 574c5c4113dSnw141292 * 575c5c4113dSnw141292 * Return: 576c5c4113dSnw141292 * Success return IDMAP_SUCCESS else IDMAP error 577c5c4113dSnw141292 */ 578c5c4113dSnw141292 idmap_stat 579bda89588Sjp151216 kidmap_getpidbysid(zone_t *zone, const char *sid_prefix, uint32_t rid, 580bda89588Sjp151216 uid_t *pid, int *is_user) 581c5c4113dSnw141292 { 582bda89588Sjp151216 idmap_zone_specific_t *zs; 583c5c4113dSnw141292 idmap_mapping_batch args; 584c5c4113dSnw141292 idmap_mapping mapping; 585c5c4113dSnw141292 idmap_ids_res results; 586c5c4113dSnw141292 uint32_t op = IDMAP_GET_MAPPED_IDS; 587c5c4113dSnw141292 const char *new_sid_prefix; 588c5c4113dSnw141292 idmap_stat status; 589c5c4113dSnw141292 590c5c4113dSnw141292 if (sid_prefix == NULL || pid == NULL || is_user == NULL) 591c5c4113dSnw141292 return (IDMAP_ERR_ARG); 592c5c4113dSnw141292 593bda89588Sjp151216 zs = idmap_get_zone_specific(zone); 594bda89588Sjp151216 595bda89588Sjp151216 if (kidmap_cache_lookup_pidbysid(&zs->cache, sid_prefix, rid, pid, 596bda89588Sjp151216 is_user) == IDMAP_SUCCESS) 597c5c4113dSnw141292 return (IDMAP_SUCCESS); 598c5c4113dSnw141292 599c5c4113dSnw141292 bzero(&mapping, sizeof (idmap_mapping)); 600c5c4113dSnw141292 mapping.id1.idtype = IDMAP_SID; 601c5c4113dSnw141292 mapping.id1.idmap_id_u.sid.prefix = (char *)sid_prefix; 602c5c4113dSnw141292 mapping.id1.idmap_id_u.sid.rid = rid; 603c5c4113dSnw141292 mapping.id2.idtype = IDMAP_POSIXID; 604c5c4113dSnw141292 605c5c4113dSnw141292 bzero(&results, sizeof (idmap_ids_res)); 606c5c4113dSnw141292 607c5c4113dSnw141292 args.idmap_mapping_batch_len = 1; 608c5c4113dSnw141292 args.idmap_mapping_batch_val = &mapping; 609c5c4113dSnw141292 610bda89588Sjp151216 if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch, 611c5c4113dSnw141292 (caddr_t)&args, xdr_idmap_ids_res, 612c5c4113dSnw141292 (caddr_t)&results) == 0) { 613c5c4113dSnw141292 /* Door call succeded */ 6149d0aba92Sjp151216 if (results.retcode != IDMAP_SUCCESS) { 6159d0aba92Sjp151216 status = results.retcode; 6169d0aba92Sjp151216 *is_user = 1; 6179d0aba92Sjp151216 *pid = UID_NOBODY; 6189d0aba92Sjp151216 } else if (results.ids.ids_len >= 1 && ( 619c5c4113dSnw141292 results.ids.ids_val[0].id.idtype == IDMAP_UID || 620c5c4113dSnw141292 results.ids.ids_val[0].id.idtype == IDMAP_GID)) { 621c5c4113dSnw141292 status = results.ids.ids_val[0].retcode; 622c5c4113dSnw141292 if (results.ids.ids_val[0].id.idtype == IDMAP_UID) { 623c5c4113dSnw141292 *is_user = 1; 624c5c4113dSnw141292 *pid = results.ids.ids_val[0].id.idmap_id_u.uid; 625c5c4113dSnw141292 } else { 626c5c4113dSnw141292 *is_user = 0; 627c5c4113dSnw141292 *pid = results.ids.ids_val[0].id.idmap_id_u.gid; 628c5c4113dSnw141292 } 629c5c4113dSnw141292 if (status == IDMAP_SUCCESS) { 630c5c4113dSnw141292 new_sid_prefix = kidmap_find_sid_prefix( 631c5c4113dSnw141292 sid_prefix); 632d15447b6Sjp151216 kidmap_cache_add_sid2pid(&zs->cache, 633c5c4113dSnw141292 new_sid_prefix, rid, *pid, 634d15447b6Sjp151216 *is_user, 635d15447b6Sjp151216 results.ids.ids_val[0].direction); 636c5c4113dSnw141292 } 637c5c4113dSnw141292 } else { 638c5c4113dSnw141292 status = IDMAP_ERR_NOMAPPING; 639c5c4113dSnw141292 *is_user = 1; 640c5c4113dSnw141292 *pid = UID_NOBODY; 641c5c4113dSnw141292 } 642c5c4113dSnw141292 xdr_free(xdr_idmap_ids_res, (char *)&results); 643c5c4113dSnw141292 } else { 644c5c4113dSnw141292 /* Door call failed */ 645c5c4113dSnw141292 status = IDMAP_ERR_NOMAPPING; 646c5c4113dSnw141292 *is_user = 1; 647c5c4113dSnw141292 *pid = UID_NOBODY; 648c5c4113dSnw141292 } 649c5c4113dSnw141292 return (status); 650c5c4113dSnw141292 } 651c5c4113dSnw141292 652c5c4113dSnw141292 653c5c4113dSnw141292 /* 654c5c4113dSnw141292 * Given UID, get Domain SID and RID 655c5c4113dSnw141292 * 656c5c4113dSnw141292 * Input: 657c5c4113dSnw141292 * uid - Posix UID 658c5c4113dSnw141292 * 659c5c4113dSnw141292 * Output: 660c5c4113dSnw141292 * sid_prefix - Domain SID if return == IDMAP_SUCCESS 661c5c4113dSnw141292 * rid - RID if return == IDMAP_SUCCESS 662c5c4113dSnw141292 * 663c5c4113dSnw141292 * Return: 664c5c4113dSnw141292 * Success return IDMAP_SUCCESS else IDMAP error 665c5c4113dSnw141292 */ 666c5c4113dSnw141292 idmap_stat 667bda89588Sjp151216 kidmap_getsidbyuid(zone_t *zone, uid_t uid, const char **sid_prefix, 668bda89588Sjp151216 uint32_t *rid) 669c5c4113dSnw141292 { 670bda89588Sjp151216 idmap_zone_specific_t *zs; 671c5c4113dSnw141292 idmap_mapping_batch args; 672c5c4113dSnw141292 idmap_mapping mapping; 673c5c4113dSnw141292 idmap_ids_res results; 674c5c4113dSnw141292 uint32_t op = IDMAP_GET_MAPPED_IDS; 675c5c4113dSnw141292 idmap_stat status; 676c5c4113dSnw141292 time_t entry_ttl; 677c5c4113dSnw141292 idmap_id *id; 678c5c4113dSnw141292 679c5c4113dSnw141292 if (sid_prefix == NULL || rid == NULL) 680c5c4113dSnw141292 return (IDMAP_ERR_ARG); 681c5c4113dSnw141292 682bda89588Sjp151216 zs = idmap_get_zone_specific(zone); 683bda89588Sjp151216 684bda89588Sjp151216 if (kidmap_cache_lookup_sidbyuid(&zs->cache, sid_prefix, rid, uid) 685c5c4113dSnw141292 == IDMAP_SUCCESS) { 686c5c4113dSnw141292 return (IDMAP_SUCCESS); 687c5c4113dSnw141292 } 688c5c4113dSnw141292 689c5c4113dSnw141292 bzero(&mapping, sizeof (idmap_mapping)); 690c5c4113dSnw141292 mapping.id1.idtype = IDMAP_UID; 691c5c4113dSnw141292 mapping.id1.idmap_id_u.uid = uid; 692c5c4113dSnw141292 mapping.id2.idtype = IDMAP_SID; 693c5c4113dSnw141292 694c5c4113dSnw141292 bzero(&results, sizeof (idmap_ids_res)); 695c5c4113dSnw141292 696c5c4113dSnw141292 args.idmap_mapping_batch_len = 1; 697c5c4113dSnw141292 args.idmap_mapping_batch_val = &mapping; 698c5c4113dSnw141292 699bda89588Sjp151216 if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch, 700c5c4113dSnw141292 (caddr_t)&args, xdr_idmap_ids_res, 701c5c4113dSnw141292 (caddr_t)&results) == 0) { 702c5c4113dSnw141292 /* Door call succeded */ 7039d0aba92Sjp151216 if (results.retcode != IDMAP_SUCCESS) { 7049d0aba92Sjp151216 status = results.retcode; 7059d0aba92Sjp151216 *rid = 0; 7069d0aba92Sjp151216 *sid_prefix = NULL; 7079d0aba92Sjp151216 } else if (results.ids.ids_len >= 1 && 708cd37da74Snw141292 (results.ids.ids_val[0].id.idtype == IDMAP_SID || 709cd37da74Snw141292 results.ids.ids_val[0].id.idtype == IDMAP_USID || 710cd37da74Snw141292 results.ids.ids_val[0].id.idtype == IDMAP_GSID)) { 711c5c4113dSnw141292 status = results.ids.ids_val[0].retcode; 712c5c4113dSnw141292 id = &results.ids.ids_val[0].id; 713c5c4113dSnw141292 *sid_prefix = kidmap_find_sid_prefix( 714c5c4113dSnw141292 id->idmap_id_u.sid.prefix); 715c5c4113dSnw141292 *rid = id->idmap_id_u.sid.rid; 716c5c4113dSnw141292 if (status == IDMAP_SUCCESS) { 717d15447b6Sjp151216 kidmap_cache_add_sid2uid(&zs->cache, 718d15447b6Sjp151216 *sid_prefix, *rid, uid, 719d15447b6Sjp151216 results.ids.ids_val[0].direction); 720c5c4113dSnw141292 } 721c5c4113dSnw141292 } else { 722c5c4113dSnw141292 status = IDMAP_ERR_NOMAPPING; 723c5c4113dSnw141292 *rid = 0; 724c5c4113dSnw141292 *sid_prefix = NULL; 725c5c4113dSnw141292 } 726c5c4113dSnw141292 xdr_free(xdr_idmap_ids_res, (char *)&results); 727c5c4113dSnw141292 } else { 728c5c4113dSnw141292 /* Door call failed */ 729c5c4113dSnw141292 status = IDMAP_ERR_NOMAPPING; 730c5c4113dSnw141292 *rid = 0; 731c5c4113dSnw141292 *sid_prefix = NULL; 732c5c4113dSnw141292 } 733c5c4113dSnw141292 return (status); 734c5c4113dSnw141292 } 735c5c4113dSnw141292 736c5c4113dSnw141292 737c5c4113dSnw141292 /* 738c5c4113dSnw141292 * Given GID, get Domain SID and RID 739c5c4113dSnw141292 * 740c5c4113dSnw141292 * Input: 741c5c4113dSnw141292 * gid - Posix GID 742c5c4113dSnw141292 * 743c5c4113dSnw141292 * Output: 744c5c4113dSnw141292 * sid_prefix - Domain SID if return == IDMAP_SUCCESS 745c5c4113dSnw141292 * rid - RID if return == IDMAP_SUCCESS 746c5c4113dSnw141292 * 747c5c4113dSnw141292 * Return: 748c5c4113dSnw141292 * Success return IDMAP_SUCCESS else IDMAP error 749c5c4113dSnw141292 */ 750c5c4113dSnw141292 idmap_stat 751bda89588Sjp151216 kidmap_getsidbygid(zone_t *zone, gid_t gid, const char **sid_prefix, 752bda89588Sjp151216 uint32_t *rid) 753c5c4113dSnw141292 { 754bda89588Sjp151216 idmap_zone_specific_t *zs; 755c5c4113dSnw141292 idmap_mapping_batch args; 756c5c4113dSnw141292 idmap_mapping mapping; 757c5c4113dSnw141292 idmap_ids_res results; 758c5c4113dSnw141292 uint32_t op = IDMAP_GET_MAPPED_IDS; 759c5c4113dSnw141292 idmap_stat status; 760c5c4113dSnw141292 idmap_id *id; 761c5c4113dSnw141292 762c5c4113dSnw141292 if (sid_prefix == NULL || rid == NULL) 763c5c4113dSnw141292 return (IDMAP_ERR_ARG); 764c5c4113dSnw141292 765bda89588Sjp151216 zs = idmap_get_zone_specific(zone); 766bda89588Sjp151216 767bda89588Sjp151216 if (kidmap_cache_lookup_sidbygid(&zs->cache, sid_prefix, rid, gid) 768c5c4113dSnw141292 == IDMAP_SUCCESS) { 769c5c4113dSnw141292 return (IDMAP_SUCCESS); 770c5c4113dSnw141292 } 771c5c4113dSnw141292 772c5c4113dSnw141292 bzero(&mapping, sizeof (idmap_mapping)); 773c5c4113dSnw141292 mapping.id1.idtype = IDMAP_GID; 774c5c4113dSnw141292 mapping.id1.idmap_id_u.uid = gid; 775c5c4113dSnw141292 mapping.id2.idtype = IDMAP_SID; 776c5c4113dSnw141292 777c5c4113dSnw141292 bzero(&results, sizeof (idmap_ids_res)); 778c5c4113dSnw141292 779c5c4113dSnw141292 args.idmap_mapping_batch_len = 1; 780c5c4113dSnw141292 args.idmap_mapping_batch_val = &mapping; 781c5c4113dSnw141292 782bda89588Sjp151216 if (kidmap_rpc_call(zs, op, xdr_idmap_mapping_batch, 783c5c4113dSnw141292 (caddr_t)&args, xdr_idmap_ids_res, 784c5c4113dSnw141292 (caddr_t)&results) == 0) { 785c5c4113dSnw141292 /* Door call succeded */ 7869d0aba92Sjp151216 if (results.retcode != IDMAP_SUCCESS) { 7879d0aba92Sjp151216 status = results.retcode; 7889d0aba92Sjp151216 *rid = 0; 7899d0aba92Sjp151216 *sid_prefix = NULL; 7909d0aba92Sjp151216 } else if (results.ids.ids_len >= 1 && 791cd37da74Snw141292 (results.ids.ids_val[0].id.idtype == IDMAP_SID || 792cd37da74Snw141292 results.ids.ids_val[0].id.idtype == IDMAP_USID || 793cd37da74Snw141292 results.ids.ids_val[0].id.idtype == IDMAP_GSID)) { 794c5c4113dSnw141292 status = results.ids.ids_val[0].retcode; 795c5c4113dSnw141292 id = &results.ids.ids_val[0].id; 796c5c4113dSnw141292 *sid_prefix = kidmap_find_sid_prefix( 797c5c4113dSnw141292 id->idmap_id_u.sid.prefix); 798c5c4113dSnw141292 *rid = id->idmap_id_u.sid.rid; 799c5c4113dSnw141292 if (status == IDMAP_SUCCESS) { 800d15447b6Sjp151216 kidmap_cache_add_sid2gid(&zs->cache, 801d15447b6Sjp151216 *sid_prefix, *rid, gid, 802d15447b6Sjp151216 results.ids.ids_val[0].direction); 803c5c4113dSnw141292 } 804c5c4113dSnw141292 } else { 805c5c4113dSnw141292 status = IDMAP_ERR_NOMAPPING; 806c5c4113dSnw141292 *rid = 0; 807c5c4113dSnw141292 *sid_prefix = NULL; 808c5c4113dSnw141292 } 809c5c4113dSnw141292 xdr_free(xdr_idmap_ids_res, (char *)&results); 810c5c4113dSnw141292 } else { 811c5c4113dSnw141292 /* Door call failed */ 812c5c4113dSnw141292 status = IDMAP_ERR_NOMAPPING; 813c5c4113dSnw141292 *rid = 0; 814c5c4113dSnw141292 *sid_prefix = NULL; 815c5c4113dSnw141292 } 816c5c4113dSnw141292 return (status); 817c5c4113dSnw141292 } 818c5c4113dSnw141292 819c5c4113dSnw141292 /* 820c5c4113dSnw141292 * Create handle to get SID to UID/GID mapping entries 821c5c4113dSnw141292 * 822c5c4113dSnw141292 * Input: 823c5c4113dSnw141292 * none 824c5c4113dSnw141292 * Return: 825c5c4113dSnw141292 * get_handle 826c5c4113dSnw141292 * 827c5c4113dSnw141292 */ 828c5c4113dSnw141292 idmap_get_handle_t * 829bda89588Sjp151216 kidmap_get_create(zone_t *zone) 830c5c4113dSnw141292 { 831bda89588Sjp151216 idmap_zone_specific_t *zs; 832c5c4113dSnw141292 idmap_get_handle_t *handle; 833bda89588Sjp151216 #define INIT_MAPPING_SIZE 32 834bda89588Sjp151216 835bda89588Sjp151216 zs = idmap_get_zone_specific(zone); 836c5c4113dSnw141292 837c5c4113dSnw141292 handle = kmem_zalloc(sizeof (idmap_get_handle_t), KM_SLEEP); 838c5c4113dSnw141292 839c5c4113dSnw141292 handle->mapping = kmem_zalloc((sizeof (idmap_mapping)) * 840c5c4113dSnw141292 INIT_MAPPING_SIZE, KM_SLEEP); 841c5c4113dSnw141292 842c5c4113dSnw141292 handle->result = kmem_zalloc((sizeof (idmap_get_res)) * 843c5c4113dSnw141292 INIT_MAPPING_SIZE, KM_SLEEP); 844c5c4113dSnw141292 handle->mapping_size = INIT_MAPPING_SIZE; 845bda89588Sjp151216 handle->zs = zs; 846c5c4113dSnw141292 847c5c4113dSnw141292 return (handle); 848c5c4113dSnw141292 } 849c5c4113dSnw141292 850c5c4113dSnw141292 /* 851c5c4113dSnw141292 * Internal routine to extend a "get_handle" 852c5c4113dSnw141292 */ 853c5c4113dSnw141292 static void 854c5c4113dSnw141292 kidmap_get_extend(idmap_get_handle_t *get_handle) 855c5c4113dSnw141292 { 856c5c4113dSnw141292 idmap_mapping *mapping; 857c5c4113dSnw141292 idmap_get_res *result; 858c5c4113dSnw141292 int new_size = get_handle->mapping_size + INIT_MAPPING_SIZE; 859c5c4113dSnw141292 860c5c4113dSnw141292 mapping = kmem_zalloc((sizeof (idmap_mapping)) * 861c5c4113dSnw141292 new_size, KM_SLEEP); 862c5c4113dSnw141292 (void) memcpy(mapping, get_handle->mapping, 863c5c4113dSnw141292 (sizeof (idmap_mapping)) * get_handle->mapping_size); 864c5c4113dSnw141292 865c5c4113dSnw141292 result = kmem_zalloc((sizeof (idmap_get_res)) * 866c5c4113dSnw141292 new_size, KM_SLEEP); 867c5c4113dSnw141292 (void) memcpy(result, get_handle->result, 868c5c4113dSnw141292 (sizeof (idmap_get_res)) * get_handle->mapping_size); 869c5c4113dSnw141292 870c5c4113dSnw141292 kmem_free(get_handle->mapping, 871c5c4113dSnw141292 (sizeof (idmap_mapping)) * get_handle->mapping_size); 872c5c4113dSnw141292 get_handle->mapping = mapping; 873c5c4113dSnw141292 874c5c4113dSnw141292 kmem_free(get_handle->result, 875c5c4113dSnw141292 (sizeof (idmap_get_res)) * get_handle->mapping_size); 876c5c4113dSnw141292 get_handle->result = result; 877c5c4113dSnw141292 878c5c4113dSnw141292 get_handle->mapping_size = new_size; 879c5c4113dSnw141292 } 880c5c4113dSnw141292 881c5c4113dSnw141292 882c5c4113dSnw141292 /* 883c5c4113dSnw141292 * Given Domain SID and RID, get UID 884c5c4113dSnw141292 * 885c5c4113dSnw141292 * Input: 886c5c4113dSnw141292 * sid_prefix - Domain SID in canonical form 887c5c4113dSnw141292 * rid - RID 888c5c4113dSnw141292 * 889c5c4113dSnw141292 * Output: 890c5c4113dSnw141292 * stat - status of the get request 891c5c4113dSnw141292 * uid - POSIX UID if stat == IDMAP_SUCCESS 892c5c4113dSnw141292 * 893*dea83360SGordon Ross * Notes: 894*dea83360SGordon Ross * The output parameters will be set by idmap_get_mappings() 895*dea83360SGordon Ross * The sid_prefix is copied. 896c5c4113dSnw141292 */ 897c5c4113dSnw141292 idmap_stat 898c5c4113dSnw141292 kidmap_batch_getuidbysid(idmap_get_handle_t *get_handle, const char *sid_prefix, 899c5c4113dSnw141292 uint32_t rid, uid_t *uid, idmap_stat *stat) 900c5c4113dSnw141292 { 901c5c4113dSnw141292 idmap_mapping *mapping; 902c5c4113dSnw141292 idmap_get_res *result; 903c5c4113dSnw141292 904c5c4113dSnw141292 if (get_handle == NULL || sid_prefix == NULL || 905c5c4113dSnw141292 uid == NULL || stat == NULL) 906c5c4113dSnw141292 return (IDMAP_ERR_ARG); 907c5c4113dSnw141292 908bda89588Sjp151216 if (kidmap_cache_lookup_uidbysid(&get_handle->zs->cache, sid_prefix, 9090b10de9fSjp151216 rid, uid) == IDMAP_SUCCESS) { 910c5c4113dSnw141292 *stat = IDMAP_SUCCESS; 911c5c4113dSnw141292 return (IDMAP_SUCCESS); 912c5c4113dSnw141292 } 913c5c4113dSnw141292 914*dea83360SGordon Ross /* Get a copy of sid_prefix */ 915*dea83360SGordon Ross sid_prefix = kidmap_find_sid_prefix(sid_prefix); 916*dea83360SGordon Ross 917c5c4113dSnw141292 if (get_handle->mapping_num >= get_handle->mapping_size) 918c5c4113dSnw141292 kidmap_get_extend(get_handle); 919c5c4113dSnw141292 920c5c4113dSnw141292 mapping = &get_handle->mapping[get_handle->mapping_num]; 921c5c4113dSnw141292 mapping->flag = 0; 922c5c4113dSnw141292 mapping->id1.idtype = IDMAP_SID; 923c5c4113dSnw141292 mapping->id1.idmap_id_u.sid.prefix = (char *)sid_prefix; 924c5c4113dSnw141292 mapping->id1.idmap_id_u.sid.rid = rid; 925c5c4113dSnw141292 mapping->id2.idtype = IDMAP_UID; 926c5c4113dSnw141292 927c5c4113dSnw141292 result = &get_handle->result[get_handle->mapping_num]; 928c5c4113dSnw141292 result->idtype = IDMAP_UID; 929c5c4113dSnw141292 result->uid = uid; 930c5c4113dSnw141292 result->gid = NULL; 9310b10de9fSjp151216 result->pid = NULL; 932c5c4113dSnw141292 result->sid_prefix = NULL; 933c5c4113dSnw141292 result->rid = NULL; 934c5c4113dSnw141292 result->is_user = NULL; 935c5c4113dSnw141292 result->stat = stat; 936c5c4113dSnw141292 937c5c4113dSnw141292 get_handle->mapping_num++; 938c5c4113dSnw141292 939c5c4113dSnw141292 return (IDMAP_SUCCESS); 940c5c4113dSnw141292 } 941c5c4113dSnw141292 942c5c4113dSnw141292 943c5c4113dSnw141292 /* 944c5c4113dSnw141292 * Given Domain SID and RID, get GID 945c5c4113dSnw141292 * 946c5c4113dSnw141292 * Input: 947c5c4113dSnw141292 * sid_prefix - Domain SID in canonical form 948c5c4113dSnw141292 * rid - RID 949c5c4113dSnw141292 * 950c5c4113dSnw141292 * Output: 951c5c4113dSnw141292 * stat - status of the get request 952c5c4113dSnw141292 * gid - POSIX GID if stat == IDMAP_SUCCESS 953c5c4113dSnw141292 * 954*dea83360SGordon Ross * Notes: 955*dea83360SGordon Ross * The output parameters will be set by idmap_get_mappings() 956*dea83360SGordon Ross * The sid_prefix is copied. 957c5c4113dSnw141292 */ 958c5c4113dSnw141292 idmap_stat 959c5c4113dSnw141292 kidmap_batch_getgidbysid(idmap_get_handle_t *get_handle, const char *sid_prefix, 960c5c4113dSnw141292 uint32_t rid, uid_t *gid, idmap_stat *stat) 961c5c4113dSnw141292 { 962c5c4113dSnw141292 idmap_mapping *mapping; 963c5c4113dSnw141292 idmap_get_res *result; 964c5c4113dSnw141292 965c5c4113dSnw141292 if (get_handle == NULL || sid_prefix == NULL || 966c5c4113dSnw141292 gid == NULL || stat == NULL) 967c5c4113dSnw141292 return (IDMAP_ERR_ARG); 968c5c4113dSnw141292 969bda89588Sjp151216 if (kidmap_cache_lookup_gidbysid(&get_handle->zs->cache, sid_prefix, 9700b10de9fSjp151216 rid, gid) == IDMAP_SUCCESS) { 971c5c4113dSnw141292 *stat = IDMAP_SUCCESS; 972c5c4113dSnw141292 return (IDMAP_SUCCESS); 973c5c4113dSnw141292 } 974c5c4113dSnw141292 975*dea83360SGordon Ross /* Get a copy of sid_prefix */ 976*dea83360SGordon Ross sid_prefix = kidmap_find_sid_prefix(sid_prefix); 977*dea83360SGordon Ross 978c5c4113dSnw141292 if (get_handle->mapping_num >= get_handle->mapping_size) 979c5c4113dSnw141292 kidmap_get_extend(get_handle); 980c5c4113dSnw141292 981c5c4113dSnw141292 mapping = &get_handle->mapping[get_handle->mapping_num]; 982c5c4113dSnw141292 mapping->flag = 0; 983c5c4113dSnw141292 mapping->id1.idtype = IDMAP_SID; 984c5c4113dSnw141292 mapping->id1.idmap_id_u.sid.prefix = (char *)sid_prefix; 985c5c4113dSnw141292 mapping->id1.idmap_id_u.sid.rid = rid; 986c5c4113dSnw141292 mapping->id2.idtype = IDMAP_GID; 987c5c4113dSnw141292 988c5c4113dSnw141292 result = &get_handle->result[get_handle->mapping_num]; 989c5c4113dSnw141292 result->idtype = IDMAP_GID; 990c5c4113dSnw141292 result->uid = NULL; 991c5c4113dSnw141292 result->gid = gid; 9920b10de9fSjp151216 result->pid = NULL; 993c5c4113dSnw141292 result->sid_prefix = NULL; 994c5c4113dSnw141292 result->rid = NULL; 995c5c4113dSnw141292 result->is_user = NULL; 996c5c4113dSnw141292 result->stat = stat; 997c5c4113dSnw141292 998c5c4113dSnw141292 get_handle->mapping_num++; 999c5c4113dSnw141292 1000c5c4113dSnw141292 return (IDMAP_SUCCESS); 1001c5c4113dSnw141292 } 1002c5c4113dSnw141292 1003c5c4113dSnw141292 1004c5c4113dSnw141292 /* 1005c5c4113dSnw141292 * Given Domain SID and RID, get Posix ID 1006c5c4113dSnw141292 * 1007c5c4113dSnw141292 * Input: 1008c5c4113dSnw141292 * sid_prefix - Domain SID in canonical form 1009c5c4113dSnw141292 * rid - RID 1010c5c4113dSnw141292 * 1011c5c4113dSnw141292 * Output: 1012c5c4113dSnw141292 * stat - status of the get request 1013c5c4113dSnw141292 * is_user - user or group 1014c5c4113dSnw141292 * pid - POSIX UID if stat == IDMAP_SUCCESS and is_user == 1 1015c5c4113dSnw141292 * POSIX GID if stat == IDMAP_SUCCESS and is_user == 0 1016c5c4113dSnw141292 * 1017*dea83360SGordon Ross * Notes: 1018*dea83360SGordon Ross * The output parameters will be set by idmap_get_mappings() 1019*dea83360SGordon Ross * The sid_prefix is copied. 1020c5c4113dSnw141292 */ 1021c5c4113dSnw141292 idmap_stat 1022c5c4113dSnw141292 kidmap_batch_getpidbysid(idmap_get_handle_t *get_handle, const char *sid_prefix, 1023c5c4113dSnw141292 uint32_t rid, uid_t *pid, int *is_user, idmap_stat *stat) 1024c5c4113dSnw141292 { 1025c5c4113dSnw141292 idmap_mapping *mapping; 1026c5c4113dSnw141292 idmap_get_res *result; 1027c5c4113dSnw141292 1028c5c4113dSnw141292 if (get_handle == NULL || sid_prefix == NULL || pid == NULL || 1029c5c4113dSnw141292 is_user == NULL || stat == NULL) 1030c5c4113dSnw141292 return (IDMAP_ERR_ARG); 1031c5c4113dSnw141292 1032bda89588Sjp151216 if (kidmap_cache_lookup_pidbysid(&get_handle->zs->cache, sid_prefix, 1033c5c4113dSnw141292 rid, pid, is_user) == IDMAP_SUCCESS) { 1034c5c4113dSnw141292 *stat = IDMAP_SUCCESS; 1035c5c4113dSnw141292 return (IDMAP_SUCCESS); 1036c5c4113dSnw141292 } 1037c5c4113dSnw141292 1038*dea83360SGordon Ross /* Get a copy of sid_prefix */ 1039*dea83360SGordon Ross sid_prefix = kidmap_find_sid_prefix(sid_prefix); 1040c5c4113dSnw141292 1041c5c4113dSnw141292 if (get_handle->mapping_num >= get_handle->mapping_size) 1042c5c4113dSnw141292 kidmap_get_extend(get_handle); 1043c5c4113dSnw141292 1044c5c4113dSnw141292 mapping = &get_handle->mapping[get_handle->mapping_num]; 1045c5c4113dSnw141292 mapping->flag = 0; 1046c5c4113dSnw141292 mapping->id1.idtype = IDMAP_SID; 1047c5c4113dSnw141292 mapping->id1.idmap_id_u.sid.prefix = (char *)sid_prefix; 1048c5c4113dSnw141292 mapping->id1.idmap_id_u.sid.rid = rid; 1049c5c4113dSnw141292 mapping->id2.idtype = IDMAP_POSIXID; 1050c5c4113dSnw141292 1051c5c4113dSnw141292 result = &get_handle->result[get_handle->mapping_num]; 1052c5c4113dSnw141292 result->idtype = IDMAP_POSIXID; 10530b10de9fSjp151216 result->uid = NULL; 10540b10de9fSjp151216 result->gid = NULL; 10550b10de9fSjp151216 result->pid = pid; 1056c5c4113dSnw141292 result->sid_prefix = NULL; 1057c5c4113dSnw141292 result->rid = NULL; 1058c5c4113dSnw141292 result->is_user = is_user; 1059c5c4113dSnw141292 result->stat = stat; 1060c5c4113dSnw141292 1061c5c4113dSnw141292 get_handle->mapping_num++; 1062c5c4113dSnw141292 1063c5c4113dSnw141292 return (IDMAP_SUCCESS); 1064c5c4113dSnw141292 } 1065c5c4113dSnw141292 1066c5c4113dSnw141292 1067c5c4113dSnw141292 /* 1068c5c4113dSnw141292 * Given UID, get SID and RID 1069c5c4113dSnw141292 * 1070c5c4113dSnw141292 * Input: 1071c5c4113dSnw141292 * uid - POSIX UID 1072c5c4113dSnw141292 * 1073c5c4113dSnw141292 * Output: 1074c5c4113dSnw141292 * stat - status of the get request 1075c5c4113dSnw141292 * sid - SID in canonical form (if stat == IDMAP_SUCCESS) 1076c5c4113dSnw141292 * rid - RID (if stat == IDMAP_SUCCESS) 1077c5c4113dSnw141292 * 1078c5c4113dSnw141292 * Note: The output parameters will be set by idmap_get_mappings() 1079c5c4113dSnw141292 */ 1080c5c4113dSnw141292 idmap_stat 1081c5c4113dSnw141292 kidmap_batch_getsidbyuid(idmap_get_handle_t *get_handle, uid_t uid, 1082c5c4113dSnw141292 const char **sid_prefix, uint32_t *rid, idmap_stat *stat) 1083c5c4113dSnw141292 { 1084c5c4113dSnw141292 idmap_mapping *mapping; 1085c5c4113dSnw141292 idmap_get_res *result; 1086c5c4113dSnw141292 1087c5c4113dSnw141292 if (get_handle == NULL || sid_prefix == NULL || 1088c5c4113dSnw141292 rid == NULL || stat == NULL) 1089c5c4113dSnw141292 return (IDMAP_ERR_ARG); 1090c5c4113dSnw141292 1091bda89588Sjp151216 if (kidmap_cache_lookup_sidbyuid(&get_handle->zs->cache, 1092bda89588Sjp151216 sid_prefix, rid, uid) == IDMAP_SUCCESS) { 1093c5c4113dSnw141292 *stat = IDMAP_SUCCESS; 1094c5c4113dSnw141292 return (IDMAP_SUCCESS); 1095c5c4113dSnw141292 } 1096c5c4113dSnw141292 1097c5c4113dSnw141292 if (get_handle->mapping_num >= get_handle->mapping_size) 1098c5c4113dSnw141292 kidmap_get_extend(get_handle); 1099c5c4113dSnw141292 1100c5c4113dSnw141292 mapping = &get_handle->mapping[get_handle->mapping_num]; 1101c5c4113dSnw141292 mapping->flag = 0; 1102c5c4113dSnw141292 mapping->id1.idtype = IDMAP_UID; 1103c5c4113dSnw141292 mapping->id1.idmap_id_u.uid = uid; 1104c5c4113dSnw141292 mapping->id2.idtype = IDMAP_SID; 1105c5c4113dSnw141292 1106c5c4113dSnw141292 result = &get_handle->result[get_handle->mapping_num]; 1107c5c4113dSnw141292 result->idtype = IDMAP_SID; 1108c5c4113dSnw141292 result->uid = NULL; 1109c5c4113dSnw141292 result->gid = NULL; 11100b10de9fSjp151216 result->pid = NULL; 1111c5c4113dSnw141292 result->sid_prefix = sid_prefix; 1112c5c4113dSnw141292 result->rid = rid; 1113c5c4113dSnw141292 result->is_user = NULL; 1114c5c4113dSnw141292 result->stat = stat; 1115c5c4113dSnw141292 1116c5c4113dSnw141292 get_handle->mapping_num++; 1117c5c4113dSnw141292 1118c5c4113dSnw141292 return (IDMAP_SUCCESS); 1119c5c4113dSnw141292 } 1120c5c4113dSnw141292 1121c5c4113dSnw141292 1122c5c4113dSnw141292 /* 1123c5c4113dSnw141292 * Given GID, get SID and RID 1124c5c4113dSnw141292 * 1125c5c4113dSnw141292 * Input: 1126c5c4113dSnw141292 * gid - POSIX GID 1127c5c4113dSnw141292 * 1128c5c4113dSnw141292 * Output: 1129c5c4113dSnw141292 * stat - status of the get request 1130c5c4113dSnw141292 * sid - SID in canonical form (if stat == IDMAP_SUCCESS) 1131c5c4113dSnw141292 * rid - RID (if stat == IDMAP_SUCCESS) 1132c5c4113dSnw141292 * 1133c5c4113dSnw141292 * Note: The output parameters will be set by idmap_get_mappings() 1134c5c4113dSnw141292 */ 1135c5c4113dSnw141292 idmap_stat 1136c5c4113dSnw141292 kidmap_batch_getsidbygid(idmap_get_handle_t *get_handle, gid_t gid, 1137c5c4113dSnw141292 const char **sid_prefix, uint32_t *rid, idmap_stat *stat) 1138c5c4113dSnw141292 { 1139c5c4113dSnw141292 idmap_mapping *mapping; 1140c5c4113dSnw141292 idmap_get_res *result; 1141c5c4113dSnw141292 1142c5c4113dSnw141292 if (get_handle == NULL || sid_prefix == NULL || 1143c5c4113dSnw141292 rid == NULL || stat == NULL) 1144c5c4113dSnw141292 return (IDMAP_ERR_ARG); 1145c5c4113dSnw141292 1146bda89588Sjp151216 if (kidmap_cache_lookup_sidbygid(&get_handle->zs->cache, 1147bda89588Sjp151216 sid_prefix, rid, gid) == IDMAP_SUCCESS) { 1148c5c4113dSnw141292 *stat = IDMAP_SUCCESS; 1149c5c4113dSnw141292 return (IDMAP_SUCCESS); 1150c5c4113dSnw141292 } 1151c5c4113dSnw141292 1152c5c4113dSnw141292 if (get_handle->mapping_num >= get_handle->mapping_size) 1153c5c4113dSnw141292 kidmap_get_extend(get_handle); 1154c5c4113dSnw141292 1155c5c4113dSnw141292 mapping = &get_handle->mapping[get_handle->mapping_num]; 1156c5c4113dSnw141292 mapping->flag = 0; 1157c5c4113dSnw141292 mapping->id1.idtype = IDMAP_GID; 1158c5c4113dSnw141292 mapping->id1.idmap_id_u.gid = gid; 1159c5c4113dSnw141292 mapping->id2.idtype = IDMAP_SID; 1160c5c4113dSnw141292 1161c5c4113dSnw141292 result = &get_handle->result[get_handle->mapping_num]; 1162c5c4113dSnw141292 result->idtype = IDMAP_SID; 1163c5c4113dSnw141292 result->uid = NULL; 1164c5c4113dSnw141292 result->gid = NULL; 11650b10de9fSjp151216 result->pid = NULL; 1166c5c4113dSnw141292 result->sid_prefix = sid_prefix; 1167c5c4113dSnw141292 result->rid = rid; 1168c5c4113dSnw141292 result->is_user = NULL; 1169c5c4113dSnw141292 result->stat = stat; 1170c5c4113dSnw141292 1171c5c4113dSnw141292 get_handle->mapping_num++; 1172c5c4113dSnw141292 1173c5c4113dSnw141292 return (IDMAP_SUCCESS); 1174c5c4113dSnw141292 } 1175c5c4113dSnw141292 1176c5c4113dSnw141292 1177c5c4113dSnw141292 /* 1178c5c4113dSnw141292 * Process the batched "get mapping" requests. The results (i.e. 1179c5c4113dSnw141292 * status and identity) will be available in the data areas 1180c5c4113dSnw141292 * provided by individual requests. 1181c5c4113dSnw141292 * 1182c5c4113dSnw141292 * If the door call fails the status IDMAP_ERR_NOMAPPING is 1183c5c4113dSnw141292 * return and the UID or UID result is set to "nobody" 1184c5c4113dSnw141292 */ 1185c5c4113dSnw141292 1186c5c4113dSnw141292 idmap_stat 1187c5c4113dSnw141292 kidmap_get_mappings(idmap_get_handle_t *get_handle) 1188c5c4113dSnw141292 { 11899d0aba92Sjp151216 idmap_mapping_batch rpc_args; 11909d0aba92Sjp151216 idmap_ids_res rpc_res; 1191c5c4113dSnw141292 uint32_t op = IDMAP_GET_MAPPED_IDS; 1192d15447b6Sjp151216 idmap_mapping *request; 1193c5c4113dSnw141292 idmap_get_res *result; 1194c5c4113dSnw141292 idmap_id *id; 1195c5c4113dSnw141292 int status; 1196c5c4113dSnw141292 int i; 1197c5c4113dSnw141292 const char *sid_prefix; 1198c5c4113dSnw141292 int is_user; 1199bda89588Sjp151216 idmap_cache_t *cache; 1200d15447b6Sjp151216 int direction; 1201c5c4113dSnw141292 1202c5c4113dSnw141292 if (get_handle == NULL) 1203c5c4113dSnw141292 return (IDMAP_ERR_ARG); 1204c5c4113dSnw141292 1205c5c4113dSnw141292 if (get_handle->mapping_num == 0) 1206c5c4113dSnw141292 return (IDMAP_SUCCESS); 1207bda89588Sjp151216 cache = &get_handle->zs->cache; 1208c5c4113dSnw141292 12099d0aba92Sjp151216 bzero(&rpc_res, sizeof (idmap_ids_res)); 1210c5c4113dSnw141292 12119d0aba92Sjp151216 rpc_args.idmap_mapping_batch_len = get_handle->mapping_num; 12129d0aba92Sjp151216 rpc_args.idmap_mapping_batch_val = get_handle->mapping; 1213c5c4113dSnw141292 1214bda89588Sjp151216 if (kidmap_rpc_call(get_handle->zs, op, xdr_idmap_mapping_batch, 12159d0aba92Sjp151216 (caddr_t)&rpc_args, xdr_idmap_ids_res, 12169d0aba92Sjp151216 (caddr_t)&rpc_res) != 0) { 12179d0aba92Sjp151216 /* Door call failed */ 12189d0aba92Sjp151216 status = IDMAP_ERR_NOMAPPING; 12199d0aba92Sjp151216 goto error; 12209d0aba92Sjp151216 } 12219d0aba92Sjp151216 12229d0aba92Sjp151216 status = rpc_res.retcode; 12239d0aba92Sjp151216 if (status != IDMAP_SUCCESS) { 12249d0aba92Sjp151216 /* RPC returned idmap error code */ 12259d0aba92Sjp151216 xdr_free(xdr_idmap_ids_res, (char *)&rpc_res); 12269d0aba92Sjp151216 goto error; 12279d0aba92Sjp151216 } 12289d0aba92Sjp151216 1229c5c4113dSnw141292 for (i = 0; i < get_handle->mapping_num; i++) { 1230d15447b6Sjp151216 request = &get_handle->mapping[i]; 1231c5c4113dSnw141292 result = &get_handle->result[i]; 1232c5c4113dSnw141292 12339d0aba92Sjp151216 if (i >= rpc_res.ids.ids_len) { 1234c5c4113dSnw141292 *result->stat = IDMAP_ERR_NOMAPPING; 1235c5c4113dSnw141292 if (result->uid) 1236c5c4113dSnw141292 *result->uid = UID_NOBODY; 12370b10de9fSjp151216 if (result->gid) 12380b10de9fSjp151216 *result->gid = GID_NOBODY; 12390b10de9fSjp151216 if (result->pid) 12400b10de9fSjp151216 *result->pid = UID_NOBODY; 1241c5c4113dSnw141292 if (result->is_user) 1242c5c4113dSnw141292 *result->is_user = 1; 1243c5c4113dSnw141292 if (result->sid_prefix) 1244c5c4113dSnw141292 *result->sid_prefix = NULL; 1245c5c4113dSnw141292 if (result->rid) 1246c5c4113dSnw141292 *result->rid = 0; 1247c5c4113dSnw141292 continue; 1248c5c4113dSnw141292 } 1249c5c4113dSnw141292 12509d0aba92Sjp151216 *result->stat = rpc_res.ids.ids_val[i].retcode; 12519d0aba92Sjp151216 12529d0aba92Sjp151216 id = &rpc_res.ids.ids_val[i].id; 1253d15447b6Sjp151216 direction = rpc_res.ids.ids_val[i].direction; 1254d15447b6Sjp151216 1255c5c4113dSnw141292 switch (id->idtype) { 1256c5c4113dSnw141292 case IDMAP_UID: 1257c5c4113dSnw141292 if (result->uid) 1258c5c4113dSnw141292 *result->uid = id->idmap_id_u.uid; 12590b10de9fSjp151216 if (result->pid) 12600b10de9fSjp151216 *result->pid = id->idmap_id_u.uid; 1261c5c4113dSnw141292 if (result->is_user) 1262c5c4113dSnw141292 *result->is_user = 1; 1263c5c4113dSnw141292 sid_prefix = kidmap_find_sid_prefix( 1264d15447b6Sjp151216 request->id1.idmap_id_u.sid.prefix); 12659d0aba92Sjp151216 if (*result->stat == IDMAP_SUCCESS && result->uid) 1266d15447b6Sjp151216 kidmap_cache_add_sid2uid( 12679d0aba92Sjp151216 cache, sid_prefix, 1268d15447b6Sjp151216 request->id1.idmap_id_u.sid.rid, 1269d15447b6Sjp151216 id->idmap_id_u.uid, 1270d15447b6Sjp151216 direction); 12719d0aba92Sjp151216 else if (*result->stat == IDMAP_SUCCESS && result->pid) 1272d15447b6Sjp151216 kidmap_cache_add_sid2pid( 12739d0aba92Sjp151216 cache, sid_prefix, 1274d15447b6Sjp151216 request->id1.idmap_id_u.sid.rid, 1275d15447b6Sjp151216 id->idmap_id_u.uid, 1, 1276d15447b6Sjp151216 direction); 1277c5c4113dSnw141292 break; 1278c5c4113dSnw141292 1279c5c4113dSnw141292 case IDMAP_GID: 1280c5c4113dSnw141292 if (result->gid) 1281c5c4113dSnw141292 *result->gid = id->idmap_id_u.gid; 12820b10de9fSjp151216 if (result->pid) 12830b10de9fSjp151216 *result->pid = id->idmap_id_u.gid; 1284c5c4113dSnw141292 if (result->is_user) 1285c5c4113dSnw141292 *result->is_user = 0; 1286c5c4113dSnw141292 sid_prefix = kidmap_find_sid_prefix( 1287d15447b6Sjp151216 request->id1.idmap_id_u.sid.prefix); 12889d0aba92Sjp151216 if (*result->stat == IDMAP_SUCCESS && result->gid) 1289d15447b6Sjp151216 kidmap_cache_add_sid2gid( 12909d0aba92Sjp151216 cache, sid_prefix, 1291d15447b6Sjp151216 request->id1.idmap_id_u.sid.rid, 1292d15447b6Sjp151216 id->idmap_id_u.gid, 1293d15447b6Sjp151216 direction); 12949d0aba92Sjp151216 else if (*result->stat == IDMAP_SUCCESS && result->pid) 1295d15447b6Sjp151216 kidmap_cache_add_sid2pid( 12969d0aba92Sjp151216 cache, sid_prefix, 1297d15447b6Sjp151216 request->id1.idmap_id_u.sid.rid, 1298d15447b6Sjp151216 id->idmap_id_u.gid, 0, 1299d15447b6Sjp151216 direction); 1300c5c4113dSnw141292 break; 1301c5c4113dSnw141292 1302c5c4113dSnw141292 case IDMAP_SID: 1303cd37da74Snw141292 case IDMAP_USID: 1304cd37da74Snw141292 case IDMAP_GSID: 1305c5c4113dSnw141292 sid_prefix = kidmap_find_sid_prefix( 1306c5c4113dSnw141292 id->idmap_id_u.sid.prefix); 1307c5c4113dSnw141292 if (result->sid_prefix && result->rid) { 1308c5c4113dSnw141292 *result->sid_prefix = sid_prefix; 1309c5c4113dSnw141292 *result->rid = id->idmap_id_u.sid.rid; 1310c5c4113dSnw141292 } 13110b10de9fSjp151216 if (*result->stat == IDMAP_SUCCESS && 1312d15447b6Sjp151216 request->id1.idtype == IDMAP_UID) 1313d15447b6Sjp151216 kidmap_cache_add_sid2uid( 13149d0aba92Sjp151216 cache, sid_prefix, 1315c5c4113dSnw141292 id->idmap_id_u.sid.rid, 1316d15447b6Sjp151216 request->id1.idmap_id_u.uid, 1317d15447b6Sjp151216 direction); 13180b10de9fSjp151216 else if (*result->stat == IDMAP_SUCCESS && 1319d15447b6Sjp151216 request->id1.idtype == IDMAP_GID) 1320d15447b6Sjp151216 kidmap_cache_add_sid2gid( 13219d0aba92Sjp151216 cache, sid_prefix, 13220b10de9fSjp151216 id->idmap_id_u.sid.rid, 1323d15447b6Sjp151216 request->id1.idmap_id_u.gid, 1324d15447b6Sjp151216 direction); 1325c5c4113dSnw141292 break; 1326c5c4113dSnw141292 1327c5c4113dSnw141292 default: 1328c5c4113dSnw141292 *result->stat = IDMAP_ERR_NORESULT; 1329c5c4113dSnw141292 if (result->uid) 1330c5c4113dSnw141292 *result->uid = UID_NOBODY; 13310b10de9fSjp151216 if (result->gid) 13320b10de9fSjp151216 *result->gid = GID_NOBODY; 13330b10de9fSjp151216 if (result->pid) 13340b10de9fSjp151216 *result->pid = UID_NOBODY; 1335c5c4113dSnw141292 if (result->is_user) 1336c5c4113dSnw141292 *result->is_user = 1; 1337c5c4113dSnw141292 if (result->sid_prefix) 1338c5c4113dSnw141292 *result->sid_prefix = NULL; 1339c5c4113dSnw141292 if (result->rid) 1340c5c4113dSnw141292 *result->rid = 0; 1341c5c4113dSnw141292 break; 1342c5c4113dSnw141292 } 1343c5c4113dSnw141292 } 13449d0aba92Sjp151216 xdr_free(xdr_idmap_ids_res, (char *)&rpc_res); 13459d0aba92Sjp151216 13469d0aba92Sjp151216 /* Reset get_handle for new resquests */ 13479d0aba92Sjp151216 get_handle->mapping_num = 0; 13489d0aba92Sjp151216 return (status); 13499d0aba92Sjp151216 13509d0aba92Sjp151216 error: 1351c5c4113dSnw141292 for (i = 0; i < get_handle->mapping_num; i++) { 1352c5c4113dSnw141292 result = &get_handle->result[i]; 1353c5c4113dSnw141292 13549d0aba92Sjp151216 *result->stat = status; 1355c5c4113dSnw141292 if (result->uid) 1356c5c4113dSnw141292 *result->uid = UID_NOBODY; 13570b10de9fSjp151216 if (result->gid) 13580b10de9fSjp151216 *result->gid = GID_NOBODY; 13590b10de9fSjp151216 if (result->pid) 13600b10de9fSjp151216 *result->pid = UID_NOBODY; 1361c5c4113dSnw141292 if (result->is_user) 1362c5c4113dSnw141292 *result->is_user = 1; 1363c5c4113dSnw141292 if (result->sid_prefix) 1364c5c4113dSnw141292 *result->sid_prefix = NULL; 1365c5c4113dSnw141292 if (result->rid) 1366c5c4113dSnw141292 *result->rid = 0; 1367c5c4113dSnw141292 } 1368c5c4113dSnw141292 1369c5c4113dSnw141292 /* Reset get_handle for new resquests */ 1370c5c4113dSnw141292 get_handle->mapping_num = 0; 1371c5c4113dSnw141292 return (status); 1372c5c4113dSnw141292 } 1373c5c4113dSnw141292 1374c5c4113dSnw141292 1375c5c4113dSnw141292 /* 1376c5c4113dSnw141292 * Destroy the "get mapping" handle 1377c5c4113dSnw141292 */ 1378c5c4113dSnw141292 void 1379c5c4113dSnw141292 kidmap_get_destroy(idmap_get_handle_t *get_handle) 1380c5c4113dSnw141292 { 1381c5c4113dSnw141292 if (get_handle == NULL) 1382c5c4113dSnw141292 return; 1383c5c4113dSnw141292 1384c5c4113dSnw141292 kmem_free(get_handle->mapping, 1385c5c4113dSnw141292 (sizeof (idmap_mapping)) * get_handle->mapping_size); 1386c5c4113dSnw141292 get_handle->mapping = NULL; 1387c5c4113dSnw141292 1388c5c4113dSnw141292 kmem_free(get_handle->result, 1389c5c4113dSnw141292 (sizeof (idmap_get_res)) * get_handle->mapping_size); 1390c5c4113dSnw141292 get_handle->result = NULL; 1391c5c4113dSnw141292 1392c5c4113dSnw141292 kmem_free(get_handle, sizeof (idmap_get_handle_t)); 1393c5c4113dSnw141292 } 1394c5c4113dSnw141292 1395c5c4113dSnw141292 1396c5c4113dSnw141292 static int 1397bda89588Sjp151216 kidmap_rpc_call(idmap_zone_specific_t *zs, uint32_t op, xdrproc_t xdr_args, 1398bda89588Sjp151216 caddr_t args, xdrproc_t xdr_res, caddr_t res) 1399c5c4113dSnw141292 { 1400c5c4113dSnw141292 XDR xdr_ctx; 1401c5c4113dSnw141292 struct rpc_msg reply_msg; 1402c5c4113dSnw141292 char *inbuf_ptr = NULL; 1403c5c4113dSnw141292 size_t inbuf_size = 4096; 1404c5c4113dSnw141292 char *outbuf_ptr = NULL; 1405c5c4113dSnw141292 size_t outbuf_size = 4096; 1406c5c4113dSnw141292 size_t size; 1407c5c4113dSnw141292 int status = 0; 1408c5c4113dSnw141292 door_arg_t params; 1409c5c4113dSnw141292 int retry = 0; 1410bda89588Sjp151216 struct rpc_msg call_msg; 1411c5c4113dSnw141292 1412c5c4113dSnw141292 params.rbuf = NULL; 1413c5c4113dSnw141292 params.rsize = 0; 1414c5c4113dSnw141292 1415c5c4113dSnw141292 retry: 1416c5c4113dSnw141292 inbuf_ptr = kmem_alloc(inbuf_size, KM_SLEEP); 1417c5c4113dSnw141292 outbuf_ptr = kmem_alloc(outbuf_size, KM_SLEEP); 1418c5c4113dSnw141292 1419c5c4113dSnw141292 xdrmem_create(&xdr_ctx, inbuf_ptr, inbuf_size, XDR_ENCODE); 1420bda89588Sjp151216 1421bda89588Sjp151216 call_msg.rm_call.cb_prog = IDMAP_PROG; 1422bda89588Sjp151216 call_msg.rm_call.cb_vers = IDMAP_V1; 1423bda89588Sjp151216 call_msg.rm_xid = atomic_inc_32_nv(&zs->message_id); 1424bda89588Sjp151216 1425c5c4113dSnw141292 if (!xdr_callhdr(&xdr_ctx, &call_msg)) { 1426c5c4113dSnw141292 #ifdef DEBUG 1427f7b4b2feSjp151216 zcmn_err(zs->zone_id, CE_WARN, 1428f7b4b2feSjp151216 "idmap: xdr encoding header error"); 1429c5c4113dSnw141292 #endif /* DEBUG */ 1430c5c4113dSnw141292 status = -1; 1431c5c4113dSnw141292 goto exit; 1432c5c4113dSnw141292 } 1433c5c4113dSnw141292 1434c5c4113dSnw141292 if (!xdr_uint32(&xdr_ctx, &op) || 1435c5c4113dSnw141292 /* Auth none */ 1436c5c4113dSnw141292 !xdr_opaque_auth(&xdr_ctx, &_null_auth) || 1437c5c4113dSnw141292 !xdr_opaque_auth(&xdr_ctx, &_null_auth) || 1438c5c4113dSnw141292 /* RPC args */ 1439c5c4113dSnw141292 !xdr_args(&xdr_ctx, args)) { 1440c5c4113dSnw141292 #ifdef DEBUG 1441f7b4b2feSjp151216 zcmn_err(zs->zone_id, CE_WARN, "idmap: xdr encoding error"); 1442c5c4113dSnw141292 #endif /* DEBUG */ 1443c5c4113dSnw141292 if (retry > 2) { 1444c5c4113dSnw141292 status = -1; 1445c5c4113dSnw141292 goto exit; 1446c5c4113dSnw141292 } 1447c5c4113dSnw141292 retry++; 1448c5c4113dSnw141292 if (inbuf_ptr) { 1449c5c4113dSnw141292 kmem_free(inbuf_ptr, inbuf_size); 1450c5c4113dSnw141292 inbuf_ptr = NULL; 1451c5c4113dSnw141292 } 1452c5c4113dSnw141292 if (outbuf_ptr) { 1453c5c4113dSnw141292 kmem_free(outbuf_ptr, outbuf_size); 1454c5c4113dSnw141292 outbuf_ptr = NULL; 1455c5c4113dSnw141292 } 1456c5c4113dSnw141292 if ((size = xdr_sizeof(xdr_args, args)) == 0) { 1457c5c4113dSnw141292 #ifdef DEBUG 1458f7b4b2feSjp151216 zcmn_err(zs->zone_id, CE_WARN, 1459f7b4b2feSjp151216 "idmap: xdr_sizeof error"); 1460c5c4113dSnw141292 #endif /* DEBUG */ 1461c5c4113dSnw141292 status = -1; 1462c5c4113dSnw141292 goto exit; 1463c5c4113dSnw141292 } 1464c5c4113dSnw141292 inbuf_size = size + 1024; 1465c5c4113dSnw141292 outbuf_size = size + 1024; 1466c5c4113dSnw141292 goto retry; 1467c5c4113dSnw141292 } 1468c5c4113dSnw141292 1469c5c4113dSnw141292 params.data_ptr = inbuf_ptr; 1470c5c4113dSnw141292 params.data_size = XDR_GETPOS(&xdr_ctx); 1471c5c4113dSnw141292 params.desc_ptr = NULL; 1472c5c4113dSnw141292 params.desc_num = 0; 1473c5c4113dSnw141292 params.rbuf = outbuf_ptr; 1474c5c4113dSnw141292 params.rsize = outbuf_size; 1475c5c4113dSnw141292 1476bda89588Sjp151216 if (kidmap_call_door(zs, ¶ms) != 0) { 1477c5c4113dSnw141292 status = -1; 1478c5c4113dSnw141292 goto exit; 1479c5c4113dSnw141292 } 1480c5c4113dSnw141292 1481c5c4113dSnw141292 reply_msg.acpted_rply.ar_verf = _null_auth; 1482c5c4113dSnw141292 reply_msg.acpted_rply.ar_results.where = res; 1483c5c4113dSnw141292 reply_msg.acpted_rply.ar_results.proc = xdr_res; 1484c5c4113dSnw141292 xdrmem_create(&xdr_ctx, params.data_ptr, params.data_size, XDR_DECODE); 1485c5c4113dSnw141292 if (xdr_replymsg(&xdr_ctx, &reply_msg)) { 1486c5c4113dSnw141292 if (reply_msg.rm_reply.rp_stat != MSG_ACCEPTED || 1487c5c4113dSnw141292 reply_msg.rm_reply.rp_acpt.ar_stat != SUCCESS) { 1488c5c4113dSnw141292 status = -1; 1489c5c4113dSnw141292 goto exit; 1490c5c4113dSnw141292 } 1491c5c4113dSnw141292 } else { 1492c5c4113dSnw141292 #ifdef DEBUG 1493f7b4b2feSjp151216 zcmn_err(zs->zone_id, CE_WARN, 1494f7b4b2feSjp151216 "idmap: xdr decoding reply message error"); 1495c5c4113dSnw141292 #endif /* DEBUG */ 1496c5c4113dSnw141292 status = -1; 1497c5c4113dSnw141292 } 1498c5c4113dSnw141292 1499c5c4113dSnw141292 exit: 1500c5c4113dSnw141292 if (outbuf_ptr != params.rbuf && params.rbuf != NULL) 1501c5c4113dSnw141292 kmem_free(params.rbuf, params.rsize); 1502c5c4113dSnw141292 if (inbuf_ptr) 1503c5c4113dSnw141292 kmem_free(inbuf_ptr, inbuf_size); 1504c5c4113dSnw141292 if (outbuf_ptr) 1505c5c4113dSnw141292 kmem_free(outbuf_ptr, outbuf_size); 1506c5c4113dSnw141292 return (status); 1507c5c4113dSnw141292 } 1508