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