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 int 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 /* Init our 'done' flags */ 128 state.sid2pid_done = state.pid2sid_done = TRUE; 129 130 /* First stage */ 131 for (i = 0; i < batch.idmap_mapping_batch_len; i++) { 132 if (IS_BATCH_SID(batch, i)) { 133 retcode = sid2pid_first_pass( 134 &state, 135 cache, 136 &batch.idmap_mapping_batch_val[i], 137 &result->ids.ids_val[i]); 138 } else if (IS_BATCH_UID(batch, i)) { 139 retcode = pid2sid_first_pass( 140 &state, 141 cache, 142 db, 143 &batch.idmap_mapping_batch_val[i], 144 &result->ids.ids_val[i], 1, 0); 145 } else if (IS_BATCH_GID(batch, i)) { 146 retcode = pid2sid_first_pass( 147 &state, 148 cache, 149 db, 150 &batch.idmap_mapping_batch_val[i], 151 &result->ids.ids_val[i], 0, 0); 152 } else { 153 result->ids.ids_val[i].retcode = IDMAP_ERR_IDTYPE; 154 continue; 155 } 156 if (IDMAP_FATAL_ERROR(retcode)) { 157 result->retcode = retcode; 158 goto out; 159 } 160 } 161 162 /* Check if we are done */ 163 if (state.sid2pid_done == TRUE && state.pid2sid_done == TRUE) 164 goto out; 165 166 /* Process Windows server lookups for sid2name */ 167 if (state.ad_nqueries) { 168 winrc = lookup_win_batch_sid2name(&state, &batch, 169 result); 170 if (IDMAP_FATAL_ERROR(winrc)) { 171 result->retcode = winrc; 172 goto out; 173 } 174 } else 175 winrc = IDMAP_SUCCESS; 176 177 /* Reset sid2pid 'done' flag */ 178 state.sid2pid_done = TRUE; 179 180 /* Second stage */ 181 for (i = 0; i < batch.idmap_mapping_batch_len; i++) { 182 /* Process sid to pid ONLY */ 183 if (IS_BATCH_SID(batch, i)) { 184 if (IDMAP_ERROR(winrc)) 185 result->ids.ids_val[i].retcode = winrc; 186 retcode = sid2pid_second_pass( 187 &state, 188 cache, 189 db, 190 &batch.idmap_mapping_batch_val[i], 191 &result->ids.ids_val[i]); 192 if (IDMAP_FATAL_ERROR(retcode)) { 193 result->retcode = retcode; 194 goto out; 195 } 196 } 197 } 198 199 /* Check if we are done */ 200 if (state.sid2pid_done == TRUE && state.pid2sid_done == TRUE) 201 goto out; 202 203 /* Reset our 'done' flags */ 204 state.sid2pid_done = state.pid2sid_done = TRUE; 205 206 /* Update cache in a single transaction */ 207 if (sql_exec_no_cb(cache, "BEGIN TRANSACTION;") != IDMAP_SUCCESS) 208 goto out; 209 210 for (i = 0; i < batch.idmap_mapping_batch_len; i++) { 211 if (IS_BATCH_SID(batch, i)) { 212 (void) update_cache_sid2pid( 213 &state, 214 cache, 215 &batch.idmap_mapping_batch_val[i], 216 &result->ids.ids_val[i]); 217 } else if ((IS_BATCH_UID(batch, i)) || 218 (IS_BATCH_GID(batch, i))) { 219 (void) update_cache_pid2sid( 220 &state, 221 cache, 222 &batch.idmap_mapping_batch_val[i], 223 &result->ids.ids_val[i]); 224 } 225 } 226 227 /* Commit if we have atleast one successful update */ 228 if (state.sid2pid_done == FALSE || state.pid2sid_done == FALSE) 229 (void) sql_exec_no_cb(cache, "COMMIT TRANSACTION;"); 230 else 231 (void) sql_exec_no_cb(cache, "END TRANSACTION;"); 232 233 out: 234 if (IDMAP_ERROR(result->retcode)) { 235 xdr_free(xdr_idmap_ids_res, (caddr_t)result); 236 result->ids.ids_len = 0; 237 result->ids.ids_val = NULL; 238 } 239 if (cache) 240 (void) sqlite_close(cache); 241 if (db) 242 (void) sqlite_close(db); 243 result->retcode = idmap_stat4prot(result->retcode); 244 return (TRUE); 245 } 246 247 248 /* ARGSUSED */ 249 static int 250 list_mappings_cb(void *parg, int argc, char **argv, char **colnames) { 251 list_cb_data_t *cb_data; 252 char *str; 253 idmap_mappings_res *result; 254 idmap_utf8str *ptr; 255 idmap_retcode retcode; 256 int w2u, u2w; 257 char *end; 258 259 cb_data = (list_cb_data_t *)parg; 260 result = (idmap_mappings_res *)cb_data->result; 261 262 _VALIDATE_LIST_CB_DATA(9, &result->mappings.mappings_val, 263 sizeof (idmap_mapping)); 264 265 result->mappings.mappings_len++; 266 267 if ((str = strdup(argv[1])) == NULL) 268 return (1); 269 result->mappings.mappings_val[cb_data->next].id1.idmap_id_u.sid.prefix = 270 str; 271 result->mappings.mappings_val[cb_data->next].id1.idmap_id_u.sid.rid = 272 strtoul(argv[2], &end, 10); 273 result->mappings.mappings_val[cb_data->next].id1.idtype = IDMAP_SID; 274 275 result->mappings.mappings_val[cb_data->next].id2.idmap_id_u.uid = 276 strtoul(argv[3], &end, 10); 277 result->mappings.mappings_val[cb_data->next].id2.idtype = IDMAP_UID; 278 279 w2u = argv[4]?strtol(argv[4], &end, 10):0; 280 u2w = argv[5]?strtol(argv[5], &end, 10):0; 281 282 if (w2u > 0 && u2w == 0) 283 result->mappings.mappings_val[cb_data->next].direction = 1; 284 else if (w2u == 0 && u2w > 0) 285 result->mappings.mappings_val[cb_data->next].direction = 2; 286 else 287 result->mappings.mappings_val[cb_data->next].direction = 0; 288 289 ptr = &result->mappings.mappings_val[cb_data->next].id1domain; 290 if (idmap_str2utf8(&ptr, argv[6], 0) != IDMAP_SUCCESS) 291 return (1); 292 293 ptr = &result->mappings.mappings_val[cb_data->next].id1name; 294 if (idmap_str2utf8(&ptr, argv[7], 0) != IDMAP_SUCCESS) 295 return (1); 296 297 ptr = &result->mappings.mappings_val[cb_data->next].id2name; 298 if (idmap_str2utf8(&ptr, argv[8], 0) != IDMAP_SUCCESS) 299 return (1); 300 301 result->lastrowid = strtoll(argv[0], &end, 10); 302 cb_data->next++; 303 result->retcode = IDMAP_SUCCESS; 304 return (0); 305 } 306 307 308 /* ARGSUSED */ 309 bool_t 310 idmap_list_mappings_1_svc(bool_t is_user, int64_t lastrowid, 311 uint64_t limit, idmap_mappings_res *result, 312 struct svc_req *rqstp) { 313 sqlite *cache = NULL; 314 char lbuf[30], rbuf[30]; 315 uint64_t maxlimit; 316 idmap_retcode retcode; 317 char *sql = NULL; 318 319 (void) memset(result, 0, sizeof (*result)); 320 lbuf[0] = rbuf[0] = 0; 321 322 RDLOCK_CONFIG(); 323 maxlimit = _idmapdstate.cfg->pgcfg.list_size_limit; 324 UNLOCK_CONFIG(); 325 326 /* Get cache handle */ 327 result->retcode = get_cache_handle(&cache); 328 if (result->retcode != IDMAP_SUCCESS) 329 goto out; 330 331 result->retcode = IDMAP_ERR_INTERNAL; 332 333 /* Create LIMIT expression. */ 334 if (limit == 0 || (maxlimit > 0 && maxlimit < limit)) 335 limit = maxlimit; 336 if (limit > 0) 337 (void) snprintf(lbuf, sizeof (lbuf), 338 "LIMIT %" PRIu64, limit + 1ULL); 339 340 (void) snprintf(rbuf, sizeof (rbuf), "rowid > %" PRIu64, lastrowid); 341 342 /* 343 * Combine all the above into a giant SELECT statement that 344 * will return the requested mappings 345 */ 346 sql = sqlite_mprintf("SELECT rowid, sidprefix, rid, pid, w2u, u2w," 347 " windomain, winname, unixname" 348 " FROM idmap_cache WHERE " 349 " %s AND is_user = %d %s;", 350 rbuf, is_user?1:0, lbuf); 351 if (sql == NULL) { 352 idmapdlog(LOG_ERR, "Out of memory"); 353 goto out; 354 } 355 356 /* Execute the SQL statement and update the return buffer */ 357 PROCESS_LIST_SVC_SQL(retcode, cache, sql, limit, list_mappings_cb, 358 result, result->mappings.mappings_len); 359 360 out: 361 if (sql) 362 sqlite_freemem(sql); 363 if (IDMAP_ERROR(result->retcode)) 364 (void) xdr_free(xdr_idmap_mappings_res, (caddr_t)result); 365 if (cache) 366 (void) sqlite_close(cache); 367 result->retcode = idmap_stat4prot(result->retcode); 368 return (TRUE); 369 } 370 371 372 /* ARGSUSED */ 373 static int 374 list_namerules_cb(void *parg, int argc, char **argv, char **colnames) { 375 list_cb_data_t *cb_data; 376 idmap_namerules_res *result; 377 idmap_retcode retcode; 378 idmap_utf8str *ptr; 379 int w2u_order, u2w_order; 380 char *end; 381 382 cb_data = (list_cb_data_t *)parg; 383 result = (idmap_namerules_res *)cb_data->result; 384 385 _VALIDATE_LIST_CB_DATA(8, &result->rules.rules_val, 386 sizeof (idmap_namerule)); 387 388 result->rules.rules_len++; 389 390 result->rules.rules_val[cb_data->next].is_user = 391 strtol(argv[1], &end, 10); 392 393 ptr = &result->rules.rules_val[cb_data->next].windomain; 394 if (idmap_str2utf8(&ptr, argv[2], 0) != IDMAP_SUCCESS) 395 return (1); 396 397 ptr = &result->rules.rules_val[cb_data->next].winname; 398 if (idmap_str2utf8(&ptr, argv[3], 0) != IDMAP_SUCCESS) 399 return (1); 400 401 result->rules.rules_val[cb_data->next].is_nt4 = 402 strtol(argv[4], &end, 10); 403 404 ptr = &result->rules.rules_val[cb_data->next].unixname; 405 if (idmap_str2utf8(&ptr, argv[5], 0) != IDMAP_SUCCESS) 406 return (1); 407 408 w2u_order = argv[6]?strtol(argv[6], &end, 10):0; 409 u2w_order = argv[7]?strtol(argv[7], &end, 10):0; 410 411 if (w2u_order > 0 && u2w_order == 0) 412 result->rules.rules_val[cb_data->next].direction = 1; 413 else if (w2u_order == 0 && u2w_order > 0) 414 result->rules.rules_val[cb_data->next].direction = 2; 415 else 416 result->rules.rules_val[cb_data->next].direction = 0; 417 418 result->lastrowid = strtoll(argv[0], &end, 10); 419 cb_data->next++; 420 result->retcode = IDMAP_SUCCESS; 421 return (0); 422 } 423 424 425 /* ARGSUSED */ 426 bool_t 427 idmap_list_namerules_1_svc(idmap_namerule rule, uint64_t lastrowid, 428 uint64_t limit, idmap_namerules_res *result, 429 struct svc_req *rqstp) { 430 431 sqlite *db = NULL; 432 char w2ubuf[15], u2wbuf[15]; 433 char lbuf[30], rbuf[30]; 434 char *sql = NULL; 435 char *s_windomain = NULL, *s_winname = NULL; 436 char *s_unixname = NULL; 437 uint64_t maxlimit; 438 idmap_retcode retcode; 439 440 (void) memset(result, 0, sizeof (*result)); 441 lbuf[0] = rbuf[0] = 0; 442 443 RDLOCK_CONFIG(); 444 maxlimit = _idmapdstate.cfg->pgcfg.list_size_limit; 445 UNLOCK_CONFIG(); 446 447 /* Get db handle */ 448 result->retcode = get_db_handle(&db); 449 if (result->retcode != IDMAP_SUCCESS) 450 goto out; 451 452 result->retcode = IDMAP_ERR_INTERNAL; 453 454 if (rule.direction < 0) { 455 w2ubuf[0] = u2wbuf[0] = 0; 456 } else if (rule.direction == 0) { 457 (void) snprintf(w2ubuf, sizeof (w2ubuf), "AND w2u_order > 0"); 458 (void) snprintf(u2wbuf, sizeof (u2wbuf), "AND u2w_order > 0"); 459 } else if (rule.direction == 1) { 460 (void) snprintf(w2ubuf, sizeof (w2ubuf), "AND w2u_order > 0"); 461 (void) snprintf(u2wbuf, sizeof (u2wbuf), 462 "AND (u2w_order = 0 OR u2w_order ISNULL)"); 463 } else if (rule.direction == 2) { 464 (void) snprintf(w2ubuf, sizeof (w2ubuf), 465 "AND (w2u_order = 0 OR w2u_order ISNULL)"); 466 (void) snprintf(u2wbuf, sizeof (u2wbuf), "AND u2w_order > 0"); 467 } 468 469 /* Create where statement for windomain */ 470 if (rule.windomain.idmap_utf8str_len > 0) { 471 if (gen_sql_expr_from_utf8str("AND", "windomain", "=", 472 &rule.windomain, 473 "", &s_windomain) != IDMAP_SUCCESS) 474 goto out; 475 } 476 477 /* Create where statement for winname */ 478 if (rule.winname.idmap_utf8str_len > 0) { 479 if (gen_sql_expr_from_utf8str("AND", "winname", "=", 480 &rule.winname, 481 "", &s_winname) != IDMAP_SUCCESS) 482 goto out; 483 } 484 485 /* Create where statement for unixname */ 486 if (rule.unixname.idmap_utf8str_len > 0) { 487 if (gen_sql_expr_from_utf8str("AND", "unixname", "=", 488 &rule.unixname, 489 "", &s_unixname) != IDMAP_SUCCESS) 490 goto out; 491 } 492 493 /* Create LIMIT expression. */ 494 if (limit == 0 || (maxlimit > 0 && maxlimit < limit)) 495 limit = maxlimit; 496 if (limit > 0) 497 (void) snprintf(lbuf, sizeof (lbuf), 498 "LIMIT %" PRIu64, limit + 1ULL); 499 500 (void) snprintf(rbuf, sizeof (rbuf), "rowid > %" PRIu64, lastrowid); 501 502 /* 503 * Combine all the above into a giant SELECT statement that 504 * will return the requested rules 505 */ 506 sql = sqlite_mprintf("SELECT rowid, is_user, windomain, winname, " 507 "is_nt4, unixname, w2u_order, u2w_order " 508 "FROM namerules WHERE " 509 " %s AND is_user = %d %s %s %s %s %s %s;", 510 rbuf, rule.is_user?1:0, 511 s_windomain?s_windomain:"", 512 s_winname?s_winname:"", 513 s_unixname?s_unixname:"", 514 w2ubuf, u2wbuf, lbuf); 515 if (sql == NULL) { 516 idmapdlog(LOG_ERR, "Out of memory"); 517 goto out; 518 } 519 520 /* Execute the SQL statement and update the return buffer */ 521 PROCESS_LIST_SVC_SQL(retcode, db, sql, limit, list_namerules_cb, 522 result, result->rules.rules_len); 523 524 out: 525 if (s_windomain) 526 sqlite_freemem(s_windomain); 527 if (s_winname) 528 sqlite_freemem(s_winname); 529 if (s_unixname) 530 sqlite_freemem(s_unixname); 531 if (sql) 532 sqlite_freemem(sql); 533 if (IDMAP_ERROR(result->retcode)) 534 (void) xdr_free(xdr_idmap_namerules_res, (caddr_t)result); 535 if (db) 536 (void) sqlite_close(db); 537 result->retcode = idmap_stat4prot(result->retcode); 538 return (TRUE); 539 } 540 541 #define IDMAP_RULES_AUTH "solaris.admin.idmap.rules" 542 static int 543 verify_rules_auth(struct svc_req *rqstp) { 544 ucred_t *uc = NULL; 545 uid_t uid; 546 char buf[1024]; 547 struct passwd pwd; 548 const char *me = "verify_rules_auth"; 549 550 if (svc_getcallerucred(rqstp->rq_xprt, &uc) != 0) { 551 idmapdlog(LOG_ERR, 552 "%s: svc_getcallerucred failed (errno=%d)", 553 me, errno); 554 return (-1); 555 } 556 557 uid = ucred_geteuid(uc); 558 if (uid == (uid_t)-1) { 559 idmapdlog(LOG_ERR, 560 "%s: ucred_geteuid failed (errno=%d)", 561 me, errno); 562 ucred_free(uc); 563 return (-1); 564 } 565 566 if (getpwuid_r(uid, &pwd, buf, sizeof (buf)) == NULL) { 567 idmapdlog(LOG_ERR, 568 "%s: getpwuid_r(%u) failed (errno=%d)", 569 me, uid, errno); 570 ucred_free(uc); 571 return (-1); 572 } 573 574 if (chkauthattr(IDMAP_RULES_AUTH, pwd.pw_name) != 1) { 575 idmapdlog(LOG_INFO, 576 "%s: %s does not have authorization.", 577 me, pwd.pw_name); 578 ucred_free(uc); 579 return (-1); 580 } 581 582 ucred_free(uc); 583 return (1); 584 } 585 586 /* ARGSUSED */ 587 bool_t 588 idmap_update_1_svc(idmap_update_batch batch, idmap_retcode *result, 589 struct svc_req *rqstp) { 590 sqlite *db = NULL; 591 idmap_update_op *up; 592 int i; 593 594 if (verify_rules_auth(rqstp) < 0) { 595 *result = IDMAP_ERR_PERMISSION_DENIED; 596 goto out; 597 } 598 599 if (batch.idmap_update_batch_len == 0 || 600 batch.idmap_update_batch_val == NULL) { 601 *result = IDMAP_SUCCESS; 602 goto out; 603 } 604 605 /* Get db handle */ 606 *result = get_db_handle(&db); 607 if (*result != IDMAP_SUCCESS) 608 goto out; 609 610 *result = sql_exec_no_cb(db, "BEGIN TRANSACTION;"); 611 if (*result != IDMAP_SUCCESS) 612 goto out; 613 614 for (i = 0; i < batch.idmap_update_batch_len; i++) { 615 up = &batch.idmap_update_batch_val[i]; 616 switch (up->opnum) { 617 case OP_NONE: 618 *result = IDMAP_SUCCESS; 619 break; 620 case OP_ADD_NAMERULE: 621 *result = add_namerule(db, 622 &up->idmap_update_op_u.rule); 623 break; 624 case OP_RM_NAMERULE: 625 *result = rm_namerule(db, 626 &up->idmap_update_op_u.rule); 627 break; 628 case OP_FLUSH_NAMERULES: 629 *result = flush_namerules(db, 630 up->idmap_update_op_u.is_user); 631 break; 632 default: 633 *result = IDMAP_ERR_NOTSUPPORTED; 634 goto out; 635 }; 636 637 if (*result != IDMAP_SUCCESS) 638 goto out; 639 } 640 641 out: 642 if (*result == IDMAP_SUCCESS && db) { 643 *result = sql_exec_no_cb(db, "COMMIT TRANSACTION;"); 644 } 645 646 if (db) 647 (void) sqlite_close(db); 648 *result = idmap_stat4prot(*result); 649 return (TRUE); 650 } 651 652 653 /* ARGSUSED */ 654 bool_t 655 idmap_get_mapped_id_by_name_1_svc(idmap_mapping request, 656 idmap_mappings_res *result, struct svc_req *rqstp) { 657 sqlite *cache = NULL, *db = NULL; 658 659 /* Init */ 660 (void) memset(result, 0, sizeof (*result)); 661 662 /* Get cache handle */ 663 result->retcode = get_cache_handle(&cache); 664 if (result->retcode != IDMAP_SUCCESS) 665 goto out; 666 667 /* Get db handle */ 668 result->retcode = get_db_handle(&db); 669 if (result->retcode != IDMAP_SUCCESS) 670 goto out; 671 672 /* Allocate result */ 673 result->mappings.mappings_val = calloc(1, sizeof (idmap_mapping)); 674 if (result->mappings.mappings_val == NULL) { 675 idmapdlog(LOG_ERR, "Out of memory"); 676 result->retcode = IDMAP_ERR_MEMORY; 677 goto out; 678 } 679 result->mappings.mappings_len = 1; 680 681 if (IS_REQUEST_SID(request)) { 682 result->retcode = get_w2u_mapping( 683 cache, 684 db, 685 &request, 686 result->mappings.mappings_val); 687 } else if (IS_REQUEST_UID(request)) { 688 result->retcode = get_u2w_mapping( 689 cache, 690 db, 691 &request, 692 result->mappings.mappings_val, 693 1); 694 } else if (IS_REQUEST_GID(request)) { 695 result->retcode = get_u2w_mapping( 696 cache, 697 db, 698 &request, 699 result->mappings.mappings_val, 700 0); 701 } else { 702 result->retcode = IDMAP_ERR_IDTYPE; 703 } 704 705 out: 706 if (IDMAP_FATAL_ERROR(result->retcode)) { 707 xdr_free(xdr_idmap_mappings_res, (caddr_t)result); 708 result->mappings.mappings_len = 0; 709 result->mappings.mappings_val = NULL; 710 } 711 if (cache) 712 (void) sqlite_close(cache); 713 if (db) 714 (void) sqlite_close(db); 715 result->retcode = idmap_stat4prot(result->retcode); 716 return (TRUE); 717 } 718 719 720 /* ARGSUSED */ 721 int 722 idmap_prog_1_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, 723 caddr_t result) { 724 (void) xdr_free(xdr_result, result); 725 return (TRUE); 726 } 727