1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Service routines 30 */ 31 32 #include "idmapd.h" 33 #include "idmap_priv.h" 34 #include <signal.h> 35 #include <thread.h> 36 #include <string.h> 37 #include <strings.h> 38 #include <errno.h> 39 #include <assert.h> 40 #include <sys/types.h> 41 #include <sys/stat.h> 42 #include <ucred.h> 43 #include <pwd.h> 44 #include <auth_attr.h> 45 #include <secdb.h> 46 47 #define _VALIDATE_LIST_CB_DATA(col, val, siz)\ 48 retcode = validate_list_cb_data(cb_data, argc, argv, col,\ 49 (uchar_t **)val, siz);\ 50 if (retcode == IDMAP_NEXT) {\ 51 result->retcode = IDMAP_NEXT;\ 52 return (0);\ 53 } else if (retcode < 0) {\ 54 result->retcode = retcode;\ 55 return (1);\ 56 } 57 58 #define PROCESS_LIST_SVC_SQL(rcode, db, sql, limit, cb, res, len)\ 59 rcode = process_list_svc_sql(db, sql, limit, cb, res);\ 60 if (rcode == IDMAP_ERR_BUSY)\ 61 res->retcode = IDMAP_ERR_BUSY;\ 62 else if (rcode == IDMAP_SUCCESS && len == 0)\ 63 res->retcode = IDMAP_ERR_NOTFOUND; 64 65 66 /* ARGSUSED */ 67 bool_t 68 idmap_null_1_svc(void *result, struct svc_req *rqstp) { 69 return (TRUE); 70 } 71 72 #define IS_BATCH_SID(batch, i)\ 73 batch.idmap_mapping_batch_val[i].id1.idtype == IDMAP_SID 74 75 #define IS_BATCH_UID(batch, i)\ 76 batch.idmap_mapping_batch_val[i].id1.idtype == IDMAP_UID 77 78 #define IS_BATCH_GID(batch, i)\ 79 batch.idmap_mapping_batch_val[i].id1.idtype == IDMAP_GID 80 81 #define IS_REQUEST_SID(request)\ 82 request.id1.idtype == IDMAP_SID 83 84 #define IS_REQUEST_UID(request)\ 85 request.id1.idtype == IDMAP_UID 86 87 #define IS_REQUEST_GID(request)\ 88 request.id1.idtype == IDMAP_GID 89 90 /* ARGSUSED */ 91 bool_t 92 idmap_get_mapped_ids_1_svc(idmap_mapping_batch batch, 93 idmap_ids_res *result, struct svc_req *rqstp) { 94 sqlite *cache = NULL, *db = NULL; 95 lookup_state_t state; 96 idmap_retcode retcode, winrc; 97 uint_t i; 98 99 /* Init */ 100 (void) memset(result, 0, sizeof (*result)); 101 (void) memset(&state, 0, sizeof (state)); 102 103 /* Return success if nothing was requested */ 104 if (batch.idmap_mapping_batch_len < 1) 105 goto out; 106 107 /* Get cache handle */ 108 result->retcode = get_cache_handle(&cache); 109 if (result->retcode != IDMAP_SUCCESS) 110 goto out; 111 112 /* Get db handle */ 113 result->retcode = get_db_handle(&db); 114 if (result->retcode != IDMAP_SUCCESS) 115 goto out; 116 117 /* Allocate result array */ 118 result->ids.ids_val = calloc(batch.idmap_mapping_batch_len, 119 sizeof (idmap_id_res)); 120 if (result->ids.ids_val == NULL) { 121 idmapdlog(LOG_ERR, "Out of memory"); 122 result->retcode = IDMAP_ERR_MEMORY; 123 goto out; 124 } 125 result->ids.ids_len = batch.idmap_mapping_batch_len; 126 127 /* Allocate hash table to check for duplicate sids */ 128 state.sid_history = calloc(batch.idmap_mapping_batch_len, 129 sizeof (*state.sid_history)); 130 if (state.sid_history == NULL) { 131 idmapdlog(LOG_ERR, "Out of memory"); 132 result->retcode = IDMAP_ERR_MEMORY; 133 goto out; 134 } 135 state.sid_history_size = batch.idmap_mapping_batch_len; 136 for (i = 0; i < state.sid_history_size; i++) { 137 state.sid_history[i].key = state.sid_history_size; 138 state.sid_history[i].next = state.sid_history_size; 139 } 140 state.batch = &batch; 141 state.result = result; 142 143 /* Init our 'done' flags */ 144 state.sid2pid_done = state.pid2sid_done = TRUE; 145 146 /* First stage */ 147 for (i = 0; i < batch.idmap_mapping_batch_len; i++) { 148 state.curpos = i; 149 if (IS_BATCH_SID(batch, i)) { 150 retcode = sid2pid_first_pass( 151 &state, 152 cache, 153 &batch.idmap_mapping_batch_val[i], 154 &result->ids.ids_val[i]); 155 } else if (IS_BATCH_UID(batch, i)) { 156 retcode = pid2sid_first_pass( 157 &state, 158 cache, 159 db, 160 &batch.idmap_mapping_batch_val[i], 161 &result->ids.ids_val[i], 1, 0); 162 } else if (IS_BATCH_GID(batch, i)) { 163 retcode = pid2sid_first_pass( 164 &state, 165 cache, 166 db, 167 &batch.idmap_mapping_batch_val[i], 168 &result->ids.ids_val[i], 0, 0); 169 } else { 170 result->ids.ids_val[i].retcode = IDMAP_ERR_IDTYPE; 171 continue; 172 } 173 if (IDMAP_FATAL_ERROR(retcode)) { 174 result->retcode = retcode; 175 goto out; 176 } 177 } 178 179 /* Check if we are done */ 180 if (state.sid2pid_done == TRUE && state.pid2sid_done == TRUE) 181 goto out; 182 183 /* Process Windows server lookups for sid2name */ 184 if (state.ad_nqueries) { 185 winrc = lookup_win_batch_sid2name(&state, &batch, 186 result); 187 if (IDMAP_FATAL_ERROR(winrc)) { 188 result->retcode = winrc; 189 goto out; 190 } 191 } else 192 winrc = IDMAP_SUCCESS; 193 194 /* Reset sid2pid 'done' flag */ 195 state.sid2pid_done = TRUE; 196 197 /* Second stage */ 198 for (i = 0; i < batch.idmap_mapping_batch_len; i++) { 199 state.curpos = i; 200 /* Process sid to pid ONLY */ 201 if (IS_BATCH_SID(batch, i)) { 202 if (IDMAP_ERROR(winrc)) 203 result->ids.ids_val[i].retcode = winrc; 204 retcode = sid2pid_second_pass( 205 &state, 206 cache, 207 db, 208 &batch.idmap_mapping_batch_val[i], 209 &result->ids.ids_val[i]); 210 if (IDMAP_FATAL_ERROR(retcode)) { 211 result->retcode = retcode; 212 goto out; 213 } 214 } 215 } 216 217 /* Check if we are done */ 218 if (state.sid2pid_done == TRUE && state.pid2sid_done == TRUE) 219 goto out; 220 221 /* Reset our 'done' flags */ 222 state.sid2pid_done = state.pid2sid_done = TRUE; 223 224 /* Update cache in a single transaction */ 225 if (sql_exec_no_cb(cache, "BEGIN TRANSACTION;") != IDMAP_SUCCESS) 226 goto out; 227 228 for (i = 0; i < batch.idmap_mapping_batch_len; i++) { 229 state.curpos = i; 230 if (IS_BATCH_SID(batch, i)) { 231 (void) update_cache_sid2pid( 232 &state, 233 cache, 234 &batch.idmap_mapping_batch_val[i], 235 &result->ids.ids_val[i]); 236 } else if ((IS_BATCH_UID(batch, i)) || 237 (IS_BATCH_GID(batch, i))) { 238 (void) update_cache_pid2sid( 239 &state, 240 cache, 241 &batch.idmap_mapping_batch_val[i], 242 &result->ids.ids_val[i]); 243 } 244 } 245 246 /* Commit if we have atleast one successful update */ 247 if (state.sid2pid_done == FALSE || state.pid2sid_done == FALSE) 248 (void) sql_exec_no_cb(cache, "COMMIT TRANSACTION;"); 249 else 250 (void) sql_exec_no_cb(cache, "END TRANSACTION;"); 251 252 out: 253 if (state.sid_history) 254 free(state.sid_history); 255 if (IDMAP_ERROR(result->retcode)) { 256 xdr_free(xdr_idmap_ids_res, (caddr_t)result); 257 result->ids.ids_len = 0; 258 result->ids.ids_val = NULL; 259 } 260 result->retcode = idmap_stat4prot(result->retcode); 261 return (TRUE); 262 } 263 264 265 /* ARGSUSED */ 266 static int 267 list_mappings_cb(void *parg, int argc, char **argv, char **colnames) { 268 list_cb_data_t *cb_data; 269 char *str; 270 idmap_mappings_res *result; 271 idmap_utf8str *ptr; 272 idmap_retcode retcode; 273 int w2u, u2w; 274 char *end; 275 276 cb_data = (list_cb_data_t *)parg; 277 result = (idmap_mappings_res *)cb_data->result; 278 279 _VALIDATE_LIST_CB_DATA(9, &result->mappings.mappings_val, 280 sizeof (idmap_mapping)); 281 282 result->mappings.mappings_len++; 283 284 if ((str = strdup(argv[1])) == NULL) 285 return (1); 286 result->mappings.mappings_val[cb_data->next].id1.idmap_id_u.sid.prefix = 287 str; 288 result->mappings.mappings_val[cb_data->next].id1.idmap_id_u.sid.rid = 289 strtoul(argv[2], &end, 10); 290 result->mappings.mappings_val[cb_data->next].id1.idtype = IDMAP_SID; 291 292 result->mappings.mappings_val[cb_data->next].id2.idmap_id_u.uid = 293 strtoul(argv[3], &end, 10); 294 result->mappings.mappings_val[cb_data->next].id2.idtype = IDMAP_UID; 295 296 w2u = argv[4]?strtol(argv[4], &end, 10):0; 297 u2w = argv[5]?strtol(argv[5], &end, 10):0; 298 299 if (w2u > 0 && u2w == 0) 300 result->mappings.mappings_val[cb_data->next].direction = 301 IDMAP_DIRECTION_W2U; 302 else if (w2u == 0 && u2w > 0) 303 result->mappings.mappings_val[cb_data->next].direction = 304 IDMAP_DIRECTION_U2W; 305 else 306 result->mappings.mappings_val[cb_data->next].direction = 307 IDMAP_DIRECTION_BI; 308 309 ptr = &result->mappings.mappings_val[cb_data->next].id1domain; 310 if (idmap_str2utf8(&ptr, argv[6], 0) != IDMAP_SUCCESS) 311 return (1); 312 313 ptr = &result->mappings.mappings_val[cb_data->next].id1name; 314 if (idmap_str2utf8(&ptr, argv[7], 0) != IDMAP_SUCCESS) 315 return (1); 316 317 ptr = &result->mappings.mappings_val[cb_data->next].id2name; 318 if (idmap_str2utf8(&ptr, argv[8], 0) != IDMAP_SUCCESS) 319 return (1); 320 321 result->lastrowid = strtoll(argv[0], &end, 10); 322 cb_data->next++; 323 result->retcode = IDMAP_SUCCESS; 324 return (0); 325 } 326 327 328 /* ARGSUSED */ 329 bool_t 330 idmap_list_mappings_1_svc(bool_t is_user, int64_t lastrowid, 331 uint64_t limit, idmap_mappings_res *result, 332 struct svc_req *rqstp) { 333 sqlite *cache = NULL; 334 char lbuf[30], rbuf[30]; 335 uint64_t maxlimit; 336 idmap_retcode retcode; 337 char *sql = NULL; 338 339 (void) memset(result, 0, sizeof (*result)); 340 lbuf[0] = rbuf[0] = 0; 341 342 RDLOCK_CONFIG(); 343 maxlimit = _idmapdstate.cfg->pgcfg.list_size_limit; 344 UNLOCK_CONFIG(); 345 346 /* Get cache handle */ 347 result->retcode = get_cache_handle(&cache); 348 if (result->retcode != IDMAP_SUCCESS) 349 goto out; 350 351 result->retcode = IDMAP_ERR_INTERNAL; 352 353 /* Create LIMIT expression. */ 354 if (limit == 0 || (maxlimit > 0 && maxlimit < limit)) 355 limit = maxlimit; 356 if (limit > 0) 357 (void) snprintf(lbuf, sizeof (lbuf), 358 "LIMIT %" PRIu64, limit + 1ULL); 359 360 (void) snprintf(rbuf, sizeof (rbuf), "rowid > %" PRIu64, lastrowid); 361 362 /* 363 * Combine all the above into a giant SELECT statement that 364 * will return the requested mappings 365 */ 366 sql = sqlite_mprintf("SELECT rowid, sidprefix, rid, pid, w2u, u2w," 367 " windomain, winname, unixname" 368 " FROM idmap_cache WHERE " 369 " %s AND is_user = %d %s;", 370 rbuf, is_user?1:0, lbuf); 371 if (sql == NULL) { 372 idmapdlog(LOG_ERR, "Out of memory"); 373 goto out; 374 } 375 376 /* Execute the SQL statement and update the return buffer */ 377 PROCESS_LIST_SVC_SQL(retcode, cache, sql, limit, list_mappings_cb, 378 result, result->mappings.mappings_len); 379 380 out: 381 if (sql) 382 sqlite_freemem(sql); 383 if (IDMAP_ERROR(result->retcode)) 384 (void) xdr_free(xdr_idmap_mappings_res, (caddr_t)result); 385 result->retcode = idmap_stat4prot(result->retcode); 386 return (TRUE); 387 } 388 389 390 /* ARGSUSED */ 391 static int 392 list_namerules_cb(void *parg, int argc, char **argv, char **colnames) { 393 list_cb_data_t *cb_data; 394 idmap_namerules_res *result; 395 idmap_retcode retcode; 396 idmap_utf8str *ptr; 397 int w2u_order, u2w_order; 398 char *end; 399 400 cb_data = (list_cb_data_t *)parg; 401 result = (idmap_namerules_res *)cb_data->result; 402 403 _VALIDATE_LIST_CB_DATA(8, &result->rules.rules_val, 404 sizeof (idmap_namerule)); 405 406 result->rules.rules_len++; 407 408 result->rules.rules_val[cb_data->next].is_user = 409 strtol(argv[1], &end, 10); 410 411 ptr = &result->rules.rules_val[cb_data->next].windomain; 412 if (idmap_str2utf8(&ptr, argv[2], 0) != IDMAP_SUCCESS) 413 return (1); 414 415 ptr = &result->rules.rules_val[cb_data->next].winname; 416 if (idmap_str2utf8(&ptr, argv[3], 0) != IDMAP_SUCCESS) 417 return (1); 418 419 result->rules.rules_val[cb_data->next].is_nt4 = 420 strtol(argv[4], &end, 10); 421 422 ptr = &result->rules.rules_val[cb_data->next].unixname; 423 if (idmap_str2utf8(&ptr, argv[5], 0) != IDMAP_SUCCESS) 424 return (1); 425 426 w2u_order = argv[6]?strtol(argv[6], &end, 10):0; 427 u2w_order = argv[7]?strtol(argv[7], &end, 10):0; 428 429 if (w2u_order > 0 && u2w_order == 0) 430 result->rules.rules_val[cb_data->next].direction = 431 IDMAP_DIRECTION_W2U; 432 else if (w2u_order == 0 && u2w_order > 0) 433 result->rules.rules_val[cb_data->next].direction = 434 IDMAP_DIRECTION_U2W; 435 else 436 result->rules.rules_val[cb_data->next].direction = 437 IDMAP_DIRECTION_BI; 438 439 result->lastrowid = strtoll(argv[0], &end, 10); 440 cb_data->next++; 441 result->retcode = IDMAP_SUCCESS; 442 return (0); 443 } 444 445 446 /* ARGSUSED */ 447 bool_t 448 idmap_list_namerules_1_svc(idmap_namerule rule, uint64_t lastrowid, 449 uint64_t limit, idmap_namerules_res *result, 450 struct svc_req *rqstp) { 451 452 sqlite *db = NULL; 453 char w2ubuf[15], u2wbuf[15]; 454 char lbuf[30], rbuf[30]; 455 char *sql = NULL; 456 char *s_windomain = NULL, *s_winname = NULL; 457 char *s_unixname = NULL; 458 uint64_t maxlimit; 459 idmap_retcode retcode; 460 461 (void) memset(result, 0, sizeof (*result)); 462 lbuf[0] = rbuf[0] = 0; 463 464 RDLOCK_CONFIG(); 465 maxlimit = _idmapdstate.cfg->pgcfg.list_size_limit; 466 UNLOCK_CONFIG(); 467 468 /* Get db handle */ 469 result->retcode = get_db_handle(&db); 470 if (result->retcode != IDMAP_SUCCESS) 471 goto out; 472 473 result->retcode = IDMAP_ERR_INTERNAL; 474 475 if (rule.direction < 0) { 476 w2ubuf[0] = u2wbuf[0] = 0; 477 } else if (rule.direction == IDMAP_DIRECTION_BI) { 478 (void) snprintf(w2ubuf, sizeof (w2ubuf), "AND w2u_order > 0"); 479 (void) snprintf(u2wbuf, sizeof (u2wbuf), "AND u2w_order > 0"); 480 } else if (rule.direction == IDMAP_DIRECTION_W2U) { 481 (void) snprintf(w2ubuf, sizeof (w2ubuf), "AND w2u_order > 0"); 482 (void) snprintf(u2wbuf, sizeof (u2wbuf), 483 "AND (u2w_order = 0 OR u2w_order ISNULL)"); 484 } else if (rule.direction == IDMAP_DIRECTION_U2W) { 485 (void) snprintf(w2ubuf, sizeof (w2ubuf), 486 "AND (w2u_order = 0 OR w2u_order ISNULL)"); 487 (void) snprintf(u2wbuf, sizeof (u2wbuf), "AND u2w_order > 0"); 488 } 489 490 /* Create where statement for windomain */ 491 if (rule.windomain.idmap_utf8str_len > 0) { 492 if (gen_sql_expr_from_utf8str("AND", "windomain", "=", 493 &rule.windomain, 494 "", &s_windomain) != IDMAP_SUCCESS) 495 goto out; 496 } 497 498 /* Create where statement for winname */ 499 if (rule.winname.idmap_utf8str_len > 0) { 500 if (gen_sql_expr_from_utf8str("AND", "winname", "=", 501 &rule.winname, 502 "", &s_winname) != IDMAP_SUCCESS) 503 goto out; 504 } 505 506 /* Create where statement for unixname */ 507 if (rule.unixname.idmap_utf8str_len > 0) { 508 if (gen_sql_expr_from_utf8str("AND", "unixname", "=", 509 &rule.unixname, 510 "", &s_unixname) != IDMAP_SUCCESS) 511 goto out; 512 } 513 514 /* Create LIMIT expression. */ 515 if (limit == 0 || (maxlimit > 0 && maxlimit < limit)) 516 limit = maxlimit; 517 if (limit > 0) 518 (void) snprintf(lbuf, sizeof (lbuf), 519 "LIMIT %" PRIu64, limit + 1ULL); 520 521 (void) snprintf(rbuf, sizeof (rbuf), "rowid > %" PRIu64, lastrowid); 522 523 /* 524 * Combine all the above into a giant SELECT statement that 525 * will return the requested rules 526 */ 527 sql = sqlite_mprintf("SELECT rowid, is_user, windomain, winname, " 528 "is_nt4, unixname, w2u_order, u2w_order " 529 "FROM namerules WHERE " 530 " %s AND is_user = %d %s %s %s %s %s %s;", 531 rbuf, rule.is_user?1:0, 532 s_windomain?s_windomain:"", 533 s_winname?s_winname:"", 534 s_unixname?s_unixname:"", 535 w2ubuf, u2wbuf, lbuf); 536 if (sql == NULL) { 537 idmapdlog(LOG_ERR, "Out of memory"); 538 goto out; 539 } 540 541 /* Execute the SQL statement and update the return buffer */ 542 PROCESS_LIST_SVC_SQL(retcode, db, sql, limit, list_namerules_cb, 543 result, result->rules.rules_len); 544 545 out: 546 if (s_windomain) 547 sqlite_freemem(s_windomain); 548 if (s_winname) 549 sqlite_freemem(s_winname); 550 if (s_unixname) 551 sqlite_freemem(s_unixname); 552 if (sql) 553 sqlite_freemem(sql); 554 if (IDMAP_ERROR(result->retcode)) 555 (void) xdr_free(xdr_idmap_namerules_res, (caddr_t)result); 556 result->retcode = idmap_stat4prot(result->retcode); 557 return (TRUE); 558 } 559 560 #define IDMAP_RULES_AUTH "solaris.admin.idmap.rules" 561 static int 562 verify_rules_auth(struct svc_req *rqstp) { 563 ucred_t *uc = NULL; 564 uid_t uid; 565 char buf[1024]; 566 struct passwd pwd; 567 const char *me = "verify_rules_auth"; 568 569 if (svc_getcallerucred(rqstp->rq_xprt, &uc) != 0) { 570 idmapdlog(LOG_ERR, 571 "%s: svc_getcallerucred failed (errno=%d)", 572 me, errno); 573 return (-1); 574 } 575 576 uid = ucred_geteuid(uc); 577 if (uid == (uid_t)-1) { 578 idmapdlog(LOG_ERR, 579 "%s: ucred_geteuid failed (errno=%d)", 580 me, errno); 581 ucred_free(uc); 582 return (-1); 583 } 584 585 if (getpwuid_r(uid, &pwd, buf, sizeof (buf)) == NULL) { 586 idmapdlog(LOG_ERR, 587 "%s: getpwuid_r(%u) failed (errno=%d)", 588 me, uid, errno); 589 ucred_free(uc); 590 return (-1); 591 } 592 593 if (chkauthattr(IDMAP_RULES_AUTH, pwd.pw_name) != 1) { 594 idmapdlog(LOG_INFO, 595 "%s: %s does not have authorization.", 596 me, pwd.pw_name); 597 ucred_free(uc); 598 return (-1); 599 } 600 601 ucred_free(uc); 602 return (1); 603 } 604 605 /* ARGSUSED */ 606 bool_t 607 idmap_update_1_svc(idmap_update_batch batch, idmap_retcode *result, 608 struct svc_req *rqstp) { 609 sqlite *db = NULL; 610 idmap_update_op *up; 611 int i; 612 int trans = FALSE; 613 614 if (verify_rules_auth(rqstp) < 0) { 615 *result = IDMAP_ERR_PERMISSION_DENIED; 616 goto out; 617 } 618 619 if (batch.idmap_update_batch_len == 0 || 620 batch.idmap_update_batch_val == NULL) { 621 *result = IDMAP_SUCCESS; 622 goto out; 623 } 624 625 /* Get db handle */ 626 *result = get_db_handle(&db); 627 if (*result != IDMAP_SUCCESS) 628 goto out; 629 630 *result = sql_exec_no_cb(db, "BEGIN TRANSACTION;"); 631 if (*result != IDMAP_SUCCESS) 632 goto out; 633 trans = TRUE; 634 635 for (i = 0; i < batch.idmap_update_batch_len; i++) { 636 up = &batch.idmap_update_batch_val[i]; 637 switch (up->opnum) { 638 case OP_NONE: 639 *result = IDMAP_SUCCESS; 640 break; 641 case OP_ADD_NAMERULE: 642 *result = add_namerule(db, 643 &up->idmap_update_op_u.rule); 644 break; 645 case OP_RM_NAMERULE: 646 *result = rm_namerule(db, 647 &up->idmap_update_op_u.rule); 648 break; 649 case OP_FLUSH_NAMERULES: 650 *result = flush_namerules(db, 651 up->idmap_update_op_u.is_user); 652 break; 653 default: 654 *result = IDMAP_ERR_NOTSUPPORTED; 655 goto out; 656 }; 657 658 if (*result != IDMAP_SUCCESS) 659 goto out; 660 } 661 662 out: 663 if (trans) { 664 if (*result == IDMAP_SUCCESS) 665 *result = sql_exec_no_cb(db, "COMMIT TRANSACTION;"); 666 else 667 (void) sql_exec_no_cb(db, "ROLLBACK TRANSACTION;"); 668 } 669 *result = idmap_stat4prot(*result); 670 return (TRUE); 671 } 672 673 674 /* ARGSUSED */ 675 bool_t 676 idmap_get_mapped_id_by_name_1_svc(idmap_mapping request, 677 idmap_mappings_res *result, struct svc_req *rqstp) { 678 sqlite *cache = NULL, *db = NULL; 679 680 /* Init */ 681 (void) memset(result, 0, sizeof (*result)); 682 683 /* Get cache handle */ 684 result->retcode = get_cache_handle(&cache); 685 if (result->retcode != IDMAP_SUCCESS) 686 goto out; 687 688 /* Get db handle */ 689 result->retcode = get_db_handle(&db); 690 if (result->retcode != IDMAP_SUCCESS) 691 goto out; 692 693 /* Allocate result */ 694 result->mappings.mappings_val = calloc(1, sizeof (idmap_mapping)); 695 if (result->mappings.mappings_val == NULL) { 696 idmapdlog(LOG_ERR, "Out of memory"); 697 result->retcode = IDMAP_ERR_MEMORY; 698 goto out; 699 } 700 result->mappings.mappings_len = 1; 701 702 if (IS_REQUEST_SID(request)) { 703 result->retcode = get_w2u_mapping( 704 cache, 705 db, 706 &request, 707 result->mappings.mappings_val); 708 } else if (IS_REQUEST_UID(request)) { 709 result->retcode = get_u2w_mapping( 710 cache, 711 db, 712 &request, 713 result->mappings.mappings_val, 714 1); 715 } else if (IS_REQUEST_GID(request)) { 716 result->retcode = get_u2w_mapping( 717 cache, 718 db, 719 &request, 720 result->mappings.mappings_val, 721 0); 722 } else { 723 result->retcode = IDMAP_ERR_IDTYPE; 724 } 725 726 out: 727 if (IDMAP_FATAL_ERROR(result->retcode)) { 728 xdr_free(xdr_idmap_mappings_res, (caddr_t)result); 729 result->mappings.mappings_len = 0; 730 result->mappings.mappings_val = NULL; 731 } 732 result->retcode = idmap_stat4prot(result->retcode); 733 return (TRUE); 734 } 735 736 737 /* ARGSUSED */ 738 int 739 idmap_prog_1_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, 740 caddr_t result) { 741 (void) xdr_free(xdr_result, result); 742 return (TRUE); 743 } 744