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