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 = 284 IDMAP_DIRECTION_W2U; 285 else if (w2u == 0 && u2w > 0) 286 result->mappings.mappings_val[cb_data->next].direction = 287 IDMAP_DIRECTION_U2W; 288 else 289 result->mappings.mappings_val[cb_data->next].direction = 290 IDMAP_DIRECTION_BI; 291 292 ptr = &result->mappings.mappings_val[cb_data->next].id1domain; 293 if (idmap_str2utf8(&ptr, argv[6], 0) != IDMAP_SUCCESS) 294 return (1); 295 296 ptr = &result->mappings.mappings_val[cb_data->next].id1name; 297 if (idmap_str2utf8(&ptr, argv[7], 0) != IDMAP_SUCCESS) 298 return (1); 299 300 ptr = &result->mappings.mappings_val[cb_data->next].id2name; 301 if (idmap_str2utf8(&ptr, argv[8], 0) != IDMAP_SUCCESS) 302 return (1); 303 304 result->lastrowid = strtoll(argv[0], &end, 10); 305 cb_data->next++; 306 result->retcode = IDMAP_SUCCESS; 307 return (0); 308 } 309 310 311 /* ARGSUSED */ 312 bool_t 313 idmap_list_mappings_1_svc(bool_t is_user, int64_t lastrowid, 314 uint64_t limit, idmap_mappings_res *result, 315 struct svc_req *rqstp) { 316 sqlite *cache = NULL; 317 char lbuf[30], rbuf[30]; 318 uint64_t maxlimit; 319 idmap_retcode retcode; 320 char *sql = NULL; 321 322 (void) memset(result, 0, sizeof (*result)); 323 lbuf[0] = rbuf[0] = 0; 324 325 RDLOCK_CONFIG(); 326 maxlimit = _idmapdstate.cfg->pgcfg.list_size_limit; 327 UNLOCK_CONFIG(); 328 329 /* Get cache handle */ 330 result->retcode = get_cache_handle(&cache); 331 if (result->retcode != IDMAP_SUCCESS) 332 goto out; 333 334 result->retcode = IDMAP_ERR_INTERNAL; 335 336 /* Create LIMIT expression. */ 337 if (limit == 0 || (maxlimit > 0 && maxlimit < limit)) 338 limit = maxlimit; 339 if (limit > 0) 340 (void) snprintf(lbuf, sizeof (lbuf), 341 "LIMIT %" PRIu64, limit + 1ULL); 342 343 (void) snprintf(rbuf, sizeof (rbuf), "rowid > %" PRIu64, lastrowid); 344 345 /* 346 * Combine all the above into a giant SELECT statement that 347 * will return the requested mappings 348 */ 349 sql = sqlite_mprintf("SELECT rowid, sidprefix, rid, pid, w2u, u2w," 350 " windomain, winname, unixname" 351 " FROM idmap_cache WHERE " 352 " %s AND is_user = %d %s;", 353 rbuf, is_user?1:0, lbuf); 354 if (sql == NULL) { 355 idmapdlog(LOG_ERR, "Out of memory"); 356 goto out; 357 } 358 359 /* Execute the SQL statement and update the return buffer */ 360 PROCESS_LIST_SVC_SQL(retcode, cache, sql, limit, list_mappings_cb, 361 result, result->mappings.mappings_len); 362 363 out: 364 if (sql) 365 sqlite_freemem(sql); 366 if (IDMAP_ERROR(result->retcode)) 367 (void) xdr_free(xdr_idmap_mappings_res, (caddr_t)result); 368 if (cache) 369 (void) sqlite_close(cache); 370 result->retcode = idmap_stat4prot(result->retcode); 371 return (TRUE); 372 } 373 374 375 /* ARGSUSED */ 376 static int 377 list_namerules_cb(void *parg, int argc, char **argv, char **colnames) { 378 list_cb_data_t *cb_data; 379 idmap_namerules_res *result; 380 idmap_retcode retcode; 381 idmap_utf8str *ptr; 382 int w2u_order, u2w_order; 383 char *end; 384 385 cb_data = (list_cb_data_t *)parg; 386 result = (idmap_namerules_res *)cb_data->result; 387 388 _VALIDATE_LIST_CB_DATA(8, &result->rules.rules_val, 389 sizeof (idmap_namerule)); 390 391 result->rules.rules_len++; 392 393 result->rules.rules_val[cb_data->next].is_user = 394 strtol(argv[1], &end, 10); 395 396 ptr = &result->rules.rules_val[cb_data->next].windomain; 397 if (idmap_str2utf8(&ptr, argv[2], 0) != IDMAP_SUCCESS) 398 return (1); 399 400 ptr = &result->rules.rules_val[cb_data->next].winname; 401 if (idmap_str2utf8(&ptr, argv[3], 0) != IDMAP_SUCCESS) 402 return (1); 403 404 result->rules.rules_val[cb_data->next].is_nt4 = 405 strtol(argv[4], &end, 10); 406 407 ptr = &result->rules.rules_val[cb_data->next].unixname; 408 if (idmap_str2utf8(&ptr, argv[5], 0) != IDMAP_SUCCESS) 409 return (1); 410 411 w2u_order = argv[6]?strtol(argv[6], &end, 10):0; 412 u2w_order = argv[7]?strtol(argv[7], &end, 10):0; 413 414 if (w2u_order > 0 && u2w_order == 0) 415 result->rules.rules_val[cb_data->next].direction = 416 IDMAP_DIRECTION_W2U; 417 else if (w2u_order == 0 && u2w_order > 0) 418 result->rules.rules_val[cb_data->next].direction = 419 IDMAP_DIRECTION_U2W; 420 else 421 result->rules.rules_val[cb_data->next].direction = 422 IDMAP_DIRECTION_BI; 423 424 result->lastrowid = strtoll(argv[0], &end, 10); 425 cb_data->next++; 426 result->retcode = IDMAP_SUCCESS; 427 return (0); 428 } 429 430 431 /* ARGSUSED */ 432 bool_t 433 idmap_list_namerules_1_svc(idmap_namerule rule, uint64_t lastrowid, 434 uint64_t limit, idmap_namerules_res *result, 435 struct svc_req *rqstp) { 436 437 sqlite *db = NULL; 438 char w2ubuf[15], u2wbuf[15]; 439 char lbuf[30], rbuf[30]; 440 char *sql = NULL; 441 char *s_windomain = NULL, *s_winname = NULL; 442 char *s_unixname = NULL; 443 uint64_t maxlimit; 444 idmap_retcode retcode; 445 446 (void) memset(result, 0, sizeof (*result)); 447 lbuf[0] = rbuf[0] = 0; 448 449 RDLOCK_CONFIG(); 450 maxlimit = _idmapdstate.cfg->pgcfg.list_size_limit; 451 UNLOCK_CONFIG(); 452 453 /* Get db handle */ 454 result->retcode = get_db_handle(&db); 455 if (result->retcode != IDMAP_SUCCESS) 456 goto out; 457 458 result->retcode = IDMAP_ERR_INTERNAL; 459 460 if (rule.direction < 0) { 461 w2ubuf[0] = u2wbuf[0] = 0; 462 } else if (rule.direction == IDMAP_DIRECTION_BI) { 463 (void) snprintf(w2ubuf, sizeof (w2ubuf), "AND w2u_order > 0"); 464 (void) snprintf(u2wbuf, sizeof (u2wbuf), "AND u2w_order > 0"); 465 } else if (rule.direction == IDMAP_DIRECTION_W2U) { 466 (void) snprintf(w2ubuf, sizeof (w2ubuf), "AND w2u_order > 0"); 467 (void) snprintf(u2wbuf, sizeof (u2wbuf), 468 "AND (u2w_order = 0 OR u2w_order ISNULL)"); 469 } else if (rule.direction == IDMAP_DIRECTION_U2W) { 470 (void) snprintf(w2ubuf, sizeof (w2ubuf), 471 "AND (w2u_order = 0 OR w2u_order ISNULL)"); 472 (void) snprintf(u2wbuf, sizeof (u2wbuf), "AND u2w_order > 0"); 473 } 474 475 /* Create where statement for windomain */ 476 if (rule.windomain.idmap_utf8str_len > 0) { 477 if (gen_sql_expr_from_utf8str("AND", "windomain", "=", 478 &rule.windomain, 479 "", &s_windomain) != IDMAP_SUCCESS) 480 goto out; 481 } 482 483 /* Create where statement for winname */ 484 if (rule.winname.idmap_utf8str_len > 0) { 485 if (gen_sql_expr_from_utf8str("AND", "winname", "=", 486 &rule.winname, 487 "", &s_winname) != IDMAP_SUCCESS) 488 goto out; 489 } 490 491 /* Create where statement for unixname */ 492 if (rule.unixname.idmap_utf8str_len > 0) { 493 if (gen_sql_expr_from_utf8str("AND", "unixname", "=", 494 &rule.unixname, 495 "", &s_unixname) != IDMAP_SUCCESS) 496 goto out; 497 } 498 499 /* Create LIMIT expression. */ 500 if (limit == 0 || (maxlimit > 0 && maxlimit < limit)) 501 limit = maxlimit; 502 if (limit > 0) 503 (void) snprintf(lbuf, sizeof (lbuf), 504 "LIMIT %" PRIu64, limit + 1ULL); 505 506 (void) snprintf(rbuf, sizeof (rbuf), "rowid > %" PRIu64, lastrowid); 507 508 /* 509 * Combine all the above into a giant SELECT statement that 510 * will return the requested rules 511 */ 512 sql = sqlite_mprintf("SELECT rowid, is_user, windomain, winname, " 513 "is_nt4, unixname, w2u_order, u2w_order " 514 "FROM namerules WHERE " 515 " %s AND is_user = %d %s %s %s %s %s %s;", 516 rbuf, rule.is_user?1:0, 517 s_windomain?s_windomain:"", 518 s_winname?s_winname:"", 519 s_unixname?s_unixname:"", 520 w2ubuf, u2wbuf, lbuf); 521 if (sql == NULL) { 522 idmapdlog(LOG_ERR, "Out of memory"); 523 goto out; 524 } 525 526 /* Execute the SQL statement and update the return buffer */ 527 PROCESS_LIST_SVC_SQL(retcode, db, sql, limit, list_namerules_cb, 528 result, result->rules.rules_len); 529 530 out: 531 if (s_windomain) 532 sqlite_freemem(s_windomain); 533 if (s_winname) 534 sqlite_freemem(s_winname); 535 if (s_unixname) 536 sqlite_freemem(s_unixname); 537 if (sql) 538 sqlite_freemem(sql); 539 if (IDMAP_ERROR(result->retcode)) 540 (void) xdr_free(xdr_idmap_namerules_res, (caddr_t)result); 541 if (db) 542 (void) sqlite_close(db); 543 result->retcode = idmap_stat4prot(result->retcode); 544 return (TRUE); 545 } 546 547 #define IDMAP_RULES_AUTH "solaris.admin.idmap.rules" 548 static int 549 verify_rules_auth(struct svc_req *rqstp) { 550 ucred_t *uc = NULL; 551 uid_t uid; 552 char buf[1024]; 553 struct passwd pwd; 554 const char *me = "verify_rules_auth"; 555 556 if (svc_getcallerucred(rqstp->rq_xprt, &uc) != 0) { 557 idmapdlog(LOG_ERR, 558 "%s: svc_getcallerucred failed (errno=%d)", 559 me, errno); 560 return (-1); 561 } 562 563 uid = ucred_geteuid(uc); 564 if (uid == (uid_t)-1) { 565 idmapdlog(LOG_ERR, 566 "%s: ucred_geteuid failed (errno=%d)", 567 me, errno); 568 ucred_free(uc); 569 return (-1); 570 } 571 572 if (getpwuid_r(uid, &pwd, buf, sizeof (buf)) == NULL) { 573 idmapdlog(LOG_ERR, 574 "%s: getpwuid_r(%u) failed (errno=%d)", 575 me, uid, errno); 576 ucred_free(uc); 577 return (-1); 578 } 579 580 if (chkauthattr(IDMAP_RULES_AUTH, pwd.pw_name) != 1) { 581 idmapdlog(LOG_INFO, 582 "%s: %s does not have authorization.", 583 me, pwd.pw_name); 584 ucred_free(uc); 585 return (-1); 586 } 587 588 ucred_free(uc); 589 return (1); 590 } 591 592 /* ARGSUSED */ 593 bool_t 594 idmap_update_1_svc(idmap_update_batch batch, idmap_retcode *result, 595 struct svc_req *rqstp) { 596 sqlite *db = NULL; 597 idmap_update_op *up; 598 int i; 599 600 if (verify_rules_auth(rqstp) < 0) { 601 *result = IDMAP_ERR_PERMISSION_DENIED; 602 goto out; 603 } 604 605 if (batch.idmap_update_batch_len == 0 || 606 batch.idmap_update_batch_val == NULL) { 607 *result = IDMAP_SUCCESS; 608 goto out; 609 } 610 611 /* Get db handle */ 612 *result = get_db_handle(&db); 613 if (*result != IDMAP_SUCCESS) 614 goto out; 615 616 *result = sql_exec_no_cb(db, "BEGIN TRANSACTION;"); 617 if (*result != IDMAP_SUCCESS) 618 goto out; 619 620 for (i = 0; i < batch.idmap_update_batch_len; i++) { 621 up = &batch.idmap_update_batch_val[i]; 622 switch (up->opnum) { 623 case OP_NONE: 624 *result = IDMAP_SUCCESS; 625 break; 626 case OP_ADD_NAMERULE: 627 *result = add_namerule(db, 628 &up->idmap_update_op_u.rule); 629 break; 630 case OP_RM_NAMERULE: 631 *result = rm_namerule(db, 632 &up->idmap_update_op_u.rule); 633 break; 634 case OP_FLUSH_NAMERULES: 635 *result = flush_namerules(db, 636 up->idmap_update_op_u.is_user); 637 break; 638 default: 639 *result = IDMAP_ERR_NOTSUPPORTED; 640 goto out; 641 }; 642 643 if (*result != IDMAP_SUCCESS) 644 goto out; 645 } 646 647 out: 648 if (*result == IDMAP_SUCCESS && db) { 649 *result = sql_exec_no_cb(db, "COMMIT TRANSACTION;"); 650 } 651 652 if (db) 653 (void) sqlite_close(db); 654 *result = idmap_stat4prot(*result); 655 return (TRUE); 656 } 657 658 659 /* ARGSUSED */ 660 bool_t 661 idmap_get_mapped_id_by_name_1_svc(idmap_mapping request, 662 idmap_mappings_res *result, struct svc_req *rqstp) { 663 sqlite *cache = NULL, *db = NULL; 664 665 /* Init */ 666 (void) memset(result, 0, sizeof (*result)); 667 668 /* Get cache handle */ 669 result->retcode = get_cache_handle(&cache); 670 if (result->retcode != IDMAP_SUCCESS) 671 goto out; 672 673 /* Get db handle */ 674 result->retcode = get_db_handle(&db); 675 if (result->retcode != IDMAP_SUCCESS) 676 goto out; 677 678 /* Allocate result */ 679 result->mappings.mappings_val = calloc(1, sizeof (idmap_mapping)); 680 if (result->mappings.mappings_val == NULL) { 681 idmapdlog(LOG_ERR, "Out of memory"); 682 result->retcode = IDMAP_ERR_MEMORY; 683 goto out; 684 } 685 result->mappings.mappings_len = 1; 686 687 if (IS_REQUEST_SID(request)) { 688 result->retcode = get_w2u_mapping( 689 cache, 690 db, 691 &request, 692 result->mappings.mappings_val); 693 } else if (IS_REQUEST_UID(request)) { 694 result->retcode = get_u2w_mapping( 695 cache, 696 db, 697 &request, 698 result->mappings.mappings_val, 699 1); 700 } else if (IS_REQUEST_GID(request)) { 701 result->retcode = get_u2w_mapping( 702 cache, 703 db, 704 &request, 705 result->mappings.mappings_val, 706 0); 707 } else { 708 result->retcode = IDMAP_ERR_IDTYPE; 709 } 710 711 out: 712 if (IDMAP_FATAL_ERROR(result->retcode)) { 713 xdr_free(xdr_idmap_mappings_res, (caddr_t)result); 714 result->mappings.mappings_len = 0; 715 result->mappings.mappings_val = NULL; 716 } 717 if (cache) 718 (void) sqlite_close(cache); 719 if (db) 720 (void) sqlite_close(db); 721 result->retcode = idmap_stat4prot(result->retcode); 722 return (TRUE); 723 } 724 725 726 /* ARGSUSED */ 727 int 728 idmap_prog_1_freeresult(SVCXPRT *transp, xdrproc_t xdr_result, 729 caddr_t result) { 730 (void) xdr_free(xdr_result, result); 731 return (TRUE); 732 } 733