Changeset 745 for trunk/server/source3/winbindd/idmap_ldap.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/winbindd/idmap_ldap.c
r414 r745 8 8 Copyright (C) Gerald Carter 2003 9 9 Copyright (C) Simo Sorce 2003-2007 10 Copyright (C) Michael Adam 2010 10 11 11 12 This program is free software; you can redistribute it and/or modify … … 25 26 #include "includes.h" 26 27 #include "winbindd.h" 28 #include "secrets.h" 29 #include "idmap.h" 30 #include "idmap_rw.h" 31 #include "../libcli/security/security.h" 27 32 28 33 #undef DBGC_CLASS … … 34 39 #include "smbldap.h" 35 40 36 static char *idmap_fetch_secret(const char *backend, bool alloc,41 static char *idmap_fetch_secret(const char *backend, 37 42 const char *domain, const char *identity) 38 43 { … … 40 45 int r; 41 46 42 if (alloc) { 43 r = asprintf(&tmp, "IDMAP_ALLOC_%s", backend); 44 } else { 45 r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain); 46 } 47 r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain); 47 48 48 49 if (r < 0) … … 62 63 char *suffix; 63 64 char *user_dn; 64 uint32_t filter_low_id, filter_high_id; /* Filter range */65 65 bool anon; 66 }; 67 68 struct idmap_ldap_alloc_context { 69 struct smbldap_state *smbldap_state; 70 char *url; 71 char *suffix; 72 char *user_dn; 73 uid_t low_uid, high_uid; /* Range of uids */ 74 gid_t low_gid, high_gid; /* Range of gids */ 75 66 struct idmap_rw_ops *rw_ops; 76 67 }; 77 68 … … 87 78 **********************************************************************/ 88 79 89 static struct idmap_ldap_alloc_context *idmap_alloc_ldap;90 91 80 /********************************************************************* 92 81 ********************************************************************/ … … 110 99 if ( tmp ) { 111 100 if (!dom) { 112 /* only the alloc backend can pass in a NULL dom */ 113 secret = idmap_fetch_secret("ldap", True, 114 NULL, tmp); 101 DEBUG(0, ("get_credentials: Invalid domain 'NULL' " 102 "encountered for user DN %s\n", 103 tmp)); 104 ret = NT_STATUS_UNSUCCESSFUL; 105 goto done; 115 106 } else { 116 secret = idmap_fetch_secret("ldap", False, 117 dom->name, tmp); 107 secret = idmap_fetch_secret("ldap", dom->name, tmp); 118 108 } 119 109 … … 154 144 **********************************************************************/ 155 145 156 static NTSTATUS verify_idpool( void)146 static NTSTATUS verify_idpool(struct idmap_domain *dom) 157 147 { 158 148 NTSTATUS ret; 159 TALLOC_CTX * ctx;149 TALLOC_CTX *mem_ctx; 160 150 LDAPMessage *result = NULL; 161 151 LDAPMod **mods = NULL; … … 164 154 int count; 165 155 int rc; 166 167 if ( ! idmap_alloc_ldap) { 168 return NT_STATUS_UNSUCCESSFUL; 169 } 170 171 ctx = talloc_new(idmap_alloc_ldap); 172 if ( ! ctx) { 156 struct idmap_ldap_context *ctx; 157 158 ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context); 159 160 mem_ctx = talloc_new(ctx); 161 if (mem_ctx == NULL) { 173 162 DEBUG(0, ("Out of memory!\n")); 174 163 return NT_STATUS_NO_MEMORY; 175 164 } 176 165 177 filter = talloc_asprintf( ctx, "(objectclass=%s)", LDAP_OBJ_IDPOOL);166 filter = talloc_asprintf(mem_ctx, "(objectclass=%s)", LDAP_OBJ_IDPOOL); 178 167 CHECK_ALLOC_DONE(filter); 179 168 180 attr_list = get_attr_list( ctx, idpool_attr_list);169 attr_list = get_attr_list(mem_ctx, idpool_attr_list); 181 170 CHECK_ALLOC_DONE(attr_list); 182 171 183 rc = smbldap_search( idmap_alloc_ldap->smbldap_state,184 idmap_alloc_ldap->suffix,172 rc = smbldap_search(ctx->smbldap_state, 173 ctx->suffix, 185 174 LDAP_SCOPE_SUBTREE, 186 175 filter, … … 195 184 } 196 185 197 count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct, 198 result); 186 count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result); 199 187 200 188 ldap_msgfree(result); … … 202 190 if ( count > 1 ) { 203 191 DEBUG(0,("Multiple entries returned from %s (base == %s)\n", 204 filter, idmap_alloc_ldap->suffix));192 filter, ctx->suffix)); 205 193 ret = NT_STATUS_UNSUCCESSFUL; 206 194 goto done; … … 209 197 char *uid_str, *gid_str; 210 198 211 uid_str = talloc_asprintf( ctx, "%lu",212 (unsigned long) idmap_alloc_ldap->low_uid);213 gid_str = talloc_asprintf( ctx, "%lu",214 (unsigned long) idmap_alloc_ldap->low_gid);199 uid_str = talloc_asprintf(mem_ctx, "%lu", 200 (unsigned long)dom->low_id); 201 gid_str = talloc_asprintf(mem_ctx, "%lu", 202 (unsigned long)dom->low_id); 215 203 216 204 smbldap_set_mod(&mods, LDAP_MOD_ADD, … … 225 213 gid_str); 226 214 if (mods) { 227 rc = smbldap_modify( idmap_alloc_ldap->smbldap_state,228 idmap_alloc_ldap->suffix,215 rc = smbldap_modify(ctx->smbldap_state, 216 ctx->suffix, 229 217 mods); 230 218 ldap_mods_free(mods, True); … … 237 225 ret = (rc == LDAP_SUCCESS)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL; 238 226 done: 239 talloc_free(ctx); 240 return ret; 241 } 242 243 /***************************************************************************** 244 Initialise idmap database. 245 *****************************************************************************/ 246 247 static NTSTATUS idmap_ldap_alloc_init(const char *params) 248 { 249 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 250 const char *tmp; 251 uid_t low_uid = 0; 252 uid_t high_uid = 0; 253 gid_t low_gid = 0; 254 gid_t high_gid = 0; 255 256 /* Only do init if we are online */ 257 if (idmap_is_offline()) { 258 return NT_STATUS_FILE_IS_OFFLINE; 259 } 260 261 idmap_alloc_ldap = TALLOC_ZERO_P(NULL, struct idmap_ldap_alloc_context); 262 CHECK_ALLOC_DONE( idmap_alloc_ldap ); 263 264 /* load ranges */ 265 266 if (!lp_idmap_uid(&low_uid, &high_uid) 267 || !lp_idmap_gid(&low_gid, &high_gid)) { 268 DEBUG(1, ("idmap uid or idmap gid missing\n")); 269 ret = NT_STATUS_UNSUCCESSFUL; 270 goto done; 271 } 272 273 idmap_alloc_ldap->low_uid = low_uid; 274 idmap_alloc_ldap->high_uid = high_uid; 275 idmap_alloc_ldap->low_gid = low_gid; 276 idmap_alloc_ldap->high_gid= high_gid; 277 278 if (idmap_alloc_ldap->high_uid <= idmap_alloc_ldap->low_uid) { 279 DEBUG(1, ("idmap uid range invalid\n")); 280 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n")); 281 ret = NT_STATUS_UNSUCCESSFUL; 282 goto done; 283 } 284 285 if (idmap_alloc_ldap->high_gid <= idmap_alloc_ldap->low_gid) { 286 DEBUG(1, ("idmap gid range invalid\n")); 287 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n")); 288 ret = NT_STATUS_UNSUCCESSFUL; 289 goto done; 290 } 291 292 if (params && *params) { 293 /* assume location is the only parameter */ 294 idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, params); 295 } else { 296 tmp = lp_parm_const_string(-1, "idmap alloc config", 297 "ldap_url", NULL); 298 299 if ( ! tmp) { 300 DEBUG(1, ("ERROR: missing idmap ldap url\n")); 301 ret = NT_STATUS_UNSUCCESSFUL; 302 goto done; 303 } 304 305 idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, tmp); 306 } 307 CHECK_ALLOC_DONE( idmap_alloc_ldap->url ); 308 309 trim_char(idmap_alloc_ldap->url, '\"', '\"'); 310 311 tmp = lp_parm_const_string(-1, "idmap alloc config", 312 "ldap_base_dn", NULL); 313 if ( ! tmp || ! *tmp) { 314 tmp = lp_ldap_idmap_suffix(); 315 if ( ! tmp) { 316 DEBUG(1, ("ERROR: missing idmap ldap suffix\n")); 317 ret = NT_STATUS_UNSUCCESSFUL; 318 goto done; 319 } 320 } 321 322 idmap_alloc_ldap->suffix = talloc_strdup(idmap_alloc_ldap, tmp); 323 CHECK_ALLOC_DONE( idmap_alloc_ldap->suffix ); 324 325 ret = smbldap_init(idmap_alloc_ldap, winbind_event_context(), 326 idmap_alloc_ldap->url, 327 &idmap_alloc_ldap->smbldap_state); 328 if (!NT_STATUS_IS_OK(ret)) { 329 DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", 330 idmap_alloc_ldap->url)); 331 goto done; 332 } 333 334 ret = get_credentials( idmap_alloc_ldap, 335 idmap_alloc_ldap->smbldap_state, 336 "idmap alloc config", NULL, 337 &idmap_alloc_ldap->user_dn ); 338 if ( !NT_STATUS_IS_OK(ret) ) { 339 DEBUG(1,("idmap_ldap_alloc_init: Failed to get connection " 340 "credentials (%s)\n", nt_errstr(ret))); 341 goto done; 342 } 343 344 /* see if the idmap suffix and sub entries exists */ 345 346 ret = verify_idpool(); 347 348 done: 349 if ( !NT_STATUS_IS_OK( ret ) ) 350 TALLOC_FREE( idmap_alloc_ldap ); 351 227 talloc_free(mem_ctx); 352 228 return ret; 353 229 } … … 357 233 ********************************/ 358 234 359 static NTSTATUS idmap_ldap_allocate_id(struct unixid *xid) 360 { 361 TALLOC_CTX *ctx; 235 static NTSTATUS idmap_ldap_allocate_id_internal(struct idmap_domain *dom, 236 struct unixid *xid) 237 { 238 TALLOC_CTX *mem_ctx; 362 239 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 363 240 int rc = LDAP_SERVER_DOWN; … … 372 249 const char **attr_list; 373 250 const char *type; 251 struct idmap_ldap_context *ctx; 374 252 375 253 /* Only do query if we are online */ … … 378 256 } 379 257 380 if ( ! idmap_alloc_ldap) { 381 return NT_STATUS_UNSUCCESSFUL; 382 } 383 384 ctx = talloc_new(idmap_alloc_ldap); 385 if ( ! ctx) { 258 ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context); 259 260 mem_ctx = talloc_new(ctx); 261 if (!mem_ctx) { 386 262 DEBUG(0, ("Out of memory!\n")); 387 263 return NT_STATUS_NO_MEMORY; … … 406 282 } 407 283 408 filter = talloc_asprintf( ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);284 filter = talloc_asprintf(mem_ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL); 409 285 CHECK_ALLOC_DONE(filter); 410 286 411 attr_list = get_attr_list( ctx, idpool_attr_list);287 attr_list = get_attr_list(mem_ctx, idpool_attr_list); 412 288 CHECK_ALLOC_DONE(attr_list); 413 289 414 290 DEBUG(10, ("Search of the id pool (filter: %s)\n", filter)); 415 291 416 rc = smbldap_search( idmap_alloc_ldap->smbldap_state,417 idmap_alloc_ldap->suffix,418 419 292 rc = smbldap_search(ctx->smbldap_state, 293 ctx->suffix, 294 LDAP_SCOPE_SUBTREE, filter, 295 attr_list, 0, &result); 420 296 421 297 if (rc != LDAP_SUCCESS) { … … 424 300 } 425 301 426 talloc_autofree_ldapmsg(ctx, result); 427 428 count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct, 429 result); 302 talloc_autofree_ldapmsg(mem_ctx, result); 303 304 count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result); 430 305 if (count != 1) { 431 306 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL)); … … 433 308 } 434 309 435 entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct, 436 result); 437 438 dn = smbldap_talloc_dn(ctx, 439 idmap_alloc_ldap->smbldap_state->ldap_struct, 310 entry = ldap_first_entry(ctx->smbldap_state->ldap_struct, result); 311 312 dn = smbldap_talloc_dn(mem_ctx, 313 ctx->smbldap_state->ldap_struct, 440 314 entry); 441 315 if ( ! dn) { … … 443 317 } 444 318 445 if ( ! (id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct, 446 entry, type, ctx))) { 319 id_str = smbldap_talloc_single_attribute( 320 ctx->smbldap_state->ldap_struct, 321 entry, type, mem_ctx); 322 if (id_str == NULL) { 447 323 DEBUG(0,("%s attribute not found\n", type)); 448 goto done; 449 } 450 if ( ! id_str) { 451 DEBUG(0,("Out of memory\n")); 452 ret = NT_STATUS_NO_MEMORY; 324 ret = NT_STATUS_UNSUCCESSFUL; 453 325 goto done; 454 326 } … … 460 332 switch (xid->type) { 461 333 case ID_TYPE_UID: 462 if (xid->id > idmap_alloc_ldap->high_uid) {334 if (xid->id > dom->high_id) { 463 335 DEBUG(0,("Cannot allocate uid above %lu!\n", 464 (unsigned long) idmap_alloc_ldap->high_uid));336 (unsigned long)dom->high_id)); 465 337 goto done; 466 338 } … … 468 340 469 341 case ID_TYPE_GID: 470 if (xid->id > idmap_alloc_ldap->high_gid) {342 if (xid->id > dom->high_id) { 471 343 DEBUG(0,("Cannot allocate gid above %lu!\n", 472 (unsigned long) idmap_alloc_ldap->high_uid));344 (unsigned long)dom->high_id)); 473 345 goto done; 474 346 } … … 480 352 } 481 353 482 new_id_str = talloc_asprintf( ctx, "%lu", (unsigned long)xid->id + 1);354 new_id_str = talloc_asprintf(mem_ctx, "%lu", (unsigned long)xid->id + 1); 483 355 if ( ! new_id_str) { 484 356 DEBUG(0,("Out of memory\n")); … … 498 370 id_str, new_id_str)); 499 371 500 rc = smbldap_modify( idmap_alloc_ldap->smbldap_state, dn, mods);372 rc = smbldap_modify(ctx->smbldap_state, dn, mods); 501 373 502 374 ldap_mods_free(mods, True); … … 511 383 512 384 done: 513 talloc_free( ctx);385 talloc_free(mem_ctx); 514 386 return ret; 515 387 } 516 388 517 /********************************** 518 Get current highest id. 519 **********************************/ 520 521 static NTSTATUS idmap_ldap_get_hwm(struct unixid *xid) 522 { 523 TALLOC_CTX *memctx; 524 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 525 int rc = LDAP_SERVER_DOWN; 526 int count = 0; 527 LDAPMessage *result = NULL; 528 LDAPMessage *entry = NULL; 529 char *id_str; 530 char *filter = NULL; 531 const char **attr_list; 532 const char *type; 533 534 /* Only do query if we are online */ 535 if (idmap_is_offline()) { 536 return NT_STATUS_FILE_IS_OFFLINE; 537 } 538 539 if ( ! idmap_alloc_ldap) { 540 return NT_STATUS_UNSUCCESSFUL; 541 } 542 543 memctx = talloc_new(idmap_alloc_ldap); 544 if ( ! memctx) { 545 DEBUG(0, ("Out of memory!\n")); 546 return NT_STATUS_NO_MEMORY; 547 } 548 549 /* get type */ 550 switch (xid->type) { 551 552 case ID_TYPE_UID: 553 type = get_attr_key2string(idpool_attr_list, 554 LDAP_ATTR_UIDNUMBER); 555 break; 556 557 case ID_TYPE_GID: 558 type = get_attr_key2string(idpool_attr_list, 559 LDAP_ATTR_GIDNUMBER); 560 break; 561 562 default: 563 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type)); 564 return NT_STATUS_INVALID_PARAMETER; 565 } 566 567 filter = talloc_asprintf(memctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL); 568 CHECK_ALLOC_DONE(filter); 569 570 attr_list = get_attr_list(memctx, idpool_attr_list); 571 CHECK_ALLOC_DONE(attr_list); 572 573 rc = smbldap_search(idmap_alloc_ldap->smbldap_state, 574 idmap_alloc_ldap->suffix, 575 LDAP_SCOPE_SUBTREE, filter, 576 attr_list, 0, &result); 577 578 if (rc != LDAP_SUCCESS) { 579 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL)); 580 goto done; 581 } 582 583 talloc_autofree_ldapmsg(memctx, result); 584 585 count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct, 586 result); 587 if (count != 1) { 588 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL)); 589 goto done; 590 } 591 592 entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct, 593 result); 594 595 id_str = smbldap_talloc_single_attribute(idmap_alloc_ldap->smbldap_state->ldap_struct, 596 entry, type, memctx); 597 if ( ! id_str) { 598 DEBUG(0,("%s attribute not found\n", type)); 599 goto done; 600 } 601 if ( ! id_str) { 602 DEBUG(0,("Out of memory\n")); 603 ret = NT_STATUS_NO_MEMORY; 604 goto done; 605 } 606 607 xid->id = strtoul(id_str, NULL, 10); 608 609 ret = NT_STATUS_OK; 610 done: 611 talloc_free(memctx); 389 /** 390 * Allocate a new unix-ID. 391 * For now this is for the default idmap domain only. 392 * Should be extended later on. 393 */ 394 static NTSTATUS idmap_ldap_allocate_id(struct idmap_domain *dom, 395 struct unixid *id) 396 { 397 NTSTATUS ret; 398 399 if (!strequal(dom->name, "*")) { 400 DEBUG(3, ("idmap_ldap_allocate_id: " 401 "Refusing allocation of a new unixid for domain'%s'. " 402 "This is only supported for the default " 403 "domain \"*\".\n", 404 dom->name)); 405 return NT_STATUS_NOT_IMPLEMENTED; 406 } 407 408 ret = idmap_ldap_allocate_id_internal(dom, id); 409 612 410 return ret; 613 }614 /**********************************615 Set highest id.616 **********************************/617 618 static NTSTATUS idmap_ldap_set_hwm(struct unixid *xid)619 {620 TALLOC_CTX *ctx;621 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;622 int rc = LDAP_SERVER_DOWN;623 int count = 0;624 LDAPMessage *result = NULL;625 LDAPMessage *entry = NULL;626 LDAPMod **mods = NULL;627 char *new_id_str;628 char *filter = NULL;629 const char *dn = NULL;630 const char **attr_list;631 const char *type;632 633 /* Only do query if we are online */634 if (idmap_is_offline()) {635 return NT_STATUS_FILE_IS_OFFLINE;636 }637 638 if ( ! idmap_alloc_ldap) {639 return NT_STATUS_UNSUCCESSFUL;640 }641 642 ctx = talloc_new(idmap_alloc_ldap);643 if ( ! ctx) {644 DEBUG(0, ("Out of memory!\n"));645 return NT_STATUS_NO_MEMORY;646 }647 648 /* get type */649 switch (xid->type) {650 651 case ID_TYPE_UID:652 type = get_attr_key2string(idpool_attr_list,653 LDAP_ATTR_UIDNUMBER);654 break;655 656 case ID_TYPE_GID:657 type = get_attr_key2string(idpool_attr_list,658 LDAP_ATTR_GIDNUMBER);659 break;660 661 default:662 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));663 return NT_STATUS_INVALID_PARAMETER;664 }665 666 filter = talloc_asprintf(ctx, "(objectClass=%s)", LDAP_OBJ_IDPOOL);667 CHECK_ALLOC_DONE(filter);668 669 attr_list = get_attr_list(ctx, idpool_attr_list);670 CHECK_ALLOC_DONE(attr_list);671 672 rc = smbldap_search(idmap_alloc_ldap->smbldap_state,673 idmap_alloc_ldap->suffix,674 LDAP_SCOPE_SUBTREE, filter,675 attr_list, 0, &result);676 677 if (rc != LDAP_SUCCESS) {678 DEBUG(0,("%s object not found\n", LDAP_OBJ_IDPOOL));679 goto done;680 }681 682 talloc_autofree_ldapmsg(ctx, result);683 684 count = ldap_count_entries(idmap_alloc_ldap->smbldap_state->ldap_struct,685 result);686 if (count != 1) {687 DEBUG(0,("Single %s object not found\n", LDAP_OBJ_IDPOOL));688 goto done;689 }690 691 entry = ldap_first_entry(idmap_alloc_ldap->smbldap_state->ldap_struct,692 result);693 694 dn = smbldap_talloc_dn(ctx,695 idmap_alloc_ldap->smbldap_state->ldap_struct,696 entry);697 if ( ! dn) {698 goto done;699 }700 701 new_id_str = talloc_asprintf(ctx, "%lu", (unsigned long)xid->id);702 if ( ! new_id_str) {703 DEBUG(0,("Out of memory\n"));704 ret = NT_STATUS_NO_MEMORY;705 goto done;706 }707 708 smbldap_set_mod(&mods, LDAP_MOD_REPLACE, type, new_id_str);709 710 if (mods == NULL) {711 DEBUG(0,("smbldap_set_mod() failed.\n"));712 goto done;713 }714 715 rc = smbldap_modify(idmap_alloc_ldap->smbldap_state, dn, mods);716 717 ldap_mods_free(mods, True);718 719 if (rc != LDAP_SUCCESS) {720 DEBUG(1,("Failed to allocate new %s. "721 "smbldap_modify() failed.\n", type));722 goto done;723 }724 725 ret = NT_STATUS_OK;726 727 done:728 talloc_free(ctx);729 return ret;730 }731 732 /**********************************733 Close idmap ldap alloc734 **********************************/735 736 static NTSTATUS idmap_ldap_alloc_close(void)737 {738 if (idmap_alloc_ldap) {739 smbldap_free_struct(&idmap_alloc_ldap->smbldap_state);740 DEBUG(5,("The connection to the LDAP server was closed\n"));741 /* maybe free the results here --metze */742 TALLOC_FREE(idmap_alloc_ldap);743 }744 return NT_STATUS_OK;745 411 } 746 412 … … 763 429 ********************************/ 764 430 765 static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom, 766 const char *params) 431 static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom, 432 const struct id_map *map); 433 434 static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom) 767 435 { 768 436 NTSTATUS ret; … … 782 450 } 783 451 784 if (strequal(dom->name, "*")) { 785 uid_t low_uid = 0; 786 uid_t high_uid = 0; 787 gid_t low_gid = 0; 788 gid_t high_gid = 0; 789 790 ctx->filter_low_id = 0; 791 ctx->filter_high_id = 0; 792 793 if (lp_idmap_uid(&low_uid, &high_uid)) { 794 ctx->filter_low_id = low_uid; 795 ctx->filter_high_id = high_uid; 796 } else { 797 DEBUG(3, ("Warning: 'idmap uid' not set!\n")); 798 } 799 800 if (lp_idmap_gid(&low_gid, &high_gid)) { 801 if ((low_gid != low_uid) || (high_gid != high_uid)) { 802 DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'" 803 " ranges do not agree -- building " 804 "intersection\n")); 805 ctx->filter_low_id = MAX(ctx->filter_low_id, 806 low_gid); 807 ctx->filter_high_id = MIN(ctx->filter_high_id, 808 high_gid); 809 } 810 } else { 811 DEBUG(3, ("Warning: 'idmap gid' not set!\n")); 812 } 813 } else { 814 const char *range = NULL; 815 816 config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); 817 if ( ! config_option) { 818 DEBUG(0, ("Out of memory!\n")); 819 ret = NT_STATUS_NO_MEMORY; 820 goto done; 821 } 822 823 /* load ranges */ 824 range = lp_parm_const_string(-1, config_option, "range", NULL); 825 if (range && range[0]) { 826 if ((sscanf(range, "%u - %u", &ctx->filter_low_id, 827 &ctx->filter_high_id) != 2)) 828 { 829 DEBUG(1, ("ERROR: invalid filter range [%s]", range)); 830 ctx->filter_low_id = 0; 831 ctx->filter_high_id = 0; 832 } 833 } 834 } 835 836 if (ctx->filter_low_id > ctx->filter_high_id) { 837 DEBUG(1, ("ERROR: invalid filter range [%u-%u]", 838 ctx->filter_low_id, ctx->filter_high_id)); 839 ctx->filter_low_id = 0; 840 ctx->filter_high_id = 0; 841 } 842 843 if (params != NULL) { 844 /* assume location is the only parameter */ 845 ctx->url = talloc_strdup(ctx, params); 846 } else { 847 tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL); 848 452 config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); 453 if (!config_option) { 454 DEBUG(0, ("Out of memory!\n")); 455 ret = NT_STATUS_NO_MEMORY; 456 goto done; 457 } 458 459 tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL); 460 461 if ( ! tmp) { 462 DEBUG(1, ("ERROR: missing idmap ldap url\n")); 463 ret = NT_STATUS_UNSUCCESSFUL; 464 goto done; 465 } 466 467 ctx->url = talloc_strdup(ctx, tmp); 468 469 trim_char(ctx->url, '\"', '\"'); 470 471 tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL); 472 if ( ! tmp || ! *tmp) { 473 tmp = lp_ldap_idmap_suffix(); 849 474 if ( ! tmp) { 850 DEBUG(1, ("ERROR: missing idmap ldap url\n"));475 DEBUG(1, ("ERROR: missing idmap ldap suffix\n")); 851 476 ret = NT_STATUS_UNSUCCESSFUL; 852 477 goto done; 853 478 } 854 855 ctx->url = talloc_strdup(ctx, tmp); 856 } 857 CHECK_ALLOC_DONE(ctx->url); 858 859 trim_char(ctx->url, '\"', '\"'); 860 861 tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL); 862 if ( ! tmp || ! *tmp) { 863 tmp = lp_ldap_idmap_suffix(); 864 if ( ! tmp) { 865 DEBUG(1, ("ERROR: missing idmap ldap suffix\n")); 866 ret = NT_STATUS_UNSUCCESSFUL; 867 goto done; 868 } 869 } 479 } 870 480 871 481 ctx->suffix = talloc_strdup(ctx, tmp); 872 482 CHECK_ALLOC_DONE(ctx->suffix); 483 484 ctx->rw_ops = talloc_zero(ctx, struct idmap_rw_ops); 485 CHECK_ALLOC_DONE(ctx->rw_ops); 486 487 ctx->rw_ops->get_new_id = idmap_ldap_allocate_id_internal; 488 ctx->rw_ops->set_mapping = idmap_ldap_set_mapping; 873 489 874 490 ret = smbldap_init(ctx, winbind_event_context(), ctx->url, … … 879 495 } 880 496 881 497 ret = get_credentials( ctx, ctx->smbldap_state, config_option, 882 498 dom, &ctx->user_dn ); 883 499 if ( !NT_STATUS_IS_OK(ret) ) { … … 887 503 } 888 504 889 /* set the destructor on the context, so that resource are properly 890 freed if the contexts is released */ 891 505 /* 506 * Set the destructor on the context, so that resources are 507 * properly freed when the context is released. 508 */ 892 509 talloc_set_destructor(ctx, idmap_ldap_close_destructor); 893 510 894 511 dom->private_data = ctx; 512 513 ret = verify_idpool(dom); 514 if (!NT_STATUS_IS_OK(ret)) { 515 DEBUG(1, ("idmap_ldap_db_init: failed to verify ID pool (%s)\n", 516 nt_errstr(ret))); 517 goto done; 518 } 895 519 896 520 talloc_free(config_option); … … 902 526 return ret; 903 527 } 528 529 /** 530 * set a mapping. 531 */ 532 533 /* TODO: change this: This function cannot be called to modify a mapping, 534 * only set a new one */ 535 536 static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom, 537 const struct id_map *map) 538 { 539 NTSTATUS ret; 540 TALLOC_CTX *memctx; 541 struct idmap_ldap_context *ctx; 542 LDAPMessage *entry = NULL; 543 LDAPMod **mods = NULL; 544 const char *type; 545 char *id_str; 546 char *sid; 547 char *dn; 548 int rc = -1; 549 550 /* Only do query if we are online */ 551 if (idmap_is_offline()) { 552 return NT_STATUS_FILE_IS_OFFLINE; 553 } 554 555 ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context); 556 557 switch(map->xid.type) { 558 case ID_TYPE_UID: 559 type = get_attr_key2string(sidmap_attr_list, 560 LDAP_ATTR_UIDNUMBER); 561 break; 562 563 case ID_TYPE_GID: 564 type = get_attr_key2string(sidmap_attr_list, 565 LDAP_ATTR_GIDNUMBER); 566 break; 567 568 default: 569 return NT_STATUS_INVALID_PARAMETER; 570 } 571 572 memctx = talloc_new(ctx); 573 if ( ! memctx) { 574 DEBUG(0, ("Out of memory!\n")); 575 return NT_STATUS_NO_MEMORY; 576 } 577 578 id_str = talloc_asprintf(memctx, "%lu", (unsigned long)map->xid.id); 579 CHECK_ALLOC_DONE(id_str); 580 581 sid = talloc_strdup(memctx, sid_string_talloc(memctx, map->sid)); 582 CHECK_ALLOC_DONE(sid); 583 584 dn = talloc_asprintf(memctx, "%s=%s,%s", 585 get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID), 586 sid, 587 ctx->suffix); 588 CHECK_ALLOC_DONE(dn); 589 590 smbldap_set_mod(&mods, LDAP_MOD_ADD, 591 "objectClass", LDAP_OBJ_IDMAP_ENTRY); 592 593 smbldap_make_mod(ctx->smbldap_state->ldap_struct, 594 entry, &mods, type, id_str); 595 596 smbldap_make_mod(ctx->smbldap_state->ldap_struct, entry, &mods, 597 get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID), 598 sid); 599 600 if ( ! mods) { 601 DEBUG(2, ("ERROR: No mods?\n")); 602 ret = NT_STATUS_UNSUCCESSFUL; 603 goto done; 604 } 605 606 /* TODO: remove conflicting mappings! */ 607 608 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY); 609 610 DEBUG(10, ("Set DN %s (%s -> %s)\n", dn, sid, id_str)); 611 612 rc = smbldap_add(ctx->smbldap_state, dn, mods); 613 ldap_mods_free(mods, True); 614 615 if (rc != LDAP_SUCCESS) { 616 char *ld_error = NULL; 617 ldap_get_option(ctx->smbldap_state->ldap_struct, 618 LDAP_OPT_ERROR_STRING, &ld_error); 619 DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu " 620 "mapping [%s]\n", sid, 621 (unsigned long)map->xid.id, type)); 622 DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n", 623 ld_error ? ld_error : "(NULL)", ldap_err2string (rc))); 624 if (ld_error) { 625 ldap_memfree(ld_error); 626 } 627 ret = NT_STATUS_UNSUCCESSFUL; 628 goto done; 629 } 630 631 DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to " 632 "%lu [%s]\n", sid, (unsigned long)map->xid.id, type)); 633 634 ret = NT_STATUS_OK; 635 636 done: 637 talloc_free(memctx); 638 return ret; 639 } 640 641 /** 642 * Create a new mapping for an unmapped SID, also allocating a new ID. 643 * If possible, this should be run inside a transaction to make the 644 * action atomic. 645 */ 646 static NTSTATUS idmap_ldap_new_mapping(struct idmap_domain *dom, struct id_map *map) 647 { 648 NTSTATUS ret; 649 struct idmap_ldap_context *ctx; 650 651 ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context); 652 653 ret = idmap_rw_new_mapping(dom, ctx->rw_ops, map); 654 655 return ret; 656 } 657 904 658 905 659 /* max number of ids requested per batch query */ … … 1026 780 for (i = 0; i < count; i++) { 1027 781 char *sidstr = NULL; 1028 782 char *tmp = NULL; 1029 783 enum id_type type; 1030 784 struct id_map *map; … … 1075 829 1076 830 id = strtoul(tmp, NULL, 10); 1077 if ((id == 0) || 1078 (ctx->filter_low_id && (id < ctx->filter_low_id)) || 1079 (ctx->filter_high_id && (id > ctx->filter_high_id))) { 831 if (!idmap_unix_id_is_in_range(id, dom)) { 1080 832 DEBUG(5, ("Requested id (%u) out of range (%u - %u). " 1081 833 "Filtered!\n", id, 1082 ctx->filter_low_id, ctx->filter_high_id));834 dom->low_id, dom->high_id)); 1083 835 TALLOC_FREE(sidstr); 1084 836 TALLOC_FREE(tmp); … … 1146 898 /* this function searches up to IDMAP_LDAP_MAX_IDS entries 1147 899 * in maps for a match */ 1148 static struct id_map *find_map_by_sid(struct id_map **maps, DOM_SID*sid)900 static struct id_map *find_map_by_sid(struct id_map **maps, struct dom_sid *sid) 1149 901 { 1150 902 int i; … … 1154 906 return NULL; 1155 907 } 1156 if ( sid_equal(maps[i]->sid, sid)) {908 if (dom_sid_equal(maps[i]->sid, sid)) { 1157 909 return maps[i]; 1158 910 } … … 1165 917 struct id_map **ids) 1166 918 { 1167 919 LDAPMessage *entry = NULL; 1168 920 NTSTATUS ret; 1169 921 TALLOC_CTX *memctx; … … 1263 1015 enum id_type type; 1264 1016 struct id_map *map; 1265 DOM_SIDsid;1017 struct dom_sid sid; 1266 1018 uint32_t id; 1267 1019 … … 1324 1076 1325 1077 id = strtoul(tmp, NULL, 10); 1326 if ((id == 0) || 1327 (ctx->filter_low_id && (id < ctx->filter_low_id)) || 1328 (ctx->filter_high_id && (id > ctx->filter_high_id))) { 1078 if (!idmap_unix_id_is_in_range(id, dom)) { 1329 1079 DEBUG(5, ("Requested id (%u) out of range (%u - %u). " 1330 1080 "Filtered!\n", id, 1331 ctx->filter_low_id, ctx->filter_high_id));1081 dom->low_id, dom->high_id)); 1332 1082 TALLOC_FREE(sidstr); 1333 1083 TALLOC_FREE(tmp); … … 1364 1114 } 1365 1115 1116 /* 1117 * try to create new mappings for unmapped sids 1118 */ 1119 for (i = 0; ids[i]; i++) { 1120 if (ids[i]->status != ID_MAPPED) { 1121 ids[i]->status = ID_UNMAPPED; 1122 if (ids[i]->sid != NULL) { 1123 ret = idmap_ldap_new_mapping(dom, ids[i]); 1124 if (!NT_STATUS_IS_OK(ret)) { 1125 goto done; 1126 } 1127 } 1128 } 1129 } 1130 1366 1131 ret = NT_STATUS_OK; 1367 1368 /* mark all unknwon/expired ones as unmapped */1369 for (i = 0; ids[i]; i++) {1370 if (ids[i]->status != ID_MAPPED)1371 ids[i]->status = ID_UNMAPPED;1372 }1373 1132 1374 1133 done: … … 1378 1137 1379 1138 /********************************** 1380 set a mapping.1381 **********************************/1382 1383 /* TODO: change this: This function cannot be called to modify a mapping,1384 * only set a new one */1385 1386 static NTSTATUS idmap_ldap_set_mapping(struct idmap_domain *dom,1387 const struct id_map *map)1388 {1389 NTSTATUS ret;1390 TALLOC_CTX *memctx;1391 struct idmap_ldap_context *ctx;1392 LDAPMessage *entry = NULL;1393 LDAPMod **mods = NULL;1394 const char *type;1395 char *id_str;1396 char *sid;1397 char *dn;1398 int rc = -1;1399 1400 /* Only do query if we are online */1401 if (idmap_is_offline()) {1402 return NT_STATUS_FILE_IS_OFFLINE;1403 }1404 1405 ctx = talloc_get_type(dom->private_data, struct idmap_ldap_context);1406 1407 switch(map->xid.type) {1408 case ID_TYPE_UID:1409 type = get_attr_key2string(sidmap_attr_list,1410 LDAP_ATTR_UIDNUMBER);1411 break;1412 1413 case ID_TYPE_GID:1414 type = get_attr_key2string(sidmap_attr_list,1415 LDAP_ATTR_GIDNUMBER);1416 break;1417 1418 default:1419 return NT_STATUS_INVALID_PARAMETER;1420 }1421 1422 memctx = talloc_new(ctx);1423 if ( ! memctx) {1424 DEBUG(0, ("Out of memory!\n"));1425 return NT_STATUS_NO_MEMORY;1426 }1427 1428 id_str = talloc_asprintf(memctx, "%lu", (unsigned long)map->xid.id);1429 CHECK_ALLOC_DONE(id_str);1430 1431 sid = talloc_strdup(memctx, sid_string_talloc(memctx, map->sid));1432 CHECK_ALLOC_DONE(sid);1433 1434 dn = talloc_asprintf(memctx, "%s=%s,%s",1435 get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),1436 sid,1437 ctx->suffix);1438 CHECK_ALLOC_DONE(dn);1439 1440 smbldap_set_mod(&mods, LDAP_MOD_ADD,1441 "objectClass", LDAP_OBJ_IDMAP_ENTRY);1442 1443 smbldap_make_mod(ctx->smbldap_state->ldap_struct,1444 entry, &mods, type, id_str);1445 1446 smbldap_make_mod(ctx->smbldap_state->ldap_struct, entry, &mods,1447 get_attr_key2string(sidmap_attr_list, LDAP_ATTR_SID),1448 sid);1449 1450 if ( ! mods) {1451 DEBUG(2, ("ERROR: No mods?\n"));1452 ret = NT_STATUS_UNSUCCESSFUL;1453 goto done;1454 }1455 1456 /* TODO: remove conflicting mappings! */1457 1458 smbldap_set_mod(&mods, LDAP_MOD_ADD, "objectClass", LDAP_OBJ_SID_ENTRY);1459 1460 DEBUG(10, ("Set DN %s (%s -> %s)\n", dn, sid, id_str));1461 1462 rc = smbldap_add(ctx->smbldap_state, dn, mods);1463 ldap_mods_free(mods, True);1464 1465 if (rc != LDAP_SUCCESS) {1466 char *ld_error = NULL;1467 ldap_get_option(ctx->smbldap_state->ldap_struct,1468 LDAP_OPT_ERROR_STRING, &ld_error);1469 DEBUG(0,("ldap_set_mapping_internals: Failed to add %s to %lu "1470 "mapping [%s]\n", sid,1471 (unsigned long)map->xid.id, type));1472 DEBUG(0, ("ldap_set_mapping_internals: Error was: %s (%s)\n",1473 ld_error ? ld_error : "(NULL)", ldap_err2string (rc)));1474 if (ld_error) {1475 ldap_memfree(ld_error);1476 }1477 ret = NT_STATUS_UNSUCCESSFUL;1478 goto done;1479 }1480 1481 DEBUG(10,("ldap_set_mapping: Successfully created mapping from %s to "1482 "%lu [%s]\n", sid, (unsigned long)map->xid.id, type));1483 1484 ret = NT_STATUS_OK;1485 1486 done:1487 talloc_free(memctx);1488 return ret;1489 }1490 1491 /**********************************1492 1139 Close the idmap ldap instance 1493 1140 **********************************/ 1494 1495 static NTSTATUS idmap_ldap_close(struct idmap_domain *dom)1496 {1497 struct idmap_ldap_context *ctx;1498 1499 if (dom->private_data) {1500 ctx = talloc_get_type(dom->private_data,1501 struct idmap_ldap_context);1502 1503 talloc_free(ctx);1504 dom->private_data = NULL;1505 }1506 1507 return NT_STATUS_OK;1508 }1509 1141 1510 1142 static struct idmap_methods idmap_ldap_methods = { … … 1513 1145 .unixids_to_sids = idmap_ldap_unixids_to_sids, 1514 1146 .sids_to_unixids = idmap_ldap_sids_to_unixids, 1515 .set_mapping = idmap_ldap_set_mapping, 1516 .close_fn = idmap_ldap_close 1147 .allocate_id = idmap_ldap_allocate_id, 1517 1148 }; 1518 1519 static struct idmap_alloc_methods idmap_ldap_alloc_methods = {1520 1521 .init = idmap_ldap_alloc_init,1522 .allocate_id = idmap_ldap_allocate_id,1523 .get_id_hwm = idmap_ldap_get_hwm,1524 .set_id_hwm = idmap_ldap_set_hwm,1525 .close_fn = idmap_ldap_alloc_close,1526 /* .dump_data = TODO */1527 };1528 1529 static NTSTATUS idmap_alloc_ldap_init(void)1530 {1531 return smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "ldap",1532 &idmap_ldap_alloc_methods);1533 }1534 1149 1535 1150 NTSTATUS idmap_ldap_init(void); 1536 1151 NTSTATUS idmap_ldap_init(void) 1537 1152 { 1538 NTSTATUS ret;1539 1540 /* FIXME: bad hack to actually register also the alloc_ldap module1541 * without changining configure.in */1542 ret = idmap_alloc_ldap_init();1543 if (! NT_STATUS_IS_OK(ret)) {1544 return ret;1545 }1546 1153 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ldap", 1547 1154 &idmap_ldap_methods);
Note:
See TracChangeset
for help on using the changeset viewer.