14520Snw141292 /* 24520Snw141292 * CDDL HEADER START 34520Snw141292 * 44520Snw141292 * The contents of this file are subject to the terms of the 54520Snw141292 * Common Development and Distribution License (the "License"). 64520Snw141292 * You may not use this file except in compliance with the License. 74520Snw141292 * 84520Snw141292 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 94520Snw141292 * or http://www.opensolaris.org/os/licensing. 104520Snw141292 * See the License for the specific language governing permissions 114520Snw141292 * and limitations under the License. 124520Snw141292 * 134520Snw141292 * When distributing Covered Code, include this CDDL HEADER in each 144520Snw141292 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 154520Snw141292 * If applicable, add the following below this CDDL HEADER, with the 164520Snw141292 * fields enclosed by brackets "[]" replaced with your own identifying 174520Snw141292 * information: Portions Copyright [yyyy] [name of copyright owner] 184520Snw141292 * 194520Snw141292 * CDDL HEADER END 204520Snw141292 */ 214520Snw141292 /* 224520Snw141292 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 234520Snw141292 * Use is subject to license terms. 244520Snw141292 */ 254520Snw141292 264520Snw141292 #pragma ident "%Z%%M% %I% %E% SMI" 274520Snw141292 284520Snw141292 /* 294520Snw141292 * libidmap API 304520Snw141292 */ 314520Snw141292 324520Snw141292 #include <stdlib.h> 334520Snw141292 #include <inttypes.h> 344520Snw141292 #include <errno.h> 354520Snw141292 #include <strings.h> 364520Snw141292 #include <ctype.h> 374520Snw141292 #include <sys/param.h> 384520Snw141292 #include <sys/types.h> 394520Snw141292 #include <sys/stat.h> 404520Snw141292 #include <dlfcn.h> 414520Snw141292 #include <libintl.h> 424520Snw141292 #include "idmap_impl.h" 434520Snw141292 444520Snw141292 static struct timeval TIMEOUT = { 25, 0 }; 454520Snw141292 464520Snw141292 static int idmap_stat2errno(idmap_stat); 47*5064Sdm199847 static idmap_stat idmap_strdupnull(char **, const char *); 484520Snw141292 494520Snw141292 #define __ITER_CREATE(itera, argu, handl, ityp)\ 504520Snw141292 if (handl == NULL) {\ 514520Snw141292 errno = EINVAL;\ 524520Snw141292 return (IDMAP_ERR_ARG);\ 534520Snw141292 }\ 544520Snw141292 itera = calloc(1, sizeof (*itera));\ 554520Snw141292 if (itera == NULL) {\ 564520Snw141292 errno = ENOMEM;\ 574520Snw141292 return (IDMAP_ERR_MEMORY);\ 584520Snw141292 }\ 594520Snw141292 argu = calloc(1, sizeof (*argu));\ 604520Snw141292 if (argu == NULL) {\ 614520Snw141292 free(itera);\ 624520Snw141292 errno = ENOMEM;\ 634520Snw141292 return (IDMAP_ERR_MEMORY);\ 644520Snw141292 }\ 654520Snw141292 itera->ih = handl;\ 664520Snw141292 itera->type = ityp;\ 674520Snw141292 itera->retcode = IDMAP_NEXT;\ 684520Snw141292 itera->limit = 1024;\ 694520Snw141292 itera->arg = argu; 704520Snw141292 714520Snw141292 724520Snw141292 #define __ITER_ERR_RETURN(itera, argu, xdr_argu, iretcod)\ 734520Snw141292 if (argu) {\ 744520Snw141292 xdr_free(xdr_argu, (caddr_t)argu);\ 754520Snw141292 free(argu);\ 764520Snw141292 }\ 774520Snw141292 if (itera)\ 784520Snw141292 free(itera);\ 794520Snw141292 return (iretcod); 804520Snw141292 814520Snw141292 824520Snw141292 #define __ITER_CHECK(itera, ityp)\ 834520Snw141292 if (itera == NULL) {\ 844520Snw141292 errno = EINVAL;\ 854520Snw141292 return (IDMAP_ERR_ARG);\ 864520Snw141292 }\ 874520Snw141292 if (itera->type != ityp) {\ 884520Snw141292 errno = EINVAL;\ 894520Snw141292 return (IDMAP_ERR_ARG);\ 904520Snw141292 } 914520Snw141292 92*5064Sdm199847 #define EMPTY_STRING(str) (str == NULL || *str == '\0') 934520Snw141292 944520Snw141292 /* 954520Snw141292 * Free memory allocated by libidmap API 964520Snw141292 * 974520Snw141292 * Input: 984520Snw141292 * ptr - memory to be freed 994520Snw141292 */ 1004520Snw141292 void 1014520Snw141292 idmap_free(void *ptr) { 1024520Snw141292 free(ptr); 1034520Snw141292 } 1044520Snw141292 1054520Snw141292 1064520Snw141292 /* 1074520Snw141292 * Create and Initialize idmap client handle for rpc/doors 1084520Snw141292 * 1094520Snw141292 * Output: 1104520Snw141292 * handle - idmap handle 1114520Snw141292 */ 1124520Snw141292 idmap_stat 1134520Snw141292 idmap_init(idmap_handle_t **handle) { 1144520Snw141292 CLIENT *clnt = NULL; 1154520Snw141292 struct idmap_handle *hptr; 1164520Snw141292 1174520Snw141292 *handle = NULL; 1184520Snw141292 hptr = (struct idmap_handle *)calloc(1, sizeof (*hptr)); 1194520Snw141292 if (hptr == NULL) 1204520Snw141292 return (IDMAP_ERR_MEMORY); 1214520Snw141292 1224520Snw141292 clnt = clnt_door_create(IDMAP_PROG, IDMAP_V1, 0); 1234520Snw141292 if (clnt == NULL) { 1244520Snw141292 free(hptr); 1254520Snw141292 return (IDMAP_ERR_RPC); 1264520Snw141292 } 1274520Snw141292 hptr->type = _IDMAP_HANDLE_RPC_DOORS; 1284520Snw141292 hptr->privhandle = clnt; 1294520Snw141292 *handle = hptr; 1304520Snw141292 return (IDMAP_SUCCESS); 1314520Snw141292 } 1324520Snw141292 1334520Snw141292 1344520Snw141292 /* 1354520Snw141292 * Finalize idmap handle 1364520Snw141292 * 1374520Snw141292 * Input: 1384520Snw141292 * handle - idmap handle 1394520Snw141292 */ 1404520Snw141292 idmap_stat 1414520Snw141292 idmap_fini(idmap_handle_t *handle) { 1424520Snw141292 CLIENT *clnt; 1434520Snw141292 struct idmap_handle *hptr; 1444520Snw141292 1454520Snw141292 if (handle == NULL) 1464520Snw141292 return (IDMAP_SUCCESS); 1474520Snw141292 1484520Snw141292 hptr = (struct idmap_handle *)handle; 1494520Snw141292 1504520Snw141292 switch (hptr->type) { 1514520Snw141292 case _IDMAP_HANDLE_RPC_DOORS: 1524520Snw141292 clnt = (CLIENT *)hptr->privhandle; 1534520Snw141292 if (clnt) { 1544520Snw141292 if (clnt->cl_auth) 1554520Snw141292 auth_destroy(clnt->cl_auth); 1564520Snw141292 clnt_destroy(clnt); 1574520Snw141292 } 1584520Snw141292 break; 1594520Snw141292 default: 1604520Snw141292 break; 1614520Snw141292 } 1624520Snw141292 free(hptr); 1634520Snw141292 return (IDMAP_SUCCESS); 1644520Snw141292 } 1654520Snw141292 1664520Snw141292 1674520Snw141292 1684520Snw141292 /* 1694520Snw141292 * Create/Initialize handle for updates 1704520Snw141292 * 1714520Snw141292 * Output: 1724520Snw141292 * udthandle - update handle 1734520Snw141292 */ 1744520Snw141292 idmap_stat 1754520Snw141292 idmap_udt_create(idmap_handle_t *handle, idmap_udt_handle_t **udthandle) { 1764520Snw141292 idmap_udt_handle_t *tmp; 1774520Snw141292 1784520Snw141292 if (handle == NULL || udthandle == NULL) { 1794520Snw141292 errno = EINVAL; 1804520Snw141292 return (IDMAP_ERR_ARG); 1814520Snw141292 } 1824520Snw141292 if ((tmp = calloc(1, sizeof (*tmp))) == NULL) { 1834520Snw141292 errno = ENOMEM; 1844520Snw141292 return (IDMAP_ERR_MEMORY); 1854520Snw141292 } 1864520Snw141292 1874520Snw141292 tmp->ih = handle; 1884520Snw141292 *udthandle = tmp; 1894520Snw141292 return (IDMAP_SUCCESS); 1904520Snw141292 } 1914520Snw141292 1924520Snw141292 1934520Snw141292 /* 1944520Snw141292 * All the updates specified by the update handle are committed 1954520Snw141292 * in a single transaction. i.e either all succeed or none. 1964520Snw141292 * 1974520Snw141292 * Input: 1984520Snw141292 * udthandle - update handle with the update requests 1994520Snw141292 * 2004520Snw141292 * Return value: 2014520Snw141292 * Status of the commit 2024520Snw141292 */ 2034520Snw141292 idmap_stat 2044520Snw141292 idmap_udt_commit(idmap_udt_handle_t *udthandle) { 2054520Snw141292 CLIENT *clnt; 2064520Snw141292 enum clnt_stat clntstat; 207*5064Sdm199847 idmap_update_res res; 208*5064Sdm199847 idmap_stat retcode; 2094520Snw141292 2104520Snw141292 if (udthandle == NULL) { 2114520Snw141292 errno = EINVAL; 2124520Snw141292 return (IDMAP_ERR_ARG); 2134520Snw141292 } 214*5064Sdm199847 215*5064Sdm199847 (void) memset(&res, 0, sizeof (res)); 216*5064Sdm199847 2174520Snw141292 _IDMAP_GET_CLIENT_HANDLE(udthandle->ih, clnt); 2184520Snw141292 clntstat = clnt_call(clnt, IDMAP_UPDATE, 2194520Snw141292 (xdrproc_t)xdr_idmap_update_batch, (caddr_t)&udthandle->batch, 220*5064Sdm199847 (xdrproc_t)xdr_idmap_update_res, (caddr_t)&res, 2214520Snw141292 TIMEOUT); 2224644Sbaban 223*5064Sdm199847 if (clntstat != RPC_SUCCESS) { 224*5064Sdm199847 retcode = _idmap_rpc2stat(clnt); 225*5064Sdm199847 goto out; 226*5064Sdm199847 } 227*5064Sdm199847 228*5064Sdm199847 retcode = udthandle->commit_stat = res.retcode; 229*5064Sdm199847 udthandle->error_index = res.error_index; 230*5064Sdm199847 231*5064Sdm199847 if (retcode != IDMAP_SUCCESS) { 232*5064Sdm199847 233*5064Sdm199847 if (udthandle->error_index < 0) 234*5064Sdm199847 goto out; 235*5064Sdm199847 236*5064Sdm199847 retcode = idmap_namerule_cpy(&udthandle->error_rule, 237*5064Sdm199847 &res.error_rule); 238*5064Sdm199847 if (retcode != IDMAP_SUCCESS) { 239*5064Sdm199847 udthandle->error_index = -2; 240*5064Sdm199847 goto out; 241*5064Sdm199847 } 242*5064Sdm199847 243*5064Sdm199847 retcode = idmap_namerule_cpy(&udthandle->conflict_rule, 244*5064Sdm199847 &res.conflict_rule); 245*5064Sdm199847 if (retcode != IDMAP_SUCCESS) { 246*5064Sdm199847 udthandle->error_index = -2; 247*5064Sdm199847 goto out; 248*5064Sdm199847 } 249*5064Sdm199847 } 250*5064Sdm199847 251*5064Sdm199847 retcode = res.retcode; 252*5064Sdm199847 253*5064Sdm199847 254*5064Sdm199847 out: 2554644Sbaban /* reset handle so that it can be used again */ 256*5064Sdm199847 if (retcode == IDMAP_SUCCESS) { 257*5064Sdm199847 _IDMAP_RESET_UDT_HANDLE(udthandle); 258*5064Sdm199847 } 259*5064Sdm199847 260*5064Sdm199847 (void) xdr_free(xdr_idmap_update_res, (caddr_t)&res); 261*5064Sdm199847 errno = idmap_stat2errno(retcode); 262*5064Sdm199847 return (retcode); 263*5064Sdm199847 } 264*5064Sdm199847 265*5064Sdm199847 266*5064Sdm199847 static void 267*5064Sdm199847 idmap_namerule_parts_clear(char **windomain, char **winname, 268*5064Sdm199847 char **unixname, boolean_t *is_user, boolean_t *is_nt4, 269*5064Sdm199847 int *direction) { 270*5064Sdm199847 if (windomain) 271*5064Sdm199847 *windomain = NULL; 272*5064Sdm199847 if (winname) 273*5064Sdm199847 *winname = NULL; 274*5064Sdm199847 if (unixname) 275*5064Sdm199847 *unixname = NULL; 276*5064Sdm199847 277*5064Sdm199847 if (is_nt4) 278*5064Sdm199847 *is_nt4 = 0; 279*5064Sdm199847 if (is_user) 280*5064Sdm199847 *is_user = -1; 281*5064Sdm199847 if (direction) 282*5064Sdm199847 *direction = IDMAP_DIRECTION_UNDEF; 283*5064Sdm199847 } 284*5064Sdm199847 285*5064Sdm199847 static idmap_stat 286*5064Sdm199847 idmap_namerule2parts(idmap_namerule *rule, 287*5064Sdm199847 char **windomain, char **winname, 288*5064Sdm199847 char **unixname, boolean_t *is_user, boolean_t *is_nt4, 289*5064Sdm199847 int *direction) { 290*5064Sdm199847 idmap_stat retcode; 291*5064Sdm199847 292*5064Sdm199847 if (EMPTY_STRING(rule->winname) && EMPTY_STRING(rule->unixname)) 293*5064Sdm199847 return (IDMAP_ERR_NORESULT); 294*5064Sdm199847 295*5064Sdm199847 296*5064Sdm199847 retcode = idmap_strdupnull(windomain, rule->windomain); 297*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 298*5064Sdm199847 goto errout; 299*5064Sdm199847 300*5064Sdm199847 retcode = idmap_strdupnull(winname, rule->winname); 301*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 302*5064Sdm199847 goto errout; 303*5064Sdm199847 304*5064Sdm199847 retcode = idmap_strdupnull(unixname, rule->unixname); 305*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 306*5064Sdm199847 goto errout; 307*5064Sdm199847 308*5064Sdm199847 309*5064Sdm199847 if (is_user) 310*5064Sdm199847 *is_user = rule->is_user; 311*5064Sdm199847 if (is_nt4) 312*5064Sdm199847 *is_nt4 = rule->is_nt4; 313*5064Sdm199847 if (direction) 314*5064Sdm199847 *direction = rule->direction; 315*5064Sdm199847 316*5064Sdm199847 317*5064Sdm199847 return (IDMAP_SUCCESS); 3184644Sbaban 319*5064Sdm199847 errout: 320*5064Sdm199847 if (windomain && *windomain) 321*5064Sdm199847 free(*windomain); 322*5064Sdm199847 if (winname && *winname) 323*5064Sdm199847 free(*winname); 324*5064Sdm199847 if (unixname && *unixname) 325*5064Sdm199847 free(*unixname); 326*5064Sdm199847 327*5064Sdm199847 idmap_namerule_parts_clear(windomain, winname, 328*5064Sdm199847 unixname, is_user, is_nt4, direction); 329*5064Sdm199847 3304520Snw141292 return (retcode); 331*5064Sdm199847 332*5064Sdm199847 } 333*5064Sdm199847 334*5064Sdm199847 /* 335*5064Sdm199847 * Retrieve the index of the failed batch element. error_index == -1 336*5064Sdm199847 * indicates failure at the beginning, -2 at the end. 337*5064Sdm199847 * 338*5064Sdm199847 * If idmap_udt_commit didn't return error, the returned value is undefined. 339*5064Sdm199847 * 340*5064Sdm199847 * Return value: 341*5064Sdm199847 * IDMAP_SUCCESS 342*5064Sdm199847 */ 343*5064Sdm199847 344*5064Sdm199847 idmap_stat 345*5064Sdm199847 idmap_udt_get_error_index(idmap_udt_handle_t *udthandle, 346*5064Sdm199847 int64_t *error_index) { 347*5064Sdm199847 if (error_index) 348*5064Sdm199847 *error_index = udthandle->error_index; 349*5064Sdm199847 350*5064Sdm199847 return (IDMAP_SUCCESS); 351*5064Sdm199847 } 352*5064Sdm199847 353*5064Sdm199847 354*5064Sdm199847 /* 355*5064Sdm199847 * Retrieve the rule which caused the batch to fail. If 356*5064Sdm199847 * idmap_udt_commit didn't return error or if error_index is < 0, the 357*5064Sdm199847 * retrieved rule is undefined. 358*5064Sdm199847 * 359*5064Sdm199847 * Return value: 360*5064Sdm199847 * IDMAP_ERR_NORESULT if there is no error rule. 361*5064Sdm199847 * IDMAP_SUCCESS if the rule was obtained OK. 362*5064Sdm199847 * other error code (IDMAP_ERR_NOMEMORY etc) 363*5064Sdm199847 */ 364*5064Sdm199847 365*5064Sdm199847 idmap_stat 366*5064Sdm199847 idmap_udt_get_error_rule(idmap_udt_handle_t *udthandle, 367*5064Sdm199847 char **windomain, char **winname, 368*5064Sdm199847 char **unixname, boolean_t *is_user, boolean_t *is_nt4, 369*5064Sdm199847 int *direction) { 370*5064Sdm199847 idmap_namerule_parts_clear(windomain, winname, 371*5064Sdm199847 unixname, is_user, is_nt4, direction); 372*5064Sdm199847 373*5064Sdm199847 if (udthandle->commit_stat == IDMAP_SUCCESS || 374*5064Sdm199847 udthandle->error_index < 0) 375*5064Sdm199847 return (IDMAP_ERR_NORESULT); 376*5064Sdm199847 377*5064Sdm199847 return (idmap_namerule2parts( 378*5064Sdm199847 &udthandle->error_rule, 379*5064Sdm199847 windomain, 380*5064Sdm199847 winname, 381*5064Sdm199847 unixname, 382*5064Sdm199847 is_user, 383*5064Sdm199847 is_nt4, 384*5064Sdm199847 direction)); 385*5064Sdm199847 } 386*5064Sdm199847 387*5064Sdm199847 /* 388*5064Sdm199847 * Retrieve the rule with which there was a conflict. TODO: retrieve 389*5064Sdm199847 * the value. 390*5064Sdm199847 * 391*5064Sdm199847 * Return value: 392*5064Sdm199847 * IDMAP_ERR_NORESULT if there is no error rule. 393*5064Sdm199847 * IDMAP_SUCCESS if the rule was obtained OK. 394*5064Sdm199847 * other error code (IDMAP_ERR_NOMEMORY etc) 395*5064Sdm199847 */ 396*5064Sdm199847 397*5064Sdm199847 idmap_stat 398*5064Sdm199847 idmap_udt_get_conflict_rule(idmap_udt_handle_t *udthandle, 399*5064Sdm199847 char **windomain, char **winname, 400*5064Sdm199847 char **unixname, boolean_t *is_user, boolean_t *is_nt4, 401*5064Sdm199847 int *direction) { 402*5064Sdm199847 idmap_namerule_parts_clear(windomain, winname, 403*5064Sdm199847 unixname, is_user, is_nt4, direction); 404*5064Sdm199847 405*5064Sdm199847 if (udthandle->commit_stat != IDMAP_ERR_W2U_NAMERULE_CONFLICT && 406*5064Sdm199847 udthandle->commit_stat != IDMAP_ERR_U2W_NAMERULE_CONFLICT) { 407*5064Sdm199847 return (IDMAP_ERR_NORESULT); 408*5064Sdm199847 } 409*5064Sdm199847 410*5064Sdm199847 return (idmap_namerule2parts( 411*5064Sdm199847 &udthandle->conflict_rule, 412*5064Sdm199847 windomain, 413*5064Sdm199847 winname, 414*5064Sdm199847 unixname, 415*5064Sdm199847 is_user, 416*5064Sdm199847 is_nt4, 417*5064Sdm199847 direction)); 4184520Snw141292 } 4194520Snw141292 4204520Snw141292 4214520Snw141292 /* 4224520Snw141292 * Destroy the update handle 4234520Snw141292 */ 4244520Snw141292 void 4254520Snw141292 idmap_udt_destroy(idmap_udt_handle_t *udthandle) { 4264520Snw141292 if (udthandle == NULL) 4274520Snw141292 return; 4284520Snw141292 (void) xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch); 429*5064Sdm199847 (void) xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->error_rule); 430*5064Sdm199847 (void) xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->conflict_rule); 4314520Snw141292 free(udthandle); 4324520Snw141292 } 4334520Snw141292 4344520Snw141292 4354520Snw141292 idmap_stat 4364520Snw141292 idmap_udt_add_namerule(idmap_udt_handle_t *udthandle, const char *windomain, 4374520Snw141292 boolean_t is_user, const char *winname, const char *unixname, 4384520Snw141292 boolean_t is_nt4, int direction) { 4394520Snw141292 idmap_retcode retcode; 4404644Sbaban idmap_namerule *rule = NULL; 4414520Snw141292 4424644Sbaban retcode = _udt_extend_batch(udthandle); 4434520Snw141292 if (retcode != IDMAP_SUCCESS) 4444520Snw141292 goto errout; 4454520Snw141292 4464520Snw141292 rule = &udthandle->batch. 4474520Snw141292 idmap_update_batch_val[udthandle->next]. 4484520Snw141292 idmap_update_op_u.rule; 4494520Snw141292 rule->is_user = is_user; 4504520Snw141292 rule->direction = direction; 4514520Snw141292 rule->is_nt4 = is_nt4; 452*5064Sdm199847 453*5064Sdm199847 retcode = idmap_strdupnull(&rule->windomain, windomain); 454*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 455*5064Sdm199847 goto errout; 456*5064Sdm199847 457*5064Sdm199847 retcode = idmap_strdupnull(&rule->winname, winname); 458*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 459*5064Sdm199847 goto errout; 460*5064Sdm199847 461*5064Sdm199847 retcode = idmap_strdupnull(&rule->unixname, unixname); 462*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 463*5064Sdm199847 goto errout; 4644644Sbaban 4654644Sbaban udthandle->batch.idmap_update_batch_val[udthandle->next].opnum = 4664644Sbaban OP_ADD_NAMERULE; 4674520Snw141292 udthandle->next++; 4684520Snw141292 return (IDMAP_SUCCESS); 4694520Snw141292 4704520Snw141292 errout: 4714644Sbaban /* The batch should still be usable */ 4724644Sbaban if (rule) 4734644Sbaban (void) xdr_free(xdr_idmap_namerule, (caddr_t)rule); 4744520Snw141292 errno = idmap_stat2errno(retcode); 4754520Snw141292 return (retcode); 4764520Snw141292 } 4774520Snw141292 4784520Snw141292 4794520Snw141292 /* ARGSUSED */ 4804520Snw141292 idmap_stat 4814520Snw141292 idmap_udt_rm_namerule(idmap_udt_handle_t *udthandle, boolean_t is_user, 4824520Snw141292 const char *windomain, const char *winname, 4834520Snw141292 const char *unixname, int direction) { 4844520Snw141292 idmap_retcode retcode; 4854644Sbaban idmap_namerule *rule = NULL; 4864520Snw141292 4874644Sbaban retcode = _udt_extend_batch(udthandle); 4884520Snw141292 if (retcode != IDMAP_SUCCESS) 4894520Snw141292 goto errout; 4904520Snw141292 4914520Snw141292 rule = &udthandle->batch. 4924520Snw141292 idmap_update_batch_val[udthandle->next]. 4934520Snw141292 idmap_update_op_u.rule; 4944520Snw141292 rule->is_user = is_user; 4954520Snw141292 rule->direction = direction; 496*5064Sdm199847 497*5064Sdm199847 retcode = idmap_strdupnull(&rule->windomain, windomain); 498*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 499*5064Sdm199847 goto errout; 500*5064Sdm199847 501*5064Sdm199847 retcode = idmap_strdupnull(&rule->winname, winname); 502*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 503*5064Sdm199847 goto errout; 504*5064Sdm199847 505*5064Sdm199847 retcode = idmap_strdupnull(&rule->unixname, unixname); 506*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 507*5064Sdm199847 goto errout; 508*5064Sdm199847 5094644Sbaban udthandle->batch.idmap_update_batch_val[udthandle->next].opnum = 5104644Sbaban OP_RM_NAMERULE; 5114520Snw141292 udthandle->next++; 5124520Snw141292 return (IDMAP_SUCCESS); 5134520Snw141292 5144520Snw141292 errout: 5154644Sbaban if (rule) 5164644Sbaban (void) xdr_free(xdr_idmap_namerule, (caddr_t)rule); 5174520Snw141292 errno = idmap_stat2errno(retcode); 5184520Snw141292 return (retcode); 5194520Snw141292 } 5204520Snw141292 5214520Snw141292 5224520Snw141292 /* ARGSUSED */ 5234520Snw141292 idmap_stat 5244520Snw141292 idmap_udt_flush_namerules(idmap_udt_handle_t *udthandle, boolean_t is_user) { 5254520Snw141292 idmap_retcode retcode; 5264520Snw141292 5274644Sbaban retcode = _udt_extend_batch(udthandle); 5284520Snw141292 if (retcode != IDMAP_SUCCESS) 5294520Snw141292 goto errout; 5304520Snw141292 5314520Snw141292 udthandle->batch.idmap_update_batch_val[udthandle->next]. 5324520Snw141292 idmap_update_op_u.is_user = is_user; 5334520Snw141292 5344644Sbaban udthandle->batch.idmap_update_batch_val[udthandle->next].opnum = 5354644Sbaban OP_FLUSH_NAMERULES; 5364520Snw141292 udthandle->next++; 5374520Snw141292 return (IDMAP_SUCCESS); 5384520Snw141292 5394520Snw141292 errout: 5404520Snw141292 errno = idmap_stat2errno(retcode); 5414520Snw141292 return (retcode); 5424520Snw141292 } 5434520Snw141292 5444520Snw141292 5454520Snw141292 /* 5464520Snw141292 * Set the number of entries requested per batch by the iterator 5474520Snw141292 * 5484520Snw141292 * Input: 5494520Snw141292 * iter - iterator 5504520Snw141292 * limit - number of entries requested per batch 5514520Snw141292 */ 5524520Snw141292 idmap_stat 5534520Snw141292 idmap_iter_set_limit(idmap_iter_t *iter, uint64_t limit) { 5544520Snw141292 if (iter == NULL) { 5554520Snw141292 errno = EINVAL; 5564520Snw141292 return (IDMAP_ERR_ARG); 5574520Snw141292 } 5584520Snw141292 iter->limit = limit; 5594520Snw141292 return (IDMAP_SUCCESS); 5604520Snw141292 } 5614520Snw141292 5624520Snw141292 5634520Snw141292 /* 5644520Snw141292 * Create iterator to get name-based mapping rules 5654520Snw141292 * 5664520Snw141292 * Input: 5674520Snw141292 * windomain - Windows domain 5684520Snw141292 * is_user - user or group rules 5694520Snw141292 * winname - Windows user or group name 5704520Snw141292 * unixname - Unix user or group name 5714520Snw141292 * 5724520Snw141292 * Output: 5734520Snw141292 * iter - iterator 5744520Snw141292 */ 5754520Snw141292 idmap_stat 5764520Snw141292 idmap_iter_namerules(idmap_handle_t *handle, const char *windomain, 5774520Snw141292 boolean_t is_user, const char *winname, 5784520Snw141292 const char *unixname, idmap_iter_t **iter) { 5794520Snw141292 5804520Snw141292 idmap_iter_t *tmpiter; 5814520Snw141292 idmap_list_namerules_1_argument *arg = NULL; 5824520Snw141292 idmap_namerule *rule; 5834520Snw141292 idmap_retcode retcode; 5844520Snw141292 5854520Snw141292 __ITER_CREATE(tmpiter, arg, handle, IDMAP_LIST_NAMERULES); 5864520Snw141292 5874520Snw141292 rule = &arg->rule; 5884520Snw141292 rule->is_user = is_user; 5894644Sbaban rule->direction = IDMAP_DIRECTION_UNDEF; 590*5064Sdm199847 591*5064Sdm199847 retcode = idmap_strdupnull(&rule->windomain, windomain); 592*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 593*5064Sdm199847 goto errout; 594*5064Sdm199847 595*5064Sdm199847 retcode = idmap_strdupnull(&rule->winname, winname); 596*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 597*5064Sdm199847 goto errout; 598*5064Sdm199847 599*5064Sdm199847 retcode = idmap_strdupnull(&rule->unixname, unixname); 600*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 601*5064Sdm199847 goto errout; 6024520Snw141292 6034520Snw141292 *iter = tmpiter; 6044520Snw141292 return (IDMAP_SUCCESS); 6054520Snw141292 6064520Snw141292 errout: 6074520Snw141292 __ITER_ERR_RETURN(tmpiter, arg, 6084520Snw141292 xdr_idmap_list_namerules_1_argument, retcode); 6094520Snw141292 } 6104520Snw141292 6114520Snw141292 6124520Snw141292 /* 6134520Snw141292 * Iterate through the name-based mapping rules 6144520Snw141292 * 6154520Snw141292 * Input: 6164520Snw141292 * iter - iterator 6174520Snw141292 * 6184520Snw141292 * Output: 6194520Snw141292 * windomain - Windows domain 6204520Snw141292 * winname - Windows user or group name 6214520Snw141292 * unixname - Unix user or group name 6224520Snw141292 * is_nt4 - NT4 or AD 6234520Snw141292 * direction - bi(0), win2unix(1), unix2win(2) 6244520Snw141292 * 6254520Snw141292 * Return value: 6264520Snw141292 * 0 - done 6274520Snw141292 * 1 - more results available 6284520Snw141292 * < 0 - error 6294520Snw141292 */ 6304520Snw141292 idmap_stat 6314520Snw141292 idmap_iter_next_namerule(idmap_iter_t *iter, char **windomain, 6324520Snw141292 char **winname, char **unixname, boolean_t *is_nt4, 6334520Snw141292 int *direction) { 6344520Snw141292 idmap_namerules_res *namerules; 6354520Snw141292 idmap_list_namerules_1_argument *arg; 6364520Snw141292 idmap_retcode retcode; 6374520Snw141292 6384520Snw141292 if (windomain) 6394520Snw141292 *windomain = NULL; 6404520Snw141292 if (winname) 6414520Snw141292 *winname = NULL; 6424520Snw141292 if (unixname) 6434520Snw141292 *unixname = NULL; 6444520Snw141292 if (is_nt4) 6454520Snw141292 *is_nt4 = 0; 6464520Snw141292 if (direction) 6474644Sbaban *direction = IDMAP_DIRECTION_UNDEF; 6484520Snw141292 6494520Snw141292 __ITER_CHECK(iter, IDMAP_LIST_NAMERULES); 6504520Snw141292 6514520Snw141292 namerules = (idmap_namerules_res *)iter->retlist; 6524520Snw141292 if (iter->retcode == IDMAP_NEXT && (namerules == NULL || 6534520Snw141292 iter->next >= namerules->rules.rules_len)) { 6544520Snw141292 6554520Snw141292 if ((arg = iter->arg) == NULL) { 6564520Snw141292 errno = EINVAL; 6574520Snw141292 return (IDMAP_ERR_ARG); 6584520Snw141292 } 6594520Snw141292 arg->limit = iter->limit; 6604520Snw141292 6614520Snw141292 retcode = _iter_get_next_list(IDMAP_LIST_NAMERULES, 6624520Snw141292 iter, arg, 6634520Snw141292 (uchar_t **)&namerules, sizeof (*namerules), 6644520Snw141292 (xdrproc_t)xdr_idmap_list_namerules_1_argument, 6654520Snw141292 (xdrproc_t)xdr_idmap_namerules_res); 6664520Snw141292 if (retcode != IDMAP_SUCCESS) 6674520Snw141292 return (retcode); 6684520Snw141292 6694520Snw141292 if (IDMAP_ERROR(namerules->retcode)) { 6704520Snw141292 retcode = namerules->retcode; 6714520Snw141292 xdr_free(xdr_idmap_namerules_res, (caddr_t)namerules); 6724520Snw141292 free(namerules); 6734520Snw141292 iter->retlist = NULL; 6744520Snw141292 return (retcode); 6754520Snw141292 } 6764520Snw141292 iter->retcode = namerules->retcode; 6774520Snw141292 arg->lastrowid = namerules->lastrowid; 6784520Snw141292 } 6794520Snw141292 6804520Snw141292 if (namerules == NULL || namerules->rules.rules_len == 0) 6814520Snw141292 return (IDMAP_SUCCESS); 6824520Snw141292 6834520Snw141292 if (iter->next >= namerules->rules.rules_len) { 6844520Snw141292 return (IDMAP_ERR_ARG); 6854520Snw141292 } 6864520Snw141292 687*5064Sdm199847 retcode = idmap_strdupnull(windomain, 688*5064Sdm199847 namerules->rules.rules_val[iter->next].windomain); 689*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 690*5064Sdm199847 goto errout; 691*5064Sdm199847 692*5064Sdm199847 retcode = idmap_strdupnull(winname, 693*5064Sdm199847 namerules->rules.rules_val[iter->next].winname); 694*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 695*5064Sdm199847 goto errout; 696*5064Sdm199847 697*5064Sdm199847 retcode = idmap_strdupnull(unixname, 698*5064Sdm199847 namerules->rules.rules_val[iter->next].unixname); 699*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 700*5064Sdm199847 goto errout; 701*5064Sdm199847 7024520Snw141292 if (is_nt4) 7034520Snw141292 *is_nt4 = namerules->rules.rules_val[iter->next].is_nt4; 7044520Snw141292 if (direction) 7054520Snw141292 *direction = namerules->rules.rules_val[iter->next].direction; 7064520Snw141292 iter->next++; 7074520Snw141292 7084520Snw141292 if (iter->next == namerules->rules.rules_len) 7094520Snw141292 return (iter->retcode); 7104520Snw141292 else 7114520Snw141292 return (IDMAP_NEXT); 7124520Snw141292 7134520Snw141292 errout: 7144520Snw141292 if (windomain && *windomain) 7154520Snw141292 free(*windomain); 7164520Snw141292 if (winname && *winname) 7174520Snw141292 free(*winname); 7184520Snw141292 if (unixname && *unixname) 7194520Snw141292 free(*unixname); 7204520Snw141292 return (retcode); 7214520Snw141292 } 7224520Snw141292 7234520Snw141292 7244520Snw141292 /* 7254520Snw141292 * Create iterator to get SID to UID/GID mappings 7264520Snw141292 * 7274520Snw141292 * Input: 7284520Snw141292 * is_user - user or group 7294520Snw141292 * 7304520Snw141292 * Output: 7314520Snw141292 * iter - iterator 7324520Snw141292 */ 7334520Snw141292 idmap_stat 7344520Snw141292 idmap_iter_mappings(idmap_handle_t *handle, boolean_t is_user, 7354520Snw141292 idmap_iter_t **iter) { 7364520Snw141292 idmap_iter_t *tmpiter; 7374520Snw141292 idmap_list_mappings_1_argument *arg = NULL; 7384520Snw141292 7394520Snw141292 __ITER_CREATE(tmpiter, arg, handle, IDMAP_LIST_MAPPINGS); 7404520Snw141292 7414520Snw141292 arg->is_user = is_user; 7424520Snw141292 *iter = tmpiter; 7434520Snw141292 return (IDMAP_SUCCESS); 7444520Snw141292 } 7454520Snw141292 7464520Snw141292 7474520Snw141292 /* 7484520Snw141292 * Iterate through the SID to UID/GID mappings 7494520Snw141292 * 7504520Snw141292 * Input: 7514520Snw141292 * iter - iterator 7524520Snw141292 * 7534520Snw141292 * Output: 7544520Snw141292 * sid - SID in canonical form 7554520Snw141292 * pid - UID or GID 7564520Snw141292 * 7574520Snw141292 * Return value: 7584520Snw141292 * 0 - done 7594520Snw141292 * 1 - more results available 7604520Snw141292 * < 0 - error 7614520Snw141292 */ 7624520Snw141292 idmap_stat 7634520Snw141292 idmap_iter_next_mapping(idmap_iter_t *iter, char **sidprefix, 7644520Snw141292 idmap_rid_t *rid, uid_t *pid, char **winname, 7654520Snw141292 char **windomain, char **unixname, int *direction) { 7664520Snw141292 idmap_mappings_res *mappings; 7674520Snw141292 idmap_list_mappings_1_argument *arg; 7684520Snw141292 idmap_retcode retcode; 7694520Snw141292 char *str; 7704520Snw141292 7714520Snw141292 if (sidprefix) 7724520Snw141292 *sidprefix = NULL; 7734520Snw141292 if (rid) 7744520Snw141292 *rid = UINT32_MAX; 7754520Snw141292 if (winname) 7764520Snw141292 *winname = NULL; 7774520Snw141292 if (windomain) 7784520Snw141292 *windomain = NULL; 7794520Snw141292 if (unixname) 7804520Snw141292 *unixname = NULL; 7814520Snw141292 if (pid) 7824520Snw141292 *pid = UINT32_MAX; 7834520Snw141292 if (direction) 7844644Sbaban *direction = IDMAP_DIRECTION_UNDEF; 7854520Snw141292 7864520Snw141292 __ITER_CHECK(iter, IDMAP_LIST_MAPPINGS); 7874520Snw141292 7884520Snw141292 mappings = (idmap_mappings_res *)iter->retlist; 7894520Snw141292 if (iter->retcode == IDMAP_NEXT && (mappings == NULL || 7904520Snw141292 iter->next >= mappings->mappings.mappings_len)) { 7914520Snw141292 7924520Snw141292 if ((arg = iter->arg) == NULL) { 7934520Snw141292 errno = EINVAL; 7944520Snw141292 return (IDMAP_ERR_ARG); 7954520Snw141292 } 7964520Snw141292 arg->limit = iter->limit; 7974520Snw141292 7984520Snw141292 retcode = _iter_get_next_list(IDMAP_LIST_MAPPINGS, 7994520Snw141292 iter, arg, 8004520Snw141292 (uchar_t **)&mappings, sizeof (*mappings), 8014520Snw141292 (xdrproc_t)xdr_idmap_list_mappings_1_argument, 8024520Snw141292 (xdrproc_t)xdr_idmap_mappings_res); 8034520Snw141292 if (retcode != IDMAP_SUCCESS) 8044520Snw141292 return (retcode); 8054520Snw141292 8064520Snw141292 if (IDMAP_ERROR(mappings->retcode)) { 8074520Snw141292 retcode = mappings->retcode; 8084520Snw141292 xdr_free(xdr_idmap_mappings_res, (caddr_t)mappings); 8094520Snw141292 free(mappings); 8104520Snw141292 iter->retlist = NULL; 8114520Snw141292 return (retcode); 8124520Snw141292 } 8134520Snw141292 iter->retcode = mappings->retcode; 8144520Snw141292 arg->lastrowid = mappings->lastrowid; 8154520Snw141292 } 8164520Snw141292 8174520Snw141292 if (mappings == NULL || mappings->mappings.mappings_len == 0) 8184520Snw141292 return (IDMAP_SUCCESS); 8194520Snw141292 8204520Snw141292 if (iter->next >= mappings->mappings.mappings_len) { 8214520Snw141292 return (IDMAP_ERR_ARG); 8224520Snw141292 } 8234520Snw141292 8244520Snw141292 if (sidprefix) { 8254520Snw141292 str = mappings->mappings.mappings_val[iter->next].id1. 8264520Snw141292 idmap_id_u.sid.prefix; 8274695Sbaban if (str && *str != '\0') { 8284520Snw141292 *sidprefix = strdup(str); 8294526Sbaban if (*sidprefix == NULL) { 8304526Sbaban retcode = IDMAP_ERR_MEMORY; 8314526Sbaban goto errout; 8324526Sbaban } 8334520Snw141292 } 8344520Snw141292 } 8354520Snw141292 if (rid) 8364520Snw141292 *rid = mappings->mappings.mappings_val[iter->next].id1. 8374520Snw141292 idmap_id_u.sid.rid; 838*5064Sdm199847 839*5064Sdm199847 retcode = idmap_strdupnull(windomain, 840*5064Sdm199847 mappings->mappings.mappings_val[iter->next].id1domain); 841*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 842*5064Sdm199847 goto errout; 843*5064Sdm199847 844*5064Sdm199847 retcode = idmap_strdupnull(winname, 845*5064Sdm199847 mappings->mappings.mappings_val[iter->next].id1name); 846*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 847*5064Sdm199847 goto errout; 848*5064Sdm199847 849*5064Sdm199847 retcode = idmap_strdupnull(unixname, 850*5064Sdm199847 mappings->mappings.mappings_val[iter->next].id2name); 851*5064Sdm199847 if (retcode != IDMAP_SUCCESS) 852*5064Sdm199847 goto errout; 853*5064Sdm199847 854*5064Sdm199847 8554520Snw141292 if (pid) 8564520Snw141292 *pid = mappings->mappings.mappings_val[iter->next].id2. 8574520Snw141292 idmap_id_u.uid; 8584520Snw141292 if (direction) 8594520Snw141292 *direction = mappings->mappings.mappings_val[iter->next]. 8604520Snw141292 direction; 8614520Snw141292 iter->next++; 8624520Snw141292 8634520Snw141292 if (iter->next == mappings->mappings.mappings_len) 8644520Snw141292 return (iter->retcode); 8654520Snw141292 else 8664520Snw141292 return (IDMAP_NEXT); 8674520Snw141292 8684520Snw141292 errout: 8694520Snw141292 if (sidprefix && *sidprefix) 8704520Snw141292 free(*sidprefix); 8714520Snw141292 if (winname && *winname) 8724520Snw141292 free(*winname); 8734520Snw141292 if (windomain && *windomain) 8744520Snw141292 free(*windomain); 8754520Snw141292 if (unixname && *unixname) 8764520Snw141292 free(*unixname); 8774520Snw141292 return (retcode); 8784520Snw141292 } 8794520Snw141292 8804520Snw141292 8814520Snw141292 /* 8824520Snw141292 * Destroy the iterator 8834520Snw141292 */ 8844520Snw141292 void 8854520Snw141292 idmap_iter_destroy(idmap_iter_t *iter) { 8864520Snw141292 xdrproc_t _xdr_argument, _xdr_result; 8874520Snw141292 8884520Snw141292 if (iter == NULL) 8894520Snw141292 return; 8904520Snw141292 8914520Snw141292 switch (iter->type) { 8924520Snw141292 case IDMAP_LIST_NAMERULES: 8934520Snw141292 _xdr_argument = (xdrproc_t)xdr_idmap_list_namerules_1_argument; 8944520Snw141292 _xdr_result = (xdrproc_t)xdr_idmap_namerules_res; 8954520Snw141292 break; 8964520Snw141292 case IDMAP_LIST_MAPPINGS: 8974520Snw141292 _xdr_argument = (xdrproc_t)xdr_idmap_list_mappings_1_argument; 8984520Snw141292 _xdr_result = (xdrproc_t)xdr_idmap_mappings_res; 8994520Snw141292 break; 9004520Snw141292 default: 9014520Snw141292 free(iter); 9024520Snw141292 return; 9034520Snw141292 }; 9044520Snw141292 9054520Snw141292 if (iter->arg) { 9064520Snw141292 xdr_free(_xdr_argument, (caddr_t)iter->arg); 9074520Snw141292 free(iter->arg); 9084520Snw141292 } 9094520Snw141292 if (iter->retlist) { 9104520Snw141292 xdr_free(_xdr_result, (caddr_t)iter->retlist); 9114520Snw141292 free(iter->retlist); 9124520Snw141292 } 9134520Snw141292 free(iter); 9144520Snw141292 } 9154520Snw141292 9164520Snw141292 9174520Snw141292 /* 9184520Snw141292 * Create handle to get SID to UID/GID mapping entries 9194520Snw141292 * 9204520Snw141292 * Input: 9214520Snw141292 * gh - "get mapping" handle 9224520Snw141292 */ 9234520Snw141292 idmap_stat 9244520Snw141292 idmap_get_create(idmap_handle_t *handle, idmap_get_handle_t **gh) { 9254520Snw141292 idmap_get_handle_t *tmp; 9264520Snw141292 9274520Snw141292 /* sanity checks */ 9284520Snw141292 if (handle == NULL || gh == NULL) { 9294520Snw141292 errno = EINVAL; 9304520Snw141292 return (IDMAP_ERR_ARG); 9314520Snw141292 } 9324520Snw141292 9334520Snw141292 /* allocate the handle */ 9344520Snw141292 if ((tmp = calloc(1, sizeof (*tmp))) == NULL) { 9354520Snw141292 errno = ENOMEM; 9364520Snw141292 return (IDMAP_ERR_MEMORY); 9374520Snw141292 } 9384520Snw141292 9394520Snw141292 tmp->ih = handle; 9404520Snw141292 *gh = tmp; 9414520Snw141292 return (IDMAP_SUCCESS); 9424520Snw141292 } 9434520Snw141292 9444520Snw141292 9454520Snw141292 /* 9464520Snw141292 * Given SID, get UID 9474520Snw141292 * 9484520Snw141292 * Input: 9494520Snw141292 * sidprefix - SID prefix 9504520Snw141292 * rid - RID 9514520Snw141292 * flag - flag 9524520Snw141292 * 9534520Snw141292 * Output: 9544520Snw141292 * stat - status of the get request 9554520Snw141292 * uid - POSIX UID if stat = 0 9564520Snw141292 * 9574520Snw141292 * Note: The output parameters will be set by idmap_get_mappings() 9584520Snw141292 */ 9594520Snw141292 idmap_stat 9604520Snw141292 idmap_get_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 9614520Snw141292 int flag, uid_t *uid, idmap_stat *stat) { 9624520Snw141292 9634520Snw141292 idmap_retcode retcode; 9644644Sbaban idmap_mapping *mapping = NULL; 9654520Snw141292 9664520Snw141292 /* sanity checks */ 9674520Snw141292 if (gh == NULL) 9684520Snw141292 return (IDMAP_ERR_ARG); 9694520Snw141292 if (uid == NULL || sidprefix == NULL) 9704520Snw141292 return (IDMAP_ERR_ARG); 9714520Snw141292 9724520Snw141292 /* Extend the request array and the return list */ 9734520Snw141292 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 9744520Snw141292 goto errout; 9754520Snw141292 9764520Snw141292 /* Setup the request */ 9774520Snw141292 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 9784520Snw141292 mapping->flag = flag; 9794520Snw141292 mapping->id1.idtype = IDMAP_SID; 9804520Snw141292 mapping->id1.idmap_id_u.sid.rid = rid; 9814520Snw141292 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) { 9824520Snw141292 retcode = IDMAP_ERR_MEMORY; 9834520Snw141292 goto errout; 9844520Snw141292 } 9854520Snw141292 mapping->id2.idtype = IDMAP_UID; 9864520Snw141292 9874520Snw141292 /* Setup pointers for the result */ 9884520Snw141292 gh->retlist[gh->next].idtype = IDMAP_UID; 9894520Snw141292 gh->retlist[gh->next].uid = uid; 9904520Snw141292 gh->retlist[gh->next].stat = stat; 9914520Snw141292 9924520Snw141292 gh->next++; 9934520Snw141292 return (IDMAP_SUCCESS); 9944520Snw141292 9954520Snw141292 errout: 9964644Sbaban /* Batch created so far should still be usable */ 9974644Sbaban if (mapping) 9984644Sbaban (void) memset(mapping, 0, sizeof (*mapping)); 9994520Snw141292 errno = idmap_stat2errno(retcode); 10004520Snw141292 return (retcode); 10014520Snw141292 } 10024520Snw141292 10034520Snw141292 10044520Snw141292 /* 10054520Snw141292 * Given SID, get GID 10064520Snw141292 * 10074520Snw141292 * Input: 10084520Snw141292 * sidprefix - SID prefix 10094520Snw141292 * rid - rid 10104520Snw141292 * flag - flag 10114520Snw141292 * 10124520Snw141292 * Output: 10134520Snw141292 * stat - status of the get request 10144520Snw141292 * gid - POSIX GID if stat = 0 10154520Snw141292 * 10164520Snw141292 * Note: The output parameters will be set by idmap_get_mappings() 10174520Snw141292 */ 10184520Snw141292 idmap_stat 10194520Snw141292 idmap_get_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 10204520Snw141292 int flag, gid_t *gid, idmap_stat *stat) { 10214520Snw141292 10224520Snw141292 idmap_retcode retcode; 10234644Sbaban idmap_mapping *mapping = NULL; 10244520Snw141292 10254520Snw141292 /* sanity checks */ 10264520Snw141292 if (gh == NULL) 10274520Snw141292 return (IDMAP_ERR_ARG); 10284520Snw141292 if (gid == NULL || sidprefix == NULL) 10294520Snw141292 return (IDMAP_ERR_ARG); 10304520Snw141292 10314520Snw141292 /* Extend the request array and the return list */ 10324520Snw141292 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 10334520Snw141292 goto errout; 10344520Snw141292 10354520Snw141292 /* Setup the request */ 10364520Snw141292 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 10374520Snw141292 mapping->flag = flag; 10384520Snw141292 mapping->id1.idtype = IDMAP_SID; 10394520Snw141292 mapping->id1.idmap_id_u.sid.rid = rid; 10404520Snw141292 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) { 10414520Snw141292 retcode = IDMAP_ERR_MEMORY; 10424520Snw141292 goto errout; 10434520Snw141292 } 10444520Snw141292 mapping->id2.idtype = IDMAP_GID; 10454520Snw141292 10464520Snw141292 /* Setup pointers for the result */ 10474520Snw141292 gh->retlist[gh->next].idtype = IDMAP_GID; 10484520Snw141292 gh->retlist[gh->next].gid = gid; 10494520Snw141292 gh->retlist[gh->next].stat = stat; 10504520Snw141292 10514520Snw141292 gh->next++; 10524520Snw141292 return (IDMAP_SUCCESS); 10534520Snw141292 10544520Snw141292 errout: 10554644Sbaban if (mapping) 10564644Sbaban (void) memset(mapping, 0, sizeof (*mapping)); 10574520Snw141292 errno = idmap_stat2errno(retcode); 10584520Snw141292 return (retcode); 10594520Snw141292 } 10604520Snw141292 10614520Snw141292 10624520Snw141292 /* 10634520Snw141292 * Given SID, get POSIX ID i.e. UID/GID 10644520Snw141292 * 10654520Snw141292 * Input: 10664520Snw141292 * sidprefix - SID prefix 10674520Snw141292 * rid - rid 10684520Snw141292 * flag - flag 10694520Snw141292 * 10704520Snw141292 * Output: 10714520Snw141292 * stat - status of the get request 10724520Snw141292 * is_user - user or group 10734520Snw141292 * pid - POSIX UID if stat = 0 and is_user = 1 10744520Snw141292 * POSIX GID if stat = 0 and is_user = 0 10754520Snw141292 * 10764520Snw141292 * Note: The output parameters will be set by idmap_get_mappings() 10774520Snw141292 */ 10784520Snw141292 idmap_stat 10794520Snw141292 idmap_get_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 10804520Snw141292 int flag, uid_t *pid, int *is_user, idmap_stat *stat) { 10814520Snw141292 idmap_retcode retcode; 10824644Sbaban idmap_mapping *mapping = NULL; 10834520Snw141292 10844520Snw141292 /* sanity checks */ 10854520Snw141292 if (gh == NULL) 10864520Snw141292 return (IDMAP_ERR_ARG); 10874520Snw141292 if (pid == NULL || sidprefix == NULL || is_user == NULL) 10884520Snw141292 return (IDMAP_ERR_ARG); 10894520Snw141292 10904520Snw141292 /* Extend the request array and the return list */ 10914520Snw141292 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 10924520Snw141292 goto errout; 10934520Snw141292 10944520Snw141292 /* Setup the request */ 10954520Snw141292 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 10964520Snw141292 mapping->flag = flag; 10974520Snw141292 mapping->id1.idtype = IDMAP_SID; 10984520Snw141292 mapping->id1.idmap_id_u.sid.rid = rid; 10994520Snw141292 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) { 11004520Snw141292 retcode = IDMAP_ERR_MEMORY; 11014520Snw141292 goto errout; 11024520Snw141292 } 11034520Snw141292 mapping->id2.idtype = IDMAP_POSIXID; 11044520Snw141292 11054520Snw141292 /* Setup pointers for the result */ 11064520Snw141292 gh->retlist[gh->next].idtype = IDMAP_POSIXID; 11074520Snw141292 gh->retlist[gh->next].uid = pid; 11084520Snw141292 gh->retlist[gh->next].gid = pid; 11094520Snw141292 gh->retlist[gh->next].is_user = is_user; 11104520Snw141292 gh->retlist[gh->next].stat = stat; 11114520Snw141292 11124520Snw141292 gh->next++; 11134520Snw141292 return (IDMAP_SUCCESS); 11144520Snw141292 11154520Snw141292 errout: 11164644Sbaban if (mapping) 11174644Sbaban (void) memset(mapping, 0, sizeof (*mapping)); 11184520Snw141292 errno = idmap_stat2errno(retcode); 11194520Snw141292 return (retcode); 11204520Snw141292 } 11214520Snw141292 11224520Snw141292 11234520Snw141292 /* 11244520Snw141292 * Given UID, get SID 11254520Snw141292 * 11264520Snw141292 * Input: 11274520Snw141292 * uid - POSIX UID 11284520Snw141292 * flag - flag 11294520Snw141292 * 11304520Snw141292 * Output: 11314520Snw141292 * stat - status of the get request 11324520Snw141292 * sid - SID prefix (if stat == 0) 11334520Snw141292 * rid - rid 11344520Snw141292 * 11354520Snw141292 * Note: The output parameters will be set by idmap_get_mappings() 11364520Snw141292 */ 11374520Snw141292 idmap_stat 11384520Snw141292 idmap_get_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag, 11394520Snw141292 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat) { 11404520Snw141292 11414520Snw141292 idmap_retcode retcode; 11424644Sbaban idmap_mapping *mapping = NULL; 11434520Snw141292 11444520Snw141292 /* sanity checks */ 11454520Snw141292 if (gh == NULL) 11464520Snw141292 return (IDMAP_ERR_ARG); 11474520Snw141292 if (sidprefix == NULL) 11484520Snw141292 return (IDMAP_ERR_ARG); 11494520Snw141292 11504520Snw141292 /* Extend the request array and the return list */ 11514520Snw141292 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 11524520Snw141292 goto errout; 11534520Snw141292 11544520Snw141292 /* Setup the request */ 11554520Snw141292 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 11564520Snw141292 mapping->flag = flag; 11574520Snw141292 mapping->id1.idtype = IDMAP_UID; 11584520Snw141292 mapping->id1.idmap_id_u.uid = uid; 11594520Snw141292 mapping->id2.idtype = IDMAP_SID; 11604520Snw141292 11614520Snw141292 /* Setup pointers for the result */ 11624520Snw141292 gh->retlist[gh->next].idtype = IDMAP_SID; 11634520Snw141292 gh->retlist[gh->next].sidprefix = sidprefix; 11644520Snw141292 gh->retlist[gh->next].rid = rid; 11654520Snw141292 gh->retlist[gh->next].stat = stat; 11664520Snw141292 11674520Snw141292 gh->next++; 11684520Snw141292 return (IDMAP_SUCCESS); 11694520Snw141292 11704520Snw141292 errout: 11714644Sbaban if (mapping) 11724644Sbaban (void) memset(mapping, 0, sizeof (*mapping)); 11734520Snw141292 errno = idmap_stat2errno(retcode); 11744520Snw141292 return (retcode); 11754520Snw141292 } 11764520Snw141292 11774520Snw141292 11784520Snw141292 /* 11794520Snw141292 * Given GID, get SID 11804520Snw141292 * 11814520Snw141292 * Input: 11824520Snw141292 * gid - POSIX GID 11834520Snw141292 * flag - flag 11844520Snw141292 * 11854520Snw141292 * Output: 11864520Snw141292 * stat - status of the get request 11874520Snw141292 * sidprefix - SID prefix (if stat == 0) 11884520Snw141292 * rid - rid 11894520Snw141292 * 11904520Snw141292 * Note: The output parameters will be set by idmap_get_mappings() 11914520Snw141292 */ 11924520Snw141292 idmap_stat 11934520Snw141292 idmap_get_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag, 11944520Snw141292 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat) { 11954520Snw141292 11964520Snw141292 idmap_retcode retcode; 11974644Sbaban idmap_mapping *mapping = NULL; 11984520Snw141292 11994520Snw141292 /* sanity checks */ 12004520Snw141292 if (gh == NULL) 12014520Snw141292 return (IDMAP_ERR_ARG); 12024520Snw141292 if (sidprefix == NULL) 12034520Snw141292 return (IDMAP_ERR_ARG); 12044520Snw141292 12054520Snw141292 /* Extend the request array and the return list */ 12064520Snw141292 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 12074520Snw141292 goto errout; 12084520Snw141292 12094520Snw141292 /* Setup the request */ 12104520Snw141292 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 12114520Snw141292 mapping->flag = flag; 12124520Snw141292 mapping->id1.idtype = IDMAP_GID; 12134520Snw141292 mapping->id1.idmap_id_u.gid = gid; 12144520Snw141292 mapping->id2.idtype = IDMAP_SID; 12154520Snw141292 12164520Snw141292 /* Setup pointers for the result */ 12174520Snw141292 gh->retlist[gh->next].idtype = IDMAP_SID; 12184520Snw141292 gh->retlist[gh->next].sidprefix = sidprefix; 12194520Snw141292 gh->retlist[gh->next].rid = rid; 12204520Snw141292 gh->retlist[gh->next].stat = stat; 12214520Snw141292 12224520Snw141292 gh->next++; 12234520Snw141292 return (IDMAP_SUCCESS); 12244520Snw141292 12254520Snw141292 errout: 12264644Sbaban if (mapping) 12274644Sbaban (void) memset(mapping, 0, sizeof (*mapping)); 12284520Snw141292 errno = idmap_stat2errno(retcode); 12294520Snw141292 return (retcode); 12304520Snw141292 } 12314520Snw141292 12324520Snw141292 12334520Snw141292 /* 12344520Snw141292 * Process the batched "get mapping" requests. The results (i.e. 12354520Snw141292 * status and identity) will be available in the data areas 12364520Snw141292 * provided by individual requests. 12374520Snw141292 */ 12384520Snw141292 idmap_stat 12394520Snw141292 idmap_get_mappings(idmap_get_handle_t *gh) { 12404520Snw141292 CLIENT *clnt; 12414520Snw141292 enum clnt_stat clntstat; 12424520Snw141292 idmap_retcode retcode; 12434520Snw141292 idmap_ids_res res; 12444520Snw141292 idmap_id *id; 12454520Snw141292 int i; 12464520Snw141292 12474520Snw141292 if (gh == NULL) { 12484520Snw141292 errno = EINVAL; 12494520Snw141292 return (IDMAP_ERR_ARG); 12504520Snw141292 } 12514520Snw141292 _IDMAP_GET_CLIENT_HANDLE(gh->ih, clnt); 12524520Snw141292 12534520Snw141292 (void) memset(&res, 0, sizeof (idmap_ids_res)); 12544520Snw141292 clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_IDS, 12554520Snw141292 (xdrproc_t)xdr_idmap_mapping_batch, 12564520Snw141292 (caddr_t)&gh->batch, 12574520Snw141292 (xdrproc_t)xdr_idmap_ids_res, 12584520Snw141292 (caddr_t)&res, 12594520Snw141292 TIMEOUT); 12604520Snw141292 if (clntstat != RPC_SUCCESS) { 12614644Sbaban retcode = _idmap_rpc2stat(clnt); 12624520Snw141292 goto out; 12634520Snw141292 } 12644520Snw141292 if (res.retcode != IDMAP_SUCCESS) { 12654520Snw141292 retcode = res.retcode; 12664520Snw141292 goto out; 12674520Snw141292 } 12684520Snw141292 for (i = 0; i < gh->next; i++) { 12694520Snw141292 if (i >= res.ids.ids_len) { 12704520Snw141292 *gh->retlist[i].stat = IDMAP_ERR_NORESULT; 12714520Snw141292 continue; 12724520Snw141292 } 12734520Snw141292 *gh->retlist[i].stat = res.ids.ids_val[i].retcode; 12744520Snw141292 id = &res.ids.ids_val[i].id; 12754520Snw141292 switch (id->idtype) { 12764520Snw141292 case IDMAP_UID: 12774520Snw141292 if (gh->retlist[i].uid) 12784520Snw141292 *gh->retlist[i].uid = id->idmap_id_u.uid; 12794520Snw141292 if (gh->retlist[i].is_user) 12804520Snw141292 *gh->retlist[i].is_user = 1; 12814520Snw141292 break; 12824520Snw141292 case IDMAP_GID: 12834520Snw141292 if (gh->retlist[i].gid) 12844520Snw141292 *gh->retlist[i].gid = id->idmap_id_u.gid; 12854520Snw141292 if (gh->retlist[i].is_user) 12864520Snw141292 *gh->retlist[i].is_user = 0; 12874520Snw141292 break; 12884864Sbaban case IDMAP_POSIXID: 12894864Sbaban if (gh->retlist[i].uid) 12904864Sbaban *gh->retlist[i].uid = 60001; 12914864Sbaban if (gh->retlist[i].is_user) 12924864Sbaban *gh->retlist[i].is_user = -1; 12934864Sbaban break; 12944520Snw141292 case IDMAP_SID: 12954520Snw141292 if (gh->retlist[i].rid) 12964520Snw141292 *gh->retlist[i].rid = id->idmap_id_u.sid.rid; 12974520Snw141292 if (gh->retlist[i].sidprefix) { 12984695Sbaban if (id->idmap_id_u.sid.prefix == NULL || 12994695Sbaban *id->idmap_id_u.sid.prefix == '\0') { 13004520Snw141292 *gh->retlist[i].sidprefix = NULL; 13014520Snw141292 break; 13024520Snw141292 } 13034520Snw141292 *gh->retlist[i].sidprefix = 13044520Snw141292 strdup(id->idmap_id_u.sid.prefix); 13054520Snw141292 if (*gh->retlist[i].sidprefix == NULL) 13064520Snw141292 *gh->retlist[i].stat = 13074520Snw141292 IDMAP_ERR_MEMORY; 13084520Snw141292 } 13094520Snw141292 break; 13104520Snw141292 case IDMAP_NONE: 13114520Snw141292 break; 13124520Snw141292 default: 13134520Snw141292 *gh->retlist[i].stat = IDMAP_ERR_NORESULT; 13144520Snw141292 break; 13154520Snw141292 } 13164520Snw141292 } 13174520Snw141292 retcode = IDMAP_SUCCESS; 13184520Snw141292 13194520Snw141292 out: 13204644Sbaban _IDMAP_RESET_GET_HANDLE(gh); 13214520Snw141292 (void) xdr_free(xdr_idmap_ids_res, (caddr_t)&res); 13224520Snw141292 errno = idmap_stat2errno(retcode); 13234520Snw141292 return (retcode); 13244520Snw141292 } 13254520Snw141292 13264520Snw141292 13274520Snw141292 /* 13284520Snw141292 * Destroy the "get mapping" handle 13294520Snw141292 */ 13304520Snw141292 void 13314520Snw141292 idmap_get_destroy(idmap_get_handle_t *gh) { 13324520Snw141292 if (gh == NULL) 13334520Snw141292 return; 13344520Snw141292 (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch); 13354520Snw141292 if (gh->retlist) 13364520Snw141292 free(gh->retlist); 13374520Snw141292 free(gh); 13384520Snw141292 } 13394520Snw141292 13404520Snw141292 13414520Snw141292 /* 13424520Snw141292 * Get windows to unix mapping 13434520Snw141292 */ 13444520Snw141292 idmap_stat 13454520Snw141292 idmap_get_w2u_mapping(idmap_handle_t *handle, 13464520Snw141292 const char *sidprefix, idmap_rid_t *rid, 13474520Snw141292 const char *winname, const char *windomain, 13484520Snw141292 int flag, int *is_user, 13494520Snw141292 uid_t *pid, char **unixname, int *direction) { 13504520Snw141292 CLIENT *clnt; 13514520Snw141292 enum clnt_stat clntstat; 13524520Snw141292 idmap_mapping request, *mapping; 13534520Snw141292 idmap_mappings_res result; 13544520Snw141292 idmap_retcode retcode, rc; 13554520Snw141292 13564520Snw141292 if (handle == NULL) { 13574520Snw141292 errno = EINVAL; 13584520Snw141292 return (IDMAP_ERR_ARG); 13594520Snw141292 } 13604520Snw141292 13614520Snw141292 _IDMAP_GET_CLIENT_HANDLE(handle, clnt); 13624520Snw141292 13634520Snw141292 (void) memset(&request, 0, sizeof (request)); 13644520Snw141292 (void) memset(&result, 0, sizeof (result)); 13654520Snw141292 13664864Sbaban if (is_user) 13674864Sbaban *is_user = -1; 13684520Snw141292 if (pid) 13694520Snw141292 *pid = UINT32_MAX; 13704520Snw141292 if (unixname) 13714520Snw141292 *unixname = NULL; 13724520Snw141292 if (direction) 13734644Sbaban *direction = IDMAP_DIRECTION_UNDEF; 13744520Snw141292 13754520Snw141292 request.flag = flag; 13764520Snw141292 request.id1.idtype = IDMAP_SID; 13774520Snw141292 if (sidprefix && rid) { 13784520Snw141292 request.id1.idmap_id_u.sid.prefix = (char *)sidprefix; 13794520Snw141292 request.id1.idmap_id_u.sid.rid = *rid; 13804520Snw141292 } else if (winname) { 1381*5064Sdm199847 retcode = idmap_strdupnull(&request.id1name, winname); 1382*5064Sdm199847 if (retcode != SUCCESS) 13834520Snw141292 goto out; 1384*5064Sdm199847 1385*5064Sdm199847 retcode = idmap_strdupnull(&request.id1domain, windomain); 1386*5064Sdm199847 if (retcode != SUCCESS) 1387*5064Sdm199847 goto out; 1388*5064Sdm199847 13894520Snw141292 request.id1.idmap_id_u.sid.prefix = NULL; 13904520Snw141292 } else { 13914520Snw141292 errno = EINVAL; 13924520Snw141292 return (IDMAP_ERR_ARG); 13934520Snw141292 } 13944520Snw141292 13954520Snw141292 if (is_user == NULL) 13964520Snw141292 request.id2.idtype = IDMAP_POSIXID; 13974520Snw141292 else if (*is_user == 1) 13984520Snw141292 request.id2.idtype = IDMAP_UID; 13994520Snw141292 else if (*is_user == 0) 14004520Snw141292 request.id2.idtype = IDMAP_GID; 14014520Snw141292 else 14024520Snw141292 request.id2.idtype = IDMAP_POSIXID; 14034520Snw141292 14044520Snw141292 clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_ID_BY_NAME, 14054520Snw141292 (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request, 14064520Snw141292 (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result, 14074520Snw141292 TIMEOUT); 14084520Snw141292 14094644Sbaban if (clntstat != RPC_SUCCESS) 14104644Sbaban return (_idmap_rpc2stat(clnt)); 14114520Snw141292 14124520Snw141292 retcode = result.retcode; 14134520Snw141292 14144520Snw141292 if ((mapping = result.mappings.mappings_val) == NULL) { 14154520Snw141292 if (retcode == IDMAP_SUCCESS) 14164520Snw141292 retcode = IDMAP_ERR_NORESULT; 14174520Snw141292 goto out; 14184520Snw141292 } 14194520Snw141292 14204864Sbaban if (mapping->id2.idtype == IDMAP_UID) { 14214864Sbaban if (is_user) *is_user = 1; 14224864Sbaban } else if (mapping->id2.idtype == IDMAP_GID) { 14234864Sbaban if (is_user) *is_user = 0; 14244864Sbaban } else { 14254864Sbaban goto out; 14264864Sbaban } 14274520Snw141292 if (direction) 14284520Snw141292 *direction = mapping->direction; 14294520Snw141292 if (pid) 14304520Snw141292 *pid = mapping->id2.idmap_id_u.uid; 1431*5064Sdm199847 1432*5064Sdm199847 rc = idmap_strdupnull(unixname, mapping->id2name); 1433*5064Sdm199847 if (rc != IDMAP_SUCCESS) 1434*5064Sdm199847 retcode = rc; 14354520Snw141292 14364520Snw141292 out: 14374520Snw141292 xdr_free(xdr_idmap_mappings_res, (caddr_t)&result); 14384520Snw141292 if (retcode != IDMAP_SUCCESS) 14394520Snw141292 errno = idmap_stat2errno(retcode); 14404520Snw141292 return (retcode); 14414520Snw141292 } 14424520Snw141292 14434520Snw141292 14444520Snw141292 /* 14454520Snw141292 * Get unix to windows mapping 14464520Snw141292 */ 14474520Snw141292 idmap_stat 14484520Snw141292 idmap_get_u2w_mapping(idmap_handle_t *handle, 14494520Snw141292 uid_t *pid, const char *unixname, 14504520Snw141292 int flag, int is_user, 14514520Snw141292 char **sidprefix, idmap_rid_t *rid, 14524520Snw141292 char **winname, char **windomain, 14534520Snw141292 int *direction) { 14544520Snw141292 CLIENT *clnt; 14554520Snw141292 enum clnt_stat clntstat; 14564520Snw141292 idmap_mapping request, *mapping; 14574520Snw141292 idmap_mappings_res result; 14584520Snw141292 idmap_retcode retcode, rc; 14594520Snw141292 14604520Snw141292 if (handle == NULL) { 14614520Snw141292 errno = EINVAL; 14624520Snw141292 return (IDMAP_ERR_ARG); 14634520Snw141292 } 14644520Snw141292 14654520Snw141292 _IDMAP_GET_CLIENT_HANDLE(handle, clnt); 14664520Snw141292 14674520Snw141292 if (sidprefix) 14684520Snw141292 *sidprefix = NULL; 14694520Snw141292 if (winname) 14704520Snw141292 *winname = NULL; 14714520Snw141292 if (windomain) 14724520Snw141292 *windomain = NULL; 14734520Snw141292 if (rid) 14744520Snw141292 *rid = UINT32_MAX; 14754520Snw141292 if (direction) 14764644Sbaban *direction = IDMAP_DIRECTION_UNDEF; 14774520Snw141292 14784520Snw141292 (void) memset(&request, 0, sizeof (request)); 14794520Snw141292 (void) memset(&result, 0, sizeof (result)); 14804520Snw141292 14814520Snw141292 request.flag = flag; 14824520Snw141292 request.id1.idtype = is_user?IDMAP_UID:IDMAP_GID; 14834520Snw141292 14844520Snw141292 if (pid && *pid != UINT32_MAX) { 14854520Snw141292 request.id1.idmap_id_u.uid = *pid; 14864520Snw141292 } else if (unixname) { 1487*5064Sdm199847 request.id1name = (char *)unixname; 14884520Snw141292 request.id1.idmap_id_u.uid = UINT32_MAX; 14894520Snw141292 } else { 14904520Snw141292 errno = EINVAL; 14914520Snw141292 return (IDMAP_ERR_ARG); 14924520Snw141292 } 14934520Snw141292 14944520Snw141292 request.id2.idtype = IDMAP_SID; 14954520Snw141292 14964520Snw141292 clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_ID_BY_NAME, 14974520Snw141292 (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request, 14984520Snw141292 (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result, 14994520Snw141292 TIMEOUT); 15004520Snw141292 15014644Sbaban if (clntstat != RPC_SUCCESS) 15024644Sbaban return (_idmap_rpc2stat(clnt)); 15034520Snw141292 15044520Snw141292 retcode = result.retcode; 15054520Snw141292 15064520Snw141292 if ((mapping = result.mappings.mappings_val) == NULL) { 15074520Snw141292 if (retcode == IDMAP_SUCCESS) 15084520Snw141292 retcode = IDMAP_ERR_NORESULT; 15094520Snw141292 goto out; 15104520Snw141292 } 15114520Snw141292 15124520Snw141292 if (direction) 15134520Snw141292 *direction = mapping->direction; 15144695Sbaban if (sidprefix && mapping->id2.idmap_id_u.sid.prefix && 15154695Sbaban *mapping->id2.idmap_id_u.sid.prefix != '\0') { 15164520Snw141292 *sidprefix = strdup(mapping->id2.idmap_id_u.sid.prefix); 15174520Snw141292 if (*sidprefix == NULL) { 15184520Snw141292 retcode = IDMAP_ERR_MEMORY; 15194520Snw141292 goto errout; 15204520Snw141292 } 15214520Snw141292 } 15224520Snw141292 if (rid) 15234520Snw141292 *rid = mapping->id2.idmap_id_u.sid.rid; 1524*5064Sdm199847 1525*5064Sdm199847 rc = idmap_strdupnull(winname, mapping->id2name); 1526*5064Sdm199847 if (rc != IDMAP_SUCCESS) 1527*5064Sdm199847 retcode = rc; 1528*5064Sdm199847 1529*5064Sdm199847 rc = idmap_strdupnull(windomain, mapping->id2domain); 1530*5064Sdm199847 if (rc != IDMAP_SUCCESS) 1531*5064Sdm199847 retcode = rc; 15324520Snw141292 15334520Snw141292 goto out; 15344520Snw141292 15354520Snw141292 errout: 15364520Snw141292 if (sidprefix && *sidprefix) { 15374520Snw141292 free(*sidprefix); 15384520Snw141292 *sidprefix = NULL; 15394520Snw141292 } 15404520Snw141292 if (winname && *winname) { 15414520Snw141292 free(*winname); 15424520Snw141292 *winname = NULL; 15434520Snw141292 } 15444520Snw141292 if (windomain && *windomain) { 15454520Snw141292 free(*windomain); 15464520Snw141292 *windomain = NULL; 15474520Snw141292 } 15484520Snw141292 15494520Snw141292 out: 15504520Snw141292 xdr_free(xdr_idmap_mappings_res, (caddr_t)&result); 15514520Snw141292 if (retcode != IDMAP_SUCCESS) 15524520Snw141292 errno = idmap_stat2errno(retcode); 15534520Snw141292 return (retcode); 15544520Snw141292 } 15554520Snw141292 15564520Snw141292 15574520Snw141292 15584520Snw141292 #define gettext(s) s 15594520Snw141292 static stat_table_t stattable[] = { 15604520Snw141292 {IDMAP_SUCCESS, gettext("Success"), 0}, 15614520Snw141292 {IDMAP_NEXT, gettext("More results available"), 0}, 15624520Snw141292 {IDMAP_ERR_OTHER, gettext("Undefined error"), EINVAL}, 15634520Snw141292 {IDMAP_ERR_INTERNAL, gettext("Internal error"), EINVAL}, 15644520Snw141292 {IDMAP_ERR_MEMORY, gettext("Out of memory"), ENOMEM}, 15654520Snw141292 {IDMAP_ERR_NORESULT, gettext("No results available"), EINVAL}, 15664520Snw141292 {IDMAP_ERR_NOTUSER, gettext("Not a user"), EINVAL}, 15674520Snw141292 {IDMAP_ERR_NOTGROUP, gettext("Not a group"), EINVAL}, 15684644Sbaban {IDMAP_ERR_NOTSUPPORTED, gettext("Operation not supported"), ENOTSUP}, 15694520Snw141292 {IDMAP_ERR_W2U_NAMERULE, 15704520Snw141292 gettext("Invalid Windows to UNIX name-based rule"), EINVAL}, 15714520Snw141292 {IDMAP_ERR_U2W_NAMERULE, 15724520Snw141292 gettext("Invalid UNIX to Windows name-based rule"), EINVAL}, 15734520Snw141292 {IDMAP_ERR_CACHE, gettext("Invalid cache"), EINVAL}, 15744520Snw141292 {IDMAP_ERR_DB, gettext("Invalid database"), EINVAL}, 15754520Snw141292 {IDMAP_ERR_ARG, gettext("Invalid argument"), EINVAL}, 15764520Snw141292 {IDMAP_ERR_SID, gettext("Invalid SID"), EINVAL}, 15774520Snw141292 {IDMAP_ERR_IDTYPE, gettext("Invalid identity type"), EINVAL}, 15784644Sbaban {IDMAP_ERR_RPC_HANDLE, gettext("Bad RPC handle"), EBADF}, 15794520Snw141292 {IDMAP_ERR_RPC, gettext("RPC error"), EINVAL}, 15804520Snw141292 {IDMAP_ERR_CLIENT_HANDLE, gettext("Bad client handle"), EINVAL}, 15814644Sbaban {IDMAP_ERR_BUSY, gettext("Server is busy"), EBUSY}, 15824695Sbaban {IDMAP_ERR_PERMISSION_DENIED, gettext("Permission denied"), EACCES}, 15834520Snw141292 {IDMAP_ERR_NOMAPPING, 15844520Snw141292 gettext("Mapping not found or inhibited"), EINVAL}, 15854520Snw141292 {IDMAP_ERR_NEW_ID_ALLOC_REQD, 15864520Snw141292 gettext("New mapping needs to be created"), EINVAL}, 15874520Snw141292 {IDMAP_ERR_DOMAIN, gettext("Invalid domain"), EINVAL}, 15884520Snw141292 {IDMAP_ERR_SECURITY, gettext("Security issue"), EINVAL}, 15894520Snw141292 {IDMAP_ERR_NOTFOUND, gettext("Not found"), EINVAL}, 15904520Snw141292 {IDMAP_ERR_DOMAIN_NOTFOUND, gettext("Domain not found"), EINVAL}, 15914520Snw141292 {IDMAP_ERR_UPDATE_NOTALLOWED, gettext("Update not allowed"), EINVAL}, 15924520Snw141292 {IDMAP_ERR_CFG, gettext("Configuration error"), EINVAL}, 15934520Snw141292 {IDMAP_ERR_CFG_CHANGE, gettext("Invalid configuration change"), EINVAL}, 15944520Snw141292 {IDMAP_ERR_NOTMAPPED_WELLKNOWN, 15954520Snw141292 gettext("No mapping for well-known SID"), EINVAL}, 15964520Snw141292 {IDMAP_ERR_RETRIABLE_NET_ERR, 15974864Sbaban gettext("Windows lookup failed"), EINVAL}, 15984864Sbaban {IDMAP_ERR_W2U_NAMERULE_CONFLICT, 15994864Sbaban gettext("Duplicate rule or conflicts with an existing " 16004864Sbaban "Windows to UNIX name-based rule"), EINVAL}, 16014864Sbaban {IDMAP_ERR_U2W_NAMERULE_CONFLICT, 16024864Sbaban gettext("Duplicate rule or conflicts with an existing " 16034864Sbaban "Unix to Windows name-based rule"), EINVAL}, 16044520Snw141292 {-1, NULL, 0} 16054520Snw141292 }; 16064520Snw141292 #undef gettext 16074520Snw141292 16084520Snw141292 16094520Snw141292 /* 16104520Snw141292 * Get description of status code 16114520Snw141292 * 16124520Snw141292 * Input: 16134520Snw141292 * status - Status code returned by libidmap API call 16144520Snw141292 * 16154520Snw141292 * Return Value: 16164520Snw141292 * human-readable localized description of idmap_stat 16174520Snw141292 */ 16184520Snw141292 /* ARGSUSED */ 16194520Snw141292 const char * 16204520Snw141292 idmap_stat2string(idmap_handle_t *handle, idmap_stat status) { 16214520Snw141292 int i; 16224520Snw141292 16234520Snw141292 for (i = 0; stattable[i].msg; i++) { 16244520Snw141292 if (stattable[i].retcode == status) 16254526Sbaban return (gettext(stattable[i].msg)); 16264520Snw141292 } 16274520Snw141292 return (gettext("Unknown error")); 16284520Snw141292 } 16294520Snw141292 16304520Snw141292 16314520Snw141292 static int 16324520Snw141292 idmap_stat2errno(idmap_stat stat) { 16334520Snw141292 int i; 16344520Snw141292 for (i = 0; stattable[i].msg; i++) { 16354520Snw141292 if (stattable[i].retcode == stat) 16364520Snw141292 return (stattable[i].errnum); 16374520Snw141292 } 16384520Snw141292 return (EINVAL); 16394520Snw141292 } 16404520Snw141292 16414520Snw141292 16424520Snw141292 /* 16434520Snw141292 * Get status code from string 16444520Snw141292 */ 16454520Snw141292 idmap_stat 16464520Snw141292 idmap_string2stat(const char *str) { 16474520Snw141292 if (str == NULL) 16484520Snw141292 return (IDMAP_ERR_INTERNAL); 16494520Snw141292 16504520Snw141292 #define return_cmp(a) \ 16514520Snw141292 if (0 == strcmp(str, "IDMAP_ERR_" #a)) \ 16524520Snw141292 return (IDMAP_ERR_ ## a); 16534520Snw141292 16544520Snw141292 return_cmp(OTHER); 16554520Snw141292 return_cmp(INTERNAL); 16564520Snw141292 return_cmp(MEMORY); 16574520Snw141292 return_cmp(NORESULT); 16584520Snw141292 return_cmp(NOTUSER); 16594520Snw141292 return_cmp(NOTGROUP); 16604520Snw141292 return_cmp(NOTSUPPORTED); 16614520Snw141292 return_cmp(W2U_NAMERULE); 16624520Snw141292 return_cmp(U2W_NAMERULE); 16634520Snw141292 return_cmp(CACHE); 16644520Snw141292 return_cmp(DB); 16654520Snw141292 return_cmp(ARG); 16664520Snw141292 return_cmp(SID); 16674520Snw141292 return_cmp(IDTYPE); 16684520Snw141292 return_cmp(RPC_HANDLE); 16694520Snw141292 return_cmp(RPC); 16704520Snw141292 return_cmp(CLIENT_HANDLE); 16714520Snw141292 return_cmp(BUSY); 16724520Snw141292 return_cmp(PERMISSION_DENIED); 16734520Snw141292 return_cmp(NOMAPPING); 16744520Snw141292 return_cmp(NEW_ID_ALLOC_REQD); 16754520Snw141292 return_cmp(DOMAIN); 16764520Snw141292 return_cmp(SECURITY); 16774520Snw141292 return_cmp(NOTFOUND); 16784520Snw141292 return_cmp(DOMAIN_NOTFOUND); 16794520Snw141292 return_cmp(MEMORY); 16804520Snw141292 return_cmp(UPDATE_NOTALLOWED); 16814520Snw141292 return_cmp(CFG); 16824520Snw141292 return_cmp(CFG_CHANGE); 16834520Snw141292 return_cmp(NOTMAPPED_WELLKNOWN); 16844520Snw141292 return_cmp(RETRIABLE_NET_ERR); 16854864Sbaban return_cmp(W2U_NAMERULE_CONFLICT); 16864864Sbaban return_cmp(U2W_NAMERULE_CONFLICT); 16874520Snw141292 #undef return_cmp 16884520Snw141292 16894520Snw141292 return (IDMAP_ERR_OTHER); 16904520Snw141292 } 16914520Snw141292 16924520Snw141292 16934520Snw141292 /* 16944520Snw141292 * Map the given status to one that can be returned by the protocol 16954520Snw141292 */ 16964520Snw141292 idmap_stat 16974520Snw141292 idmap_stat4prot(idmap_stat status) { 16984520Snw141292 switch (status) { 16994520Snw141292 case IDMAP_ERR_MEMORY: 17004520Snw141292 case IDMAP_ERR_CACHE: 17014520Snw141292 return (IDMAP_ERR_INTERNAL); 17024520Snw141292 } 17034520Snw141292 return (status); 17044520Snw141292 } 17055043Sbaban 17065043Sbaban 17075043Sbaban /* 1708*5064Sdm199847 * duplicate a string, possibly null 1709*5064Sdm199847 */ 1710*5064Sdm199847 static idmap_stat 1711*5064Sdm199847 idmap_strdupnull(char **to, const char *from) { 1712*5064Sdm199847 if (from == NULL || *from == '\0') { 1713*5064Sdm199847 *to = NULL; 1714*5064Sdm199847 return (IDMAP_SUCCESS); 1715*5064Sdm199847 } 1716*5064Sdm199847 1717*5064Sdm199847 *to = strdup(from); 1718*5064Sdm199847 if (*to == NULL) 1719*5064Sdm199847 return (IDMAP_ERR_MEMORY); 1720*5064Sdm199847 return (IDMAP_SUCCESS); 1721*5064Sdm199847 } 1722*5064Sdm199847 1723*5064Sdm199847 idmap_stat 1724*5064Sdm199847 idmap_namerule_cpy(idmap_namerule *to, idmap_namerule *from) { 1725*5064Sdm199847 idmap_stat retval; 1726*5064Sdm199847 1727*5064Sdm199847 (void) memcpy(to, from, sizeof (idmap_namerule)); 1728*5064Sdm199847 1729*5064Sdm199847 retval = idmap_strdupnull(&to->windomain, from->windomain); 1730*5064Sdm199847 if (retval != IDMAP_SUCCESS) 1731*5064Sdm199847 return (retval); 1732*5064Sdm199847 1733*5064Sdm199847 retval = idmap_strdupnull(&to->winname, from->winname); 1734*5064Sdm199847 if (retval != IDMAP_SUCCESS) 1735*5064Sdm199847 return (retval); 1736*5064Sdm199847 1737*5064Sdm199847 retval = idmap_strdupnull(&to->unixname, from->unixname); 1738*5064Sdm199847 1739*5064Sdm199847 return (retval); 1740*5064Sdm199847 } 1741*5064Sdm199847 1742*5064Sdm199847 1743*5064Sdm199847 /* 17445043Sbaban * Get uid given Windows name 17455043Sbaban */ 17465043Sbaban idmap_stat 17475043Sbaban idmap_getuidbywinname(const char *name, const char *domain, uid_t *uid) { 17485043Sbaban idmap_handle_t *ih; 17495043Sbaban idmap_retcode rc; 17505043Sbaban int is_user; 17515043Sbaban 17525043Sbaban if (uid == NULL) 17535043Sbaban return (IDMAP_ERR_ARG); 17545043Sbaban 17555043Sbaban /* Get mapping */ 17565043Sbaban if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS) 17575043Sbaban return (rc); 17585043Sbaban rc = idmap_get_w2u_mapping(ih, NULL, NULL, name, domain, 0, 17595043Sbaban &is_user, uid, NULL, NULL); 17605043Sbaban (void) idmap_fini(ih); 17615043Sbaban 17625043Sbaban /* 17635043Sbaban * XXX Until we have diagonal mapping support, check if 17645043Sbaban * the given name belongs to a user 17655043Sbaban */ 17665043Sbaban if (rc == IDMAP_SUCCESS && !is_user) 17675043Sbaban return (IDMAP_ERR_NOTUSER); 17685043Sbaban return (rc); 17695043Sbaban } 17705043Sbaban 17715043Sbaban 17725043Sbaban /* 17735043Sbaban * Get gid given Windows name 17745043Sbaban */ 17755043Sbaban idmap_stat 17765043Sbaban idmap_getgidbywinname(const char *name, const char *domain, gid_t *gid) { 17775043Sbaban idmap_handle_t *ih; 17785043Sbaban idmap_retcode rc; 17795043Sbaban int is_user; 17805043Sbaban 17815043Sbaban if (gid == NULL) 17825043Sbaban return (IDMAP_ERR_ARG); 17835043Sbaban 17845043Sbaban /* Get mapping */ 17855043Sbaban if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS) 17865043Sbaban return (rc); 17875043Sbaban rc = idmap_get_w2u_mapping(ih, NULL, NULL, name, domain, 0, 17885043Sbaban &is_user, gid, NULL, NULL); 17895043Sbaban (void) idmap_fini(ih); 17905043Sbaban 17915043Sbaban /* 17925043Sbaban * XXX Until we have diagonal mapping support, check if 17935043Sbaban * the given name belongs to a group 17945043Sbaban */ 17955043Sbaban if (rc == IDMAP_SUCCESS && is_user) 17965043Sbaban return (IDMAP_ERR_NOTGROUP); 17975043Sbaban return (rc); 17985043Sbaban } 17995043Sbaban 18005043Sbaban 18015043Sbaban /* 18025043Sbaban * Get winname given pid 18035043Sbaban */ 18045043Sbaban static idmap_retcode 18055043Sbaban idmap_getwinnamebypid(uid_t pid, int is_user, char **name, char **domain) { 18065043Sbaban idmap_handle_t *ih; 18075043Sbaban idmap_retcode rc; 18085043Sbaban int len; 18095043Sbaban char *winname, *windomain; 18105043Sbaban 18115043Sbaban if (name == NULL) 18125043Sbaban return (IDMAP_ERR_ARG); 18135043Sbaban 18145043Sbaban /* Get mapping */ 18155043Sbaban if ((rc = idmap_init(&ih)) != IDMAP_SUCCESS) 18165043Sbaban return (rc); 18175043Sbaban rc = idmap_get_u2w_mapping(ih, &pid, NULL, 0, is_user, NULL, 18185043Sbaban NULL, &winname, &windomain, NULL); 18195043Sbaban (void) idmap_fini(ih); 18205043Sbaban 18215043Sbaban /* Return on error */ 18225043Sbaban if (rc != IDMAP_SUCCESS) 18235043Sbaban return (rc); 18245043Sbaban 18255043Sbaban /* 18265043Sbaban * The given PID may have been mapped to a locally 18275043Sbaban * generated SID in which case there isn't any 18285043Sbaban * Windows name 18295043Sbaban */ 18305043Sbaban if (winname == NULL || windomain == NULL) { 18315043Sbaban idmap_free(winname); 18325043Sbaban idmap_free(windomain); 18335043Sbaban return (IDMAP_ERR_NORESULT); 18345043Sbaban } 18355043Sbaban 18365043Sbaban if (domain != NULL) { 18375043Sbaban *name = winname; 18385043Sbaban *domain = windomain; 18395043Sbaban } else { 18405043Sbaban len = strlen(winname) + strlen(windomain) + 2; 18415043Sbaban if ((*name = malloc(len)) != NULL) 18425043Sbaban (void) snprintf(*name, len, "%s@%s", winname, 18435043Sbaban windomain); 18445043Sbaban else 18455043Sbaban rc = IDMAP_ERR_MEMORY; 18465043Sbaban idmap_free(winname); 18475043Sbaban idmap_free(windomain); 18485043Sbaban } 18495043Sbaban return (rc); 18505043Sbaban } 18515043Sbaban 18525043Sbaban 18535043Sbaban /* 18545043Sbaban * Get winname given uid 18555043Sbaban */ 18565043Sbaban idmap_stat 18575043Sbaban idmap_getwinnamebyuid(uid_t uid, char **name, char **domain) { 18585043Sbaban return (idmap_getwinnamebypid(uid, 1, name, domain)); 18595043Sbaban } 18605043Sbaban 18615043Sbaban 18625043Sbaban /* 18635043Sbaban * Get winname given gid 18645043Sbaban */ 18655043Sbaban idmap_stat 18665043Sbaban idmap_getwinnamebygid(gid_t gid, char **name, char **domain) { 18675043Sbaban return (idmap_getwinnamebypid(gid, 0, name, domain)); 18685043Sbaban } 1869