Changeset 740 for vendor/current/source3/winbindd
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- Location:
- vendor/current/source3/winbindd
- Files:
-
- 16 added
- 4 deleted
- 88 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/winbindd/idmap.c
r594 r740 6 6 Copyright (C) Simo Sorce 2003-2007 7 7 Copyright (C) Jeremy Allison 2006 8 Copyright (C) Michael Adam 2010 8 9 9 10 This program is free software; you can redistribute it and/or modify … … 23 24 #include "includes.h" 24 25 #include "winbindd.h" 26 #include "idmap.h" 27 #include "passdb/machine_sid.h" 25 28 26 29 #undef DBGC_CLASS … … 28 31 29 32 static_decl_idmap; 33 34 static void idmap_init(void) 35 { 36 static bool initialized; 37 38 if (initialized) { 39 return; 40 } 41 42 DEBUG(10, ("idmap_init(): calling static_init_idmap\n")); 43 44 static_init_idmap; 45 46 initialized = true; 47 } 30 48 31 49 /** … … 42 60 43 61 /** 44 * Pointer to the alloc backend methods. Modules register themselves here via45 * smb_register_idmap_alloc.46 */47 struct idmap_alloc_backend {48 const char *name;49 struct idmap_alloc_methods *methods;50 struct idmap_alloc_backend *prev, *next;51 };52 static struct idmap_alloc_backend *alloc_backends = NULL;53 54 /**55 * The idmap alloc context that is configured via "idmap alloc56 * backend". Defaults to "idmap backend" in case the module (tdb, ldap) also57 * provides alloc methods.58 */59 struct idmap_alloc_context {60 struct idmap_alloc_methods *methods;61 };62 static struct idmap_alloc_context *idmap_alloc_ctx = NULL;63 64 /**65 62 * Default idmap domain configured via "idmap backend". 66 63 */ … … 87 84 88 85 for (b = backends; b; b = b->next) { 89 if (strequal(b->name, name)) {90 return b->methods;91 }92 }93 94 return NULL;95 }96 97 static struct idmap_alloc_methods *get_alloc_methods(const char *name)98 {99 struct idmap_alloc_backend *b;100 101 for (b = alloc_backends; b; b = b->next) {102 86 if (strequal(b->name, name)) { 103 87 return b->methods; … … 171 155 } 172 156 173 /**********************************************************************174 Allow a module to register itself as an alloc method.175 **********************************************************************/176 177 NTSTATUS smb_register_idmap_alloc(int version, const char *name,178 struct idmap_alloc_methods *methods)179 {180 struct idmap_alloc_methods *test;181 struct idmap_alloc_backend *entry;182 183 if ((version != SMB_IDMAP_INTERFACE_VERSION)) {184 DEBUG(0, ("Failed to register idmap alloc module.\n"185 "The module was compiled against "186 "SMB_IDMAP_INTERFACE_VERSION %d,\n"187 "current SMB_IDMAP_INTERFACE_VERSION is %d.\n"188 "Please recompile against the current version "189 "of samba!\n",190 version, SMB_IDMAP_INTERFACE_VERSION));191 return NT_STATUS_OBJECT_TYPE_MISMATCH;192 }193 194 if (!name || !name[0] || !methods) {195 DEBUG(0,("Called with NULL pointer or empty name!\n"));196 return NT_STATUS_INVALID_PARAMETER;197 }198 199 test = get_alloc_methods(name);200 if (test) {201 DEBUG(0,("idmap_alloc module %s already registered!\n", name));202 return NT_STATUS_OBJECT_NAME_COLLISION;203 }204 205 entry = talloc(NULL, struct idmap_alloc_backend);206 if ( ! entry) {207 DEBUG(0,("Out of memory!\n"));208 return NT_STATUS_NO_MEMORY;209 }210 entry->name = talloc_strdup(entry, name);211 if ( ! entry->name) {212 DEBUG(0,("Out of memory!\n"));213 return NT_STATUS_NO_MEMORY;214 }215 entry->methods = methods;216 217 DLIST_ADD(alloc_backends, entry);218 DEBUG(5, ("Successfully added idmap alloc backend '%s'\n", name));219 return NT_STATUS_OK;220 }221 222 static int close_domain_destructor(struct idmap_domain *dom)223 {224 NTSTATUS ret;225 226 ret = dom->methods->close_fn(dom);227 if (!NT_STATUS_IS_OK(ret)) {228 DEBUG(3, ("Failed to close idmap domain [%s]!\n", dom->name));229 }230 231 return 0;232 }233 234 static bool parse_idmap_module(TALLOC_CTX *mem_ctx, const char *param,235 char **pmodulename, char **pargs)236 {237 char *modulename;238 char *args;239 240 if (strncmp(param, "idmap_", 6) == 0) {241 param += 6;242 DEBUG(1, ("idmap_init: idmap backend uses deprecated "243 "'idmap_' prefix. Please replace 'idmap_%s' by "244 "'%s'\n", param, param));245 }246 247 modulename = talloc_strdup(mem_ctx, param);248 if (modulename == NULL) {249 return false;250 }251 252 args = strchr(modulename, ':');253 if (args == NULL) {254 *pmodulename = modulename;255 *pargs = NULL;256 return true;257 }258 259 *args = '\0';260 261 args = talloc_strdup(mem_ctx, args+1);262 if (args == NULL) {263 TALLOC_FREE(modulename);264 return false;265 }266 267 *pmodulename = modulename;268 *pargs = args;269 return true;270 }271 272 157 /** 273 158 * Initialize a domain structure … … 275 160 * @param[in] domainname which domain is this for 276 161 * @param[in] modulename which backend module 277 * @param[in] params parameter to pass to the init function162 * @param[in] check_range whether range checking should be done 278 163 * @result The initialized structure 279 164 */ … … 281 166 const char *domainname, 282 167 const char *modulename, 283 const char *params)168 bool check_range) 284 169 { 285 170 struct idmap_domain *result; 286 171 NTSTATUS status; 172 char *config_option = NULL; 173 const char *range; 287 174 288 175 result = talloc_zero(mem_ctx, struct idmap_domain); … … 296 183 DEBUG(0, ("talloc failed\n")); 297 184 goto fail; 185 } 186 187 /* 188 * load ranges and read only information from the config 189 */ 190 191 config_option = talloc_asprintf(result, "idmap config %s", 192 result->name); 193 if (config_option == NULL) { 194 DEBUG(0, ("Out of memory!\n")); 195 goto fail; 196 } 197 198 range = lp_parm_const_string(-1, config_option, "range", NULL); 199 if (range == NULL) { 200 DEBUG(1, ("idmap range not specified for domain %s\n", 201 result->name)); 202 if (check_range) { 203 goto fail; 204 } 205 } else if (sscanf(range, "%u - %u", &result->low_id, 206 &result->high_id) != 2) 207 { 208 DEBUG(1, ("invalid range '%s' specified for domain " 209 "'%s'\n", range, result->name)); 210 if (check_range) { 211 goto fail; 212 } 213 } 214 215 result->read_only = lp_parm_bool(-1, config_option, "read only", false); 216 217 talloc_free(config_option); 218 219 if (result->low_id > result->high_id) { 220 DEBUG(1, ("Error: invalid idmap range detected: %lu - %lu\n", 221 (unsigned long)result->low_id, 222 (unsigned long)result->high_id)); 223 if (check_range) { 224 goto fail; 225 } 298 226 } 299 227 … … 316 244 } 317 245 318 status = result->methods->init(result , params);246 status = result->methods->init(result); 319 247 if (!NT_STATUS_IS_OK(status)) { 320 248 DEBUG(1, ("idmap initialization returned %s\n", … … 323 251 } 324 252 325 talloc_set_destructor(result, close_domain_destructor);326 327 253 return result; 328 254 329 255 fail: 330 TALLOC_FREE(result);331 return NULL;332 }333 334 /**335 * Initialize the default domain structure336 * @param[in] mem_ctx memory context for the result337 * @result The default domain structure338 *339 * This routine takes the module name from the "idmap backend" parameter,340 * passing a possible parameter like ldap:ldap://ldap-url/ to the module.341 */342 343 static struct idmap_domain *idmap_init_default_domain(TALLOC_CTX *mem_ctx)344 {345 struct idmap_domain *result;346 char *modulename;347 char *params;348 349 DEBUG(10, ("idmap_init_default_domain: calling static_init_idmap\n"));350 351 static_init_idmap;352 353 if (!parse_idmap_module(talloc_tos(), lp_idmap_backend(), &modulename,354 ¶ms)) {355 DEBUG(1, ("parse_idmap_module failed\n"));356 return NULL;357 }358 359 DEBUG(3, ("idmap_init: using '%s' as remote backend\n", modulename));360 361 result = idmap_init_domain(mem_ctx, "*", modulename, params);362 if (result == NULL) {363 goto fail;364 }365 366 TALLOC_FREE(modulename);367 TALLOC_FREE(params);368 return result;369 370 fail:371 TALLOC_FREE(modulename);372 TALLOC_FREE(params);373 256 TALLOC_FREE(result); 374 257 return NULL; … … 392 275 const char *backend; 393 276 277 idmap_init(); 278 394 279 config_option = talloc_asprintf(talloc_tos(), "idmap config %s", 395 280 domname); … … 405 290 } 406 291 407 result = idmap_init_domain(mem_ctx, domname, backend, NULL);292 result = idmap_init_domain(mem_ctx, domname, backend, true); 408 293 if (result == NULL) { 409 294 goto fail; … … 417 302 TALLOC_FREE(result); 418 303 return NULL; 304 } 305 306 /** 307 * Initialize the default domain structure 308 * @param[in] mem_ctx memory context for the result 309 * @result The default domain structure 310 * 311 * This routine takes the module name from the "idmap backend" parameter, 312 * passing a possible parameter like ldap:ldap://ldap-url/ to the module. 313 */ 314 315 static struct idmap_domain *idmap_init_default_domain(TALLOC_CTX *mem_ctx) 316 { 317 return idmap_init_named_domain(mem_ctx, "*"); 419 318 } 420 319 … … 429 328 static struct idmap_domain *idmap_init_passdb_domain(TALLOC_CTX *mem_ctx) 430 329 { 330 idmap_init(); 331 431 332 /* 432 333 * Always init the default domain, we can't go without one … … 444 345 445 346 passdb_idmap_domain = idmap_init_domain(NULL, get_global_sam_name(), 446 "passdb", NULL);347 "passdb", false); 447 348 if (passdb_idmap_domain == NULL) { 448 349 DEBUG(1, ("Could not init passdb idmap domain\n")); … … 467 368 */ 468 369 469 st atic struct idmap_domain *idmap_find_domain(const char *domname)370 struct idmap_domain *idmap_find_domain(const char *domname) 470 371 { 471 372 struct idmap_domain *result; … … 474 375 DEBUG(10, ("idmap_find_domain called for domain '%s'\n", 475 376 domname?domname:"NULL")); 377 378 idmap_init(); 476 379 477 380 /* … … 522 425 void idmap_close(void) 523 426 { 524 if (idmap_alloc_ctx) {525 idmap_alloc_ctx->methods->close_fn();526 idmap_alloc_ctx->methods = NULL;527 }528 alloc_backends = NULL;529 427 TALLOC_FREE(default_idmap_domain); 530 428 TALLOC_FREE(passdb_idmap_domain); … … 533 431 } 534 432 535 /**536 * Initialize the idmap alloc backend537 * @param[out] ctx Where to put the alloc_ctx?538 * @result Did it work fine?539 *540 * This routine first looks at "idmap alloc backend" and if that is not541 * defined, it uses "idmap backend" for the module name.542 */543 static NTSTATUS idmap_alloc_init(struct idmap_alloc_context **ctx)544 {545 const char *backend;546 char *modulename, *params;547 NTSTATUS ret = NT_STATUS_NO_MEMORY;;548 549 static_init_idmap;550 551 if (idmap_alloc_ctx != NULL) {552 *ctx = idmap_alloc_ctx;553 return NT_STATUS_OK;554 }555 556 idmap_alloc_ctx = talloc(NULL, struct idmap_alloc_context);557 if (idmap_alloc_ctx == NULL) {558 DEBUG(0, ("talloc failed\n"));559 goto fail;560 }561 562 backend = lp_idmap_alloc_backend();563 if ((backend == NULL) || (backend[0] == '\0')) {564 backend = lp_idmap_backend();565 }566 567 if (backend == NULL) {568 DEBUG(3, ("no idmap alloc backend defined\n"));569 ret = NT_STATUS_INVALID_PARAMETER;570 goto fail;571 }572 573 if (!parse_idmap_module(idmap_alloc_ctx, backend, &modulename,574 ¶ms)) {575 DEBUG(1, ("parse_idmap_module %s failed\n", backend));576 goto fail;577 }578 579 idmap_alloc_ctx->methods = get_alloc_methods(modulename);580 581 if (idmap_alloc_ctx->methods == NULL) {582 ret = smb_probe_module("idmap", modulename);583 if (NT_STATUS_IS_OK(ret)) {584 idmap_alloc_ctx->methods =585 get_alloc_methods(modulename);586 }587 }588 589 if (idmap_alloc_ctx->methods == NULL) {590 DEBUG(1, ("could not find idmap alloc module %s\n", backend));591 ret = NT_STATUS_INVALID_PARAMETER;592 goto fail;593 }594 595 ret = idmap_alloc_ctx->methods->init(params);596 597 if (!NT_STATUS_IS_OK(ret)) {598 DEBUG(0, ("ERROR: Initialization failed for alloc "599 "backend, deferred!\n"));600 goto fail;601 }602 603 TALLOC_FREE(modulename);604 TALLOC_FREE(params);605 606 *ctx = idmap_alloc_ctx;607 return NT_STATUS_OK;608 609 fail:610 TALLOC_FREE(idmap_alloc_ctx);611 return ret;612 }613 614 433 /************************************************************************** 615 434 idmap allocator interface functions 616 435 **************************************************************************/ 617 436 437 static NTSTATUS idmap_allocate_unixid(struct unixid *id) 438 { 439 struct idmap_domain *dom; 440 NTSTATUS ret; 441 442 dom = idmap_find_domain(NULL); 443 444 if (dom == NULL) { 445 return NT_STATUS_UNSUCCESSFUL; 446 } 447 448 if (dom->methods->allocate_id == NULL) { 449 return NT_STATUS_NOT_IMPLEMENTED; 450 } 451 452 ret = dom->methods->allocate_id(dom, id); 453 454 return ret; 455 } 456 457 618 458 NTSTATUS idmap_allocate_uid(struct unixid *id) 619 459 { 620 struct idmap_alloc_context *ctx;621 NTSTATUS ret;622 623 if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) {624 return ret;625 }626 627 460 id->type = ID_TYPE_UID; 628 return ctx->methods->allocate_id(id);461 return idmap_allocate_unixid(id); 629 462 } 630 463 631 464 NTSTATUS idmap_allocate_gid(struct unixid *id) 632 465 { 633 struct idmap_alloc_context *ctx;634 NTSTATUS ret;635 636 if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) {637 return ret;638 }639 640 466 id->type = ID_TYPE_GID; 641 return ctx->methods->allocate_id(id); 642 } 643 644 NTSTATUS idmap_set_uid_hwm(struct unixid *id) 645 { 646 struct idmap_alloc_context *ctx; 647 NTSTATUS ret; 648 649 if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) { 650 return ret; 651 } 652 653 id->type = ID_TYPE_UID; 654 return ctx->methods->set_id_hwm(id); 655 } 656 657 NTSTATUS idmap_set_gid_hwm(struct unixid *id) 658 { 659 struct idmap_alloc_context *ctx; 660 NTSTATUS ret; 661 662 if (!NT_STATUS_IS_OK(ret = idmap_alloc_init(&ctx))) { 663 return ret; 664 } 665 666 id->type = ID_TYPE_GID; 667 return ctx->methods->set_id_hwm(id); 668 } 669 670 NTSTATUS idmap_new_mapping(const struct dom_sid *psid, enum id_type type, 671 struct unixid *pxid) 672 { 673 struct dom_sid sid; 674 struct idmap_domain *dom; 675 struct id_map map; 676 NTSTATUS status; 677 678 dom = idmap_find_domain(NULL); 679 if (dom == NULL) { 680 DEBUG(3, ("no default domain, no place to write\n")); 681 return NT_STATUS_ACCESS_DENIED; 682 } 683 if (dom->methods->set_mapping == NULL) { 684 DEBUG(3, ("default domain not writable\n")); 685 return NT_STATUS_MEDIA_WRITE_PROTECTED; 686 } 687 688 sid_copy(&sid, psid); 689 map.sid = &sid; 690 map.xid.type = type; 691 692 switch (type) { 693 case ID_TYPE_UID: 694 status = idmap_allocate_uid(&map.xid); 695 break; 696 case ID_TYPE_GID: 697 status = idmap_allocate_gid(&map.xid); 698 break; 699 default: 700 status = NT_STATUS_INVALID_PARAMETER; 701 break; 702 } 703 704 if (!NT_STATUS_IS_OK(status)) { 705 DEBUG(3, ("Could not allocate id: %s\n", nt_errstr(status))); 706 return status; 707 } 708 709 map.status = ID_MAPPED; 710 711 DEBUG(10, ("Setting mapping: %s <-> %s %lu\n", 712 sid_string_dbg(map.sid), 713 (map.xid.type == ID_TYPE_UID) ? "UID" : "GID", 714 (unsigned long)map.xid.id)); 715 716 status = dom->methods->set_mapping(dom, &map); 717 718 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { 719 struct id_map *ids[2]; 720 DEBUG(5, ("Mapping for %s exists - retrying to map sid\n", 721 sid_string_dbg(map.sid))); 722 ids[0] = ↦ 723 ids[1] = NULL; 724 status = dom->methods->sids_to_unixids(dom, ids); 725 } 726 727 if (!NT_STATUS_IS_OK(status)) { 728 DEBUG(3, ("Could not store the new mapping: %s\n", 729 nt_errstr(status))); 730 return status; 731 } 732 733 *pxid = map.xid; 734 735 return NT_STATUS_OK; 467 return idmap_allocate_unixid(id); 736 468 } 737 469 … … 772 504 struct id_map *maps[2]; 773 505 774 775 506 DEBUG(10, ("idmap_backends_sid_to_unixid: domain = '%s', sid = [%s]\n", 507 domain?domain:"NULL", sid_string_dbg(id->sid))); 776 508 777 509 maps[0] = id; … … 779 511 780 512 if (sid_check_is_in_builtin(id->sid) 781 || (sid_check_is_in_our_domain(id->sid))) { 513 || (sid_check_is_in_our_domain(id->sid))) 514 { 515 NTSTATUS status; 516 517 DEBUG(10, ("asking passdb...\n")); 782 518 783 519 dom = idmap_init_passdb_domain(NULL); … … 785 521 return NT_STATUS_NONE_MAPPED; 786 522 } 787 return dom->methods->sids_to_unixids(dom, maps); 523 status = dom->methods->sids_to_unixids(dom, maps); 524 525 if (NT_STATUS_IS_OK(status) && id->status == ID_MAPPED) { 526 return status; 527 } 528 529 DEBUG(10, ("passdb could not map.\n")); 530 531 return NT_STATUS_NONE_MAPPED; 788 532 } 789 533 … … 795 539 return dom->methods->sids_to_unixids(dom, maps); 796 540 } 797 798 NTSTATUS idmap_set_mapping(const struct id_map *map)799 {800 struct idmap_domain *dom;801 802 dom = idmap_find_domain(NULL);803 if (dom == NULL) {804 DEBUG(3, ("no default domain, no place to write\n"));805 return NT_STATUS_ACCESS_DENIED;806 }807 if (dom->methods->set_mapping == NULL) {808 DEBUG(3, ("default domain not writable\n"));809 return NT_STATUS_MEDIA_WRITE_PROTECTED;810 }811 812 return dom->methods->set_mapping(dom, map);813 }814 815 NTSTATUS idmap_remove_mapping(const struct id_map *map)816 {817 struct idmap_domain *dom;818 819 dom = idmap_find_domain(NULL);820 if (dom == NULL) {821 DEBUG(3, ("no default domain, no place to write\n"));822 return NT_STATUS_ACCESS_DENIED;823 }824 if (dom->methods->remove_mapping == NULL) {825 DEBUG(3, ("default domain not writable\n"));826 return NT_STATUS_MEDIA_WRITE_PROTECTED;827 }828 829 return dom->methods->remove_mapping(dom, map);830 } -
vendor/current/source3/winbindd/idmap_ad.c
r414 r740 10 10 * Copyright (C) Gerald (Jerry) Carter 2004-2007 11 11 * Copyright (C) Luke Howard 2001-2004 12 * Copyright (C) Michael Adam 2008 12 * Copyright (C) Michael Adam 2008,2010 13 13 * 14 14 * This program is free software; you can redistribute it and/or modify … … 28 28 #include "includes.h" 29 29 #include "winbindd.h" 30 #include "../libds/common/flags.h" 31 #include "ads.h" 32 #include "libads/ldap_schema.h" 33 #include "nss_info.h" 34 #include "secrets.h" 35 #include "idmap.h" 36 #include "../libcli/ldap/ldap_ndr.h" 37 #include "../libcli/security/security.h" 30 38 31 39 #undef DBGC_CLASS … … 44 52 45 53 struct idmap_ad_context { 46 uint32_t filter_low_id;47 uint32_t filter_high_id;48 54 ADS_STRUCT *ads; 49 55 struct posix_schema *ad_schema; … … 95 101 ads_kdestroy(WINBIND_CCACHE_NAME); 96 102 ctx->ads = NULL; 97 TALLOC_FREE( ctx->ad_schema );98 103 } 99 104 } … … 138 143 139 144 get_dc_name(dom->name, realm, dc_name, &dc_ip ); 140 145 141 146 status = ads_connect(ads); 142 147 if (!ADS_ERR_OK(status)) { 143 DEBUG(1, ("ad_idmap_init: failed to connect to AD\n")); 148 DEBUG(1, ("ad_idmap_cached_connection_internal: failed to " 149 "connect to AD\n")); 144 150 ads_destroy(&ads); 145 151 return status; … … 181 187 (ctx->ad_map_type == WB_POSIX_MAP_RFC2307) ) 182 188 { 183 status = ads_check_posix_schema_mapping(NULL, ctx->ads, ctx->ad_map_type, &ctx->ad_schema); 189 status = ads_check_posix_schema_mapping( 190 ctx, ctx->ads, ctx->ad_map_type, &ctx->ad_schema); 184 191 if ( !ADS_ERR_OK(status) ) { 185 192 DEBUG(2,("ad_idmap_cached_connection: Failed to obtain schema details!\n")); 186 193 } 187 194 } 188 195 189 196 return status; 197 } 198 199 static int idmap_ad_context_destructor(struct idmap_ad_context *ctx) 200 { 201 if (ctx->ads != NULL) { 202 /* we own this ADS_STRUCT so make sure it goes away */ 203 ctx->ads->is_mine = True; 204 ads_destroy( &ctx->ads ); 205 ctx->ads = NULL; 206 } 207 return 0; 190 208 } 191 209 … … 193 211 ***********************************************************************/ 194 212 195 static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom, 196 const char *params) 213 static NTSTATUS idmap_ad_initialize(struct idmap_domain *dom) 197 214 { 198 215 struct idmap_ad_context *ctx; 199 216 char *config_option; 200 const char *range = NULL;201 217 const char *schema_mode = NULL; 202 218 203 if ( (ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context)) == NULL ) { 219 ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context); 220 if (ctx == NULL) { 204 221 DEBUG(0, ("Out of memory!\n")); 205 222 return NT_STATUS_NO_MEMORY; 206 223 } 207 208 if ( (config_option = talloc_asprintf(ctx, "idmap config %s", dom->name)) == NULL ) { 224 talloc_set_destructor(ctx, idmap_ad_context_destructor); 225 226 config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); 227 if (config_option == NULL) { 209 228 DEBUG(0, ("Out of memory!\n")); 210 229 talloc_free(ctx); 211 230 return NT_STATUS_NO_MEMORY; 212 }213 214 /* load ranges */215 range = lp_parm_const_string(-1, config_option, "range", NULL);216 if (range && range[0]) {217 if ((sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2) ||218 (ctx->filter_low_id > ctx->filter_high_id)) {219 DEBUG(1, ("ERROR: invalid filter range [%s]", range));220 ctx->filter_low_id = 0;221 ctx->filter_high_id = 0;222 }223 231 } 224 232 … … 268 276 ***********************************************************************/ 269 277 270 static struct id_map *find_map_by_sid(struct id_map **maps, DOM_SID*sid)278 static struct id_map *find_map_by_sid(struct id_map **maps, struct dom_sid *sid) 271 279 { 272 280 int i; 273 281 274 282 for (i = 0; maps[i] && i<IDMAP_AD_MAX_IDS; i++) { 275 if ( sid_equal(maps[i]->sid, sid)) {283 if (dom_sid_equal(maps[i]->sid, sid)) { 276 284 return maps[i]; 277 285 } … … 309 317 ids[i]->status = ID_UNKNOWN; 310 318 } 311 319 312 320 /* Only do query if we are online */ 313 321 if (idmap_is_offline()) { … … 352 360 CHECK_ALLOC_DONE(u_filter); 353 361 break; 354 362 355 363 case ID_TYPE_GID: 356 364 if ( ! g_filter) { … … 401 409 entry = res; 402 410 for (i = 0; (i < count) && entry; i++) { 403 DOM_SIDsid;411 struct dom_sid sid; 404 412 enum id_type type; 405 413 struct id_map *map; … … 454 462 } 455 463 456 if ((id == 0) || 457 (ctx->filter_low_id && (id < ctx->filter_low_id)) || 458 (ctx->filter_high_id && (id > ctx->filter_high_id))) { 464 if (!idmap_unix_id_is_in_range(id, dom)) { 459 465 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n", 460 id, ctx->filter_low_id, ctx->filter_high_id));466 id, dom->low_id, dom->high_id)); 461 467 continue; 462 468 } … … 563 569 ATYPE_NORMAL_ACCOUNT, ATYPE_WORKSTATION_TRUST, ATYPE_INTERDOMAIN_TRUST, 564 570 ATYPE_SECURITY_GLOBAL_GROUP, ATYPE_SECURITY_LOCAL_GROUP); 565 571 566 572 CHECK_ALLOC_DONE(filter); 567 573 … … 571 577 ids[idx]->status = ID_UNKNOWN; 572 578 573 sidstr = sid_binstring(talloc_tos(), ids[idx]->sid);579 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), ids[idx]->sid); 574 580 filter = talloc_asprintf_append_buffer(filter, "(objectSid=%s)", sidstr); 575 581 576 582 TALLOC_FREE(sidstr); 577 583 CHECK_ALLOC_DONE(filter); … … 594 600 entry = res; 595 601 for (i = 0; (i < count) && entry; i++) { 596 DOM_SIDsid;602 struct dom_sid sid; 597 603 enum id_type type; 598 604 struct id_map *map; … … 652 658 continue; 653 659 } 654 if ((id == 0) || 655 (ctx->filter_low_id && (id < ctx->filter_low_id)) || 656 (ctx->filter_high_id && (id > ctx->filter_high_id))) { 660 if (!idmap_unix_id_is_in_range(id, dom)) { 657 661 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n", 658 id, ctx->filter_low_id, ctx->filter_high_id));662 id, dom->low_id, dom->high_id)); 659 663 continue; 660 664 } … … 680 684 ret = NT_STATUS_OK; 681 685 682 /* mark all unkn woni/expired ones as unmapped */686 /* mark all unknown/expired ones as unmapped */ 683 687 for (i = 0; ids[i]; i++) { 684 688 if (ids[i]->status != ID_MAPPED) … … 689 693 talloc_free(memctx); 690 694 return ret; 691 }692 693 /************************************************************************694 ***********************************************************************/695 696 static NTSTATUS idmap_ad_close(struct idmap_domain *dom)697 {698 struct idmap_ad_context * ctx;699 700 ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);701 702 if (ctx->ads != NULL) {703 /* we own this ADS_STRUCT so make sure it goes away */704 ctx->ads->is_mine = True;705 ads_destroy( &ctx->ads );706 ctx->ads = NULL;707 }708 709 TALLOC_FREE( ctx->ad_schema );710 711 return NT_STATUS_OK;712 695 } 713 696 … … 819 802 820 803 static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e, 821 const DOM_SID *sid,804 const struct dom_sid *sid, 822 805 TALLOC_CTX *mem_ctx, 823 ADS_STRUCT *ads,824 LDAPMessage *msg,825 806 const char **homedir, 826 807 const char **shell, … … 866 847 } 867 848 868 /* See if we can use the ADS connection struct swe were given */869 870 if (ads) {871 DEBUG(10, ("nss_ad_get_info: using given ads connection and "872 "LDAP message (%p)\n", msg));873 874 *homedir = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_homedir_attr );875 *shell = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_shell_attr );876 *gecos = ads_pull_string( ads, mem_ctx, msg, ctx->ad_schema->posix_gecos_attr );877 878 if (gid) {879 if ( !ads_pull_uint32(ads, msg, ctx->ad_schema->posix_gidnumber_attr, gid ) )880 *gid = (uint32)-1;881 }882 883 nt_status = NT_STATUS_OK;884 goto done;885 }886 887 849 /* Have to do our own query */ 888 850 … … 895 857 attrs[3] = ctx->ad_schema->posix_gidnumber_attr; 896 858 897 sidstr = sid_binstring(mem_ctx, sid);859 sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid); 898 860 filter = talloc_asprintf(mem_ctx, "(objectSid=%s)", sidstr); 899 861 TALLOC_FREE(sidstr); … … 1095 1057 } 1096 1058 1097 1098 /************************************************************************1099 ***********************************************************************/1100 1101 static NTSTATUS nss_ad_close( void )1102 {1103 /* nothing to do. All memory is free()'d by the idmap close_fn() */1104 1105 return NT_STATUS_OK;1106 }1107 1108 1059 /************************************************************************ 1109 1060 Function dispatch tables for the idmap and nss plugins … … 1114 1065 .unixids_to_sids = idmap_ad_unixids_to_sids, 1115 1066 .sids_to_unixids = idmap_ad_sids_to_unixids, 1116 .close_fn = idmap_ad_close1117 1067 }; 1118 1068 1119 1069 /* The SFU and RFC2307 NSS plugins share everything but the init 1120 1070 function which sets the intended schema model to use */ 1121 1071 1122 1072 static struct nss_info_methods nss_rfc2307_methods = { 1123 1073 .init = nss_rfc2307_init, … … 1125 1075 .map_to_alias = nss_ad_map_to_alias, 1126 1076 .map_from_alias = nss_ad_map_from_alias, 1127 .close_fn = nss_ad_close1128 1077 }; 1129 1078 … … 1133 1082 .map_to_alias = nss_ad_map_to_alias, 1134 1083 .map_from_alias = nss_ad_map_from_alias, 1135 .close_fn = nss_ad_close1136 1084 }; 1137 1085 … … 1141 1089 .map_to_alias = nss_ad_map_to_alias, 1142 1090 .map_from_alias = nss_ad_map_from_alias, 1143 .close_fn = nss_ad_close1144 1091 }; 1145 1092 … … 1166 1113 return status_idmap_ad; 1167 1114 } 1168 1115 1169 1116 if ( !NT_STATUS_IS_OK( status_nss_rfc2307 ) ) { 1170 1117 status_nss_rfc2307 = smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION, -
vendor/current/source3/winbindd/idmap_adex/cell_util.c
r414 r740 20 20 21 21 #include "includes.h" 22 #include "ads.h" 23 #include "idmap.h" 22 24 #include "idmap_adex.h" 25 #include "../libds/common/flags.h" 23 26 24 27 #undef DBGC_CLASS … … 139 142 char *domain_dn = ads_build_dn(lp_realm()); 140 143 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; 141 DOM_SIDsid;144 struct dom_sid sid; 142 145 struct likewise_cell *cell = NULL; 143 146 -
vendor/current/source3/winbindd/idmap_adex/domain_util.c
r414 r740 20 20 21 21 #include "includes.h" 22 #include "ads.h" 23 #include "idmap.h" 22 24 #include "idmap_adex.h" 23 25 … … 209 211 LDAPMessage **msg, 210 212 const char *dn, 211 const DOM_SID*sid)213 const struct dom_sid *sid) 212 214 { 213 215 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; -
vendor/current/source3/winbindd/idmap_adex/gc_util.c
r414 r740 20 20 21 21 #include "includes.h" 22 #include "ads.h" 23 #include "idmap.h" 22 24 #include "idmap_adex.h" 25 #include "libads/cldap.h" 26 #include "../libcli/ldap/ldap_ndr.h" 23 27 24 28 #undef DBGC_CLASS … … 546 550 NTSTATUS gc_name_to_sid(const char *domain, 547 551 const char *name, 548 DOM_SID*sid,552 struct dom_sid *sid, 549 553 enum lsa_SidType *sid_type) 550 554 { … … 704 708 ********************************************************************/ 705 709 706 NTSTATUS gc_sid_to_name(const DOM_SID*sid,710 NTSTATUS gc_sid_to_name(const struct dom_sid *sid, 707 711 char **name, 708 712 enum lsa_SidType *sid_type) … … 717 721 *name = NULL; 718 722 719 sid_string = sid_binstring(frame, sid);723 sid_string = ldap_encode_ndr_dom_sid(frame, sid); 720 724 BAIL_ON_PTR_ERROR(sid_string, nt_status); 721 725 -
vendor/current/source3/winbindd/idmap_adex/idmap_adex.c
r414 r740 20 20 21 21 #include "includes.h" 22 #include "ads.h" 23 #include "idmap.h" 22 24 #include "idmap_adex.h" 25 #include "nss_info.h" 26 #include "secrets.h" 23 27 24 28 #undef DBGC_CLASS … … 39 43 *******************************************************************/ 40 44 41 static NTSTATUS _idmap_adex_init(struct idmap_domain *dom, 42 const char *params) 45 static NTSTATUS _idmap_adex_init(struct idmap_domain *dom) 43 46 { 44 47 ADS_STRUCT *ads = NULL; 45 48 ADS_STATUS status; 46 49 static NTSTATUS init_status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; 47 DOM_SIDdomain_sid;50 struct dom_sid domain_sid; 48 51 fstring dcname; 49 52 struct sockaddr_storage ip; … … 165 168 } 166 169 167 nt_status = _idmap_adex_init(dom , NULL);170 nt_status = _idmap_adex_init(dom); 168 171 if (!NT_STATUS_IS_OK(nt_status)) 169 172 return nt_status; … … 218 221 } 219 222 220 nt_status = _idmap_adex_init(dom , NULL);223 nt_status = _idmap_adex_init(dom); 221 224 if (!NT_STATUS_IS_OK(nt_status)) 222 225 return nt_status; … … 251 254 } 252 255 253 /**********************************************************************254 *********************************************************************/255 256 static NTSTATUS _idmap_adex_set_mapping(struct257 idmap_domain258 *dom, const struct259 id_map *map)260 {261 DEBUG(0, ("_idmap_adex_set_mapping: not implemented\n"));262 return NT_STATUS_NOT_IMPLEMENTED;263 }264 265 /**********************************************************************266 *********************************************************************/267 268 static NTSTATUS _idmap_adex_remove_mapping(struct269 idmap_domain270 *dom, const271 struct272 id_map273 *map)274 {275 DEBUG(0, ("_idmap_adex_remove_mapping: not implemented\n"));276 return NT_STATUS_NOT_IMPLEMENTED;277 }278 279 /**********************************************************************280 *********************************************************************/281 282 static NTSTATUS _idmap_adex_dump(struct idmap_domain283 *dom, struct id_map **maps, int *num_map)284 {285 return NT_STATUS_NOT_IMPLEMENTED;286 }287 288 /**********************************************************************289 *********************************************************************/290 291 static NTSTATUS _idmap_adex_close(struct idmap_domain292 *dom)293 {294 /* FIXME! need to do cleanup here */295 296 return NT_STATUS_OK;297 }298 299 256 /* 300 257 * IdMap NSS plugin … … 307 264 *e) 308 265 { 309 return _idmap_adex_init(NULL , NULL);266 return _idmap_adex_init(NULL); 310 267 } 311 268 … … 315 272 static NTSTATUS _nss_adex_get_info(struct 316 273 nss_domain_entry *e, 317 const DOM_SID* sid,274 const struct dom_sid * sid, 318 275 TALLOC_CTX * ctx, 319 ADS_STRUCT * ads,320 LDAPMessage * msg,321 276 const char **homedir, 322 277 const char **shell, … … 326 281 struct likewise_cell *cell; 327 282 328 nt_status = _idmap_adex_init(NULL , NULL);283 nt_status = _idmap_adex_init(NULL); 329 284 if (!NT_STATUS_IS_OK(nt_status)) 330 285 return nt_status; … … 348 303 struct likewise_cell *cell = NULL; 349 304 350 nt_status = _idmap_adex_init(NULL , NULL);305 nt_status = _idmap_adex_init(NULL); 351 306 BAIL_ON_NTSTATUS_ERROR(nt_status); 352 307 … … 379 334 struct likewise_cell *cell = NULL; 380 335 381 nt_status = _idmap_adex_init(NULL , NULL);336 nt_status = _idmap_adex_init(NULL); 382 337 BAIL_ON_NTSTATUS_ERROR(nt_status); 383 338 … … 417 372 .unixids_to_sids = _idmap_adex_get_sid_from_id, 418 373 .sids_to_unixids = _idmap_adex_get_id_from_sid, 419 .set_mapping = _idmap_adex_set_mapping,420 .remove_mapping = _idmap_adex_remove_mapping,421 .dump_data = _idmap_adex_dump,422 .close_fn = _idmap_adex_close423 374 }; 424 375 static struct nss_info_methods adex_nss_methods = { … … 465 416 return NT_STATUS_OK; 466 417 } 467 468 static NTSTATUS nss_info_adex_init(void)469 {470 return idmap_adex_init();471 } -
vendor/current/source3/winbindd/idmap_adex/idmap_adex.h
r414 r740 92 92 93 93 struct cell_provider_api { 94 NTSTATUS(*get_sid_from_id) ( DOM_SID* sid,94 NTSTATUS(*get_sid_from_id) (struct dom_sid * sid, 95 95 uint32_t id, enum id_type type); 96 96 NTSTATUS(*get_id_from_sid) (uint32_t * id, 97 enum id_type * type, const DOM_SID* sid);98 NTSTATUS(*get_nss_info) (const DOM_SID* sid,97 enum id_type * type, const struct dom_sid * sid); 98 NTSTATUS(*get_nss_info) (const struct dom_sid * sid, 99 99 TALLOC_CTX * ctx, 100 100 const char **homedir, … … 123 123 ADS_STRUCT *conn; 124 124 struct likewise_cell *gc_search_cell; 125 DOM_SIDdomain_sid;125 struct dom_sid domain_sid; 126 126 char *dns_domain; 127 127 char *forest_name; … … 158 158 NTSTATUS cell_locate_membership(ADS_STRUCT * ads); 159 159 NTSTATUS cell_lookup_settings(struct likewise_cell * cell); 160 NTSTATUS cell_follow_links(struct likewise_cell *cell);161 NTSTATUS cell_set_local_provider(void);162 160 163 161 /* likewise_cell.c */ … … 171 169 void cell_list_destroy(void); 172 170 void cell_destroy(struct likewise_cell *c); 173 void cell_set_forest_searches(struct likewise_cell *c,174 bool search);175 171 void cell_set_dns_domain(struct likewise_cell *c, 176 172 const char *dns_domain); … … 180 176 const char *dn); 181 177 void cell_set_domain_sid(struct likewise_cell *c, 182 DOM_SID*sid);178 struct dom_sid *sid); 183 179 void cell_set_flags(struct likewise_cell *c, uint32_t flags); 184 180 void cell_clear_flags(struct likewise_cell *c, uint32_t flags); … … 225 221 NTSTATUS gc_name_to_sid(const char *domain, 226 222 const char *name, 227 DOM_SID*sid,223 struct dom_sid *sid, 228 224 enum lsa_SidType *sid_type); 229 225 230 NTSTATUS gc_sid_to_name(const DOM_SID*sid,226 NTSTATUS gc_sid_to_name(const struct dom_sid *sid, 231 227 char **name, 232 228 enum lsa_SidType *sid_type); … … 253 249 LDAPMessage **msg, 254 250 const char *dn, 255 const DOM_SID*user_sid);251 const struct dom_sid *user_sid); 256 252 257 253 -
vendor/current/source3/winbindd/idmap_adex/likewise_cell.c
r414 r740 20 20 21 21 #include "includes.h" 22 #include "ads.h" 23 #include "idmap.h" 22 24 #include "idmap_adex.h" 25 #include "secrets.h" 26 #include "../libcli/security/dom_sid.h" 23 27 24 28 #undef DBGC_CLASS … … 177 181 *********************************************************************/ 178 182 179 void cell_set_domain_sid(struct likewise_cell *c, DOM_SID*sid)183 void cell_set_domain_sid(struct likewise_cell *c, struct dom_sid *sid) 180 184 { 181 185 sid_copy(&c->domain_sid, sid); -
vendor/current/source3/winbindd/idmap_adex/provider_unified.c
r414 r740 22 22 23 23 #include "includes.h" 24 #include "ads.h" 25 #include "idmap.h" 24 26 #include "idmap_adex.h" 27 #include "../libcli/ldap/ldap_ndr.h" 28 #include "../libcli/security/dom_sid.h" 25 29 26 30 #undef DBGC_CLASS … … 36 40 bool use2307; 37 41 union { 38 DOM_SIDsid;42 struct dom_sid sid; 39 43 struct { 40 44 uint32_t id; … … 246 250 LDAPMessage **msg, 247 251 const char *dn, 248 const DOM_SID*sid)252 const struct dom_sid *sid) 249 253 { 250 254 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; … … 342 346 int num_resp, 343 347 char **dn, 344 DOM_SID*user_sid)348 struct dom_sid *user_sid) 345 349 { 346 350 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; … … 466 470 int num_resp = 0; 467 471 LDAPMessage *m; 468 DOM_SIDuser_sid;472 struct dom_sid user_sid; 469 473 struct likewise_cell *domain_cell = NULL; 470 474 … … 484 488 switch (fdata->ftype) { 485 489 case SidFilter: 486 sid_binstr = sid_binstring(frame, &fdata->filter.sid);490 sid_binstr = ldap_encode_ndr_dom_sid(frame, &fdata->filter.sid); 487 491 BAIL_ON_PTR_ERROR(sid_binstr, nt_status); 488 492 … … 612 616 static NTSTATUS pull_sid(struct likewise_cell *c, 613 617 LDAPMessage *msg, 614 DOM_SID*sid)618 struct dom_sid *sid) 615 619 { 616 620 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; … … 968 972 *******************************************************************/ 969 973 970 static NTSTATUS _ccp_get_sid_from_id( DOM_SID* sid,974 static NTSTATUS _ccp_get_sid_from_id(struct dom_sid * sid, 971 975 uint32_t id, enum id_type type) 972 976 { … … 997 1001 static NTSTATUS _ccp_get_id_from_sid(uint32_t * id, 998 1002 enum id_type *type, 999 const DOM_SID* sid)1003 const struct dom_sid * sid) 1000 1004 { 1001 1005 struct likewise_cell *cell = NULL; … … 1027 1031 *******************************************************************/ 1028 1032 1029 static NTSTATUS _ccp_nss_get_info(const DOM_SID* sid,1033 static NTSTATUS _ccp_nss_get_info(const struct dom_sid * sid, 1030 1034 TALLOC_CTX * ctx, 1031 1035 const char **homedir, … … 1072 1076 TALLOC_CTX *frame = talloc_stackframe(); 1073 1077 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; 1074 DOM_SIDsid;1078 struct dom_sid sid; 1075 1079 struct likewise_cell *cell = NULL; 1076 1080 LDAPMessage *msg = NULL; … … 1117 1121 TALLOC_CTX *frame = talloc_stackframe(); 1118 1122 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; 1119 DOM_SIDsid;1123 struct dom_sid sid; 1120 1124 struct likewise_cell *cell_alias = NULL; 1121 1125 LDAPMessage *msg_alias = NULL; -
vendor/current/source3/winbindd/idmap_hash/idmap_hash.c
r414 r740 21 21 #include "includes.h" 22 22 #include "winbindd/winbindd.h" 23 #include "idmap.h" 23 24 #include "idmap_hash.h" 25 #include "ads.h" 26 #include "nss_info.h" 27 #include "../libcli/security/dom_sid.h" 24 28 25 29 #undef DBGC_CLASS … … 27 31 28 32 struct sid_hash_table { 29 DOM_SID*sid;33 struct dom_sid *sid; 30 34 }; 31 35 32 struct sid_hash_table *hashed_domains = NULL;33 34 36 /********************************************************************* 35 37 Hash a domain SID (S-1-5-12-aaa-bbb-ccc) to a 12bit number 36 38 ********************************************************************/ 37 39 38 static uint32_t hash_domain_sid(const DOM_SID*sid)40 static uint32_t hash_domain_sid(const struct dom_sid *sid) 39 41 { 40 42 uint32_t hash; … … 103 105 ********************************************************************/ 104 106 105 static NTSTATUS be_init(struct idmap_domain *dom ,106 const char *params) 107 { 107 static NTSTATUS be_init(struct idmap_domain *dom) 108 { 109 struct sid_hash_table *hashed_domains; 108 110 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; 109 111 struct winbindd_tdc_domain *dom_list = NULL; … … 111 113 int i; 112 114 113 /* If the domain SID hash ta lbe has been initialized, assume115 /* If the domain SID hash table has been initialized, assume 114 116 that we completed this function previously */ 115 117 116 if ( hashed_domains) {118 if (dom->private_data != NULL) { 117 119 nt_status = NT_STATUS_OK; 118 120 goto done; … … 126 128 /* Create the hash table of domain SIDs */ 127 129 128 hashed_domains = TALLOC_ZERO_ARRAY( NULL, struct sid_hash_table, 4096);130 hashed_domains = TALLOC_ZERO_ARRAY(dom, struct sid_hash_table, 4096); 129 131 BAIL_ON_PTR_NT_ERROR(hashed_domains, nt_status); 130 132 … … 144 146 hash)); 145 147 146 hashed_domains[hash].sid = talloc(hashed_domains, DOM_SID);148 hashed_domains[hash].sid = talloc(hashed_domains, struct dom_sid); 147 149 sid_copy(hashed_domains[hash].sid, &dom_list[i].sid); 148 150 } 151 152 dom->private_data = hashed_domains; 149 153 150 154 done: … … 158 162 struct id_map **ids) 159 163 { 164 struct sid_hash_table *hashed_domains = talloc_get_type_abort( 165 dom->private_data, struct sid_hash_table); 160 166 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; 161 167 int i; … … 165 171 ids[i]->status = ID_UNKNOWN; 166 172 } 167 168 nt_status = be_init(dom , NULL);173 174 nt_status = be_init(dom); 169 175 BAIL_ON_NTSTATUS_ERROR(nt_status); 170 176 … … 194 200 continue; 195 201 196 sid_copy(ids[i]->sid, hashed_domains[h_domain].sid); 197 sid_append_rid(ids[i]->sid, h_rid); 202 sid_compose(ids[i]->sid, hashed_domains[h_domain].sid, h_rid); 198 203 ids[i]->status = ID_MAPPED; 199 204 } … … 216 221 ids[i]->status = ID_UNKNOWN; 217 222 } 218 219 nt_status = be_init(dom , NULL);223 224 nt_status = be_init(dom); 220 225 BAIL_ON_NTSTATUS_ERROR(nt_status); 221 226 … … 226 231 227 232 for (i=0; ids[i]; i++) { 228 DOM_SIDsid;233 struct dom_sid sid; 229 234 uint32_t rid; 230 235 uint32_t h_domain, h_rid; … … 253 258 ********************************************************************/ 254 259 255 static NTSTATUS be_close(struct idmap_domain *dom)256 {257 if (hashed_domains)258 talloc_free(hashed_domains);259 260 return NT_STATUS_OK;261 }262 263 /*********************************************************************264 ********************************************************************/265 266 260 static NTSTATUS nss_hash_init(struct nss_domain_entry *e ) 267 261 { 268 return be_init(NULL , NULL);262 return be_init(NULL); 269 263 } 270 264 … … 273 267 274 268 static NTSTATUS nss_hash_get_info(struct nss_domain_entry *e, 275 const DOM_SID*sid,269 const struct dom_sid *sid, 276 270 TALLOC_CTX *ctx, 277 ADS_STRUCT *ads,278 LDAPMessage *msg,279 271 const char **homedir, 280 272 const char **shell, … … 359 351 .unixids_to_sids = unixids_to_sids, 360 352 .sids_to_unixids = sids_to_unixids, 361 .close_fn = be_close362 353 }; 363 354 -
vendor/current/source3/winbindd/idmap_hash/mapfile.c
r414 r740 20 20 21 21 #include "includes.h" 22 #include "system/filesys.h" 22 23 #include "winbindd/winbindd.h" 24 #include "idmap.h" 23 25 #include "idmap_hash.h" 24 26 #include <stdio.h> -
vendor/current/source3/winbindd/idmap_ldap.c
r414 r740 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); -
vendor/current/source3/winbindd/idmap_nss.c
r414 r740 2 2 Unix SMB/CIFS implementation. 3 3 4 idmap PASSDBbackend4 idmap NSS backend 5 5 6 6 Copyright (C) Simo Sorce 2006 7 7 8 8 This program is free software; you can redistribute it and/or modify 9 9 it under the terms of the GNU General Public License as published by 10 10 the Free Software Foundation; either version 3 of the License, or 11 11 (at your option) any later version. 12 12 13 13 This program is distributed in the hope that it will be useful, 14 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 16 GNU General Public License for more details. 17 17 18 18 You should have received a copy of the GNU General Public License 19 19 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 21 21 22 22 #include "includes.h" 23 #include "system/passwd.h" 23 24 #include "winbindd.h" 25 #include "nsswitch/winbind_client.h" 26 #include "idmap.h" 27 #include "lib/winbind_util.h" 24 28 25 29 #undef DBGC_CLASS … … 30 34 *****************************/ 31 35 32 static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom, 33 const char *params) 36 static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom) 34 37 { 35 38 return NT_STATUS_OK; … … 42 45 static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids) 43 46 { 44 TALLOC_CTX *ctx;45 47 int i; 46 48 … … 48 50 for (i = 0; ids[i]; i++) { 49 51 ids[i]->status = ID_UNKNOWN; 50 }51 52 ctx = talloc_new(dom);53 if ( ! ctx) {54 DEBUG(0, ("Out of memory!\n"));55 return NT_STATUS_NO_MEMORY;56 52 } 57 53 … … 62 58 enum lsa_SidType type; 63 59 bool ret; 64 60 65 61 switch (ids[i]->xid.type) { 66 62 case ID_TYPE_UID: … … 121 117 } 122 118 } 123 124 125 talloc_free(ctx);126 119 return NT_STATUS_OK; 127 120 } … … 133 126 static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids) 134 127 { 135 TALLOC_CTX *ctx;136 128 int i; 137 129 … … 139 131 for (i = 0; ids[i]; i++) { 140 132 ids[i]->status = ID_UNKNOWN; 141 }142 143 ctx = talloc_new(dom);144 if ( ! ctx) {145 DEBUG(0, ("Out of memory!\n"));146 return NT_STATUS_NO_MEMORY;147 133 } 148 134 … … 150 136 struct group *gr; 151 137 enum lsa_SidType type; 152 const char *dom_name = NULL; 153 const char *name = NULL; 138 char *name = NULL; 154 139 bool ret; 155 140 … … 157 142 the following call will not recurse so this is safe */ 158 143 (void)winbind_on(); 159 ret = winbind_lookup_sid(ctx, ids[i]->sid, &dom_name, &name, &type); 144 ret = winbind_lookup_sid(talloc_tos(), ids[i]->sid, NULL, 145 (const char **)&name, &type); 160 146 (void)winbind_off(); 161 147 … … 199 185 break; 200 186 } 201 } 202 203 talloc_free(ctx); 187 TALLOC_FREE(name); 188 } 204 189 return NT_STATUS_OK; 205 190 } … … 209 194 **********************************/ 210 195 211 static NTSTATUS idmap_nss_close(struct idmap_domain *dom)212 {213 return NT_STATUS_OK;214 }215 216 196 static struct idmap_methods nss_methods = { 217 197 … … 219 199 .unixids_to_sids = idmap_nss_unixids_to_sids, 220 200 .sids_to_unixids = idmap_nss_sids_to_unixids, 221 .close_fn = idmap_nss_close222 201 }; 223 202 -
vendor/current/source3/winbindd/idmap_passdb.c
r414 r740 5 5 6 6 Copyright (C) Simo Sorce 2006 7 7 8 8 This program is free software; you can redistribute it and/or modify 9 9 it under the terms of the GNU General Public License as published by 10 10 the Free Software Foundation; either version 3 of the License, or 11 11 (at your option) any later version. 12 12 13 13 This program is distributed in the hope that it will be useful, 14 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 16 GNU General Public License for more details. 17 17 18 18 You should have received a copy of the GNU General Public License 19 19 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 21 21 22 22 #include "includes.h" 23 #include "idmap.h" 24 #include "passdb.h" 23 25 24 26 #undef DBGC_CLASS … … 29 31 *****************************/ 30 32 31 static NTSTATUS idmap_pdb_init(struct idmap_domain *dom , const char *params)33 static NTSTATUS idmap_pdb_init(struct idmap_domain *dom) 32 34 { 33 35 return NT_STATUS_OK; … … 77 79 enum lsa_SidType type; 78 80 union unid_t id; 79 81 80 82 if (pdb_sid_to_id(ids[i]->sid, &id, &type)) { 81 83 switch (type) { … … 112 114 **********************************/ 113 115 114 static NTSTATUS idmap_pdb_close(struct idmap_domain *dom)115 {116 return NT_STATUS_OK;117 }118 119 116 static struct idmap_methods passdb_methods = { 120 117 … … 122 119 .unixids_to_sids = idmap_pdb_unixids_to_sids, 123 120 .sids_to_unixids = idmap_pdb_sids_to_unixids, 124 .close_fn =idmap_pdb_close125 121 }; 126 122 -
vendor/current/source3/winbindd/idmap_rid.c
r414 r740 21 21 #include "includes.h" 22 22 #include "winbindd.h" 23 #include "idmap.h" 24 #include "../libcli/security/dom_sid.h" 23 25 24 26 #undef DBGC_CLASS … … 26 28 27 29 struct idmap_rid_context { 28 const char *domain_name;29 uint32_t low_id;30 uint32_t high_id;31 30 uint32_t base_rid; 32 31 }; … … 37 36 *****************************************************************************/ 38 37 39 static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom, 40 const char *params) 38 static NTSTATUS idmap_rid_initialize(struct idmap_domain *dom) 41 39 { 42 40 NTSTATUS ret; 43 41 struct idmap_rid_context *ctx; 44 42 char *config_option = NULL; 45 const char *range;46 uid_t low_uid = 0;47 uid_t high_uid = 0;48 gid_t low_gid = 0;49 gid_t high_gid = 0;50 43 51 if ( (ctx = TALLOC_ZERO_P(dom, struct idmap_rid_context)) == NULL ) { 44 ctx = TALLOC_ZERO_P(dom, struct idmap_rid_context); 45 if (ctx == NULL) { 52 46 DEBUG(0, ("Out of memory!\n")); 53 47 return NT_STATUS_NO_MEMORY; … … 61 55 } 62 56 63 range = lp_parm_const_string(-1, config_option, "range", NULL); 64 if ( !range || 65 (sscanf(range, "%u - %u", &ctx->low_id, &ctx->high_id) != 2) || 66 (ctx->low_id > ctx->high_id)) 67 { 68 ctx->low_id = 0; 69 ctx->high_id = 0; 70 } 57 ctx->base_rid = lp_parm_int(-1, config_option, "base_rid", 0); 71 58 72 /* lets see if the range is defined by the old idmap uid/idmap gid */73 if (!ctx->low_id && !ctx->high_id) {74 if (lp_idmap_uid(&low_uid, &high_uid)) {75 ctx->low_id = low_uid;76 ctx->high_id = high_uid;77 }78 79 if (lp_idmap_gid(&low_gid, &high_gid)) {80 if ((ctx->low_id != low_gid) ||81 (ctx->high_id != high_uid)) {82 DEBUG(1, ("ERROR: idmap uid range must match idmap gid range\n"));83 ret = NT_STATUS_UNSUCCESSFUL;84 goto failed;85 }86 }87 }88 89 if (!ctx->low_id || !ctx->high_id) {90 DEBUG(1, ("ERROR: Invalid configuration, ID range missing or invalid\n"));91 ret = NT_STATUS_UNSUCCESSFUL;92 goto failed;93 }94 95 ctx->base_rid = lp_parm_int(-1, config_option, "base_rid", 0);96 ctx->domain_name = talloc_strdup( ctx, dom->name );97 98 59 dom->private_data = ctx; 99 60 … … 106 67 } 107 68 108 static NTSTATUS idmap_rid_id_to_sid( TALLOC_CTX *memctx, struct idmap_rid_context *ctx, struct id_map *map)69 static NTSTATUS idmap_rid_id_to_sid(struct idmap_domain *dom, struct id_map *map) 109 70 { 110 struct winbindd_domain *domain; 71 struct winbindd_domain *domain; 72 struct idmap_rid_context *ctx; 73 74 ctx = talloc_get_type(dom->private_data, struct idmap_rid_context); 111 75 112 76 /* apply filters before checking */ 113 if ( (map->xid.id < ctx->low_id) || (map->xid.id > ctx->high_id)) {77 if (!idmap_unix_id_is_in_range(map->xid.id, dom)) { 114 78 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n", 115 map->xid.id, ctx->low_id, ctx->high_id));79 map->xid.id, dom->low_id, dom->high_id)); 116 80 return NT_STATUS_NONE_MAPPED; 117 81 } 118 82 119 if ( (domain = find_domain_from_name_noinit(ctx->domain_name)) == NULL ) { 83 domain = find_domain_from_name_noinit(dom->name); 84 if (domain == NULL ) { 120 85 return NT_STATUS_NO_SUCH_DOMAIN; 121 86 } 122 123 sid_compose(map->sid, &domain->sid, map->xid.id - ctx->low_id + ctx->base_rid);87 88 sid_compose(map->sid, &domain->sid, map->xid.id - dom->low_id + ctx->base_rid); 124 89 125 90 /* We **really** should have some way of validating … … 136 101 **********************************/ 137 102 138 static NTSTATUS idmap_rid_sid_to_id( TALLOC_CTX *memctx, struct idmap_rid_context *ctx, struct id_map *map)103 static NTSTATUS idmap_rid_sid_to_id(struct idmap_domain *dom, struct id_map *map) 139 104 { 140 105 uint32_t rid; 106 struct idmap_rid_context *ctx; 107 108 ctx = talloc_get_type(dom->private_data, struct idmap_rid_context); 141 109 142 110 sid_peek_rid(map->sid, &rid); 143 map->xid.id = rid - ctx->base_rid + ctx->low_id;111 map->xid.id = rid - ctx->base_rid + dom->low_id; 144 112 145 113 /* apply filters before returning result */ 146 114 147 if ( (map->xid.id < ctx->low_id) || (map->xid.id > ctx->high_id)) {115 if (!idmap_unix_id_is_in_range(map->xid.id, dom)) { 148 116 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n", 149 map->xid.id, ctx->low_id, ctx->high_id));117 map->xid.id, dom->low_id, dom->high_id)); 150 118 map->status = ID_UNMAPPED; 151 119 return NT_STATUS_NONE_MAPPED; 152 120 } 153 154 /* We **really** should have some way of validating155 the SID exists and is the correct type here. But156 that is a deficiency in the idmap_rid design. */157 121 158 122 map->status = ID_MAPPED; … … 167 131 static NTSTATUS idmap_rid_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids) 168 132 { 169 struct idmap_rid_context *ridctx;170 TALLOC_CTX *ctx;171 133 NTSTATUS ret; 172 134 int i; … … 176 138 ids[i]->status = ID_UNKNOWN; 177 139 } 178 179 ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);180 181 ctx = talloc_new(dom);182 if ( ! ctx) {183 DEBUG(0, ("Out of memory!\n"));184 return NT_STATUS_NO_MEMORY;185 }186 140 187 141 for (i = 0; ids[i]; i++) { 188 142 189 ret = idmap_rid_id_to_sid( ctx, ridctx, ids[i]);143 ret = idmap_rid_id_to_sid(dom, ids[i]); 190 144 191 145 if (( ! NT_STATUS_IS_OK(ret)) && … … 196 150 } 197 151 198 talloc_free(ctx);199 152 return NT_STATUS_OK; 200 153 } … … 206 159 static NTSTATUS idmap_rid_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids) 207 160 { 208 struct idmap_rid_context *ridctx;209 TALLOC_CTX *ctx;210 161 NTSTATUS ret; 211 162 int i; … … 215 166 ids[i]->status = ID_UNKNOWN; 216 167 } 217 218 ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);219 220 ctx = talloc_new(dom);221 if ( ! ctx) {222 DEBUG(0, ("Out of memory!\n"));223 return NT_STATUS_NO_MEMORY;224 }225 168 226 169 for (i = 0; ids[i]; i++) { 227 170 228 ret = idmap_rid_sid_to_id( ctx, ridctx, ids[i]);171 ret = idmap_rid_sid_to_id(dom, ids[i]); 229 172 230 173 if (( ! NT_STATUS_IS_OK(ret)) && … … 236 179 } 237 180 238 talloc_free(ctx);239 return NT_STATUS_OK;240 }241 242 static NTSTATUS idmap_rid_close(struct idmap_domain *dom)243 {244 if (dom->private_data) {245 TALLOC_FREE(dom->private_data);246 }247 181 return NT_STATUS_OK; 248 182 } … … 252 186 .unixids_to_sids = idmap_rid_unixids_to_sids, 253 187 .sids_to_unixids = idmap_rid_sids_to_unixids, 254 .close_fn = idmap_rid_close255 188 }; 256 189 -
vendor/current/source3/winbindd/idmap_tdb.c
r414 r740 8 8 Copyright (C) Jeremy Allison 2006 9 9 Copyright (C) Simo Sorce 2003-2006 10 10 Copyright (C) Michael Adam 2009-2010 11 11 12 This program is free software; you can redistribute it and/or modify 12 13 it under the terms of the GNU General Public License as published by 13 14 the Free Software Foundation; either version 3 of the License, or 14 15 (at your option) any later version. 15 16 16 17 This program is distributed in the hope that it will be useful, 17 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 20 GNU General Public License for more details. 20 21 21 22 You should have received a copy of the GNU General Public License 22 23 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 24 25 25 26 #include "includes.h" 27 #include "system/filesys.h" 26 28 #include "winbindd.h" 29 #include "idmap.h" 30 #include "idmap_rw.h" 31 #include "dbwrap.h" 32 #include "../libcli/security/security.h" 33 #include "util_tdb.h" 27 34 28 35 #undef DBGC_CLASS … … 33 40 34 41 #define IDMAP_VERSION 2 42 43 struct idmap_tdb_context { 44 struct db_context *db; 45 struct idmap_rw_ops *rw_ops; 46 }; 35 47 36 48 /* High water mark keys */ 37 49 #define HWM_GROUP "GROUP HWM" 38 50 #define HWM_USER "USER HWM" 39 40 static struct idmap_tdb_state {41 42 /* User and group id pool */43 uid_t low_uid, high_uid; /* Range of uids to allocate */44 gid_t low_gid, high_gid; /* Range of gids to allocate */45 46 } idmap_tdb_state;47 51 48 52 struct convert_fn_state { … … 61 65 char *p; 62 66 NTSTATUS status; 63 DOM_SIDsid;67 struct dom_sid sid; 64 68 uint32 rid; 65 69 fstring keystr; … … 98 102 rid = atoi(p); 99 103 100 sid_copy(&sid, &domain->sid); 101 sid_append_rid(&sid, rid); 104 sid_compose(&sid, &domain->sid, rid); 102 105 103 106 sid_to_fstring(keystr, &sid); … … 138 141 *****************************************************************************/ 139 142 140 static bool idmap_tdb_upgrade(struct db_context *db)143 static bool idmap_tdb_upgrade(struct idmap_domain *dom, struct db_context *db) 141 144 { 142 145 int32 vers; … … 164 167 wm = IREV(wm); 165 168 } else { 166 wm = idmap_tdb_state.low_uid;169 wm = dom->low_id; 167 170 } 168 171 … … 176 179 wm = IREV(wm); 177 180 } else { 178 wm = idmap_tdb_state.low_gid;181 wm = dom->low_id; 179 182 } 180 183 … … 197 200 198 201 if (dbwrap_store_int32(db, "IDMAP_VERSION", IDMAP_VERSION) == -1) { 199 DEBUG(0, ("Unable to store idmap version in datab se\n"));202 DEBUG(0, ("Unable to store idmap version in database\n")); 200 203 return False; 201 204 } … … 204 207 } 205 208 206 static NTSTATUS idmap_tdb_load_ranges(void) 207 { 208 uid_t low_uid = 0; 209 uid_t high_uid = 0; 210 gid_t low_gid = 0; 211 gid_t high_gid = 0; 212 213 if (!lp_idmap_uid(&low_uid, &high_uid)) { 214 DEBUG(1, ("idmap uid missing\n")); 215 return NT_STATUS_UNSUCCESSFUL; 216 } 217 218 if (!lp_idmap_gid(&low_gid, &high_gid)) { 219 DEBUG(1, ("idmap gid missing\n")); 220 return NT_STATUS_UNSUCCESSFUL; 221 } 222 223 idmap_tdb_state.low_uid = low_uid; 224 idmap_tdb_state.high_uid = high_uid; 225 idmap_tdb_state.low_gid = low_gid; 226 idmap_tdb_state.high_gid = high_gid; 227 228 if (idmap_tdb_state.high_uid <= idmap_tdb_state.low_uid) { 229 DEBUG(1, ("idmap uid range missing or invalid\n")); 230 return NT_STATUS_UNSUCCESSFUL; 231 } 232 233 if (idmap_tdb_state.high_gid <= idmap_tdb_state.low_gid) { 234 DEBUG(1, ("idmap gid range missing or invalid\n")); 235 return NT_STATUS_UNSUCCESSFUL; 209 static NTSTATUS idmap_tdb_init_hwm(struct idmap_domain *dom) 210 { 211 int ret; 212 uint32_t low_uid; 213 uint32_t low_gid; 214 bool update_uid = false; 215 bool update_gid = false; 216 struct idmap_tdb_context *ctx; 217 218 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); 219 220 low_uid = dbwrap_fetch_int32(ctx->db, HWM_USER); 221 if (low_uid == -1 || low_uid < dom->low_id) { 222 update_uid = true; 223 } 224 225 low_gid = dbwrap_fetch_int32(ctx->db, HWM_GROUP); 226 if (low_gid == -1 || low_gid < dom->low_id) { 227 update_gid = true; 228 } 229 230 if (!update_uid && !update_gid) { 231 return NT_STATUS_OK; 232 } 233 234 if (ctx->db->transaction_start(ctx->db) != 0) { 235 DEBUG(0, ("Unable to start upgrade transaction!\n")); 236 return NT_STATUS_INTERNAL_DB_ERROR; 237 } 238 239 if (update_uid) { 240 ret = dbwrap_store_int32(ctx->db, HWM_USER, dom->low_id); 241 if (ret == -1) { 242 ctx->db->transaction_cancel(ctx->db); 243 DEBUG(0, ("Unable to initialise user hwm in idmap " 244 "database\n")); 245 return NT_STATUS_INTERNAL_DB_ERROR; 246 } 247 } 248 249 if (update_gid) { 250 ret = dbwrap_store_int32(ctx->db, HWM_GROUP, dom->low_id); 251 if (ret == -1) { 252 ctx->db->transaction_cancel(ctx->db); 253 DEBUG(0, ("Unable to initialise group hwm in idmap " 254 "database\n")); 255 return NT_STATUS_INTERNAL_DB_ERROR; 256 } 257 } 258 259 if (ctx->db->transaction_commit(ctx->db) != 0) { 260 DEBUG(0, ("Unable to commit upgrade transaction!\n")); 261 return NT_STATUS_INTERNAL_DB_ERROR; 236 262 } 237 263 … … 239 265 } 240 266 241 static NTSTATUS idmap_tdb_open_db(TALLOC_CTX *memctx, 242 bool check_config, 243 struct db_context **dbctx) 244 { 245 NTSTATUS ret; 246 TALLOC_CTX *ctx; 267 static NTSTATUS idmap_tdb_open_db(struct idmap_domain *dom) 268 { 269 NTSTATUS ret; 270 TALLOC_CTX *mem_ctx; 247 271 char *tdbfile = NULL; 248 272 struct db_context *db = NULL; 249 273 int32_t version; 250 274 bool config_error = false; 251 252 ret = idmap_tdb_load_ranges(); 253 if (!NT_STATUS_IS_OK(ret)) {254 config_error = true; 255 if (check_config) {256 return ret;257 }275 struct idmap_tdb_context *ctx; 276 277 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); 278 279 if (ctx->db) { 280 /* it is already open */ 281 return NT_STATUS_OK; 258 282 } 259 283 260 284 /* use our own context here */ 261 ctx = talloc_stackframe();285 mem_ctx = talloc_stackframe(); 262 286 263 287 /* use the old database if present */ … … 272 296 273 297 /* Open idmap repository */ 274 db = db_open( ctx, tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644);298 db = db_open(mem_ctx, tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644); 275 299 if (!db) { 276 300 DEBUG(0, ("Unable to open idmap database\n")); … … 295 319 } 296 320 297 if (!idmap_tdb_upgrade(d b)) {321 if (!idmap_tdb_upgrade(dom, db)) { 298 322 db->transaction_cancel(db); 299 323 DEBUG(0, ("Unable to open idmap database, it's in an old format, and upgrade failed!\n")); … … 309 333 } 310 334 311 *dbctx = talloc_move(memctx, &db); 312 ret = NT_STATUS_OK; 335 ctx->db = talloc_move(ctx, &db); 336 337 ret = idmap_tdb_init_hwm(dom); 313 338 314 339 done: 315 talloc_free( ctx);340 talloc_free(mem_ctx); 316 341 return ret; 317 342 } … … 320 345 IDMAP ALLOC TDB BACKEND 321 346 **********************************************************************/ 322 323 static struct db_context *idmap_alloc_db;324 325 /**********************************326 Initialise idmap alloc database.327 **********************************/328 329 static NTSTATUS idmap_tdb_alloc_init( const char *params )330 {331 int ret;332 NTSTATUS status;333 uint32_t low_uid;334 uint32_t low_gid;335 bool update_uid = false;336 bool update_gid = false;337 338 status = idmap_tdb_open_db(NULL, true, &idmap_alloc_db);339 if (!NT_STATUS_IS_OK(status)) {340 DEBUG(0, ("idmap will be unable to map foreign SIDs: %s\n",341 nt_errstr(status)));342 return status;343 }344 345 low_uid = dbwrap_fetch_int32(idmap_alloc_db, HWM_USER);346 if (low_uid == -1 || low_uid < idmap_tdb_state.low_uid) {347 update_uid = true;348 }349 350 low_gid = dbwrap_fetch_int32(idmap_alloc_db, HWM_GROUP);351 if (low_gid == -1 || low_gid < idmap_tdb_state.low_gid) {352 update_gid = true;353 }354 355 if (!update_uid && !update_gid) {356 return NT_STATUS_OK;357 }358 359 if (idmap_alloc_db->transaction_start(idmap_alloc_db) != 0) {360 TALLOC_FREE(idmap_alloc_db);361 DEBUG(0, ("Unable to start upgrade transaction!\n"));362 return NT_STATUS_INTERNAL_DB_ERROR;363 }364 365 if (update_uid) {366 ret = dbwrap_store_int32(idmap_alloc_db, HWM_USER,367 idmap_tdb_state.low_uid);368 if (ret == -1) {369 idmap_alloc_db->transaction_cancel(idmap_alloc_db);370 TALLOC_FREE(idmap_alloc_db);371 DEBUG(0, ("Unable to initialise user hwm in idmap "372 "database\n"));373 return NT_STATUS_INTERNAL_DB_ERROR;374 }375 }376 377 if (update_gid) {378 ret = dbwrap_store_int32(idmap_alloc_db, HWM_GROUP,379 idmap_tdb_state.low_gid);380 if (ret == -1) {381 idmap_alloc_db->transaction_cancel(idmap_alloc_db);382 TALLOC_FREE(idmap_alloc_db);383 DEBUG(0, ("Unable to initialise group hwm in idmap "384 "database\n"));385 return NT_STATUS_INTERNAL_DB_ERROR;386 }387 }388 389 if (idmap_alloc_db->transaction_commit(idmap_alloc_db) != 0) {390 TALLOC_FREE(idmap_alloc_db);391 DEBUG(0, ("Unable to commit upgrade transaction!\n"));392 return NT_STATUS_INTERNAL_DB_ERROR;393 }394 395 return NT_STATUS_OK;396 }397 347 398 348 /********************************** … … 400 350 **********************************/ 401 351 402 static NTSTATUS idmap_tdb_allocate_id(struct unixid *xid) 403 { 404 NTSTATUS ret; 352 struct idmap_tdb_allocate_id_context { 405 353 const char *hwmkey; 406 354 const char *hwmtype; 407 355 uint32_t high_hwm; 408 356 uint32_t hwm; 409 int res; 357 }; 358 359 static NTSTATUS idmap_tdb_allocate_id_action(struct db_context *db, 360 void *private_data) 361 { 362 NTSTATUS ret; 363 struct idmap_tdb_allocate_id_context *state; 364 uint32_t hwm; 365 366 state = (struct idmap_tdb_allocate_id_context *)private_data; 367 368 hwm = dbwrap_fetch_int32(db, state->hwmkey); 369 if (hwm == -1) { 370 ret = NT_STATUS_INTERNAL_DB_ERROR; 371 goto done; 372 } 373 374 /* check it is in the range */ 375 if (hwm > state->high_hwm) { 376 DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n", 377 state->hwmtype, (unsigned long)state->high_hwm)); 378 ret = NT_STATUS_UNSUCCESSFUL; 379 goto done; 380 } 381 382 /* fetch a new id and increment it */ 383 ret = dbwrap_trans_change_uint32_atomic(db, state->hwmkey, &hwm, 1); 384 if (!NT_STATUS_IS_OK(ret)) { 385 DEBUG(0, ("Fatal error while fetching a new %s value: %s\n!", 386 state->hwmtype, nt_errstr(ret))); 387 goto done; 388 } 389 390 /* recheck it is in the range */ 391 if (hwm > state->high_hwm) { 392 DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n", 393 state->hwmtype, (unsigned long)state->high_hwm)); 394 ret = NT_STATUS_UNSUCCESSFUL; 395 goto done; 396 } 397 398 ret = NT_STATUS_OK; 399 state->hwm = hwm; 400 401 done: 402 return ret; 403 } 404 405 static NTSTATUS idmap_tdb_allocate_id(struct idmap_domain *dom, 406 struct unixid *xid) 407 { 408 const char *hwmkey; 409 const char *hwmtype; 410 uint32_t high_hwm; 411 uint32_t hwm = 0; 412 NTSTATUS status; 413 struct idmap_tdb_allocate_id_context state; 414 struct idmap_tdb_context *ctx; 415 416 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); 410 417 411 418 /* Get current high water mark */ … … 415 422 hwmkey = HWM_USER; 416 423 hwmtype = "UID"; 417 high_hwm = idmap_tdb_state.high_uid;418 424 break; 419 425 … … 421 427 hwmkey = HWM_GROUP; 422 428 hwmtype = "GID"; 423 high_hwm = idmap_tdb_state.high_gid;424 429 break; 425 430 … … 429 434 } 430 435 431 res = idmap_alloc_db->transaction_start(idmap_alloc_db); 432 if (res != 0) { 433 DEBUG(1, (__location__ " Failed to start transaction.\n")); 434 return NT_STATUS_UNSUCCESSFUL; 435 } 436 437 if ((hwm = dbwrap_fetch_int32(idmap_alloc_db, hwmkey)) == -1) { 438 idmap_alloc_db->transaction_cancel(idmap_alloc_db); 439 return NT_STATUS_INTERNAL_DB_ERROR; 440 } 441 442 /* check it is in the range */ 443 if (hwm > high_hwm) { 444 DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n", 445 hwmtype, (unsigned long)high_hwm)); 446 idmap_alloc_db->transaction_cancel(idmap_alloc_db); 447 return NT_STATUS_UNSUCCESSFUL; 448 } 449 450 /* fetch a new id and increment it */ 451 ret = dbwrap_change_uint32_atomic(idmap_alloc_db, hwmkey, &hwm, 1); 452 if (!NT_STATUS_IS_OK(ret)) { 453 DEBUG(0, ("Fatal error while fetching a new %s value: %s\n!", 454 hwmtype, nt_errstr(ret))); 455 idmap_alloc_db->transaction_cancel(idmap_alloc_db); 456 return ret; 457 } 458 459 /* recheck it is in the range */ 460 if (hwm > high_hwm) { 461 DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n", 462 hwmtype, (unsigned long)high_hwm)); 463 idmap_alloc_db->transaction_cancel(idmap_alloc_db); 464 return NT_STATUS_UNSUCCESSFUL; 465 } 466 467 res = idmap_alloc_db->transaction_commit(idmap_alloc_db); 468 if (res != 0) { 469 DEBUG(1, (__location__ " Failed to commit transaction.\n")); 470 return NT_STATUS_UNSUCCESSFUL; 471 } 472 473 xid->id = hwm; 474 DEBUG(10,("New %s = %d\n", hwmtype, hwm)); 475 476 return NT_STATUS_OK; 477 } 478 479 /********************************** 480 Get current highest id. 481 **********************************/ 482 483 static NTSTATUS idmap_tdb_get_hwm(struct unixid *xid) 484 { 485 const char *hwmkey; 486 const char *hwmtype; 487 uint32_t hwm; 488 uint32_t high_hwm; 489 490 /* Get current high water mark */ 491 switch (xid->type) { 492 493 case ID_TYPE_UID: 494 hwmkey = HWM_USER; 495 hwmtype = "UID"; 496 high_hwm = idmap_tdb_state.high_uid; 497 break; 498 499 case ID_TYPE_GID: 500 hwmkey = HWM_GROUP; 501 hwmtype = "GID"; 502 high_hwm = idmap_tdb_state.high_gid; 503 break; 504 505 default: 506 return NT_STATUS_INVALID_PARAMETER; 507 } 508 509 if ((hwm = dbwrap_fetch_int32(idmap_alloc_db, hwmkey)) == -1) { 510 return NT_STATUS_INTERNAL_DB_ERROR; 511 } 512 513 xid->id = hwm; 514 515 /* Warn if it is out of range */ 516 if (hwm >= high_hwm) { 517 DEBUG(0, ("Warning: %s range full!! (max: %lu)\n", 518 hwmtype, (unsigned long)high_hwm)); 519 } 520 521 return NT_STATUS_OK; 522 } 523 524 /********************************** 525 Set high id. 526 **********************************/ 527 528 static NTSTATUS idmap_tdb_set_hwm(struct unixid *xid) 529 { 530 const char *hwmkey; 531 const char *hwmtype; 532 uint32_t hwm; 533 uint32_t high_hwm; 534 NTSTATUS ret; 535 536 /* Get current high water mark */ 537 switch (xid->type) { 538 539 case ID_TYPE_UID: 540 hwmkey = HWM_USER; 541 hwmtype = "UID"; 542 high_hwm = idmap_tdb_state.high_uid; 543 break; 544 545 case ID_TYPE_GID: 546 hwmkey = HWM_GROUP; 547 hwmtype = "GID"; 548 high_hwm = idmap_tdb_state.high_gid; 549 break; 550 551 default: 552 return NT_STATUS_INVALID_PARAMETER; 553 } 554 555 hwm = xid->id; 556 557 /* Warn if it is out of range */ 558 if (hwm >= high_hwm) { 559 DEBUG(0, ("Warning: %s range full!! (max: %lu)\n", 560 hwmtype, (unsigned long)high_hwm)); 561 } 562 563 ret = dbwrap_trans_store_uint32(idmap_alloc_db, hwmkey, hwm); 564 565 return ret; 566 } 567 568 /********************************** 569 Close the alloc tdb 570 **********************************/ 571 572 static NTSTATUS idmap_tdb_alloc_close(void) 573 { 574 TALLOC_FREE(idmap_alloc_db); 575 return NT_STATUS_OK; 436 high_hwm = dom->high_id; 437 438 state.hwm = hwm; 439 state.high_hwm = high_hwm; 440 state.hwmtype = hwmtype; 441 state.hwmkey = hwmkey; 442 443 status = dbwrap_trans_do(ctx->db, idmap_tdb_allocate_id_action, 444 &state); 445 446 if (NT_STATUS_IS_OK(status)) { 447 xid->id = state.hwm; 448 DEBUG(10,("New %s = %d\n", hwmtype, state.hwm)); 449 } else { 450 DEBUG(1, ("Error allocating a new %s\n", hwmtype)); 451 } 452 453 return status; 454 } 455 456 /** 457 * Allocate a new unix-ID. 458 * For now this is for the default idmap domain only. 459 * Should be extended later on. 460 */ 461 static NTSTATUS idmap_tdb_get_new_id(struct idmap_domain *dom, 462 struct unixid *id) 463 { 464 NTSTATUS ret; 465 466 if (!strequal(dom->name, "*")) { 467 DEBUG(3, ("idmap_tdb_get_new_id: " 468 "Refusing allocation of a new unixid for domain'%s'. " 469 "Currently only supported for the default " 470 "domain \"*\".\n", 471 dom->name)); 472 return NT_STATUS_NOT_IMPLEMENTED; 473 } 474 475 ret = idmap_tdb_allocate_id(dom, id); 476 477 return ret; 576 478 } 577 479 … … 579 481 IDMAP MAPPING TDB BACKEND 580 482 **********************************************************************/ 581 582 struct idmap_tdb_context {583 struct db_context *db;584 uint32_t filter_low_id;585 uint32_t filter_high_id;586 };587 483 588 484 /***************************** … … 590 486 *****************************/ 591 487 592 static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *params) 488 static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, 489 const struct id_map *map); 490 491 static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom) 593 492 { 594 493 NTSTATUS ret; … … 597 496 DEBUG(10, ("idmap_tdb_db_init called for domain '%s'\n", dom->name)); 598 497 599 ctx = talloc (dom, struct idmap_tdb_context);498 ctx = talloc_zero(dom, struct idmap_tdb_context); 600 499 if ( ! ctx) { 601 500 DEBUG(0, ("Out of memory!\n")); … … 603 502 } 604 503 504 /* load backend specific configuration here: */ 505 #if 0 605 506 if (strequal(dom->name, "*")) { 606 uid_t low_uid = 0;607 uid_t high_uid = 0;608 gid_t low_gid = 0;609 gid_t high_gid = 0;610 611 ctx->filter_low_id = 0;612 ctx->filter_high_id = 0;613 614 if (lp_idmap_uid(&low_uid, &high_uid)) {615 ctx->filter_low_id = low_uid;616 ctx->filter_high_id = high_uid;617 } else {618 DEBUG(3, ("Warning: 'idmap uid' not set!\n"));619 }620 621 if (lp_idmap_gid(&low_gid, &high_gid)) {622 if ((low_gid != low_uid) || (high_gid != high_uid)) {623 DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'"624 " ranges do not agree -- building "625 "intersection\n"));626 ctx->filter_low_id = MAX(ctx->filter_low_id,627 low_gid);628 ctx->filter_high_id = MIN(ctx->filter_high_id,629 high_gid);630 }631 } else {632 DEBUG(3, ("Warning: 'idmap gid' not set!\n"));633 }634 507 } else { 635 char *config_option = NULL; 636 const char *range; 637 638 config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); 639 if ( ! config_option) { 640 DEBUG(0, ("Out of memory!\n")); 641 ret = NT_STATUS_NO_MEMORY; 642 goto failed; 643 } 644 645 range = lp_parm_const_string(-1, config_option, "range", NULL); 646 if (( ! range) || 647 (sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2)) 648 { 649 ctx->filter_low_id = 0; 650 ctx->filter_high_id = 0; 651 } 652 653 talloc_free(config_option); 654 } 655 656 if (ctx->filter_low_id > ctx->filter_high_id) { 657 ctx->filter_low_id = 0; 658 ctx->filter_high_id = 0; 659 } 660 661 DEBUG(10, ("idmap_tdb_db_init: filter range %u-%u loaded for domain " 662 "'%s'\n", ctx->filter_low_id, ctx->filter_high_id, dom->name)); 663 664 ret = idmap_tdb_open_db(ctx, false, &ctx->db); 508 } 509 #endif 510 511 ctx->rw_ops = talloc_zero(ctx, struct idmap_rw_ops); 512 if (ctx->rw_ops == NULL) { 513 DEBUG(0, ("Out of memory!\n")); 514 ret = NT_STATUS_NO_MEMORY; 515 goto failed; 516 } 517 518 ctx->rw_ops->get_new_id = idmap_tdb_get_new_id; 519 ctx->rw_ops->set_mapping = idmap_tdb_set_mapping; 520 521 dom->private_data = ctx; 522 523 ret = idmap_tdb_open_db(dom); 665 524 if ( ! NT_STATUS_IS_OK(ret)) { 666 525 goto failed; 667 526 } 668 527 669 dom->private_data = ctx;670 671 528 return NT_STATUS_OK; 672 529 … … 675 532 return ret; 676 533 } 534 535 536 /** 537 * store a mapping in the database 538 */ 539 540 struct idmap_tdb_set_mapping_context { 541 const char *ksidstr; 542 const char *kidstr; 543 }; 544 545 static NTSTATUS idmap_tdb_set_mapping_action(struct db_context *db, 546 void *private_data) 547 { 548 NTSTATUS ret; 549 struct idmap_tdb_set_mapping_context *state; 550 551 state = (struct idmap_tdb_set_mapping_context *)private_data; 552 553 DEBUG(10, ("Storing %s <-> %s map\n", state->ksidstr, state->kidstr)); 554 555 ret = dbwrap_store_bystring(db, state->ksidstr, 556 string_term_tdb_data(state->kidstr), 557 TDB_REPLACE); 558 if (!NT_STATUS_IS_OK(ret)) { 559 DEBUG(0, ("Error storing SID -> ID (%s -> %s): %s\n", 560 state->ksidstr, state->kidstr, nt_errstr(ret))); 561 goto done; 562 } 563 564 ret = dbwrap_store_bystring(db, state->kidstr, 565 string_term_tdb_data(state->ksidstr), 566 TDB_REPLACE); 567 if (!NT_STATUS_IS_OK(ret)) { 568 DEBUG(0, ("Error storing ID -> SID (%s -> %s): %s\n", 569 state->kidstr, state->ksidstr, nt_errstr(ret))); 570 goto done; 571 } 572 573 DEBUG(10,("Stored %s <-> %s\n", state->ksidstr, state->kidstr)); 574 ret = NT_STATUS_OK; 575 576 done: 577 return ret; 578 } 579 580 static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, 581 const struct id_map *map) 582 { 583 struct idmap_tdb_context *ctx; 584 NTSTATUS ret; 585 char *ksidstr, *kidstr; 586 struct idmap_tdb_set_mapping_context state; 587 588 if (!map || !map->sid) { 589 return NT_STATUS_INVALID_PARAMETER; 590 } 591 592 ksidstr = kidstr = NULL; 593 594 /* TODO: should we filter a set_mapping using low/high filters ? */ 595 596 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); 597 598 switch (map->xid.type) { 599 600 case ID_TYPE_UID: 601 kidstr = talloc_asprintf(ctx, "UID %lu", 602 (unsigned long)map->xid.id); 603 break; 604 605 case ID_TYPE_GID: 606 kidstr = talloc_asprintf(ctx, "GID %lu", 607 (unsigned long)map->xid.id); 608 break; 609 610 default: 611 DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type)); 612 return NT_STATUS_INVALID_PARAMETER; 613 } 614 615 if (kidstr == NULL) { 616 DEBUG(0, ("ERROR: Out of memory!\n")); 617 ret = NT_STATUS_NO_MEMORY; 618 goto done; 619 } 620 621 ksidstr = sid_string_talloc(ctx, map->sid); 622 if (ksidstr == NULL) { 623 DEBUG(0, ("Out of memory!\n")); 624 ret = NT_STATUS_NO_MEMORY; 625 goto done; 626 } 627 628 state.ksidstr = ksidstr; 629 state.kidstr = kidstr; 630 631 ret = dbwrap_trans_do(ctx->db, idmap_tdb_set_mapping_action, &state); 632 633 done: 634 talloc_free(ksidstr); 635 talloc_free(kidstr); 636 return ret; 637 } 638 639 /** 640 * Create a new mapping for an unmapped SID, also allocating a new ID. 641 * This should be run inside a transaction. 642 * 643 * TODO: 644 * Properly integrate this with multi domain idmap config: 645 * Currently, the allocator is default-config only. 646 */ 647 static NTSTATUS idmap_tdb_new_mapping(struct idmap_domain *dom, struct id_map *map) 648 { 649 NTSTATUS ret; 650 struct idmap_tdb_context *ctx; 651 652 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); 653 654 ret = idmap_rw_new_mapping(dom, ctx->rw_ops, map); 655 656 return ret; 657 } 658 677 659 678 660 /********************************** … … 680 662 **********************************/ 681 663 682 static NTSTATUS idmap_tdb_id_to_sid(struct idmap_ tdb_context *ctx, struct id_map *map)664 static NTSTATUS idmap_tdb_id_to_sid(struct idmap_domain *dom, struct id_map *map) 683 665 { 684 666 NTSTATUS ret; 685 667 TDB_DATA data; 686 668 char *keystr; 687 688 if (!ctx || !map) { 669 struct idmap_tdb_context *ctx; 670 671 if (!dom || !map) { 689 672 return NT_STATUS_INVALID_PARAMETER; 690 673 } 691 674 675 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); 676 692 677 /* apply filters before checking */ 693 if ((ctx->filter_low_id && (map->xid.id < ctx->filter_low_id)) || 694 (ctx->filter_high_id && (map->xid.id > ctx->filter_high_id))) { 678 if (!idmap_unix_id_is_in_range(map->xid.id, dom)) { 695 679 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n", 696 map->xid.id, ctx->filter_low_id, ctx->filter_high_id));680 map->xid.id, dom->low_id, dom->high_id)); 697 681 return NT_STATUS_NONE_MAPPED; 698 682 } … … 703 687 keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id); 704 688 break; 705 689 706 690 case ID_TYPE_GID: 707 691 keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id); … … 732 716 goto done; 733 717 } 734 718 735 719 if (!string_to_sid(map->sid, (const char *)data.dptr)) { 736 720 DEBUG(10,("INVALID SID (%s) in record %s\n", … … 753 737 **********************************/ 754 738 755 static NTSTATUS idmap_tdb_sid_to_id(struct idmap_ tdb_context *ctx, struct id_map *map)739 static NTSTATUS idmap_tdb_sid_to_id(struct idmap_domain *dom, struct id_map *map) 756 740 { 757 741 NTSTATUS ret; … … 759 743 char *keystr; 760 744 unsigned long rec_id = 0; 745 struct idmap_tdb_context *ctx; 761 746 TALLOC_CTX *tmp_ctx = talloc_stackframe(); 747 748 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); 762 749 763 750 keystr = sid_string_talloc(tmp_ctx, map->sid); … … 794 781 DEBUG(2, ("Found INVALID record %s -> %s\n", keystr, (const char *)data.dptr)); 795 782 ret = NT_STATUS_INTERNAL_DB_ERROR; 783 goto done; 796 784 } 797 785 798 786 /* apply filters before returning result */ 799 if ((ctx->filter_low_id && (map->xid.id < ctx->filter_low_id)) || 800 (ctx->filter_high_id && (map->xid.id > ctx->filter_high_id))) { 787 if (!idmap_unix_id_is_in_range(map->xid.id, dom)) { 801 788 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n", 802 map->xid.id, ctx->filter_low_id, ctx->filter_high_id));789 map->xid.id, dom->low_id, dom->high_id)); 803 790 ret = NT_STATUS_NONE_MAPPED; 804 791 } … … 815 802 static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids) 816 803 { 817 struct idmap_tdb_context *ctx;818 804 NTSTATUS ret; 819 805 int i; … … 823 809 ids[i]->status = ID_UNKNOWN; 824 810 } 825 826 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);827 811 828 812 for (i = 0; ids[i]; i++) { 829 ret = idmap_tdb_id_to_sid( ctx, ids[i]);813 ret = idmap_tdb_id_to_sid(dom, ids[i]); 830 814 if ( ! NT_STATUS_IS_OK(ret)) { 831 815 … … 837 821 continue; 838 822 } 839 823 840 824 /* some fatal error occurred, return immediately */ 841 825 goto done; … … 856 840 **********************************/ 857 841 842 struct idmap_tdb_sids_to_unixids_context { 843 struct idmap_domain *dom; 844 struct id_map **ids; 845 bool allocate_unmapped; 846 }; 847 848 static NTSTATUS idmap_tdb_sids_to_unixids_action(struct db_context *db, 849 void *private_data) 850 { 851 struct idmap_tdb_sids_to_unixids_context *state; 852 int i; 853 NTSTATUS ret = NT_STATUS_OK; 854 855 state = (struct idmap_tdb_sids_to_unixids_context *)private_data; 856 857 DEBUG(10, ("idmap_tdb_sids_to_unixids_action: " 858 " domain: [%s], allocate: %s\n", 859 state->dom->name, 860 state->allocate_unmapped ? "yes" : "no")); 861 862 for (i = 0; state->ids[i]; i++) { 863 if ((state->ids[i]->status == ID_UNKNOWN) || 864 /* retry if we could not map in previous run: */ 865 (state->ids[i]->status == ID_UNMAPPED)) 866 { 867 NTSTATUS ret2; 868 869 ret2 = idmap_tdb_sid_to_id(state->dom, state->ids[i]); 870 if (!NT_STATUS_IS_OK(ret2)) { 871 872 /* if it is just a failed mapping, continue */ 873 if (NT_STATUS_EQUAL(ret2, NT_STATUS_NONE_MAPPED)) { 874 875 /* make sure it is marked as unmapped */ 876 state->ids[i]->status = ID_UNMAPPED; 877 ret = STATUS_SOME_UNMAPPED; 878 } else { 879 /* some fatal error occurred, return immediately */ 880 ret = ret2; 881 goto done; 882 } 883 } else { 884 /* all ok, id is mapped */ 885 state->ids[i]->status = ID_MAPPED; 886 } 887 } 888 889 if ((state->ids[i]->status == ID_UNMAPPED) && 890 state->allocate_unmapped) 891 { 892 ret = idmap_tdb_new_mapping(state->dom, state->ids[i]); 893 if (!NT_STATUS_IS_OK(ret)) { 894 goto done; 895 } 896 } 897 } 898 899 done: 900 return ret; 901 } 902 858 903 static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids) 859 904 { … … 861 906 NTSTATUS ret; 862 907 int i; 908 struct idmap_tdb_sids_to_unixids_context state; 863 909 864 910 /* initialize the status to avoid suprise */ … … 866 912 ids[i]->status = ID_UNKNOWN; 867 913 } 868 914 869 915 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); 870 916 871 for (i = 0; ids[i]; i++) { 872 ret = idmap_tdb_sid_to_id(ctx, ids[i]); 873 if ( ! NT_STATUS_IS_OK(ret)) { 874 875 /* if it is just a failed mapping continue */ 876 if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) { 877 878 /* make sure it is marked as unmapped */ 879 ids[i]->status = ID_UNMAPPED; 880 continue; 881 } 882 883 /* some fatal error occurred, return immediately */ 884 goto done; 885 } 886 887 /* all ok, id is mapped */ 888 ids[i]->status = ID_MAPPED; 889 } 890 891 ret = NT_STATUS_OK; 892 893 done: 894 return ret; 895 } 896 897 /********************************** 898 set a mapping. 899 **********************************/ 900 901 static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom, 902 const struct id_map *map) 903 { 904 struct idmap_tdb_context *ctx; 905 NTSTATUS ret; 906 TDB_DATA ksid, kid; 907 char *ksidstr, *kidstr; 908 fstring tmp; 909 910 if (!map || !map->sid) { 911 return NT_STATUS_INVALID_PARAMETER; 912 } 913 914 ksidstr = kidstr = NULL; 915 916 /* TODO: should we filter a set_mapping using low/high filters ? */ 917 918 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); 919 920 switch (map->xid.type) { 921 922 case ID_TYPE_UID: 923 kidstr = talloc_asprintf(ctx, "UID %lu", 924 (unsigned long)map->xid.id); 925 break; 926 927 case ID_TYPE_GID: 928 kidstr = talloc_asprintf(ctx, "GID %lu", 929 (unsigned long)map->xid.id); 930 break; 931 932 default: 933 DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type)); 934 return NT_STATUS_INVALID_PARAMETER; 935 } 936 937 if (kidstr == NULL) { 938 DEBUG(0, ("ERROR: Out of memory!\n")); 939 ret = NT_STATUS_NO_MEMORY; 940 goto done; 941 } 942 943 if ((ksidstr = talloc_asprintf( 944 ctx, "%s", sid_to_fstring(tmp, map->sid))) == NULL) { 945 DEBUG(0, ("Out of memory!\n")); 946 ret = NT_STATUS_NO_MEMORY; 947 goto done; 948 } 949 950 DEBUG(10, ("Storing %s <-> %s map\n", ksidstr, kidstr)); 951 kid = string_term_tdb_data(kidstr); 952 ksid = string_term_tdb_data(ksidstr); 953 954 if (ctx->db->transaction_start(ctx->db) != 0) { 955 DEBUG(0, ("Failed to start transaction for %s\n", 956 ksidstr)); 957 ret = NT_STATUS_INTERNAL_DB_ERROR; 958 goto done; 959 } 960 961 ret = dbwrap_store(ctx->db, ksid, kid, TDB_REPLACE); 962 if (!NT_STATUS_IS_OK(ret)) { 963 ctx->db->transaction_cancel(ctx->db); 964 DEBUG(0, ("Error storing SID -> ID (%s -> %s): %s\n", 965 ksidstr, kidstr, nt_errstr(ret))); 966 goto done; 967 } 968 ret = dbwrap_store(ctx->db, kid, ksid, TDB_REPLACE); 969 if (!NT_STATUS_IS_OK(ret)) { 970 ctx->db->transaction_cancel(ctx->db); 971 DEBUG(0, ("Error storing ID -> SID (%s -> %s): %s\n", 972 kidstr, ksidstr, nt_errstr(ret))); 973 goto done; 974 } 975 976 if (ctx->db->transaction_commit(ctx->db) != 0) { 977 DEBUG(0, ("Failed to commit transaction for (%s -> %s)\n", 978 ksidstr, kidstr)); 979 ret = NT_STATUS_INTERNAL_DB_ERROR; 980 goto done; 981 } 982 983 DEBUG(10,("Stored %s <-> %s\n", ksidstr, kidstr)); 984 ret = NT_STATUS_OK; 985 986 done: 987 talloc_free(ksidstr); 988 talloc_free(kidstr); 989 return ret; 990 } 991 992 /********************************** 993 remove a mapping. 994 **********************************/ 995 996 static NTSTATUS idmap_tdb_remove_mapping(struct idmap_domain *dom, 997 const struct id_map *map) 998 { 999 struct idmap_tdb_context *ctx; 1000 NTSTATUS ret; 1001 TDB_DATA ksid, kid, data; 1002 char *ksidstr, *kidstr; 1003 fstring tmp; 1004 1005 if (!map || !map->sid) { 1006 return NT_STATUS_INVALID_PARAMETER; 1007 } 1008 1009 ksidstr = kidstr = NULL; 1010 data.dptr = NULL; 1011 1012 /* TODO: should we filter a remove_mapping using low/high filters ? */ 1013 1014 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); 1015 1016 switch (map->xid.type) { 1017 1018 case ID_TYPE_UID: 1019 kidstr = talloc_asprintf(ctx, "UID %lu", 1020 (unsigned long)map->xid.id); 1021 break; 1022 1023 case ID_TYPE_GID: 1024 kidstr = talloc_asprintf(ctx, "GID %lu", 1025 (unsigned long)map->xid.id); 1026 break; 1027 1028 default: 1029 DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type)); 1030 return NT_STATUS_INVALID_PARAMETER; 1031 } 1032 1033 if (kidstr == NULL) { 1034 DEBUG(0, ("ERROR: Out of memory!\n")); 1035 ret = NT_STATUS_NO_MEMORY; 1036 goto done; 1037 } 1038 1039 if ((ksidstr = talloc_asprintf( 1040 ctx, "%s", sid_to_fstring(tmp, map->sid))) == NULL) { 1041 DEBUG(0, ("Out of memory!\n")); 1042 ret = NT_STATUS_NO_MEMORY; 1043 goto done; 1044 } 1045 1046 DEBUG(10, ("Checking %s <-> %s map\n", ksidstr, kidstr)); 1047 ksid = string_term_tdb_data(ksidstr); 1048 kid = string_term_tdb_data(kidstr); 1049 1050 if (ctx->db->transaction_start(ctx->db) != 0) { 1051 DEBUG(0, ("Failed to start transaction for %s\n", 1052 ksidstr)); 1053 return NT_STATUS_INTERNAL_DB_ERROR; 1054 } 1055 1056 /* Check if sid is present in database */ 1057 data = dbwrap_fetch(ctx->db, NULL, ksid); 1058 if (!data.dptr) { 1059 ctx->db->transaction_cancel(ctx->db); 1060 DEBUG(10,("Record %s not found\n", ksidstr)); 1061 ret = NT_STATUS_NONE_MAPPED; 1062 goto done; 1063 } 1064 1065 /* Check if sid is mapped to the specified ID */ 1066 if ((data.dsize != kid.dsize) || 1067 (memcmp(data.dptr, kid.dptr, data.dsize) != 0)) { 1068 ctx->db->transaction_cancel(ctx->db); 1069 DEBUG(10,("Specified SID does not map to specified ID\n")); 1070 DEBUGADD(10,("Actual mapping is %s -> %s\n", ksidstr, 1071 (const char *)data.dptr)); 1072 ret = NT_STATUS_NONE_MAPPED; 1073 goto done; 1074 } 1075 1076 DEBUG(10, ("Removing %s <-> %s map\n", ksidstr, kidstr)); 1077 1078 /* Delete previous mappings. */ 1079 1080 DEBUG(10, ("Deleting existing mapping %s -> %s\n", ksidstr, kidstr )); 1081 ret = dbwrap_delete(ctx->db, ksid); 1082 if (!NT_STATUS_IS_OK(ret)) { 1083 DEBUG(0,("Warning: Failed to delete %s: %s\n", 1084 ksidstr, nt_errstr(ret))); 1085 } 1086 1087 DEBUG(10,("Deleting existing mapping %s -> %s\n", kidstr, ksidstr )); 1088 ret = dbwrap_delete(ctx->db, kid); 1089 if (!NT_STATUS_IS_OK(ret)) { 1090 DEBUG(0,("Warning: Failed to delete %s: %s\n", 1091 kidstr, nt_errstr(ret))); 1092 } 1093 1094 if (ctx->db->transaction_commit(ctx->db) != 0) { 1095 DEBUG(0, ("Failed to commit transaction for (%s -> %s)\n", 1096 ksidstr, kidstr)); 1097 ret = NT_STATUS_INTERNAL_DB_ERROR; 1098 goto done; 1099 } 1100 1101 ret = NT_STATUS_OK; 1102 1103 done: 1104 talloc_free(ksidstr); 1105 talloc_free(kidstr); 1106 talloc_free(data.dptr); 1107 return ret; 1108 } 917 state.dom = dom; 918 state.ids = ids; 919 state.allocate_unmapped = false; 920 921 ret = idmap_tdb_sids_to_unixids_action(ctx->db, &state); 922 923 if (NT_STATUS_EQUAL(ret, STATUS_SOME_UNMAPPED) && !dom->read_only) { 924 state.allocate_unmapped = true; 925 ret = dbwrap_trans_do(ctx->db, 926 idmap_tdb_sids_to_unixids_action, 927 &state); 928 } 929 930 return ret; 931 } 932 1109 933 1110 934 /********************************** … … 1112 936 **********************************/ 1113 937 1114 static NTSTATUS idmap_tdb_close(struct idmap_domain *dom)1115 {1116 struct idmap_tdb_context *ctx;1117 1118 if (dom->private_data) {1119 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);1120 1121 TALLOC_FREE(ctx->db);1122 }1123 return NT_STATUS_OK;1124 }1125 1126 struct dump_data {1127 TALLOC_CTX *memctx;1128 struct id_map **maps;1129 int *num_maps;1130 NTSTATUS ret;1131 };1132 1133 static int idmap_tdb_dump_one_entry(struct db_record *rec, void *pdata)1134 {1135 struct dump_data *data = talloc_get_type(pdata, struct dump_data);1136 struct id_map *maps;1137 int num_maps = *data->num_maps;1138 1139 /* ignore any record but the ones with a SID as key */1140 if (strncmp((const char *)rec->key.dptr, "S-", 2) == 0) {1141 1142 maps = talloc_realloc(NULL, *data->maps, struct id_map, num_maps+1);1143 if ( ! maps) {1144 DEBUG(0, ("Out of memory!\n"));1145 data->ret = NT_STATUS_NO_MEMORY;1146 return -1;1147 }1148 *data->maps = maps;1149 maps[num_maps].sid = talloc(maps, DOM_SID);1150 if ( ! maps[num_maps].sid) {1151 DEBUG(0, ("Out of memory!\n"));1152 data->ret = NT_STATUS_NO_MEMORY;1153 return -1;1154 }1155 1156 if (!string_to_sid(maps[num_maps].sid, (const char *)rec->key.dptr)) {1157 DEBUG(10,("INVALID record %s\n", (const char *)rec->key.dptr));1158 /* continue even with errors */1159 return 0;1160 }1161 1162 /* Try a UID record. */1163 if (sscanf((const char *)rec->value.dptr, "UID %u", &(maps[num_maps].xid.id)) == 1) {1164 maps[num_maps].xid.type = ID_TYPE_UID;1165 maps[num_maps].status = ID_MAPPED;1166 *data->num_maps = num_maps + 1;1167 1168 /* Try a GID record. */1169 } else1170 if (sscanf((const char *)rec->value.dptr, "GID %u", &(maps[num_maps].xid.id)) == 1) {1171 maps[num_maps].xid.type = ID_TYPE_GID;1172 maps[num_maps].status = ID_MAPPED;1173 *data->num_maps = num_maps + 1;1174 1175 /* Unknown record type ! */1176 } else {1177 maps[num_maps].status = ID_UNKNOWN;1178 DEBUG(2, ("Found INVALID record %s -> %s\n",1179 (const char *)rec->key.dptr,1180 (const char *)rec->value.dptr));1181 /* do not increment num_maps */1182 }1183 }1184 1185 return 0;1186 }1187 1188 /**********************************1189 Dump all mappings out1190 **********************************/1191 1192 static NTSTATUS idmap_tdb_dump_data(struct idmap_domain *dom, struct id_map **maps, int *num_maps)1193 {1194 struct idmap_tdb_context *ctx;1195 struct dump_data *data;1196 NTSTATUS ret = NT_STATUS_OK;1197 1198 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);1199 1200 data = TALLOC_ZERO_P(ctx, struct dump_data);1201 if ( ! data) {1202 DEBUG(0, ("Out of memory!\n"));1203 return NT_STATUS_NO_MEMORY;1204 }1205 data->maps = maps;1206 data->num_maps = num_maps;1207 data->ret = NT_STATUS_OK;1208 1209 ctx->db->traverse_read(ctx->db, idmap_tdb_dump_one_entry, data);1210 1211 if ( ! NT_STATUS_IS_OK(data->ret)) {1212 ret = data->ret;1213 }1214 1215 talloc_free(data);1216 return ret;1217 }1218 1219 938 static struct idmap_methods db_methods = { 1220 1221 939 .init = idmap_tdb_db_init, 1222 940 .unixids_to_sids = idmap_tdb_unixids_to_sids, 1223 941 .sids_to_unixids = idmap_tdb_sids_to_unixids, 1224 .set_mapping = idmap_tdb_set_mapping, 1225 .remove_mapping = idmap_tdb_remove_mapping, 1226 .dump_data = idmap_tdb_dump_data, 1227 .close_fn = idmap_tdb_close 942 .allocate_id = idmap_tdb_get_new_id, 1228 943 }; 1229 944 1230 static struct idmap_alloc_methods db_alloc_methods = {1231 1232 .init = idmap_tdb_alloc_init,1233 .allocate_id = idmap_tdb_allocate_id,1234 .get_id_hwm = idmap_tdb_get_hwm,1235 .set_id_hwm = idmap_tdb_set_hwm,1236 .close_fn = idmap_tdb_alloc_close1237 };1238 1239 NTSTATUS idmap_alloc_tdb_init(void)1240 {1241 return smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "tdb", &db_alloc_methods);1242 }1243 1244 945 NTSTATUS idmap_tdb_init(void) 1245 946 { 1246 NTSTATUS ret;1247 1248 947 DEBUG(10, ("calling idmap_tdb_init\n")); 1249 948 1250 /* FIXME: bad hack to actually register also the alloc_tdb module without changining configure.in */1251 ret = idmap_alloc_tdb_init();1252 if (! NT_STATUS_IS_OK(ret)) {1253 return ret;1254 }1255 949 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "tdb", &db_methods); 1256 950 } -
vendor/current/source3/winbindd/idmap_tdb2.c
r414 r740 15 15 Copyright (C) Jeremy Allison 2006 16 16 Copyright (C) Simo Sorce 2003-2006 17 17 Copyright (C) Michael Adam 2009-2010 18 18 19 This program is free software; you can redistribute it and/or modify 19 20 it under the terms of the GNU General Public License as published by 20 21 the Free Software Foundation; either version 2 of the License, or 21 22 (at your option) any later version. 22 23 23 24 This program is distributed in the hope that it will be useful, 24 25 but WITHOUT ANY WARRANTY; without even the implied warranty of 25 26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 26 27 GNU General Public License for more details. 27 28 28 29 You should have received a copy of the GNU General Public License 29 30 along with this program; if not, write to the Free Software … … 32 33 33 34 #include "includes.h" 35 #include "system/filesys.h" 34 36 #include "winbindd.h" 37 #include "idmap.h" 38 #include "idmap_rw.h" 39 #include "dbwrap.h" 40 #include "../libcli/security/dom_sid.h" 41 #include "util_tdb.h" 35 42 36 43 #undef DBGC_CLASS 37 44 #define DBGC_CLASS DBGC_IDMAP 45 46 struct idmap_tdb2_context { 47 struct db_context *db; 48 const char *script; /* script to provide idmaps */ 49 struct idmap_rw_ops *rw_ops; 50 }; 38 51 39 52 /* High water mark keys */ … … 41 54 #define HWM_USER "USER HWM" 42 55 43 static struct idmap_tdb2_state { 44 /* User and group id pool */ 45 uid_t low_uid, high_uid; /* Range of uids to allocate */ 46 gid_t low_gid, high_gid; /* Range of gids to allocate */ 47 const char *idmap_script; 48 } idmap_tdb2_state; 49 50 51 52 /* handle to the permanent tdb */ 53 static struct db_context *idmap_tdb2; 54 55 static NTSTATUS idmap_tdb2_alloc_load(void); 56 57 static NTSTATUS idmap_tdb2_load_ranges(void) 58 { 59 uid_t low_uid = 0; 60 uid_t high_uid = 0; 61 gid_t low_gid = 0; 62 gid_t high_gid = 0; 63 64 if (!lp_idmap_uid(&low_uid, &high_uid)) { 65 DEBUG(1, ("idmap uid missing\n")); 66 return NT_STATUS_UNSUCCESSFUL; 67 } 68 69 if (!lp_idmap_gid(&low_gid, &high_gid)) { 70 DEBUG(1, ("idmap gid missing\n")); 71 return NT_STATUS_UNSUCCESSFUL; 72 } 73 74 idmap_tdb2_state.low_uid = low_uid; 75 idmap_tdb2_state.high_uid = high_uid; 76 idmap_tdb2_state.low_gid = low_gid; 77 idmap_tdb2_state.high_gid = high_gid; 78 79 if (idmap_tdb2_state.high_uid <= idmap_tdb2_state.low_uid) { 80 DEBUG(1, ("idmap uid range missing or invalid\n")); 81 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n")); 82 return NT_STATUS_UNSUCCESSFUL; 83 } 84 85 if (idmap_tdb2_state.high_gid <= idmap_tdb2_state.low_gid) { 86 DEBUG(1, ("idmap gid range missing or invalid\n")); 87 DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n")); 88 return NT_STATUS_UNSUCCESSFUL; 56 57 /* 58 * check and initialize high/low water marks in the db 59 */ 60 static NTSTATUS idmap_tdb2_init_hwm(struct idmap_domain *dom) 61 { 62 NTSTATUS status; 63 uint32 low_id; 64 struct idmap_tdb2_context *ctx; 65 66 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 67 68 /* Create high water marks for group and user id */ 69 70 low_id = dbwrap_fetch_int32(ctx->db, HWM_USER); 71 if ((low_id == -1) || (low_id < dom->low_id)) { 72 status = dbwrap_trans_store_int32(ctx->db, HWM_USER, 73 dom->low_id); 74 if (!NT_STATUS_IS_OK(status)) { 75 DEBUG(0, ("Unable to initialise user hwm in idmap " 76 "database: %s\n", nt_errstr(status))); 77 return NT_STATUS_INTERNAL_DB_ERROR; 78 } 79 } 80 81 low_id = dbwrap_fetch_int32(ctx->db, HWM_GROUP); 82 if ((low_id == -1) || (low_id < dom->low_id)) { 83 status = dbwrap_trans_store_int32(ctx->db, HWM_GROUP, 84 dom->low_id); 85 if (!NT_STATUS_IS_OK(status)) { 86 DEBUG(0, ("Unable to initialise group hwm in idmap " 87 "database: %s\n", nt_errstr(status))); 88 return NT_STATUS_INTERNAL_DB_ERROR; 89 } 89 90 } 90 91 91 92 return NT_STATUS_OK; 92 93 } 94 93 95 94 96 /* 95 97 open the permanent tdb 96 98 */ 97 static NTSTATUS idmap_tdb2_open_db( void)99 static NTSTATUS idmap_tdb2_open_db(struct idmap_domain *dom) 98 100 { 99 101 char *db_path; 100 101 if (idmap_tdb2) { 102 struct idmap_tdb2_context *ctx; 103 104 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 105 106 if (ctx->db) { 102 107 /* its already open */ 103 108 return NT_STATUS_OK; 104 109 } 105 110 106 db_path = lp_parm_talloc_string(-1, "tdb", "idmap2.tdb", NULL); 107 if (db_path == NULL) { 108 /* fall back to the private directory, which, despite 109 its name, is usually on shared storage */ 110 db_path = talloc_asprintf(NULL, "%s/idmap2.tdb", lp_private_dir()); 111 } 111 db_path = talloc_asprintf(NULL, "%s/idmap2.tdb", lp_private_dir()); 112 112 NT_STATUS_HAVE_NO_MEMORY(db_path); 113 113 114 114 /* Open idmap repository */ 115 idmap_tdb2 = db_open(NULL, db_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644);115 ctx->db = db_open(ctx, db_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644); 116 116 TALLOC_FREE(db_path); 117 117 118 if ( idmap_tdb2== NULL) {118 if (ctx->db == NULL) { 119 119 DEBUG(0, ("Unable to open idmap_tdb2 database '%s'\n", 120 120 db_path)); … … 122 122 } 123 123 124 /* load the ranges and high/low water marks */ 125 return idmap_tdb2_alloc_load(); 126 } 127 128 129 /* 130 load the idmap allocation ranges and high/low water marks 131 */ 132 static NTSTATUS idmap_tdb2_alloc_load(void) 133 { 134 NTSTATUS status; 135 uint32 low_id; 136 137 /* see if a idmap script is configured */ 138 idmap_tdb2_state.idmap_script = lp_parm_const_string(-1, "idmap", 139 "script", NULL); 140 141 if (idmap_tdb2_state.idmap_script) { 142 DEBUG(1, ("using idmap script '%s'\n", 143 idmap_tdb2_state.idmap_script)); 144 } 145 146 /* load ranges */ 147 148 status = idmap_tdb2_load_ranges(); 149 if (!NT_STATUS_IS_OK(status)) { 150 return status; 151 } 152 153 /* Create high water marks for group and user id */ 154 155 low_id = dbwrap_fetch_int32(idmap_tdb2, HWM_USER); 156 if ((low_id == -1) || (low_id < idmap_tdb2_state.low_uid)) { 157 if (!NT_STATUS_IS_OK(dbwrap_trans_store_int32( 158 idmap_tdb2, HWM_USER, 159 idmap_tdb2_state.low_uid))) { 160 DEBUG(0, ("Unable to initialise user hwm in idmap " 161 "database\n")); 162 return NT_STATUS_INTERNAL_DB_ERROR; 163 } 164 } 165 166 low_id = dbwrap_fetch_int32(idmap_tdb2, HWM_GROUP); 167 if ((low_id == -1) || (low_id < idmap_tdb2_state.low_gid)) { 168 if (!NT_STATUS_IS_OK(dbwrap_trans_store_int32( 169 idmap_tdb2, HWM_GROUP, 170 idmap_tdb2_state.low_gid))) { 171 DEBUG(0, ("Unable to initialise group hwm in idmap " 172 "database\n")); 173 return NT_STATUS_INTERNAL_DB_ERROR; 174 } 175 } 176 177 return NT_STATUS_OK; 178 } 179 180 181 /* 182 Initialise idmap alloc database. 183 */ 184 static NTSTATUS idmap_tdb2_alloc_init(const char *params) 185 { 186 /* nothing to do - we want to avoid opening the permanent 187 database if possible. Instead we load the params when we 188 first need it. */ 189 return NT_STATUS_OK; 124 return idmap_tdb2_init_hwm(dom); 190 125 } 191 126 … … 248 183 } 249 184 250 static NTSTATUS idmap_tdb2_allocate_id(struct unixid *xid) 185 static NTSTATUS idmap_tdb2_allocate_id(struct idmap_domain *dom, 186 struct unixid *xid) 251 187 { 252 188 const char *hwmkey; … … 256 192 NTSTATUS status; 257 193 struct idmap_tdb2_allocate_id_context state; 258 259 status = idmap_tdb2_open_db(); 194 struct idmap_tdb2_context *ctx; 195 196 status = idmap_tdb2_open_db(dom); 260 197 NT_STATUS_NOT_OK_RETURN(status); 198 199 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 261 200 262 201 /* Get current high water mark */ … … 266 205 hwmkey = HWM_USER; 267 206 hwmtype = "UID"; 268 high_hwm = idmap_tdb2_state.high_uid;269 207 break; 270 208 … … 272 210 hwmkey = HWM_GROUP; 273 211 hwmtype = "GID"; 274 high_hwm = idmap_tdb2_state.high_gid;275 212 break; 276 213 … … 279 216 return NT_STATUS_INVALID_PARAMETER; 280 217 } 218 219 high_hwm = dom->high_id; 281 220 282 221 state.hwm = hwm; … … 285 224 state.hwmkey = hwmkey; 286 225 287 status = dbwrap_trans_do( idmap_tdb2, idmap_tdb2_allocate_id_action,226 status = dbwrap_trans_do(ctx->db, idmap_tdb2_allocate_id_action, 288 227 &state); 289 228 290 229 if (NT_STATUS_IS_OK(status)) { 291 230 xid->id = state.hwm; 292 DEBUG(10,("New %s = %d\n", hwmtype, hwm));231 DEBUG(10,("New %s = %d\n", hwmtype, state.hwm)); 293 232 } else { 294 233 DEBUG(1, ("Error allocating a new %s\n", hwmtype)); … … 298 237 } 299 238 300 /* 301 Get current highest id. 302 */ 303 static NTSTATUS idmap_tdb2_get_hwm(struct unixid *xid) 304 { 305 const char *hwmkey; 306 const char *hwmtype; 307 uint32_t hwm; 308 uint32_t high_hwm; 309 NTSTATUS status; 310 311 status = idmap_tdb2_open_db(); 312 NT_STATUS_NOT_OK_RETURN(status); 313 314 /* Get current high water mark */ 315 switch (xid->type) { 316 317 case ID_TYPE_UID: 318 hwmkey = HWM_USER; 319 hwmtype = "UID"; 320 high_hwm = idmap_tdb2_state.high_uid; 321 break; 322 323 case ID_TYPE_GID: 324 hwmkey = HWM_GROUP; 325 hwmtype = "GID"; 326 high_hwm = idmap_tdb2_state.high_gid; 327 break; 328 329 default: 330 return NT_STATUS_INVALID_PARAMETER; 331 } 332 333 if ((hwm = dbwrap_fetch_int32(idmap_tdb2, hwmkey)) == -1) { 334 return NT_STATUS_INTERNAL_DB_ERROR; 335 } 336 337 xid->id = hwm; 338 339 /* Warn if it is out of range */ 340 if (hwm >= high_hwm) { 341 DEBUG(0, ("Warning: %s range full!! (max: %lu)\n", 342 hwmtype, (unsigned long)high_hwm)); 343 } 344 345 return NT_STATUS_OK; 346 } 347 348 /* 349 Set high id. 350 */ 351 static NTSTATUS idmap_tdb2_set_hwm(struct unixid *xid) 352 { 353 /* not supported, or we would invalidate the cache tdb on 354 other nodes */ 355 DEBUG(0,("idmap_tdb2_set_hwm not supported\n")); 356 return NT_STATUS_NOT_SUPPORTED; 357 } 358 359 /* 360 Close the alloc tdb 361 */ 362 static NTSTATUS idmap_tdb2_alloc_close(void) 363 { 364 /* don't actually close it */ 365 return NT_STATUS_OK; 239 /** 240 * Allocate a new unix-ID. 241 * For now this is for the default idmap domain only. 242 * Should be extended later on. 243 */ 244 static NTSTATUS idmap_tdb2_get_new_id(struct idmap_domain *dom, 245 struct unixid *id) 246 { 247 NTSTATUS ret; 248 249 if (!strequal(dom->name, "*")) { 250 DEBUG(3, ("idmap_tdb2_get_new_id: " 251 "Refusing creation of mapping for domain'%s'. " 252 "Currently only supported for the default " 253 "domain \"*\".\n", 254 dom->name)); 255 return NT_STATUS_NOT_IMPLEMENTED; 256 } 257 258 ret = idmap_tdb2_allocate_id(dom, id); 259 260 return ret; 366 261 } 367 262 … … 369 264 IDMAP MAPPING TDB BACKEND 370 265 */ 371 struct idmap_tdb2_context { 372 uint32_t filter_low_id; 373 uint32_t filter_high_id; 374 }; 266 267 static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom, 268 const struct id_map *map); 375 269 376 270 /* 377 271 Initialise idmap database. 378 272 */ 379 static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom, 380 const char *params) 273 static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom) 381 274 { 382 275 NTSTATUS ret; 383 276 struct idmap_tdb2_context *ctx; 384 NTSTATUS status; 385 386 status = idmap_tdb2_open_db(); 387 NT_STATUS_NOT_OK_RETURN(status); 388 389 ctx = talloc(dom, struct idmap_tdb2_context); 277 char *config_option = NULL; 278 const char * idmap_script = NULL; 279 280 ctx = talloc_zero(dom, struct idmap_tdb2_context); 390 281 if ( ! ctx) { 391 282 DEBUG(0, ("Out of memory!\n")); … … 393 284 } 394 285 395 if (strequal(dom->name, "*")) { 396 uid_t low_uid = 0; 397 uid_t high_uid = 0; 398 gid_t low_gid = 0; 399 gid_t high_gid = 0; 400 401 ctx->filter_low_id = 0; 402 ctx->filter_high_id = 0; 403 404 if (lp_idmap_uid(&low_uid, &high_uid)) { 405 ctx->filter_low_id = low_uid; 406 ctx->filter_high_id = high_uid; 407 } else { 408 DEBUG(3, ("Warning: 'idmap uid' not set!\n")); 409 } 410 411 if (lp_idmap_gid(&low_gid, &high_gid)) { 412 if ((low_gid != low_uid) || (high_gid != high_uid)) { 413 DEBUG(1, ("Warning: 'idmap uid' and 'idmap gid'" 414 " ranges do not agree -- building " 415 "intersection\n")); 416 ctx->filter_low_id = MAX(ctx->filter_low_id, 417 low_gid); 418 ctx->filter_high_id = MIN(ctx->filter_high_id, 419 high_gid); 420 } 421 } else { 422 DEBUG(3, ("Warning: 'idmap gid' not set!\n")); 423 } 424 } else { 425 char *config_option = NULL; 426 const char *range; 427 config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); 428 if ( ! config_option) { 429 DEBUG(0, ("Out of memory!\n")); 430 ret = NT_STATUS_NO_MEMORY; 431 goto failed; 432 } 433 434 range = lp_parm_const_string(-1, config_option, "range", NULL); 435 if (( ! range) || 436 (sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2)) 437 { 438 ctx->filter_low_id = 0; 439 ctx->filter_high_id = 0; 440 } 441 442 talloc_free(config_option); 443 } 444 445 if (ctx->filter_low_id > ctx->filter_high_id) { 446 ctx->filter_low_id = 0; 447 ctx->filter_high_id = 0; 448 } 286 config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); 287 if (config_option == NULL) { 288 DEBUG(0, ("Out of memory!\n")); 289 ret = NT_STATUS_NO_MEMORY; 290 goto failed; 291 } 292 ctx->script = lp_parm_const_string(-1, config_option, "script", "NULL"); 293 talloc_free(config_option); 294 295 idmap_script = lp_parm_const_string(-1, "idmap", "script", NULL); 296 if (idmap_script != NULL) { 297 DEBUG(0, ("Warning: 'idmap:script' is deprecated. " 298 " Please use 'idmap config * : script' instead!\n")); 299 } 300 301 if (strequal(dom->name, "*") && ctx->script == NULL) { 302 /* fall back to idmap:script for backwards compatibility */ 303 ctx->script = idmap_script; 304 } 305 306 if (ctx->script) { 307 DEBUG(1, ("using idmap script '%s'\n", ctx->script)); 308 } 309 310 ctx->rw_ops = talloc_zero(ctx, struct idmap_rw_ops); 311 if (ctx->rw_ops == NULL) { 312 DEBUG(0, ("Out of memory!\n")); 313 ret = NT_STATUS_NO_MEMORY; 314 goto failed; 315 } 316 317 ctx->rw_ops->get_new_id = idmap_tdb2_get_new_id; 318 ctx->rw_ops->set_mapping = idmap_tdb2_set_mapping; 449 319 450 320 dom->private_data = ctx; 321 322 ret = idmap_tdb2_open_db(dom); 323 if (!NT_STATUS_IS_OK(ret)) { 324 goto failed; 325 } 451 326 452 327 return NT_STATUS_OK; … … 456 331 return ret; 457 332 } 333 334 335 /** 336 * store a mapping in the database. 337 */ 458 338 459 339 struct idmap_tdb2_set_mapping_context { … … 503 383 done: 504 384 talloc_free(tmp_ctx); 385 return ret; 386 } 387 388 static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom, const struct id_map *map) 389 { 390 struct idmap_tdb2_context *ctx; 391 NTSTATUS ret; 392 char *ksidstr, *kidstr; 393 struct idmap_tdb2_set_mapping_context state; 394 395 if (!map || !map->sid) { 396 return NT_STATUS_INVALID_PARAMETER; 397 } 398 399 ksidstr = kidstr = NULL; 400 401 /* TODO: should we filter a set_mapping using low/high filters ? */ 402 403 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 404 405 switch (map->xid.type) { 406 407 case ID_TYPE_UID: 408 kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id); 409 break; 410 411 case ID_TYPE_GID: 412 kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id); 413 break; 414 415 default: 416 DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type)); 417 return NT_STATUS_INVALID_PARAMETER; 418 } 419 420 if (kidstr == NULL) { 421 DEBUG(0, ("ERROR: Out of memory!\n")); 422 ret = NT_STATUS_NO_MEMORY; 423 goto done; 424 } 425 426 ksidstr = sid_string_talloc(ctx, map->sid); 427 if (ksidstr == NULL) { 428 DEBUG(0, ("Out of memory!\n")); 429 ret = NT_STATUS_NO_MEMORY; 430 goto done; 431 } 432 433 state.ksidstr = ksidstr; 434 state.kidstr = kidstr; 435 436 ret = dbwrap_trans_do(ctx->db, idmap_tdb2_set_mapping_action, 437 &state); 438 439 done: 440 talloc_free(ksidstr); 441 talloc_free(kidstr); 442 return ret; 443 } 444 445 /** 446 * Create a new mapping for an unmapped SID, also allocating a new ID. 447 * This should be run inside a transaction. 448 * 449 * TODO: 450 * Properly integrate this with multi domain idmap config: 451 * Currently, the allocator is default-config only. 452 */ 453 static NTSTATUS idmap_tdb2_new_mapping(struct idmap_domain *dom, struct id_map *map) 454 { 455 NTSTATUS ret; 456 struct idmap_tdb2_context *ctx; 457 458 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 459 460 ret = idmap_rw_new_mapping(dom, ctx->rw_ops, map); 461 505 462 return ret; 506 463 } … … 531 488 unsigned long v; 532 489 533 cmd = talloc_asprintf(ctx, "%s ", idmap_tdb2_state.idmap_script);490 cmd = talloc_asprintf(ctx, "%s ", ctx->script); 534 491 NT_STATUS_HAVE_NO_MEMORY(cmd); 535 492 … … 562 519 if (!string_to_sid(map->sid, &line[4])) { 563 520 DEBUG(0,("Bad SID in '%s' from idmap script %s\n", 564 line, idmap_tdb2_state.idmap_script));521 line, ctx->script)); 565 522 return NT_STATUS_NONE_MAPPED; 566 523 } 567 524 } else { 568 525 DEBUG(0,("Bad reply '%s' from idmap script %s\n", 569 line, idmap_tdb2_state.idmap_script));526 line, ctx->script)); 570 527 return NT_STATUS_NONE_MAPPED; 571 528 } … … 579 536 Single id to sid lookup function. 580 537 */ 581 static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_ tdb2_context *ctx, struct id_map *map)538 static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_domain *dom, struct id_map *map) 582 539 { 583 540 NTSTATUS ret; … … 585 542 char *keystr; 586 543 NTSTATUS status; 587 588 status = idmap_tdb2_open_db(); 544 struct idmap_tdb2_context *ctx; 545 546 547 if (!dom || !map) { 548 return NT_STATUS_INVALID_PARAMETER; 549 } 550 551 status = idmap_tdb2_open_db(dom); 589 552 NT_STATUS_NOT_OK_RETURN(status); 590 553 591 if (!ctx || !map) { 592 return NT_STATUS_INVALID_PARAMETER; 593 } 554 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 594 555 595 556 /* apply filters before checking */ 596 if ((ctx->filter_low_id && (map->xid.id < ctx->filter_low_id)) || 597 (ctx->filter_high_id && (map->xid.id > ctx->filter_high_id))) { 557 if (!idmap_unix_id_is_in_range(map->xid.id, dom)) { 598 558 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n", 599 map->xid.id, ctx->filter_low_id, ctx->filter_high_id));559 map->xid.id, dom->low_id, dom->high_id)); 600 560 return NT_STATUS_NONE_MAPPED; 601 561 } … … 606 566 keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id); 607 567 break; 608 568 609 569 case ID_TYPE_GID: 610 570 keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id); … … 616 576 } 617 577 618 /* final SAFE_FREE safe */619 data.dptr = NULL;620 621 578 if (keystr == NULL) { 622 579 DEBUG(0, ("Out of memory!\n")); … … 628 585 629 586 /* Check if the mapping exists */ 630 data = dbwrap_fetch_bystring( idmap_tdb2, keystr, keystr);587 data = dbwrap_fetch_bystring(ctx->db, keystr, keystr); 631 588 632 589 if (!data.dptr) { … … 635 592 636 593 DEBUG(10,("Record %s not found\n", keystr)); 637 if ( idmap_tdb2_state.idmap_script == NULL) {594 if (ctx->script == NULL) { 638 595 ret = NT_STATUS_NONE_MAPPED; 639 596 goto done; … … 641 598 642 599 ret = idmap_tdb2_script(ctx, map, "IDTOSID %s", keystr); 643 644 /* store it on shared storage */645 600 if (!NT_STATUS_IS_OK(ret)) { 646 601 goto done; … … 656 611 store_state.kidstr = keystr; 657 612 658 ret = dbwrap_trans_do( idmap_tdb2, idmap_tdb2_set_mapping_action,613 ret = dbwrap_trans_do(ctx->db, idmap_tdb2_set_mapping_action, 659 614 &store_state); 660 615 goto done; 661 616 } 662 617 663 618 if (!string_to_sid(map->sid, (const char *)data.dptr)) { 664 619 DEBUG(10,("INVALID SID (%s) in record %s\n", … … 680 635 Single sid to id lookup function. 681 636 */ 682 static NTSTATUS idmap_tdb2_sid_to_id(struct idmap_ tdb2_context *ctx, struct id_map *map)637 static NTSTATUS idmap_tdb2_sid_to_id(struct idmap_domain *dom, struct id_map *map) 683 638 { 684 639 NTSTATUS ret; … … 686 641 char *keystr; 687 642 unsigned long rec_id = 0; 643 struct idmap_tdb2_context *ctx; 688 644 TALLOC_CTX *tmp_ctx = talloc_stackframe(); 689 645 690 ret = idmap_tdb2_open_db( );646 ret = idmap_tdb2_open_db(dom); 691 647 NT_STATUS_NOT_OK_RETURN(ret); 648 649 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 692 650 693 651 keystr = sid_string_talloc(tmp_ctx, map->sid); … … 701 659 702 660 /* Check if sid is present in database */ 703 data = dbwrap_fetch_bystring( idmap_tdb2, tmp_ctx, keystr);661 data = dbwrap_fetch_bystring(ctx->db, tmp_ctx, keystr); 704 662 if (!data.dptr) { 705 663 char *idstr; … … 708 666 DEBUG(10,(__location__ " Record %s not found\n", keystr)); 709 667 710 if ( idmap_tdb2_state.idmap_script == NULL) {668 if (ctx->script == NULL) { 711 669 ret = NT_STATUS_NONE_MAPPED; 712 670 goto done; 713 671 } 714 672 715 673 ret = idmap_tdb2_script(ctx, map, "SIDTOID %s", keystr); 716 /* store it on shared storage */717 674 if (!NT_STATUS_IS_OK(ret)) { 675 goto done; 676 } 677 678 /* apply filters before returning result */ 679 if (!idmap_unix_id_is_in_range(map->xid.id, dom)) { 680 DEBUG(5, ("Script returned id (%u) out of range " 681 "(%u - %u). Filtered!\n", 682 map->xid.id, dom->low_id, dom->high_id)); 683 ret = NT_STATUS_NONE_MAPPED; 718 684 goto done; 719 685 } … … 730 696 store_state.kidstr = idstr; 731 697 732 ret = dbwrap_trans_do( idmap_tdb2, idmap_tdb2_set_mapping_action,698 ret = dbwrap_trans_do(ctx->db, idmap_tdb2_set_mapping_action, 733 699 &store_state); 734 700 goto done; … … 751 717 DEBUG(2, ("Found INVALID record %s -> %s\n", keystr, (const char *)data.dptr)); 752 718 ret = NT_STATUS_INTERNAL_DB_ERROR; 753 } 754 719 goto done; 720 } 721 755 722 /* apply filters before returning result */ 756 if ((ctx->filter_low_id && (map->xid.id < ctx->filter_low_id)) || 757 (ctx->filter_high_id && (map->xid.id > ctx->filter_high_id))) { 723 if (!idmap_unix_id_is_in_range(map->xid.id, dom)) { 758 724 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n", 759 map->xid.id, ctx->filter_low_id, ctx->filter_high_id));725 map->xid.id, dom->low_id, dom->high_id)); 760 726 ret = NT_STATUS_NONE_MAPPED; 761 727 } … … 771 737 static NTSTATUS idmap_tdb2_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids) 772 738 { 773 struct idmap_tdb2_context *ctx;774 739 NTSTATUS ret; 775 740 int i; … … 779 744 ids[i]->status = ID_UNKNOWN; 780 745 } 781 782 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);783 746 784 747 for (i = 0; ids[i]; i++) { 785 ret = idmap_tdb2_id_to_sid( ctx, ids[i]);748 ret = idmap_tdb2_id_to_sid(dom, ids[i]); 786 749 if ( ! NT_STATUS_IS_OK(ret)) { 787 750 … … 793 756 continue; 794 757 } 795 758 796 759 /* some fatal error occurred, return immediately */ 797 760 goto done; … … 811 774 lookup a set of sids. 812 775 */ 776 777 struct idmap_tdb2_sids_to_unixids_context { 778 struct idmap_domain *dom; 779 struct id_map **ids; 780 bool allocate_unmapped; 781 }; 782 783 static NTSTATUS idmap_tdb2_sids_to_unixids_action(struct db_context *db, 784 void *private_data) 785 { 786 struct idmap_tdb2_sids_to_unixids_context *state; 787 int i; 788 NTSTATUS ret = NT_STATUS_OK; 789 790 state = (struct idmap_tdb2_sids_to_unixids_context *)private_data; 791 792 DEBUG(10, ("idmap_tdb2_sids_to_unixids_action: " 793 " domain: [%s], allocate: %s\n", 794 state->dom->name, 795 state->allocate_unmapped ? "yes" : "no")); 796 797 for (i = 0; state->ids[i]; i++) { 798 if ((state->ids[i]->status == ID_UNKNOWN) || 799 /* retry if we could not map in previous run: */ 800 (state->ids[i]->status == ID_UNMAPPED)) 801 { 802 NTSTATUS ret2; 803 804 ret2 = idmap_tdb2_sid_to_id(state->dom, state->ids[i]); 805 if (!NT_STATUS_IS_OK(ret2)) { 806 807 /* if it is just a failed mapping, continue */ 808 if (NT_STATUS_EQUAL(ret2, NT_STATUS_NONE_MAPPED)) { 809 810 /* make sure it is marked as unmapped */ 811 state->ids[i]->status = ID_UNMAPPED; 812 ret = STATUS_SOME_UNMAPPED; 813 } else { 814 /* some fatal error occurred, return immediately */ 815 ret = ret2; 816 goto done; 817 } 818 } else { 819 /* all ok, id is mapped */ 820 state->ids[i]->status = ID_MAPPED; 821 } 822 } 823 824 if ((state->ids[i]->status == ID_UNMAPPED) && 825 state->allocate_unmapped) 826 { 827 ret = idmap_tdb2_new_mapping(state->dom, state->ids[i]); 828 if (!NT_STATUS_IS_OK(ret)) { 829 goto done; 830 } 831 } 832 } 833 834 done: 835 return ret; 836 } 837 813 838 static NTSTATUS idmap_tdb2_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids) 814 839 { 840 NTSTATUS ret; 841 int i; 842 struct idmap_tdb2_sids_to_unixids_context state; 815 843 struct idmap_tdb2_context *ctx; 816 NTSTATUS ret; 817 int i;844 845 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 818 846 819 847 /* initialize the status to avoid suprise */ … … 821 849 ids[i]->status = ID_UNKNOWN; 822 850 } 823 824 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 825 826 for (i = 0; ids[i]; i++) { 827 ret = idmap_tdb2_sid_to_id(ctx, ids[i]); 828 if ( ! NT_STATUS_IS_OK(ret)) { 829 830 /* if it is just a failed mapping continue */ 831 if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) { 832 833 /* make sure it is marked as unmapped */ 834 ids[i]->status = ID_UNMAPPED; 835 continue; 836 } 837 838 /* some fatal error occurred, return immediately */ 839 goto done; 840 } 841 842 /* all ok, id is mapped */ 843 ids[i]->status = ID_MAPPED; 844 } 845 846 ret = NT_STATUS_OK; 847 848 done: 849 return ret; 850 } 851 852 853 /* 854 set a mapping. 855 */ 856 857 static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom, const struct id_map *map) 858 { 859 struct idmap_tdb2_context *ctx; 860 NTSTATUS ret; 861 char *ksidstr, *kidstr; 862 struct idmap_tdb2_set_mapping_context state; 863 864 if (!map || !map->sid) { 865 return NT_STATUS_INVALID_PARAMETER; 866 } 867 868 ksidstr = kidstr = NULL; 869 870 /* TODO: should we filter a set_mapping using low/high filters ? */ 871 872 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 873 874 switch (map->xid.type) { 875 876 case ID_TYPE_UID: 877 kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id); 878 break; 879 880 case ID_TYPE_GID: 881 kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id); 882 break; 883 884 default: 885 DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type)); 886 return NT_STATUS_INVALID_PARAMETER; 887 } 888 889 if (kidstr == NULL) { 890 DEBUG(0, ("ERROR: Out of memory!\n")); 891 ret = NT_STATUS_NO_MEMORY; 892 goto done; 893 } 894 895 if (!(ksidstr = sid_string_talloc(ctx, map->sid))) { 896 DEBUG(0, ("Out of memory!\n")); 897 ret = NT_STATUS_NO_MEMORY; 898 goto done; 899 } 900 901 state.ksidstr = ksidstr; 902 state.kidstr = kidstr; 903 904 ret = dbwrap_trans_do(idmap_tdb2, idmap_tdb2_set_mapping_action, 905 &state); 906 907 done: 908 talloc_free(ksidstr); 909 talloc_free(kidstr); 910 return ret; 911 } 912 913 /* 914 remove a mapping. 915 */ 916 static NTSTATUS idmap_tdb2_remove_mapping(struct idmap_domain *dom, const struct id_map *map) 917 { 918 /* not supported as it would invalidate the cache tdb on other 919 nodes */ 920 DEBUG(0,("idmap_tdb2_remove_mapping not supported\n")); 921 return NT_STATUS_NOT_SUPPORTED; 922 } 923 924 /* 925 Close the idmap tdb instance 926 */ 927 static NTSTATUS idmap_tdb2_close(struct idmap_domain *dom) 928 { 929 /* don't do anything */ 930 return NT_STATUS_OK; 931 } 932 933 934 /* 935 Dump all mappings out 936 */ 937 static NTSTATUS idmap_tdb2_dump_data(struct idmap_domain *dom, struct id_map **maps, int *num_maps) 938 { 939 DEBUG(0,("idmap_tdb2_dump_data not supported\n")); 940 return NT_STATUS_NOT_SUPPORTED; 941 } 851 852 state.dom = dom; 853 state.ids = ids; 854 state.allocate_unmapped = false; 855 856 ret = idmap_tdb2_sids_to_unixids_action(ctx->db, &state); 857 858 if (NT_STATUS_EQUAL(ret, STATUS_SOME_UNMAPPED) && !dom->read_only) { 859 state.allocate_unmapped = true; 860 ret = dbwrap_trans_do(ctx->db, 861 idmap_tdb2_sids_to_unixids_action, 862 &state); 863 } 864 865 return ret; 866 } 867 942 868 943 869 static struct idmap_methods db_methods = { … … 945 871 .unixids_to_sids = idmap_tdb2_unixids_to_sids, 946 872 .sids_to_unixids = idmap_tdb2_sids_to_unixids, 947 .set_mapping = idmap_tdb2_set_mapping, 948 .remove_mapping = idmap_tdb2_remove_mapping, 949 .dump_data = idmap_tdb2_dump_data, 950 .close_fn = idmap_tdb2_close 873 .allocate_id = idmap_tdb2_get_new_id 951 874 }; 952 875 953 static struct idmap_alloc_methods db_alloc_methods = {954 .init = idmap_tdb2_alloc_init,955 .allocate_id = idmap_tdb2_allocate_id,956 .get_id_hwm = idmap_tdb2_get_hwm,957 .set_id_hwm = idmap_tdb2_set_hwm,958 .close_fn = idmap_tdb2_alloc_close959 };960 961 876 NTSTATUS idmap_tdb2_init(void) 962 877 { 963 NTSTATUS ret;964 965 /* register both backends */966 ret = smb_register_idmap_alloc(SMB_IDMAP_INTERFACE_VERSION, "tdb2", &db_alloc_methods);967 if (! NT_STATUS_IS_OK(ret)) {968 DEBUG(0, ("Unable to register idmap alloc tdb2 module: %s\n", get_friendly_nt_error_msg(ret)));969 return ret;970 }971 972 878 return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "tdb2", &db_methods); 973 879 } -
vendor/current/source3/winbindd/idmap_util.c
r594 r740 4 4 Copyright (C) Simo Sorce 2003 5 5 Copyright (C) Jeremy Allison 2006 6 Copyright (C) Michael Adam 2010 6 7 7 8 This program is free software; you can redistribute it and/or modify … … 21 22 #include "winbindd.h" 22 23 #include "winbindd_proto.h" 24 #include "idmap.h" 25 #include "idmap_cache.h" 26 #include "../libcli/security/security.h" 23 27 24 28 #undef DBGC_CLASS 25 29 #define DBGC_CLASS DBGC_IDMAP 26 27 /*****************************************************************28 Returns true if the request was for a specific domain, or29 for a sid we are authoritative for - BUILTIN, or our own domain.30 *****************************************************************/31 32 static bool is_specific_domain_request(const char *dom_name, DOM_SID *sid)33 {34 if (dom_name && dom_name[0] != '\0') {35 return true;36 }37 if (sid_check_is_in_builtin(sid) ||38 sid_check_is_in_our_domain(sid)) {39 return true;40 }41 return false;42 }43 30 44 31 /***************************************************************** … … 47 34 *****************************************************************/ 48 35 49 NTSTATUS idmap_uid_to_sid(const char *domname, DOM_SID*sid, uid_t uid)36 NTSTATUS idmap_uid_to_sid(const char *domname, struct dom_sid *sid, uid_t uid) 50 37 { 51 38 NTSTATUS ret; … … 106 93 *****************************************************************/ 107 94 108 NTSTATUS idmap_gid_to_sid(const char *domname, DOM_SID*sid, gid_t gid)95 NTSTATUS idmap_gid_to_sid(const char *domname, struct dom_sid *sid, gid_t gid) 109 96 { 110 97 NTSTATUS ret; … … 147 134 struct dom_sid null_sid; 148 135 ZERO_STRUCT(null_sid); 149 idmap_cache_set_sid2 uid(&null_sid, gid);136 idmap_cache_set_sid2gid(&null_sid, gid); 150 137 } 151 138 DEBUG(10, ("gid [%lu] not mapped\n", (unsigned long)gid)); … … 165 152 *****************************************************************/ 166 153 167 NTSTATUS idmap_sid_to_uid(const char *dom_name, DOM_SID*sid, uid_t *uid)154 NTSTATUS idmap_sid_to_uid(const char *dom_name, struct dom_sid *sid, uid_t *uid) 168 155 { 169 156 NTSTATUS ret; … … 196 183 ret = idmap_backends_sid_to_unixid(dom_name, &map); 197 184 198 if (NT_STATUS_IS_OK(ret) && (map.status == ID_MAPPED)) { 199 if (map.xid.type != ID_TYPE_UID) { 200 DEBUG(10, ("sid [%s] not mapped to a uid " 201 "[%u,%u,%u]\n", 202 sid_string_dbg(sid), 203 map.status, 204 map.xid.type, 205 map.xid.id)); 206 if (winbindd_use_idmap_cache()) { 207 idmap_cache_set_sid2uid(sid, -1); 208 } 209 return NT_STATUS_NONE_MAPPED; 210 } 211 goto done; 212 } 213 214 if (is_specific_domain_request(dom_name, sid)) { 215 /* 216 * We had the task to go to a specific domain or 217 * a domain for which we are authoritative for and 218 * it could not answer our request. Fail. 219 */ 185 if (!NT_STATUS_IS_OK(ret)) { 186 DEBUG(10, ("idmap_backends_sid_to_unixid failed: %s\n", 187 nt_errstr(ret))); 220 188 if (winbindd_use_idmap_cache()) { 221 189 idmap_cache_set_sid2uid(sid, -1); 222 190 } 223 return NT_STATUS_NONE_MAPPED; 224 } 225 226 ret = idmap_new_mapping(sid, ID_TYPE_UID, &map.xid); 227 228 if (!NT_STATUS_IS_OK(ret)) { 229 DEBUG(10, ("idmap_new_mapping failed: %s\n", 230 nt_errstr(ret))); 191 return ret; 192 } 193 194 if (map.status != ID_MAPPED) { 195 DEBUG(10, ("sid [%s] is not mapped\n", sid_string_dbg(sid))); 231 196 if (winbindd_use_idmap_cache()) { 232 197 idmap_cache_set_sid2uid(sid, -1); 233 198 } 234 return ret; 235 } 236 237 done: 199 return NT_STATUS_NONE_MAPPED; 200 } 201 202 if (map.xid.type != ID_TYPE_UID) { 203 DEBUG(10, ("sid [%s] not mapped to a uid " 204 "[%u,%u,%u]\n", 205 sid_string_dbg(sid), 206 map.status, 207 map.xid.type, 208 map.xid.id)); 209 if (winbindd_use_idmap_cache()) { 210 idmap_cache_set_sid2uid(sid, -1); 211 } 212 return NT_STATUS_NONE_MAPPED; 213 } 214 238 215 *uid = (uid_t)map.xid.id; 239 216 if (winbindd_use_idmap_cache()) { … … 248 225 *****************************************************************/ 249 226 250 NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID*sid, gid_t *gid)227 NTSTATUS idmap_sid_to_gid(const char *domname, struct dom_sid *sid, gid_t *gid) 251 228 { 252 229 NTSTATUS ret; … … 278 255 279 256 ret = idmap_backends_sid_to_unixid(domname, &map); 280 if (NT_STATUS_IS_OK(ret) && (map.status == ID_MAPPED)) {281 if (map.xid.type != ID_TYPE_GID) {282 DEBUG(10, ("sid [%s] not mapped to a gid "283 "[%u,%u,%u]\n",284 sid_string_dbg(sid),285 map.status,286 map.xid.type,287 map.xid.id));288 if (winbindd_use_idmap_cache()) {289 idmap_cache_set_sid2gid(sid, -1);290 }291 return NT_STATUS_NONE_MAPPED;292 }293 goto done;294 }295 296 if (is_specific_domain_request(domname, sid)) {297 /*298 * We had the task to go to a specific domain or299 * a domain for which we are authoritative for and300 * it could not answer our request. Fail.301 */302 if (winbindd_use_idmap_cache()) {303 idmap_cache_set_sid2uid(sid, -1);304 }305 return NT_STATUS_NONE_MAPPED;306 }307 308 ret = idmap_new_mapping(sid, ID_TYPE_GID, &map.xid);309 257 310 258 if (!NT_STATUS_IS_OK(ret)) { 311 DEBUG(10, ("idmap_ new_mappingfailed: %s\n",259 DEBUG(10, ("idmap_backends_sid_to_unixid failed: %s\n", 312 260 nt_errstr(ret))); 313 261 if (winbindd_use_idmap_cache()) { … … 317 265 } 318 266 319 done: 267 if (map.status != ID_MAPPED) { 268 DEBUG(10, ("sid [%s] is not mapped\n", sid_string_dbg(sid))); 269 if (winbindd_use_idmap_cache()) { 270 idmap_cache_set_sid2gid(sid, -1); 271 } 272 return NT_STATUS_NONE_MAPPED; 273 } 274 275 if (map.xid.type != ID_TYPE_GID) { 276 DEBUG(10, ("sid [%s] not mapped to a gid " 277 "[%u,%u,%u]\n", 278 sid_string_dbg(sid), 279 map.status, 280 map.xid.type, 281 map.xid.id)); 282 if (winbindd_use_idmap_cache()) { 283 idmap_cache_set_sid2gid(sid, -1); 284 } 285 return NT_STATUS_NONE_MAPPED; 286 } 287 320 288 *gid = map.xid.id; 321 289 if (winbindd_use_idmap_cache()) { … … 324 292 return NT_STATUS_OK; 325 293 } 294 295 /** 296 * check whether a given unix id is inside the filter range of an idmap domain 297 */ 298 bool idmap_unix_id_is_in_range(uint32_t id, struct idmap_domain *dom) 299 { 300 if (id == 0) { 301 /* 0 is not an allowed unix id for id mapping */ 302 return false; 303 } 304 305 if ((dom->low_id && (id < dom->low_id)) || 306 (dom->high_id && (id > dom->high_id))) 307 { 308 return false; 309 } 310 311 return true; 312 } -
vendor/current/source3/winbindd/nss_info.c
r414 r740 21 21 22 22 #include "includes.h" 23 #include "ads.h" 23 24 #include "nss_info.h" 24 25 … … 88 89 { 89 90 char *p; 90 char *q;91 int len;92 91 93 92 *backend = *domain = NULL; … … 111 110 } 112 111 113 len = PTR_DIFF(p,config)+1; 114 if ( (q = SMB_MALLOC_ARRAY( char, len )) == NULL ) { 115 SAFE_FREE( *backend ); 116 return False; 117 } 118 119 StrnCpy( q, config, len-1); 120 q[len-1] = '\0'; 121 *backend = q; 122 123 return True; 112 *backend = SMB_STRNDUP(config, PTR_DIFF(p, config)); 113 return (*backend != NULL); 124 114 } 125 115 … … 165 155 *******************************************************************/ 166 156 167 NTSTATUS nss_init( const char **nss_list)157 static NTSTATUS nss_init(const char **nss_list) 168 158 { 169 159 NTSTATUS status; 170 static NTSTATUS nss_initialized = NT_STATUS_UNSUCCESSFUL;160 static bool nss_initialized = false; 171 161 int i; 172 162 char *backend, *domain; … … 175 165 /* check for previous successful initializations */ 176 166 177 if ( NT_STATUS_IS_OK(nss_initialized) )167 if (nss_initialized) { 178 168 return NT_STATUS_OK; 179 180 /* The "template" backend should alqays be registered as it 169 } 170 171 /* The "template" backend should always be registered as it 181 172 is a static module */ 182 173 183 if ( (nss_backend = nss_get_backend( "template" )) == NULL ) { 174 nss_backend = nss_get_backend("template"); 175 if (nss_backend == NULL) { 184 176 static_init_nss_info; 185 177 } … … 201 193 /* validate the backend */ 202 194 203 if ( (nss_backend = nss_get_backend( backend )) == NULL ) { 195 nss_backend = nss_get_backend(backend); 196 if (nss_backend == NULL) { 197 /* 198 * This is a freaking hack. We don't have proper 199 * modules for nss_info backends. Right now we have 200 * our standard nss_info backends in the ad backend. 201 */ 202 status = smb_probe_module("idmap", "ad"); 203 if ( !NT_STATUS_IS_OK(status) ) { 204 continue; 205 } 206 } 207 208 nss_backend = nss_get_backend(backend); 209 if (nss_backend == NULL) { 204 210 /* attempt to register the backend */ 205 211 status = smb_probe_module( "nss_info", backend ); … … 207 213 continue; 208 214 } 209 210 /* try again */ 211 if ( (nss_backend = nss_get_backend( backend )) == NULL ) { 212 DEBUG(0,("nss_init: unregistered backend %s!. Skipping\n", 213 backend)); 214 continue; 215 } 215 } 216 217 /* try again */ 218 nss_backend = nss_get_backend(backend); 219 if (nss_backend == NULL) { 220 DEBUG(0, ("nss_init: unregistered backend %s!. " 221 "Skipping\n", backend)); 222 continue; 216 223 } 217 224 … … 242 249 243 250 244 /* we shou ild default to use template here */245 } 246 247 nss_initialized = NT_STATUS_OK;251 /* we should default to use template here */ 252 } 253 254 nss_initialized = true; 248 255 249 256 return NT_STATUS_OK; … … 260 267 status = nss_init( lp_winbind_nss_info() ); 261 268 if ( !NT_STATUS_IS_OK(status) ) { 262 DEBUG(4,(" nss_get_info: Failed to init nss_info API (%s)!\n",263 nt_errstr(status)));269 DEBUG(4,("find_nss_domain: Failed to init nss_info API " 270 "(%s)!\n", nt_errstr(status))); 264 271 return NULL; 265 272 } … … 300 307 *******************************************************************/ 301 308 302 NTSTATUS nss_get_info( const char *domain, const DOM_SID*user_sid,309 NTSTATUS nss_get_info( const char *domain, const struct dom_sid *user_sid, 303 310 TALLOC_CTX *ctx, 304 ADS_STRUCT *ads, LDAPMessage *msg,305 311 const char **homedir, const char **shell, 306 312 const char **gecos, gid_t *p_gid) … … 320 326 m = p->backend->methods; 321 327 322 return m->get_nss_info( p, user_sid, ctx, ads, msg,328 return m->get_nss_info( p, user_sid, ctx, 323 329 homedir, shell, gecos, p_gid ); 324 330 } -
vendor/current/source3/winbindd/nss_info_template.c
r414 r740 9 9 License as published by the Free Software Foundation; either 10 10 version 3 of the License, or (at your option) any later version. 11 11 12 12 This library is distributed in the hope that it will be useful, 13 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 15 Library General Public License for more details. 16 16 17 17 You should have received a copy of the GNU Lesser General Public License 18 18 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 20 20 21 21 #include "includes.h" 22 #include "ads.h" 22 23 #include "nss_info.h" 23 24 … … 34 35 35 36 static NTSTATUS nss_template_get_info( struct nss_domain_entry *e, 36 const DOM_SID *sid,37 const struct dom_sid *sid, 37 38 TALLOC_CTX *ctx, 38 ADS_STRUCT *ads,39 LDAPMessage *msg,40 39 const char **homedir, 41 40 const char **shell, … … 45 44 if ( !homedir || !shell || !gecos ) 46 45 return NT_STATUS_INVALID_PARAMETER; 47 46 48 47 /* protect against home directories using whitespace in the 49 48 username */ … … 55 54 return NT_STATUS_NO_MEMORY; 56 55 } 57 56 58 57 return NT_STATUS_OK; 59 58 } … … 100 99 .close_fn = nss_template_close 101 100 }; 102 101 103 102 NTSTATUS nss_info_template_init( void ) 104 103 { -
vendor/current/source3/winbindd/wb_dsgetdcname.c
r594 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ cli_wbint.h"22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 23 24 24 struct wb_dsgetdcname_state { … … 65 65 } else { 66 66 struct winbindd_domain *domain = find_our_domain(); 67 child = &domain->child;67 child = choose_domain_child(domain); 68 68 } 69 69 … … 74 74 } 75 75 76 subreq = rpccli_wbint_DsGetDcName_send(77 state, ev, child-> rpccli, domain_name, guid_ptr, site_name,76 subreq = dcerpc_wbint_DsGetDcName_send( 77 state, ev, child->binding_handle, domain_name, guid_ptr, site_name, 78 78 flags, &state->dcinfo); 79 79 if (tevent_req_nomem(subreq, req)) { … … 92 92 NTSTATUS status, result; 93 93 94 status = rpccli_wbint_DsGetDcName_recv(subreq, state, &result);94 status = dcerpc_wbint_DsGetDcName_recv(subreq, state, &result); 95 95 TALLOC_FREE(subreq); 96 if ( !NT_STATUS_IS_OK(status)) {96 if (any_nt_status_not_ok(status, result, &status)) { 97 97 tevent_req_nterror(req, status); 98 return;99 }100 if (!NT_STATUS_IS_OK(result)) {101 tevent_req_nterror(req, result);102 98 return; 103 99 } -
vendor/current/source3/winbindd/wb_fill_pwent.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ cli_wbint.h"22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 23 24 24 struct wb_fill_pwent_state { … … 73 73 status = wb_sid2uid_recv(subreq, &state->pw->pw_uid); 74 74 TALLOC_FREE(subreq); 75 if (!NT_STATUS_IS_OK(status)) { 76 tevent_req_nterror(req, status); 75 if (tevent_req_nterror(req, status)) { 77 76 return; 78 77 } … … 99 98 status = wb_sid2gid_recv(subreq, &state->pw->pw_gid); 100 99 TALLOC_FREE(subreq); 101 if (!NT_STATUS_IS_OK(status)) { 102 tevent_req_nterror(req, status); 100 if (tevent_req_nterror(req, status)) { 103 101 return; 104 102 } -
vendor/current/source3/winbindd/wb_getgrsid.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "../libcli/security/security.h" 23 24 24 25 struct wb_getgrsid_state { … … 56 57 struct winbindd_domain *our_domain = find_our_domain(); 57 58 58 if ( sid_compare_domain(group_sid, &our_domain->sid) == 0) {59 if (dom_sid_compare_domain(group_sid, &our_domain->sid) == 0) { 59 60 DEBUG(7, ("winbindd_getgrsid: My domain -- rejecting " 60 61 "getgrsid() for %s\n", sid_string_tos(group_sid))); … … 83 84 &state->domname, &state->name); 84 85 TALLOC_FREE(subreq); 85 if (!NT_STATUS_IS_OK(status)) { 86 tevent_req_nterror(req, status); 86 if (tevent_req_nterror(req, status)) { 87 87 return; 88 88 } … … 115 115 status = wb_sid2gid_recv(subreq, &state->gid); 116 116 TALLOC_FREE(subreq); 117 if (!NT_STATUS_IS_OK(status)) { 118 tevent_req_nterror(req, status); 117 if (tevent_req_nterror(req, status)) { 119 118 return; 120 119 } … … 137 136 status = wb_group_members_recv(subreq, state, &state->members); 138 137 TALLOC_FREE(subreq); 139 if (!NT_STATUS_IS_OK(status)) { 140 tevent_req_nterror(req, status); 138 if (tevent_req_nterror(req, status)) { 141 139 return; 142 140 } -
vendor/current/source3/winbindd/wb_getpwsid.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "../libcli/security/security.h" 23 24 24 25 struct wb_getpwsid_state { … … 74 75 status = wb_queryuser_recv(subreq, state, &state->userinfo); 75 76 TALLOC_FREE(subreq); 76 if (!NT_STATUS_IS_OK(status)) { 77 tevent_req_nterror(req, status); 77 if (tevent_req_nterror(req, status)) { 78 78 return; 79 79 } … … 118 118 &state->userinfo->acct_name); 119 119 TALLOC_FREE(subreq); 120 if (!NT_STATUS_IS_OK(status)) { 121 tevent_req_nterror(req, status); 120 if (tevent_req_nterror(req, status)) { 122 121 return; 123 122 } … … 137 136 138 137 status = wb_fill_pwent_recv(subreq); 139 if (!NT_STATUS_IS_OK(status)) { 140 tevent_req_nterror(req, status); 138 if (tevent_req_nterror(req, status)) { 141 139 return; 142 140 } -
vendor/current/source3/winbindd/wb_gettoken.c
r594 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "../libcli/security/security.h" 24 #include "passdb/machine_sid.h" 23 25 24 26 struct wb_gettoken_state { … … 89 91 &state->sids); 90 92 TALLOC_FREE(subreq); 91 if (!NT_STATUS_IS_OK(status)) { 92 tevent_req_nterror(req, status); 93 if (tevent_req_nterror(req, status)) { 93 94 return; 94 95 } … … 134 135 status = wb_lookupuseraliases_recv(subreq, state, &num_rids, &rids); 135 136 TALLOC_FREE(subreq); 136 if (!NT_STATUS_IS_OK(status)) { 137 tevent_req_nterror(req, status); 137 if (tevent_req_nterror(req, status)) { 138 138 return; 139 139 } 140 140 domain = find_domain_from_sid_noinit(get_global_sam_sid()); 141 if (domain == NULL) { 142 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); 143 return; 144 } 141 145 if (!wb_add_rids_to_sids(state, &state->num_sids, &state->sids, 142 146 &domain->sid, num_rids, rids)) { … … 176 180 status = wb_lookupuseraliases_recv(subreq, state, &num_rids, &rids); 177 181 TALLOC_FREE(subreq); 178 if (!NT_STATUS_IS_OK(status)) { 179 tevent_req_nterror(req, status); 182 if (tevent_req_nterror(req, status)) { 180 183 return; 181 184 } -
vendor/current/source3/winbindd/wb_gid2sid.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "idmap_cache.h" 24 #include "idmap.h" 25 #include "../libcli/security/security.h" 23 26 24 27 struct wb_gid2sid_state { … … 75 78 child = idmap_child(); 76 79 77 subreq = rpccli_wbint_Gid2Sid_send(78 state, ev, child-> rpccli, state->dom_name,80 subreq = dcerpc_wbint_Gid2Sid_send( 81 state, ev, child->binding_handle, state->dom_name, 79 82 gid, &state->sid); 80 83 if (tevent_req_nomem(subreq, req)) { … … 93 96 NTSTATUS status, result; 94 97 95 status = rpccli_wbint_Gid2Sid_recv(subreq, state, &result);98 status = dcerpc_wbint_Gid2Sid_recv(subreq, state, &result); 96 99 TALLOC_FREE(subreq); 97 if ( !NT_STATUS_IS_OK(status)) {100 if (any_nt_status_not_ok(status, result, &status)) { 98 101 tevent_req_nterror(req, status); 99 return;100 }101 if (!NT_STATUS_IS_OK(result)) {102 tevent_req_nterror(req, result);103 102 return; 104 103 } -
vendor/current/source3/winbindd/wb_group_members.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "../librpc/gen_ndr/ndr_security.h" 24 #include "../libcli/security/security.h" 23 25 24 26 /* … … 71 73 } 72 74 73 subreq = rpccli_wbint_LookupGroupMembers_send(74 state, ev, dom ain->child.rpccli, &state->sid, type,75 subreq = dcerpc_wbint_LookupGroupMembers_send( 76 state, ev, dom_child_handle(domain), &state->sid, type, 75 77 &state->members); 76 78 if (tevent_req_nomem(subreq, req)) { … … 89 91 NTSTATUS status, result; 90 92 91 status = rpccli_wbint_LookupGroupMembers_recv(subreq, state, &result);93 status = dcerpc_wbint_LookupGroupMembers_recv(subreq, state, &result); 92 94 TALLOC_FREE(subreq); 93 if ( !NT_STATUS_IS_OK(status)) {95 if (any_nt_status_not_ok(status, result, &status)) { 94 96 tevent_req_nterror(req, status); 95 return;96 }97 if (!NT_STATUS_IS_OK(result)) {98 tevent_req_nterror(req, result);99 97 return; 100 98 } … … 158 156 159 157 status = wb_groups_members_next_subreq(state, state, &subreq); 160 if (!NT_STATUS_IS_OK(status)) { 161 tevent_req_nterror(req, status); 158 if (tevent_req_nterror(req, status)) { 162 159 return tevent_req_post(req, ev); 163 160 } … … 213 210 */ 214 211 215 if (!NT_STATUS_IS_OK(status)) { 216 tevent_req_nterror(req, status); 212 if (tevent_req_nterror(req, status)) { 217 213 return; 218 214 } … … 238 234 239 235 status = wb_groups_members_next_subreq(state, state, &subreq); 240 if (!NT_STATUS_IS_OK(status)) { 241 tevent_req_nterror(req, status); 236 if (tevent_req_nterror(req, status)) { 242 237 return; 243 238 } … … 270 265 * This is the routine expanding a list of groups up to a certain level. We 271 266 * collect the users in a talloc_dict: We have to add them without duplicates, 272 * and andtalloc_dict is an indexed (here indexed by SID) data structure.267 * and talloc_dict is an indexed (here indexed by SID) data structure. 273 268 */ 274 269 … … 316 311 317 312 status = wb_group_members_next_subreq(state, state, &subreq); 318 if (!NT_STATUS_IS_OK(status)) { 319 tevent_req_nterror(req, status); 313 if (tevent_req_nterror(req, status)) { 320 314 return tevent_req_post(req, ev); 321 315 } … … 364 358 status = wb_groups_members_recv(subreq, state, &num_members, &members); 365 359 TALLOC_FREE(subreq); 366 if (!NT_STATUS_IS_OK(status)) { 367 tevent_req_nterror(req, status); 360 if (tevent_req_nterror(req, status)) { 368 361 return; 369 362 } … … 414 407 sid = &members[i].sid; 415 408 key = data_blob_const( 416 sid, ndr_size_dom_sid(sid, NULL,0));409 sid, ndr_size_dom_sid(sid, 0)); 417 410 418 411 if (!talloc_dict_set(state->users, key, &m)) { … … 443 436 444 437 status = wb_group_members_next_subreq(state, state, &subreq); 445 if (!NT_STATUS_IS_OK(status)) { 446 tevent_req_nterror(req, status); 438 if (tevent_req_nterror(req, status)) { 447 439 return; 448 440 } -
vendor/current/source3/winbindd/wb_lookupname.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "../libcli/security/security.h" 23 24 24 25 struct wb_lookupname_state { … … 69 70 } 70 71 71 subreq = rpccli_wbint_LookupName_send( 72 state, ev, domain->child.rpccli, state->dom_name, state->name, 72 subreq = dcerpc_wbint_LookupName_send( 73 state, ev, dom_child_handle(domain), 74 state->dom_name, state->name, 73 75 flags, &state->type, &state->sid); 74 76 if (tevent_req_nomem(subreq, req)) { … … 88 90 NTSTATUS status, result; 89 91 90 status = rpccli_wbint_LookupName_recv(subreq, state, &result);92 status = dcerpc_wbint_LookupName_recv(subreq, state, &result); 91 93 TALLOC_FREE(subreq); 92 if (!NT_STATUS_IS_OK(status)) { 93 tevent_req_nterror(req, status); 94 if (tevent_req_nterror(req, status)) { 94 95 return; 95 96 } … … 110 111 } 111 112 112 subreq = rpccli_wbint_LookupName_send( 113 state, state->ev, root_domain->child.rpccli, state->dom_name, 113 subreq = dcerpc_wbint_LookupName_send( 114 state, state->ev, dom_child_handle(root_domain), 115 state->dom_name, 114 116 state->name, state->flags, &state->type, &state->sid); 115 117 if (tevent_req_nomem(subreq, req)) { … … 127 129 NTSTATUS status, result; 128 130 129 status = rpccli_wbint_LookupName_recv(subreq, state, &result);131 status = dcerpc_wbint_LookupName_recv(subreq, state, &result); 130 132 TALLOC_FREE(subreq); 131 if ( !NT_STATUS_IS_OK(status)) {133 if (any_nt_status_not_ok(status, result, &status)) { 132 134 tevent_req_nterror(req, status); 133 return;134 }135 if (!NT_STATUS_IS_OK(result)) {136 tevent_req_nterror(req, result);137 135 return; 138 136 } -
vendor/current/source3/winbindd/wb_lookupsid.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "../libcli/security/security.h" 23 24 24 25 struct wb_lookupsid_state { … … 55 56 } 56 57 57 subreq = rpccli_wbint_LookupSid_send(58 state, ev, state->lookup_domain->child.rpccli,58 subreq = dcerpc_wbint_LookupSid_send( 59 state, ev, dom_child_handle(state->lookup_domain), 59 60 &state->sid, &state->type, &state->domname, &state->name); 60 61 if (tevent_req_nomem(subreq, req)) { … … 74 75 NTSTATUS status, result; 75 76 76 status = rpccli_wbint_LookupSid_recv(subreq, state, &result);77 status = dcerpc_wbint_LookupSid_recv(subreq, state, &result); 77 78 TALLOC_FREE(subreq); 78 if (!NT_STATUS_IS_OK(status)) { 79 tevent_req_nterror(req, status); 79 if (tevent_req_nterror(req, status)) { 80 80 return; 81 81 } … … 95 95 state->lookup_domain = forest_root; 96 96 97 subreq = rpccli_wbint_LookupSid_send(98 state, state->ev, state->lookup_domain->child.rpccli,97 subreq = dcerpc_wbint_LookupSid_send( 98 state, state->ev, dom_child_handle(state->lookup_domain), 99 99 &state->sid, &state->type, &state->domname, &state->name); 100 100 if (tevent_req_nomem(subreq, req)) { -
vendor/current/source3/winbindd/wb_lookupuseraliases.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ cli_wbint.h"22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 23 24 24 struct wb_lookupuseraliases_state { … … 47 47 state->sids.sids = CONST_DISCARD(struct dom_sid *, sids); 48 48 49 subreq = rpccli_wbint_LookupUserAliases_send(50 state, ev, dom ain->child.rpccli, &state->sids, &state->rids);49 subreq = dcerpc_wbint_LookupUserAliases_send( 50 state, ev, dom_child_handle(domain), &state->sids, &state->rids); 51 51 if (tevent_req_nomem(subreq, req)) { 52 52 return tevent_req_post(req, ev); … … 64 64 NTSTATUS status, result; 65 65 66 status = rpccli_wbint_LookupUserAliases_recv(subreq, state, &result);66 status = dcerpc_wbint_LookupUserAliases_recv(subreq, state, &result); 67 67 TALLOC_FREE(subreq); 68 if ( !NT_STATUS_IS_OK(status)) {68 if (any_nt_status_not_ok(status, result, &status)) { 69 69 tevent_req_nterror(req, status); 70 return;71 }72 if (!NT_STATUS_IS_OK(result)) {73 tevent_req_nterror(req, result);74 70 return; 75 71 } -
vendor/current/source3/winbindd/wb_lookupusergroups.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "../libcli/security/security.h" 23 24 24 25 struct wb_lookupusergroups_state { … … 45 46 sid_copy(&state->sid, sid); 46 47 47 subreq = rpccli_wbint_LookupUserGroups_send(48 state, ev, dom ain->child.rpccli, &state->sid, &state->sids);48 subreq = dcerpc_wbint_LookupUserGroups_send( 49 state, ev, dom_child_handle(domain), &state->sid, &state->sids); 49 50 if (tevent_req_nomem(subreq, req)) { 50 51 return tevent_req_post(req, ev); … … 62 63 NTSTATUS status, result; 63 64 64 status = rpccli_wbint_LookupUserGroups_recv(subreq, state, &result);65 status = dcerpc_wbint_LookupUserGroups_recv(subreq, state, &result); 65 66 TALLOC_FREE(subreq); 66 if ( !NT_STATUS_IS_OK(status)) {67 if (any_nt_status_not_ok(status, result, &status)) { 67 68 tevent_req_nterror(req, status); 68 return;69 }70 if (!NT_STATUS_IS_OK(result)) {71 tevent_req_nterror(req, result);72 69 return; 73 70 } -
vendor/current/source3/winbindd/wb_next_grent.c
r427 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "passdb/machine_sid.h" 23 24 24 25 struct wb_next_grent_state { … … 70 71 return tevent_req_post(req, ev); 71 72 } 72 subreq = rpccli_wbint_QueryGroupList_send(73 state, state->ev, state->gstate->domain->child.rpccli,73 subreq = dcerpc_wbint_QueryGroupList_send( 74 state, state->ev, dom_child_handle(state->gstate->domain), 74 75 &state->next_groups); 75 76 if (tevent_req_nomem(subreq, req)) { … … 99 100 NTSTATUS status, result; 100 101 101 status = rpccli_wbint_QueryGroupList_recv(subreq, state, &result);102 status = dcerpc_wbint_QueryGroupList_recv(subreq, state, &result); 102 103 TALLOC_FREE(subreq); 103 if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(result)) { 104 if (tevent_req_nterror(req, status)) { 105 /* Ignore errors here, just log it */ 106 DEBUG(10, ("query_user_list for domain %s returned %s\n", 107 state->gstate->domain->name, 108 nt_errstr(status))); 109 return; 110 } 111 if (!NT_STATUS_IS_OK(result)) { 104 112 /* Ignore errors here, just log it */ 105 113 DEBUG(10, ("query_user_list for domain %s returned %s/%s\n", … … 126 134 return; 127 135 } 128 subreq = rpccli_wbint_QueryGroupList_send(129 state, state->ev, state->gstate->domain->child.rpccli,136 subreq = dcerpc_wbint_QueryGroupList_send( 137 state, state->ev, dom_child_handle(state->gstate->domain), 130 138 &state->next_groups); 131 139 if (tevent_req_nomem(subreq, req)) { … … 161 169 &state->gr->gr_gid, &state->members); 162 170 TALLOC_FREE(subreq); 163 if (!NT_STATUS_IS_OK(status)) { 164 tevent_req_nterror(req, status); 171 if (tevent_req_nterror(req, status)) { 165 172 return; 166 173 } -
vendor/current/source3/winbindd/wb_next_pwent.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "passdb/machine_sid.h" 23 24 24 25 struct wb_next_pwent_state { … … 148 149 status = wb_fill_pwent_recv(subreq); 149 150 TALLOC_FREE(subreq); 150 if (!NT_STATUS_IS_OK(status)) { 151 tevent_req_nterror(req, status); 151 if (tevent_req_nterror(req, status)) { 152 152 return; 153 153 } -
vendor/current/source3/winbindd/wb_query_user_list.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ cli_wbint.h"22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 23 24 24 struct wb_query_user_list_state { … … 41 41 } 42 42 43 subreq = rpccli_wbint_QueryUserList_send(state, ev,44 dom ain->child.rpccli,43 subreq = dcerpc_wbint_QueryUserList_send(state, ev, 44 dom_child_handle(domain), 45 45 &state->users); 46 46 if (tevent_req_nomem(subreq, req)) { … … 59 59 NTSTATUS status, result; 60 60 61 status = rpccli_wbint_QueryUserList_recv(subreq, state, &result);61 status = dcerpc_wbint_QueryUserList_recv(subreq, state, &result); 62 62 TALLOC_FREE(subreq); 63 if ( !NT_STATUS_IS_OK(status)) {63 if (any_nt_status_not_ok(status, result, &status)) { 64 64 tevent_req_nterror(req, status); 65 65 return; 66 66 } 67 if (!NT_STATUS_IS_OK(result)) {68 tevent_req_nterror(req, result);69 return;70 }71 67 72 DEBUG(10, (" rpccli_wbint_QueryUserList returned %d users\n",68 DEBUG(10, ("dcerpc_wbint_QueryUserList returned %d users\n", 73 69 state->users.num_userinfos)); 74 70 -
vendor/current/source3/winbindd/wb_queryuser.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "../libcli/security/security.h" 23 24 24 25 struct wb_queryuser_state { … … 54 55 } 55 56 56 subreq = rpccli_wbint_QueryUser_send(state, ev, domain->child.rpccli,57 subreq = dcerpc_wbint_QueryUser_send(state, ev, dom_child_handle(domain), 57 58 &state->sid, state->info); 58 59 if (tevent_req_nomem(subreq, req)) { … … 71 72 NTSTATUS status, result; 72 73 73 status = rpccli_wbint_QueryUser_recv(subreq, state->info, &result);74 status = dcerpc_wbint_QueryUser_recv(subreq, state->info, &result); 74 75 TALLOC_FREE(subreq); 75 if ( !NT_STATUS_IS_OK(status)) {76 if (any_nt_status_not_ok(status, result, &status)) { 76 77 tevent_req_nterror(req, status); 77 return;78 }79 if (!NT_STATUS_IS_OK(result)) {80 tevent_req_nterror(req, result);81 78 return; 82 79 } -
vendor/current/source3/winbindd/wb_seqnum.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ cli_wbint.h"22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 23 24 24 struct wb_seqnum_state { … … 39 39 return NULL; 40 40 } 41 subreq = rpccli_wbint_QuerySequenceNumber_send(42 state, ev, dom ain->child.rpccli, &state->seqnum);41 subreq = dcerpc_wbint_QuerySequenceNumber_send( 42 state, ev, dom_child_handle(domain), &state->seqnum); 43 43 if (tevent_req_nomem(subreq, req)) { 44 44 return tevent_req_post(req, ev); … … 56 56 NTSTATUS status, result; 57 57 58 status = rpccli_wbint_QuerySequenceNumber_recv(subreq, state, &result);58 status = dcerpc_wbint_QuerySequenceNumber_recv(subreq, state, &result); 59 59 TALLOC_FREE(subreq); 60 if ( !NT_STATUS_IS_OK(status)) {60 if (any_nt_status_not_ok(status, result, &status)) { 61 61 tevent_req_nterror(req, status); 62 return;63 }64 if (!NT_STATUS_IS_OK(result)) {65 tevent_req_nterror(req, result);66 62 return; 67 63 } -
vendor/current/source3/winbindd/wb_seqnums.c
r414 r740 22 22 #include "includes.h" 23 23 #include "winbindd.h" 24 #include "librpc/gen_ndr/ cli_wbint.h"24 #include "librpc/gen_ndr/ndr_wbint_c.h" 25 25 26 26 struct wb_seqnums_state { -
vendor/current/source3/winbindd/wb_sid2gid.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "idmap_cache.h" 24 #include "../libcli/security/security.h" 23 25 24 26 struct wb_sid2gid_state { … … 93 95 status = wb_lookupsid_recv(subreq, talloc_tos(), &type, &domname, 94 96 &name); 95 if (!NT_STATUS_IS_OK(status)) { 96 tevent_req_nterror(req, status); 97 if (tevent_req_nterror(req, status)) { 97 98 return; 98 99 } … … 125 126 child = idmap_child(); 126 127 127 subreq = rpccli_wbint_Sid2Gid_send(state, state->ev, child->rpccli,128 subreq = dcerpc_wbint_Sid2Gid_send(state, state->ev, child->binding_handle, 128 129 state->dom_name, &state->sid, 129 130 &state->gid64); … … 142 143 NTSTATUS status, result; 143 144 144 status = rpccli_wbint_Sid2Gid_recv(subreq, state, &result);145 status = dcerpc_wbint_Sid2Gid_recv(subreq, state, &result); 145 146 TALLOC_FREE(subreq); 146 if ( !NT_STATUS_IS_OK(status)) {147 if (any_nt_status_not_ok(status, result, &status)) { 147 148 tevent_req_nterror(req, status); 148 return;149 }150 if (!NT_STATUS_IS_OK(result)) {151 tevent_req_nterror(req, result);152 149 return; 153 150 } -
vendor/current/source3/winbindd/wb_sid2uid.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "idmap_cache.h" 24 #include "../libcli/security/security.h" 23 25 24 26 struct wb_sid2uid_state { … … 92 94 status = wb_lookupsid_recv(subreq, talloc_tos(), &type, &domname, 93 95 &name); 94 if (!NT_STATUS_IS_OK(status)) { 95 tevent_req_nterror(req, status); 96 if (tevent_req_nterror(req, status)) { 96 97 return; 97 98 } … … 123 124 child = idmap_child(); 124 125 125 subreq = rpccli_wbint_Sid2Uid_send(state, state->ev, child->rpccli,126 subreq = dcerpc_wbint_Sid2Uid_send(state, state->ev, child->binding_handle, 126 127 state->dom_name, &state->sid, 127 128 &state->uid64); … … 140 141 NTSTATUS status, result; 141 142 142 status = rpccli_wbint_Sid2Uid_recv(subreq, state, &result);143 status = dcerpc_wbint_Sid2Uid_recv(subreq, state, &result); 143 144 TALLOC_FREE(subreq); 144 if ( !NT_STATUS_IS_OK(status)) {145 if (any_nt_status_not_ok(status, result, &status)) { 145 146 tevent_req_nterror(req, status); 146 return;147 }148 if (!NT_STATUS_IS_OK(result)) {149 tevent_req_nterror(req, result);150 147 return; 151 148 } -
vendor/current/source3/winbindd/wb_uid2sid.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "idmap_cache.h" 24 #include "idmap.h" 25 #include "../libcli/security/security.h" 23 26 24 27 struct wb_uid2sid_state { … … 75 78 child = idmap_child(); 76 79 77 subreq = rpccli_wbint_Uid2Sid_send(78 state, ev, child-> rpccli, state->dom_name,80 subreq = dcerpc_wbint_Uid2Sid_send( 81 state, ev, child->binding_handle, state->dom_name, 79 82 uid, &state->sid); 80 83 if (tevent_req_nomem(subreq, req)) { … … 93 96 NTSTATUS status, result; 94 97 95 status = rpccli_wbint_Uid2Sid_recv(subreq, state, &result);98 status = dcerpc_wbint_Uid2Sid_recv(subreq, state, &result); 96 99 TALLOC_FREE(subreq); 97 if ( !NT_STATUS_IS_OK(status)) {100 if (any_nt_status_not_ok(status, result, &status)) { 98 101 tevent_req_nterror(req, status); 99 return;100 }101 if (!NT_STATUS_IS_OK(result)) {102 tevent_req_nterror(req, result);103 102 return; 104 103 } -
vendor/current/source3/winbindd/winbindd.c
r597 r740 24 24 25 25 #include "includes.h" 26 #include "popt_common.h" 26 27 #include "winbindd.h" 27 #include "../../nsswitch/libwbclient/wbc_async.h" 28 #include "nsswitch/winbind_client.h" 29 #include "nsswitch/wb_reqtrans.h" 30 #include "ntdomain.h" 31 #include "../librpc/gen_ndr/srv_lsa.h" 32 #include "../librpc/gen_ndr/srv_samr.h" 33 #include "secrets.h" 34 #include "idmap.h" 35 #include "lib/addrchange.h" 36 #include "serverid.h" 37 #include "auth.h" 38 #include "messages.h" 28 39 29 40 #undef DBGC_CLASS 30 41 #define DBGC_CLASS DBGC_WINBIND 31 42 43 static bool client_is_idle(struct winbindd_cli_state *state); 32 44 static void remove_client(struct winbindd_cli_state *state); 33 45 … … 37 49 extern bool override_logfile; 38 50 39 struct event_context *winbind_event_context(void)40 {41 static struct event_context *ctx;42 43 if (!ctx && !(ctx = event_context_init(NULL))) {44 smb_panic("Could not init winbind event context");45 }46 return ctx;47 }48 49 51 struct messaging_context *winbind_messaging_context(void) 50 52 { 51 static struct messaging_context *ctx; 52 53 if (ctx == NULL) { 54 ctx = messaging_init(NULL, server_id_self(), 55 winbind_event_context()); 56 } 57 if (ctx == NULL) { 58 DEBUG(0, ("Could not init winbind messaging context.\n")); 59 } 60 return ctx; 53 struct messaging_context *msg_ctx = server_messaging_context(); 54 if (likely(msg_ctx != NULL)) { 55 return msg_ctx; 56 } 57 smb_panic("Could not init winbindd's messaging context.\n"); 58 return NULL; 61 59 } 62 60 … … 113 111 DEBUG(2, ("\tclient list:\n")); 114 112 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) { 115 DEBUGADD(2, ("\t\tpid %lu, sock %d\n", 116 (unsigned long)tmp->pid, tmp->sock)); 117 } 118 } 119 } 120 121 /* Print winbindd status to log file */ 122 123 static void print_winbindd_status(void) 124 { 125 winbindd_status(); 113 DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n", 114 (unsigned long)tmp->pid, tmp->sock, 115 client_is_idle(tmp) ? "idle" : "active")); 116 } 117 } 126 118 } 127 119 … … 135 127 136 128 if (!wcache_invalidate_cache()) { 129 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n")); 130 if (!winbindd_cache_validate_and_initialize()) { 131 exit(1); 132 } 133 } 134 } 135 136 static void flush_caches_noinit(void) 137 { 138 /* 139 * We need to invalidate cached user list entries on a SIGHUP 140 * otherwise cached access denied errors due to restrict anonymous 141 * hang around until the sequence number changes. 142 * NB 143 * Skip uninitialized domains when flush cache. 144 * If domain is not initialized, it means it is never 145 * used or never become online. look, wcache_invalidate_cache() 146 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic 147 * for unused domains and large traffic for primay domain's DC if there 148 * are many domains.. 149 */ 150 151 if (!wcache_invalidate_cache_noinit()) { 137 152 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n")); 138 153 if (!winbindd_cache_validate_and_initialize()) { … … 177 192 178 193 if (is_parent) { 194 serverid_deregister(procid_self()); 179 195 pidfile_unlink(); 180 196 } … … 255 271 256 272 DEBUG(1,("Reloading services after SIGHUP\n")); 257 flush_caches ();273 flush_caches_noinit(); 258 274 reload_services_file(file); 259 275 } … … 321 337 void *private_data) 322 338 { 323 print_winbindd_status();339 winbindd_status(); 324 340 } 325 341 … … 373 389 uint8 ret; 374 390 pid_t child_pid; 391 NTSTATUS status; 375 392 376 393 DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache " … … 399 416 /* child */ 400 417 401 if (!winbindd_reinit_after_fork(NULL)) { 418 status = winbindd_reinit_after_fork(NULL, NULL); 419 if (!NT_STATUS_IS_OK(status)) { 420 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n", 421 nt_errstr(status))); 402 422 _exit(0); 403 423 } … … 419 439 } dispatch_table[] = { 420 440 421 /* PAM auth functions */422 423 { WINBINDD_PAM_AUTH, winbindd_pam_auth, "PAM_AUTH" },424 { WINBINDD_PAM_AUTH_CRAP, winbindd_pam_auth_crap, "AUTH_CRAP" },425 { WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok, "CHAUTHTOK" },426 { WINBINDD_PAM_LOGOFF, winbindd_pam_logoff, "PAM_LOGOFF" },427 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, winbindd_pam_chng_pswd_auth_crap, "CHNG_PSWD_AUTH_CRAP" },428 429 441 /* Enumeration functions */ 430 442 … … 439 451 { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" }, 440 452 { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" }, 453 { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" }, 441 454 { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" }, 442 455 { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir, … … 473 486 { WINBINDD_LOOKUPSID, "LOOKUPSID", 474 487 winbindd_lookupsid_send, winbindd_lookupsid_recv }, 488 { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS", 489 winbindd_lookupsids_send, winbindd_lookupsids_recv }, 475 490 { WINBINDD_LOOKUPNAME, "LOOKUPNAME", 476 491 winbindd_lookupname_send, winbindd_lookupname_recv }, … … 483 498 { WINBINDD_GID_TO_SID, "GID_TO_SID", 484 499 winbindd_gid_to_sid_send, winbindd_gid_to_sid_recv }, 500 { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS", 501 winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv }, 485 502 { WINBINDD_GETPWSID, "GETPWSID", 486 503 winbindd_getpwsid_send, winbindd_getpwsid_recv }, … … 529 546 { WINBINDD_PING_DC, "PING_DC", 530 547 winbindd_ping_dc_send, winbindd_ping_dc_recv }, 548 { WINBINDD_PAM_AUTH, "PAM_AUTH", 549 winbindd_pam_auth_send, winbindd_pam_auth_recv }, 550 { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF", 551 winbindd_pam_logoff_send, winbindd_pam_logoff_recv }, 552 { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK", 553 winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv }, 554 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP", 555 winbindd_pam_chng_pswd_auth_crap_send, 556 winbindd_pam_chng_pswd_auth_crap_recv }, 531 557 532 558 { 0, NULL, NULL, NULL } … … 538 564 { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID", 539 565 winbindd_allocate_gid_send, winbindd_allocate_gid_recv }, 540 { WINBINDD_SET_MAPPING, "SET_MAPPING",541 winbindd_set_mapping_send, winbindd_set_mapping_recv },542 { WINBINDD_REMOVE_MAPPING, "SET_MAPPING",543 winbindd_remove_mapping_send, winbindd_remove_mapping_recv },544 { WINBINDD_SET_HWM, "SET_HWM",545 winbindd_set_hwm_send, winbindd_set_hwm_recv },546 566 { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC", 547 567 winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv }, 568 { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP", 569 winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv }, 548 570 549 571 { 0, NULL, NULL, NULL } … … 557 579 struct winbindd_async_dispatch_table *atable; 558 580 559 state->mem_ctx = talloc_ init("winbind request");581 state->mem_ctx = talloc_named(state, 0, "winbind request"); 560 582 if (state->mem_ctx == NULL) 561 583 return; … … 713 735 } 714 736 715 DEBUG(10,("winbind_client_response_written[%d:%s]: deliver d response to client\n",716 (int)state->pid, state->cmd_name));737 DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response " 738 "to client\n", (int)state->pid, state->cmd_name)); 717 739 718 740 TALLOC_FREE(state->mem_ctx); … … 758 780 len = sizeof(sunaddr); 759 781 760 do { 761 sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, 762 &len); 763 } while (sock == -1 && errno == EINTR); 764 765 if (sock == -1) 766 return; 782 sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len); 783 784 if (sock == -1) { 785 if (errno != EINTR) { 786 DEBUG(0, ("Faild to accept socket - %s\n", 787 strerror(errno))); 788 } 789 return; 790 } 767 791 768 792 DEBUG(6,("accepted socket %d\n", sock)); … … 862 886 } 863 887 888 /* Is a client idle? */ 889 890 static bool client_is_idle(struct winbindd_cli_state *state) { 891 return (state->response == NULL && 892 !state->pwent_state && !state->grent_state); 893 } 894 864 895 /* Shutdown client connection which has been idle for the longest time */ 865 896 … … 871 902 872 903 for (state = winbindd_client_list(); state; state = state->next) { 873 if (state->response == NULL && 874 !state->pwent_state && !state->grent_state) { 904 if (client_is_idle(state)) { 875 905 nidle++; 876 906 if (!last_access || state->last_access < last_access) { … … 904 934 struct winbindd_listen_state); 905 935 906 while (winbindd_num_clients() > 907 WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) { 936 while (winbindd_num_clients() > lp_winbind_max_clients() - 1) { 908 937 DEBUG(5,("winbindd: Exceeding %d client " 909 938 "connections, removing idle " 910 "connection.\n", 911 WINBINDD_MAX_SIMULTANEOUS_CLIENTS)); 939 "connection.\n", lp_winbind_max_clients())); 912 940 if (!remove_idle_client()) { 913 941 DEBUG(0,("winbindd: Exceeding %d " 914 942 "client connections, no idle " 915 943 "connection found\n", 916 WINBINDD_MAX_SIMULTANEOUS_CLIENTS));944 lp_winbind_max_clients())); 917 945 break; 918 946 } 919 947 } 920 948 new_connection(s->fd, s->privileged); 949 } 950 951 /* 952 * Winbindd socket accessor functions 953 */ 954 955 const char *get_winbind_pipe_dir(void) 956 { 957 return lp_parm_const_string(-1, "winbindd", "socket dir", WINBINDD_SOCKET_DIR); 958 } 959 960 char *get_winbind_priv_pipe_dir(void) 961 { 962 return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR); 921 963 } 922 964 … … 934 976 935 977 pub_state->privileged = false; 936 pub_state->fd = open_winbindd_socket(); 978 pub_state->fd = create_pipe_sock( 979 get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME, 0755); 937 980 if (pub_state->fd == -1) { 938 981 goto failed; … … 955 998 956 999 priv_state->privileged = true; 957 priv_state->fd = open_winbindd_priv_socket(); 1000 priv_state->fd = create_pipe_sock( 1001 get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750); 958 1002 if (priv_state->fd == -1) { 959 1003 goto failed; … … 984 1028 { 985 1029 return !opt_nocache; 1030 } 1031 1032 void winbindd_register_handlers(void) 1033 { 1034 /* Setup signal handlers */ 1035 1036 if (!winbindd_setup_sig_term_handler(true)) 1037 exit(1); 1038 if (!winbindd_setup_sig_hup_handler(NULL)) 1039 exit(1); 1040 if (!winbindd_setup_sig_chld_handler()) 1041 exit(1); 1042 if (!winbindd_setup_sig_usr2_handler()) 1043 exit(1); 1044 1045 CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */ 1046 1047 /* 1048 * Ensure all cache and idmap caches are consistent 1049 * and initialized before we startup. 1050 */ 1051 if (!winbindd_cache_validate_and_initialize()) { 1052 exit(1); 1053 } 1054 1055 /* get broadcast messages */ 1056 1057 if (!serverid_register(procid_self(), 1058 FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP)) { 1059 DEBUG(1, ("Could not register myself in serverid.tdb\n")); 1060 exit(1); 1061 } 1062 1063 /* React on 'smbcontrol winbindd reload-config' in the same way 1064 as to SIGHUP signal */ 1065 messaging_register(winbind_messaging_context(), NULL, 1066 MSG_SMB_CONF_UPDATED, msg_reload_services); 1067 messaging_register(winbind_messaging_context(), NULL, 1068 MSG_SHUTDOWN, msg_shutdown); 1069 1070 /* Handle online/offline messages. */ 1071 messaging_register(winbind_messaging_context(), NULL, 1072 MSG_WINBIND_OFFLINE, winbind_msg_offline); 1073 messaging_register(winbind_messaging_context(), NULL, 1074 MSG_WINBIND_ONLINE, winbind_msg_online); 1075 messaging_register(winbind_messaging_context(), NULL, 1076 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus); 1077 1078 messaging_register(winbind_messaging_context(), NULL, 1079 MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list); 1080 1081 messaging_register(winbind_messaging_context(), NULL, 1082 MSG_WINBIND_VALIDATE_CACHE, 1083 winbind_msg_validate_cache); 1084 1085 messaging_register(winbind_messaging_context(), NULL, 1086 MSG_WINBIND_DUMP_DOMAIN_LIST, 1087 winbind_msg_dump_domain_list); 1088 1089 messaging_register(winbind_messaging_context(), NULL, 1090 MSG_WINBIND_IP_DROPPED, 1091 winbind_msg_ip_dropped_parent); 1092 1093 /* Register handler for MSG_DEBUG. */ 1094 messaging_register(winbind_messaging_context(), NULL, 1095 MSG_DEBUG, 1096 winbind_msg_debug); 1097 1098 netsamlogon_cache_init(); /* Non-critical */ 1099 1100 /* clear the cached list of trusted domains */ 1101 1102 wcache_tdc_clear(); 1103 1104 if (!init_domain_list()) { 1105 DEBUG(0,("unable to initialize domain list\n")); 1106 exit(1); 1107 } 1108 1109 init_idmap_child(); 1110 init_locator_child(); 1111 1112 smb_nscd_flush_user_cache(); 1113 smb_nscd_flush_group_cache(); 1114 1115 if (lp_allow_trusted_domains()) { 1116 if (tevent_add_timer(winbind_event_context(), NULL, timeval_zero(), 1117 rescan_trusted_domains, NULL) == NULL) { 1118 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n")); 1119 exit(1); 1120 } 1121 } 1122 1123 } 1124 1125 struct winbindd_addrchanged_state { 1126 struct addrchange_context *ctx; 1127 struct tevent_context *ev; 1128 struct messaging_context *msg_ctx; 1129 }; 1130 1131 static void winbindd_addr_changed(struct tevent_req *req); 1132 1133 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx, 1134 struct tevent_context *ev, 1135 struct messaging_context *msg_ctx) 1136 { 1137 struct winbindd_addrchanged_state *state; 1138 struct tevent_req *req; 1139 NTSTATUS status; 1140 1141 state = talloc(mem_ctx, struct winbindd_addrchanged_state); 1142 if (state == NULL) { 1143 DEBUG(10, ("talloc failed\n")); 1144 return; 1145 } 1146 state->ev = ev; 1147 state->msg_ctx = msg_ctx; 1148 1149 status = addrchange_context_create(state, &state->ctx); 1150 if (!NT_STATUS_IS_OK(status)) { 1151 DEBUG(10, ("addrchange_context_create failed: %s\n", 1152 nt_errstr(status))); 1153 TALLOC_FREE(state); 1154 return; 1155 } 1156 req = addrchange_send(state, ev, state->ctx); 1157 if (req == NULL) { 1158 DEBUG(0, ("addrchange_send failed\n")); 1159 TALLOC_FREE(state); 1160 return; 1161 } 1162 tevent_req_set_callback(req, winbindd_addr_changed, state); 1163 } 1164 1165 static void winbindd_addr_changed(struct tevent_req *req) 1166 { 1167 struct winbindd_addrchanged_state *state = tevent_req_callback_data( 1168 req, struct winbindd_addrchanged_state); 1169 enum addrchange_type type; 1170 struct sockaddr_storage addr; 1171 NTSTATUS status; 1172 1173 status = addrchange_recv(req, &type, &addr); 1174 TALLOC_FREE(req); 1175 if (!NT_STATUS_IS_OK(status)) { 1176 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n", 1177 nt_errstr(status))); 1178 TALLOC_FREE(state); 1179 return; 1180 } 1181 if (type == ADDRCHANGE_DEL) { 1182 char addrstr[INET6_ADDRSTRLEN]; 1183 DATA_BLOB blob; 1184 1185 print_sockaddr(addrstr, sizeof(addrstr), &addr); 1186 1187 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n", 1188 addrstr)); 1189 1190 blob = data_blob_const(addrstr, strlen(addrstr)+1); 1191 1192 status = messaging_send(state->msg_ctx, 1193 messaging_server_id(state->msg_ctx), 1194 MSG_WINBIND_IP_DROPPED, &blob); 1195 if (!NT_STATUS_IS_OK(status)) { 1196 DEBUG(10, ("messaging_send failed: %s - ignoring\n", 1197 nt_errstr(status))); 1198 } 1199 } 1200 req = addrchange_send(state, state->ev, state->ctx); 1201 if (req == NULL) { 1202 DEBUG(0, ("addrchange_send failed\n")); 1203 TALLOC_FREE(state); 1204 return; 1205 } 1206 tevent_req_set_callback(req, winbindd_addr_changed, state); 986 1207 } 987 1208 … … 1013 1234 poptContext pc; 1014 1235 int opt; 1015 TALLOC_CTX *frame = talloc_stackframe(); 1236 TALLOC_CTX *frame; 1237 NTSTATUS status; 1238 1239 /* 1240 * Do this before any other talloc operation 1241 */ 1242 talloc_enable_null_tracking(); 1243 frame = talloc_stackframe(); 1016 1244 1017 1245 /* glibc (?) likes to print "User defined signal 1" and exit if a … … 1099 1327 } 1100 1328 } 1101 setup_logging("winbindd", log_stdout); 1329 if (log_stdout) { 1330 setup_logging("winbindd", DEBUG_STDOUT); 1331 } else { 1332 setup_logging("winbindd", DEBUG_FILE); 1333 } 1102 1334 reopen_logs(); 1103 1335 … … 1137 1369 return False; 1138 1370 } 1139 1140 /* Enable netbios namecache */1141 1142 namecache_enable();1143 1371 1144 1372 /* Unblock all signals we are interested in as they may have been … … 1154 1382 1155 1383 if (!interactive) 1156 become_daemon(Fork, no_process_group );1384 become_daemon(Fork, no_process_group, log_stdout); 1157 1385 1158 1386 pidfile_create("winbindd"); … … 1174 1402 */ 1175 1403 1176 if (!NT_STATUS_IS_OK(reinit_after_fork(winbind_messaging_context(), 1177 winbind_event_context(), 1178 false))) { 1404 status = reinit_after_fork(winbind_messaging_context(), 1405 winbind_event_context(), 1406 procid_self(), false); 1407 if (!NT_STATUS_IS_OK(status)) { 1179 1408 DEBUG(0,("reinit_after_fork() failed\n")); 1180 1409 exit(1); 1181 1410 } 1182 1411 1183 /* Setup signal handlers */ 1184 1185 if (!winbindd_setup_sig_term_handler(true)) 1186 exit(1); 1187 if (!winbindd_setup_sig_hup_handler(NULL)) 1188 exit(1); 1189 if (!winbindd_setup_sig_chld_handler()) 1190 exit(1); 1191 if (!winbindd_setup_sig_usr2_handler()) 1192 exit(1); 1193 1194 CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */ 1195 1196 /* 1197 * Ensure all cache and idmap caches are consistent 1198 * and initialized before we startup. 1199 */ 1200 if (!winbindd_cache_validate_and_initialize()) { 1201 exit(1); 1202 } 1203 1204 /* get broadcast messages */ 1205 claim_connection(NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP); 1206 1207 /* React on 'smbcontrol winbindd reload-config' in the same way 1208 as to SIGHUP signal */ 1209 messaging_register(winbind_messaging_context(), NULL, 1210 MSG_SMB_CONF_UPDATED, msg_reload_services); 1211 messaging_register(winbind_messaging_context(), NULL, 1212 MSG_SHUTDOWN, msg_shutdown); 1213 1214 /* Handle online/offline messages. */ 1215 messaging_register(winbind_messaging_context(), NULL, 1216 MSG_WINBIND_OFFLINE, winbind_msg_offline); 1217 messaging_register(winbind_messaging_context(), NULL, 1218 MSG_WINBIND_ONLINE, winbind_msg_online); 1219 messaging_register(winbind_messaging_context(), NULL, 1220 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus); 1221 1222 messaging_register(winbind_messaging_context(), NULL, 1223 MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list); 1224 1225 messaging_register(winbind_messaging_context(), NULL, 1226 MSG_WINBIND_VALIDATE_CACHE, 1227 winbind_msg_validate_cache); 1228 1229 messaging_register(winbind_messaging_context(), NULL, 1230 MSG_WINBIND_DUMP_DOMAIN_LIST, 1231 winbind_msg_dump_domain_list); 1232 1233 /* Register handler for MSG_DEBUG. */ 1234 messaging_register(winbind_messaging_context(), NULL, 1235 MSG_DEBUG, 1236 winbind_msg_debug); 1237 1238 netsamlogon_cache_init(); /* Non-critical */ 1239 1240 /* clear the cached list of trusted domains */ 1241 1242 wcache_tdc_clear(); 1243 1244 if (!init_domain_list()) { 1245 DEBUG(0,("unable to initialize domain list\n")); 1246 exit(1); 1247 } 1248 1249 init_idmap_child(); 1250 init_locator_child(); 1251 1252 smb_nscd_flush_user_cache(); 1253 smb_nscd_flush_group_cache(); 1412 winbindd_register_handlers(); 1413 1414 status = init_system_info(); 1415 if (!NT_STATUS_IS_OK(status)) { 1416 DEBUG(1, ("ERROR: failed to setup system user info: %s.\n", 1417 nt_errstr(status))); 1418 exit(1); 1419 } 1420 1421 rpc_lsarpc_init(NULL); 1422 rpc_samr_init(NULL); 1423 1424 winbindd_init_addrchange(NULL, winbind_event_context(), 1425 winbind_messaging_context()); 1254 1426 1255 1427 /* setup listen sockets */ … … 1258 1430 DEBUG(0,("winbindd_setup_listeners() failed\n")); 1259 1431 exit(1); 1260 }1261 1262 if (lp_allow_trusted_domains()) {1263 if (tevent_add_timer(winbind_event_context(), NULL, timeval_zero(),1264 rescan_trusted_domains, NULL) == NULL) {1265 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));1266 exit(1);1267 }1268 1432 } 1269 1433 -
vendor/current/source3/winbindd/winbindd.h
r594 r740 28 28 #include "librpc/gen_ndr/wbint.h" 29 29 30 #include "talloc_dict.h" 31 #include "smb_ldap.h" 32 33 #include "../lib/util/tevent_ntstatus.h" 34 30 35 #ifdef HAVE_LIBNSCD 31 36 #include <libnscd.h> … … 42 47 43 48 struct sid_ctr { 44 DOM_SID*sid;49 struct dom_sid *sid; 45 50 bool finished; 46 51 const char *domain; … … 93 98 fstring homedir; /* User Home Directory */ 94 99 fstring shell; /* User Login Shell */ 95 DOM_SIDuser_sid; /* NT user and primary group SIDs */96 DOM_SIDgroup_sid;100 struct dom_sid user_sid; /* NT user and primary group SIDs */ 101 struct dom_sid group_sid; 97 102 }; 98 103 … … 132 137 int sock; 133 138 struct tevent_queue *queue; 134 struct rpc_pipe_client *rpccli;139 struct dcerpc_binding_handle *binding_handle; 135 140 136 141 struct timed_event *lockout_policy_event; … … 146 151 fstring alt_name; /* alt Domain name, if any (FQDN for ADS) */ 147 152 fstring forest_name; /* Name of the AD forest we're in */ 148 DOM_SIDsid; /* SID for this domain */153 struct dom_sid sid; /* SID for this domain */ 149 154 uint32 domain_flags; /* Domain flags from netlogon.h */ 150 155 uint32 domain_type; /* Domain type from netlogon.h */ … … 156 161 bool internal; /* BUILTIN and member SAM */ 157 162 bool online; /* is this domain available ? */ 158 time_t startup_time; /* When we set "startup" true. */163 time_t startup_time; /* When we set "startup" true. monotonic clock */ 159 164 bool startup; /* are we in the first 30 seconds after startup_time ? */ 160 165 … … 205 210 /* The child pid we're talking to */ 206 211 207 struct winbindd_child child;212 struct winbindd_child *children; 208 213 209 214 /* Callback we use to try put us back online. */ … … 215 220 216 221 struct winbindd_domain *prev, *next; 222 }; 223 224 struct wb_acct_info { 225 fstring acct_name; /* account name */ 226 fstring acct_desc; /* account name */ 227 uint32_t rid; /* domain-relative RID */ 217 228 }; 218 229 … … 234 245 TALLOC_CTX *mem_ctx, 235 246 uint32 *num_entries, 236 struct acct_info **info);247 struct wb_acct_info **info); 237 248 238 249 /* get a list of domain local groups */ … … 240 251 TALLOC_CTX *mem_ctx, 241 252 uint32 *num_entries, 242 struct acct_info **info);253 struct wb_acct_info **info); 243 254 244 255 /* convert one user or group name to a sid */ … … 248 259 const char *name, 249 260 uint32_t flags, 250 DOM_SID*sid,261 struct dom_sid *sid, 251 262 enum lsa_SidType *type); 252 263 … … 254 265 NTSTATUS (*sid_to_name)(struct winbindd_domain *domain, 255 266 TALLOC_CTX *mem_ctx, 256 const DOM_SID*sid,267 const struct dom_sid *sid, 257 268 char **domain_name, 258 269 char **name, … … 261 272 NTSTATUS (*rids_to_names)(struct winbindd_domain *domain, 262 273 TALLOC_CTX *mem_ctx, 263 const DOM_SID*domain_sid,274 const struct dom_sid *domain_sid, 264 275 uint32 *rids, 265 276 size_t num_rids, … … 271 282 NTSTATUS (*query_user)(struct winbindd_domain *domain, 272 283 TALLOC_CTX *mem_ctx, 273 const DOM_SID*user_sid,284 const struct dom_sid *user_sid, 274 285 struct wbint_userinfo *user_info); 275 286 … … 279 290 NTSTATUS (*lookup_usergroups)(struct winbindd_domain *domain, 280 291 TALLOC_CTX *mem_ctx, 281 const DOM_SID*user_sid,282 uint32 *num_groups, DOM_SID**user_gids);292 const struct dom_sid *user_sid, 293 uint32 *num_groups, struct dom_sid **user_gids); 283 294 284 295 /* Lookup all aliases that the sids delivered are member of. This is … … 287 298 TALLOC_CTX *mem_ctx, 288 299 uint32 num_sids, 289 const DOM_SID*sids,300 const struct dom_sid *sids, 290 301 uint32 *num_aliases, 291 302 uint32 **alias_rids); … … 294 305 NTSTATUS (*lookup_groupmem)(struct winbindd_domain *domain, 295 306 TALLOC_CTX *mem_ctx, 296 const DOM_SID*group_sid,307 const struct dom_sid *group_sid, 297 308 enum lsa_SidType type, 298 309 uint32 *num_names, 299 DOM_SID **sid_mem, char ***names,310 struct dom_sid **sid_mem, char ***names, 300 311 uint32 **name_types); 301 312 … … 324 335 bool (*init)(void); 325 336 326 bool (*get_sid_from_uid)(uid_t uid, DOM_SID*sid);327 bool (*get_sid_from_gid)(gid_t gid, DOM_SID*sid);328 329 bool (*get_uid_from_sid)( DOM_SID*sid, uid_t *uid);330 bool (*get_gid_from_sid)( DOM_SID*sid, gid_t *gid);337 bool (*get_sid_from_uid)(uid_t uid, struct dom_sid *sid); 338 bool (*get_sid_from_gid)(gid_t gid, struct dom_sid *sid); 339 340 bool (*get_uid_from_sid)(struct dom_sid *sid, uid_t *uid); 341 bool (*get_gid_from_sid)(struct dom_sid *sid, gid_t *gid); 331 342 332 343 /* Called when backend is unloaded */ … … 341 352 const char *domain_name; 342 353 const char *dns_name; 343 DOM_SIDsid;354 struct dom_sid sid; 344 355 uint32 trust_flags; 345 356 uint32 trust_attribs; … … 387 398 #define DOM_SEQUENCE_NONE ((uint32)-1) 388 399 400 #define winbind_event_context server_event_context 401 389 402 #endif /* _WINBINDD_H */ -
vendor/current/source3/winbindd/winbindd_ads.c
r414 r740 24 24 #include "includes.h" 25 25 #include "winbindd.h" 26 #include "../librpc/gen_ndr/cli_netlogon.h" 26 #include "rpc_client/rpc_client.h" 27 #include "../librpc/gen_ndr/ndr_netlogon_c.h" 28 #include "../libds/common/flags.h" 29 #include "ads.h" 30 #include "secrets.h" 31 #include "../libcli/ldap/ldap_ndr.h" 32 #include "../libcli/security/security.h" 33 #include "../libds/common/flag_mapping.h" 34 #include "passdb.h" 27 35 28 36 #ifdef HAVE_ADS … … 153 161 TALLOC_CTX *mem_ctx, 154 162 uint32 *num_entries, 155 struct wbint_userinfo ** info)163 struct wbint_userinfo **pinfo) 156 164 { 157 165 ADS_STRUCT *ads = NULL; … … 192 200 } 193 201 194 (* info) = TALLOC_ZERO_ARRAY(mem_ctx, struct wbint_userinfo, count);195 if (!* info) {202 (*pinfo) = TALLOC_ZERO_ARRAY(mem_ctx, struct wbint_userinfo, count); 203 if (!*pinfo) { 196 204 status = NT_STATUS_NO_MEMORY; 197 205 goto done; 198 206 } 199 207 200 i= 0;208 count = 0; 201 209 202 210 for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { 203 const char *name; 204 const char *gecos = NULL; 205 const char *homedir = NULL; 206 const char *shell = NULL; 211 struct wbint_userinfo *info = &((*pinfo)[count]); 207 212 uint32 group; 208 213 uint32 atype; 209 DOM_SID user_sid;210 gid_t primary_gid = (gid_t)-1;211 214 212 215 if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) || … … 216 219 } 217 220 218 name = ads_pull_username(ads, mem_ctx, msg); 219 220 if ( ads_pull_sid( ads, msg, "objectSid", &user_sid ) ) { 221 status = nss_get_info_cached( domain, &user_sid, mem_ctx, 222 ads, msg, &homedir, &shell, &gecos, 223 &primary_gid ); 224 } 225 226 if (gecos == NULL) { 227 gecos = ads_pull_string(ads, mem_ctx, msg, "name"); 228 } 221 info->acct_name = ads_pull_username(ads, mem_ctx, msg); 222 info->full_name = ads_pull_string(ads, mem_ctx, msg, "name"); 223 info->homedir = NULL; 224 info->shell = NULL; 225 info->primary_gid = (gid_t)-1; 229 226 230 227 if (!ads_pull_sid(ads, msg, "objectSid", 231 & (*info)[i].user_sid)) {232 DEBUG(1, ("No sid for %s !?\n",name));228 &info->user_sid)) { 229 DEBUG(1, ("No sid for %s !?\n", info->acct_name)); 233 230 continue; 234 231 } 232 235 233 if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group)) { 236 DEBUG(1,("No primary group for %s !?\n", name)); 234 DEBUG(1, ("No primary group for %s !?\n", 235 info->acct_name)); 237 236 continue; 238 237 } 239 240 (*info)[i].acct_name = name; 241 (*info)[i].full_name = gecos; 242 (*info)[i].homedir = homedir; 243 (*info)[i].shell = shell; 244 (*info)[i].primary_gid = primary_gid; 245 sid_compose(&(*info)[i].group_sid, &domain->sid, group); 246 i++; 247 } 248 249 (*num_entries) = i; 238 sid_compose(&info->group_sid, &domain->sid, group); 239 240 count += 1; 241 } 242 243 (*num_entries) = count; 244 ads_msgfree(ads, res); 245 246 for (i=0; i<count; i++) { 247 struct wbint_userinfo *info = &((*pinfo)[i]); 248 const char *gecos = NULL; 249 gid_t primary_gid = (gid_t)-1; 250 251 status = nss_get_info_cached(domain, &info->user_sid, mem_ctx, 252 &info->homedir, &info->shell, 253 &gecos, &primary_gid); 254 if (!NT_STATUS_IS_OK(status)) { 255 /* 256 * Deliberately ignore this error, there might be more 257 * users to fill 258 */ 259 continue; 260 } 261 262 if (gecos != NULL) { 263 info->full_name = gecos; 264 } 265 info->primary_gid = primary_gid; 266 } 267 250 268 status = NT_STATUS_OK; 251 269 … … 253 271 254 272 done: 255 if (res)256 ads_msgfree(ads, res);257 258 273 return status; 259 274 } … … 263 278 TALLOC_CTX *mem_ctx, 264 279 uint32 *num_entries, 265 struct acct_info **info)280 struct wb_acct_info **info) 266 281 { 267 282 ADS_STRUCT *ads = NULL; … … 337 352 } 338 353 339 (*info) = TALLOC_ZERO_ARRAY(mem_ctx, struct acct_info, count);354 (*info) = TALLOC_ZERO_ARRAY(mem_ctx, struct wb_acct_info, count); 340 355 if (!*info) { 341 356 status = NT_STATUS_NO_MEMORY; … … 347 362 for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { 348 363 char *name, *gecos; 349 DOM_SIDsid;364 struct dom_sid sid; 350 365 uint32 rid; 351 366 … … 385 400 TALLOC_CTX *mem_ctx, 386 401 uint32 *num_entries, 387 struct acct_info **info)402 struct wb_acct_info **info) 388 403 { 389 404 /* … … 408 423 const char *name, 409 424 uint32_t flags, 410 DOM_SID*sid,425 struct dom_sid *sid, 411 426 enum lsa_SidType *type) 412 427 { … … 419 434 static NTSTATUS sid_to_name(struct winbindd_domain *domain, 420 435 TALLOC_CTX *mem_ctx, 421 const DOM_SID*sid,436 const struct dom_sid *sid, 422 437 char **domain_name, 423 438 char **name, … … 431 446 static NTSTATUS rids_to_names(struct winbindd_domain *domain, 432 447 TALLOC_CTX *mem_ctx, 433 const DOM_SID*sid,448 const struct dom_sid *sid, 434 449 uint32 *rids, 435 450 size_t num_rids, … … 451 466 static NTSTATUS query_user(struct winbindd_domain *domain, 452 467 TALLOC_CTX *mem_ctx, 453 const DOM_SID *sid,468 const struct dom_sid *sid, 454 469 struct wbint_userinfo *info) 455 470 { … … 464 479 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 465 480 struct netr_SamInfo3 *user = NULL; 466 gid_t gid; 481 gid_t gid = -1; 482 int ret; 483 char *ads_name; 467 484 468 485 DEBUG(3,("ads: query_user\n")); … … 470 487 info->homedir = NULL; 471 488 info->shell = NULL; 472 info->primary_gid = (gid_t)-1;473 489 474 490 /* try netsamlogon cache first */ … … 485 501 info->full_name = talloc_strdup(mem_ctx, user->base.full_name.string); 486 502 487 nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL,503 nss_get_info_cached( domain, sid, mem_ctx, 488 504 &info->homedir, &info->shell, &info->full_name, 489 505 &gid ); … … 507 523 /* Assume "Domain Users" for the primary group */ 508 524 509 sid_compose(&info->group_sid, &domain->sid, DOMAIN_ GROUP_RID_USERS );525 sid_compose(&info->group_sid, &domain->sid, DOMAIN_RID_USERS ); 510 526 511 527 /* Try to fill in what the nss_info backend can do */ 512 528 513 nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL,529 nss_get_info_cached( domain, sid, mem_ctx, 514 530 &info->homedir, &info->shell, &info->full_name, 515 531 &gid); 516 532 info->primary_gid = gid; 517 533 518 status = NT_STATUS_OK; 519 goto done; 534 return NT_STATUS_OK; 520 535 } 521 536 … … 524 539 if ( (ads = ads_cached_connection(domain)) == NULL ) { 525 540 domain->last_status = NT_STATUS_SERVER_DISABLED; 526 goto done; 527 } 528 529 sidstr = sid_binstring(talloc_tos(), sid); 530 if (asprintf(&ldap_exp, "(objectSid=%s)", sidstr) == -1) { 531 status = NT_STATUS_NO_MEMORY; 532 goto done; 541 return NT_STATUS_SERVER_DISABLED; 542 } 543 544 sidstr = ldap_encode_ndr_dom_sid(talloc_tos(), sid); 545 546 ret = asprintf(&ldap_exp, "(objectSid=%s)", sidstr); 547 TALLOC_FREE(sidstr); 548 if (ret == -1) { 549 return NT_STATUS_NO_MEMORY; 533 550 } 534 551 rc = ads_search_retry(ads, &msg, ldap_exp, attrs); 535 free(ldap_exp); 536 TALLOC_FREE(sidstr); 552 SAFE_FREE(ldap_exp); 537 553 if (!ADS_ERR_OK(rc) || !msg) { 538 554 DEBUG(1,("query_user(sid=%s) ads_search: %s\n", 539 555 sid_string_dbg(sid), ads_errstr(rc))); 540 goto done;556 return ads_ntstatus(rc); 541 557 } 542 558 … … 545 561 DEBUG(1,("query_user(sid=%s): Not found\n", 546 562 sid_string_dbg(sid))); 547 goto done; 563 ads_msgfree(ads, msg); 564 return NT_STATUS_NO_SUCH_USER; 548 565 } 549 566 550 567 info->acct_name = ads_pull_username(ads, mem_ctx, msg); 551 568 552 nss_get_info_cached( domain, sid, mem_ctx, ads, msg, 569 if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group_rid)) { 570 DEBUG(1,("No primary group for %s !?\n", 571 sid_string_dbg(sid))); 572 ads_msgfree(ads, msg); 573 return NT_STATUS_NO_SUCH_USER; 574 } 575 sid_copy(&info->user_sid, sid); 576 sid_compose(&info->group_sid, &domain->sid, group_rid); 577 578 /* 579 * We have to fetch the "name" attribute before doing the 580 * nss_get_info_cached call. nss_get_info_cached might destroy 581 * the ads struct, potentially invalidating the ldap message. 582 */ 583 ads_name = ads_pull_string(ads, mem_ctx, msg, "name"); 584 585 ads_msgfree(ads, msg); 586 msg = NULL; 587 588 status = nss_get_info_cached( domain, sid, mem_ctx, 553 589 &info->homedir, &info->shell, &info->full_name, 554 590 &gid); 555 591 info->primary_gid = gid; 592 if (!NT_STATUS_IS_OK(status)) { 593 DEBUG(1, ("nss_get_info_cached failed: %s\n", 594 nt_errstr(status))); 595 return status; 596 } 556 597 557 598 if (info->full_name == NULL) { 558 info->full_name = ads_pull_string(ads, mem_ctx, msg, "name"); 559 } 560 561 if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group_rid)) { 562 DEBUG(1,("No primary group for %s !?\n", 563 sid_string_dbg(sid))); 564 goto done; 565 } 566 567 sid_copy(&info->user_sid, sid); 568 sid_compose(&info->group_sid, &domain->sid, group_rid); 599 info->full_name = ads_name; 600 } else { 601 TALLOC_FREE(ads_name); 602 } 569 603 570 604 status = NT_STATUS_OK; 571 605 572 606 DEBUG(3,("ads query_user gave %s\n", info->acct_name)); 573 done: 574 if (msg) 575 ads_msgfree(ads, msg); 576 577 return status; 607 return NT_STATUS_OK; 578 608 } 579 609 … … 583 613 TALLOC_CTX *mem_ctx, 584 614 const char *user_dn, 585 DOM_SID*primary_group,586 size_t *p_num_groups, DOM_SID**user_sids)615 struct dom_sid *primary_group, 616 uint32_t *p_num_groups, struct dom_sid **user_sids) 587 617 { 588 618 ADS_STATUS rc; … … 595 625 const char *group_attrs[] = {"objectSid", NULL}; 596 626 char *escaped_dn; 597 size_t num_groups = 0;627 uint32_t num_groups = 0; 598 628 599 629 DEBUG(3,("ads: lookup_usergroups_member\n")); … … 653 683 for (msg = ads_first_entry(ads, res); msg; 654 684 msg = ads_next_entry(ads, msg)) { 655 DOM_SIDgroup_sid;685 struct dom_sid group_sid; 656 686 657 687 if (!ads_pull_sid(ads, msg, "objectSid", &group_sid)) { … … 690 720 TALLOC_CTX *mem_ctx, 691 721 const char *user_dn, 692 DOM_SID*primary_group,693 size_t *p_num_groups,694 DOM_SID**user_sids)722 struct dom_sid *primary_group, 723 uint32_t *p_num_groups, 724 struct dom_sid **user_sids) 695 725 { 696 726 ADS_STATUS rc; … … 698 728 ADS_STRUCT *ads; 699 729 const char *attrs[] = {"memberOf", NULL}; 700 size_t num_groups = 0;701 DOM_SID*group_sids = NULL;730 uint32_t num_groups = 0; 731 struct dom_sid *group_sids = NULL; 702 732 int i; 703 733 char **strings = NULL; … … 740 770 } 741 771 742 group_sids = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_strings + 1);772 group_sids = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_strings + 1); 743 773 if (!group_sids) { 744 774 status = NT_STATUS_NO_MEMORY; … … 802 832 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, 803 833 TALLOC_CTX *mem_ctx, 804 const DOM_SID *sid,805 uint32 *p_num_groups, DOM_SID**user_sids)834 const struct dom_sid *sid, 835 uint32 *p_num_groups, struct dom_sid **user_sids) 806 836 { 807 837 ADS_STRUCT *ads = NULL; … … 811 841 LDAPMessage *msg = NULL; 812 842 char *user_dn = NULL; 813 DOM_SID*sids;843 struct dom_sid *sids; 814 844 int i; 815 DOM_SIDprimary_group;845 struct dom_sid primary_group; 816 846 uint32 primary_group_rid; 817 847 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 818 size_t num_groups = 0;848 uint32_t num_groups = 0; 819 849 820 850 DEBUG(3,("ads: lookup_usergroups\n")); … … 881 911 } 882 912 883 sid_copy(&primary_group, &domain->sid); 884 sid_append_rid(&primary_group, primary_group_rid); 913 sid_compose(&primary_group, &domain->sid, primary_group_rid); 885 914 886 915 count = ads_pull_sids(ads, mem_ctx, msg, "tokenGroups", &sids); … … 902 931 &primary_group, 903 932 &num_groups, user_sids); 904 *p_num_groups = (uint32)num_groups;933 *p_num_groups = num_groups; 905 934 if (NT_STATUS_IS_OK(status)) { 906 935 goto done; … … 913 942 &primary_group, 914 943 &num_groups, user_sids); 915 *p_num_groups = (uint32)num_groups;944 *p_num_groups = num_groups; 916 945 goto done; 917 946 } … … 954 983 static NTSTATUS lookup_useraliases(struct winbindd_domain *domain, 955 984 TALLOC_CTX *mem_ctx, 956 uint32 num_sids, const DOM_SID*sids,985 uint32 num_sids, const struct dom_sid *sids, 957 986 uint32 *num_aliases, uint32 **alias_rids) 958 987 { … … 968 997 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, 969 998 TALLOC_CTX *mem_ctx, 970 const DOM_SID*group_sid,999 const struct dom_sid *group_sid, 971 1000 enum lsa_SidType type, 972 1001 uint32 *num_names, 973 DOM_SID**sid_mem, char ***names,1002 struct dom_sid **sid_mem, char ***names, 974 1003 uint32 **name_types) 975 1004 { … … 983 1012 size_t num_members = 0; 984 1013 ads_control args; 985 DOM_SID*sid_mem_nocache = NULL;1014 struct dom_sid *sid_mem_nocache = NULL; 986 1015 char **names_nocache = NULL; 987 1016 enum lsa_SidType *name_types_nocache = NULL; … … 1015 1044 } 1016 1045 1017 if ((sidbinstr = sid_binstring(talloc_tos(), group_sid)) == NULL) {1046 if ((sidbinstr = ldap_encode_ndr_dom_sid(talloc_tos(), group_sid)) == NULL) { 1018 1047 status = NT_STATUS_NO_MEMORY; 1019 1048 goto done; … … 1057 1086 1058 1087 if (num_members) { 1059 (*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, num_members);1088 (*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_members); 1060 1089 (*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members); 1061 1090 (*name_types) = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_members); 1062 (sid_mem_nocache) = TALLOC_ZERO_ARRAY(tmp_ctx, DOM_SID, num_members);1091 (sid_mem_nocache) = TALLOC_ZERO_ARRAY(tmp_ctx, struct dom_sid, num_members); 1063 1092 1064 1093 if ((members == NULL) || (*sid_mem == NULL) || … … 1080 1109 enum lsa_SidType name_type; 1081 1110 char *name, *domain_name; 1082 DOM_SIDsid;1111 struct dom_sid sid; 1083 1112 1084 1113 rc = ads_get_sid_from_extended_dn(tmp_ctx, members[i], args.val, … … 1261 1290 { 1262 1291 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 1292 WERROR werr; 1263 1293 int i; 1264 1294 uint32 flags; 1265 1295 struct rpc_pipe_client *cli; 1266 uint32 fr_flags = (NETR_TRUST_FLAG_IN_FOREST | NETR_TRUST_FLAG_TREEROOT);1267 1296 int ret_count; 1297 struct dcerpc_binding_handle *b; 1268 1298 1269 1299 DEBUG(3,("ads: trusted_domains\n")); … … 1275 1305 trusts in the target forest */ 1276 1306 1277 if ( domain->primary || 1278 ((domain->domain_flags&fr_flags) == fr_flags) ) 1279 { 1307 if (domain->primary || domain_is_forest_root(domain)) { 1280 1308 flags = NETR_TRUST_FLAG_OUTBOUND | 1281 1309 NETR_TRUST_FLAG_INBOUND | … … 1294 1322 } 1295 1323 1296 result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx, 1324 b = cli->binding_handle; 1325 1326 result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx, 1297 1327 cli->desthost, 1298 1328 flags, 1299 1329 trusts, 1300 NULL);1330 &werr); 1301 1331 if (!NT_STATUS_IS_OK(result)) { 1302 1332 return result; 1333 } 1334 1335 if (!W_ERROR_IS_OK(werr)) { 1336 return werror_to_ntstatus(werr); 1303 1337 } 1304 1338 if (trusts->count == 0) { … … 1355 1389 wcache_tdc_add_domain( &d ); 1356 1390 ret_count++; 1357 } else if ( (domain->domain_flags&fr_flags) == fr_flags) {1391 } else if (domain_is_forest_root(domain)) { 1358 1392 /* Check if we already have this record. If 1359 1393 * we are following our forest root that is not -
vendor/current/source3/winbindd/winbindd_allocate_gid.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ cli_wbint.h"22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 23 24 24 struct winbindd_allocate_gid_state { … … 47 47 child = idmap_child(); 48 48 49 subreq = rpccli_wbint_AllocateGid_send(state, ev, child->rpccli,49 subreq = dcerpc_wbint_AllocateGid_send(state, ev, child->binding_handle, 50 50 &state->gid); 51 51 if (tevent_req_nomem(subreq, req)) { … … 64 64 NTSTATUS status, result; 65 65 66 status = rpccli_wbint_AllocateGid_recv(subreq, state, &result);66 status = dcerpc_wbint_AllocateGid_recv(subreq, state, &result); 67 67 TALLOC_FREE(subreq); 68 if ( !NT_STATUS_IS_OK(status)) {68 if (any_nt_status_not_ok(status, result, &status)) { 69 69 tevent_req_nterror(req, status); 70 return;71 }72 if (!NT_STATUS_IS_OK(result)) {73 tevent_req_nterror(req, result);74 70 return; 75 71 } -
vendor/current/source3/winbindd/winbindd_allocate_uid.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ cli_wbint.h"22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 23 24 24 struct winbindd_allocate_uid_state { … … 47 47 child = idmap_child(); 48 48 49 subreq = rpccli_wbint_AllocateUid_send(state, ev, child->rpccli,49 subreq = dcerpc_wbint_AllocateUid_send(state, ev, child->binding_handle, 50 50 &state->uid); 51 51 if (tevent_req_nomem(subreq, req)) { … … 64 64 NTSTATUS status, result; 65 65 66 status = rpccli_wbint_AllocateUid_recv(subreq, state, &result);66 status = dcerpc_wbint_AllocateUid_recv(subreq, state, &result); 67 67 TALLOC_FREE(subreq); 68 if ( !NT_STATUS_IS_OK(status)) {68 if (any_nt_status_not_ok(status, result, &status)) { 69 69 tevent_req_nterror(req, status); 70 return;71 }72 if (!NT_STATUS_IS_OK(result)) {73 tevent_req_nterror(req, result);74 70 return; 75 71 } -
vendor/current/source3/winbindd/winbindd_async.c
r414 r740 23 23 #include "includes.h" 24 24 #include "winbindd.h" 25 #include "../libcli/security/security.h" 25 26 26 27 #undef DBGC_CLASS 27 28 #define DBGC_CLASS DBGC_WINBIND 28 29 bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids,30 size_t num_sids, char **result, ssize_t *len)31 {32 size_t i;33 size_t buflen = 0;34 35 *len = 0;36 *result = NULL;37 for (i=0; i<num_sids; i++) {38 fstring tmp;39 sprintf_append(mem_ctx, result, len, &buflen,40 "%s\n", sid_to_fstring(tmp, &sids[i]));41 }42 43 if ((num_sids != 0) && (*result == NULL)) {44 return False;45 }46 47 return True;48 }49 50 bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr,51 DOM_SID **sids, size_t *num_sids)52 {53 const char *p, *q;54 55 p = sidstr;56 if (p == NULL)57 return False;58 59 while (p[0] != '\0') {60 fstring tmp;61 size_t sidlen;62 DOM_SID sid;63 q = strchr(p, '\n');64 if (q == NULL) {65 DEBUG(0, ("Got invalid sidstr: %s\n", p));66 return False;67 }68 sidlen = PTR_DIFF(q, p);69 if (sidlen >= sizeof(tmp)-1) {70 return false;71 }72 memcpy(tmp, p, sidlen);73 tmp[sidlen] = '\0';74 q += 1;75 if (!string_to_sid(&sid, tmp)) {76 DEBUG(0, ("Could not parse sid %s\n", p));77 return False;78 }79 if (!NT_STATUS_IS_OK(add_sid_to_array(mem_ctx, &sid, sids,80 num_sids)))81 {82 return False;83 }84 p = q;85 }86 return True;87 }88 29 89 30 enum winbindd_result winbindd_dual_ping(struct winbindd_domain *domain, -
vendor/current/source3/winbindd/winbindd_cache.c
r597 r740 25 25 26 26 #include "includes.h" 27 #include "system/filesys.h" 27 28 #include "winbindd.h" 28 29 #include "tdb_validate.h" 29 30 #include "../libcli/auth/libcli_auth.h" 30 31 #include "../librpc/gen_ndr/ndr_wbint.h" 32 #include "ads.h" 33 #include "nss_info.h" 34 #include "../libcli/security/security.h" 35 #include "passdb/machine_sid.h" 36 #include "util_tdb.h" 31 37 32 38 #undef DBGC_CLASS 33 39 #define DBGC_CLASS DBGC_WINBIND 34 40 35 #define WINBINDD_CACHE_VERSION 141 #define WINBINDD_CACHE_VERSION 2 36 42 #define WINBINDD_CACHE_VERSION_KEYSTR "WINBINDD_CACHE_VERSION" 37 43 … … 41 47 #endif 42 48 extern struct winbindd_methods builtin_passdb_methods; 49 extern struct winbindd_methods sam_passdb_methods; 43 50 44 51 /* … … 93 100 NTSTATUS status; 94 101 uint32 sequence_number; 102 uint64_t timeout; 95 103 uint8 *data; 96 104 uint32 len, ofs; … … 103 111 static struct winbind_cache *wcache; 104 112 105 void winbindd_check_cache_size(time_t t)106 {107 static time_t last_check_time;108 struct stat st;109 110 if (last_check_time == (time_t)0)111 last_check_time = t;112 113 if (t - last_check_time < 60 && t - last_check_time > 0)114 return;115 116 if (wcache == NULL || wcache->tdb == NULL) {117 DEBUG(0, ("Unable to check size of tdb cache - cache not open !\n"));118 return;119 }120 121 if (fstat(tdb_fd(wcache->tdb), &st) == -1) {122 DEBUG(0, ("Unable to check size of tdb cache %s!\n", strerror(errno) ));123 return;124 }125 126 if (st.st_size > WINBINDD_MAX_CACHE_SIZE) {127 DEBUG(10,("flushing cache due to size (%lu) > (%lu)\n",128 (unsigned long)st.st_size,129 (unsigned long)WINBINDD_MAX_CACHE_SIZE));130 wcache_flush_cache();131 }132 }133 134 113 /* get the winbind_cache structure */ 135 114 static struct winbind_cache *get_cache(struct winbindd_domain *domain) … … 143 122 domain->initialized = True; 144 123 } 124 125 if (strequal(domain->name, get_global_sam_name()) && 126 sid_check_is_domain(&domain->sid)) { 127 domain->backend = &sam_passdb_methods; 128 domain->initialized = True; 129 } 130 145 131 if ( !domain->initialized ) { 146 132 init_dc_connection( domain ); … … 224 210 225 211 /* 212 pull a uint64_t from a cache entry 213 */ 214 static uint64_t centry_uint64_t(struct cache_entry *centry) 215 { 216 uint64_t ret; 217 218 if (!centry_check_bytes(centry, 8)) { 219 smb_panic_fn("centry_uint64_t"); 220 } 221 ret = BVAL(centry->data, centry->ofs); 222 centry->ofs += 8; 223 return ret; 224 } 225 226 /* 226 227 pull a uint32 from a cache entry 227 228 */ … … 277 278 ret = IVAL(centry->data, centry->ofs); 278 279 centry->ofs += 4; 279 ret += (uint64 _t)IVAL(centry->data, centry->ofs) << 32;280 ret += (uint64)IVAL(centry->data, centry->ofs) << 32; 280 281 centry->ofs += 4; 281 282 return ret; … … 615 616 616 617 /* if the server is down or the cache entry is not older than the 617 current sequence number then it is OK */ 618 if (wcache_server_down(domain) || 619 centry->sequence_number == domain->sequence_number) { 618 current sequence number or it did not timeout then it is OK */ 619 if (wcache_server_down(domain) 620 || ((centry->sequence_number == domain->sequence_number) 621 && (centry->timeout > time(NULL)))) { 620 622 DEBUG(10,("centry_expired: Key %s for domain %s is good.\n", 621 623 keystr, domain->name )); … … 648 650 centry->ofs = 0; 649 651 650 if (centry->len < 8) {652 if (centry->len < 16) { 651 653 /* huh? corrupt cache? */ 652 DEBUG(10,("wcache_fetch_raw: Corrupt cache for key %s (len < 8) ?\n", kstr)); 654 DEBUG(10,("wcache_fetch_raw: Corrupt cache for key %s " 655 "(len < 16)?\n", kstr)); 653 656 centry_free(centry); 654 657 return NULL; … … 657 660 centry->status = centry_ntstatus(centry); 658 661 centry->sequence_number = centry_uint32(centry); 662 centry->timeout = centry_uint64_t(centry); 659 663 660 664 return centry; 665 } 666 667 static bool is_my_own_sam_domain(struct winbindd_domain *domain) 668 { 669 if (strequal(domain->name, get_global_sam_name()) && 670 sid_check_is_domain(&domain->sid)) { 671 return true; 672 } 673 674 return false; 675 } 676 677 static bool is_builtin_domain(struct winbindd_domain *domain) 678 { 679 if (strequal(domain->name, "BUILTIN") && 680 sid_check_is_builtin(&domain->sid)) { 681 return true; 682 } 683 684 return false; 661 685 } 662 686 … … 676 700 struct cache_entry *centry; 677 701 678 if (!winbindd_use_cache()) { 702 if (!winbindd_use_cache() || 703 is_my_own_sam_domain(domain) || 704 is_builtin_domain(domain)) { 679 705 return NULL; 680 706 } … … 743 769 744 770 /* 771 push a uint64_t into a centry 772 */ 773 static void centry_put_uint64_t(struct cache_entry *centry, uint64_t v) 774 { 775 centry_expand(centry, 8); 776 SBVAL(centry->data, centry->ofs, v); 777 centry->ofs += 8; 778 } 779 780 /* 745 781 push a uint32 into a centry 746 782 */ … … 808 844 } 809 845 810 static void centry_put_sid(struct cache_entry *centry, const DOM_SID *sid)846 static void centry_put_sid(struct cache_entry *centry, const struct dom_sid *sid) 811 847 { 812 848 fstring sid_string; … … 863 899 centry->ofs = 0; 864 900 centry->sequence_number = domain->sequence_number; 901 centry->timeout = lp_winbind_cache_time() + time(NULL); 865 902 centry_put_ntstatus(centry, status); 866 903 centry_put_uint32(centry, centry->sequence_number); 904 centry_put_uint64_t(centry, centry->timeout); 867 905 return centry; 868 906 } … … 896 934 static void wcache_save_name_to_sid(struct winbindd_domain *domain, 897 935 NTSTATUS status, const char *domain_name, 898 const char *name, const DOM_SID *sid,936 const char *name, const struct dom_sid *sid, 899 937 enum lsa_SidType type) 900 938 { … … 916 954 917 955 static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS status, 918 const DOM_SID*sid, const char *domain_name, const char *name, enum lsa_SidType type)956 const struct dom_sid *sid, const char *domain_name, const char *name, enum lsa_SidType type) 919 957 { 920 958 struct cache_entry *centry; … … 1213 1251 } 1214 1252 1215 NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const DOM_SID*sid)1253 NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const struct dom_sid *sid) 1216 1254 { 1217 1255 struct winbind_cache *cache = get_cache(domain); … … 1248 1286 NTSTATUS wcache_get_creds(struct winbindd_domain *domain, 1249 1287 TALLOC_CTX *mem_ctx, 1250 const DOM_SID*sid,1288 const struct dom_sid *sid, 1251 1289 const uint8 **cached_nt_pass, 1252 1290 const uint8 **cached_salt) … … 1328 1366 1329 1367 NTSTATUS wcache_save_creds(struct winbindd_domain *domain, 1330 TALLOC_CTX *mem_ctx, 1331 const DOM_SID *sid, 1368 const struct dom_sid *sid, 1332 1369 const uint8 nt_pass[NT_HASH_LEN]) 1333 1370 { … … 1526 1563 TALLOC_CTX *mem_ctx, 1527 1564 uint32 *num_entries, 1528 struct acct_info **info)1565 struct wb_acct_info **info) 1529 1566 { 1530 1567 struct winbind_cache *cache = get_cache(domain); … … 1548 1585 goto do_cached; 1549 1586 1550 (*info) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_entries);1587 (*info) = TALLOC_ARRAY(mem_ctx, struct wb_acct_info, *num_entries); 1551 1588 if (! (*info)) { 1552 1589 smb_panic_fn("enum_dom_groups out of memory"); … … 1621 1658 TALLOC_CTX *mem_ctx, 1622 1659 uint32 *num_entries, 1623 struct acct_info **info)1660 struct wb_acct_info **info) 1624 1661 { 1625 1662 struct winbind_cache *cache = get_cache(domain); … … 1643 1680 goto do_cached; 1644 1681 1645 (*info) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_entries);1682 (*info) = TALLOC_ARRAY(mem_ctx, struct wb_acct_info, *num_entries); 1646 1683 if (! (*info)) { 1647 1684 smb_panic_fn("enum_dom_groups out of memory"); … … 1767 1804 const char *name, 1768 1805 uint32_t flags, 1769 DOM_SID*sid,1806 struct dom_sid *sid, 1770 1807 enum lsa_SidType *type) 1771 1808 { … … 1876 1913 static NTSTATUS sid_to_name(struct winbindd_domain *domain, 1877 1914 TALLOC_CTX *mem_ctx, 1878 const DOM_SID*sid,1915 const struct dom_sid *sid, 1879 1916 char **domain_name, 1880 1917 char **name, … … 1939 1976 static NTSTATUS rids_to_names(struct winbindd_domain *domain, 1940 1977 TALLOC_CTX *mem_ctx, 1941 const DOM_SID*domain_sid,1978 const struct dom_sid *domain_sid, 1942 1979 uint32 *rids, 1943 1980 size_t num_rids, … … 1977 2014 1978 2015 for (i=0; i<num_rids; i++) { 1979 DOM_SIDsid;2016 struct dom_sid sid; 1980 2017 struct cache_entry *centry; 1981 2018 fstring tmp; … … 2009 2046 (*names)[i] = centry_string(centry, *names); 2010 2047 2011 } else if (NT_STATUS_EQUAL(centry->status, NT_STATUS_NONE_MAPPED)) { 2048 } else if (NT_STATUS_EQUAL(centry->status, NT_STATUS_NONE_MAPPED) 2049 || NT_STATUS_EQUAL(centry->status, STATUS_SOME_UNMAPPED)) { 2012 2050 have_unmapped = true; 2013 2051 … … 2050 2088 2051 2089 for (i=0; i<num_rids; i++) { 2052 DOM_SIDsid;2090 struct dom_sid sid; 2053 2091 struct cache_entry *centry; 2054 2092 fstring tmp; … … 2110 2148 if (NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED)) { 2111 2149 for (i = 0; i < num_rids; i++) { 2112 DOM_SIDsid;2150 struct dom_sid sid; 2113 2151 const char *name = ""; 2114 2152 const enum lsa_SidType type = SID_NAME_UNKNOWN; … … 2137 2175 2138 2176 for (i=0; i<num_rids; i++) { 2139 DOM_SIDsid;2177 struct dom_sid sid; 2140 2178 NTSTATUS status; 2141 2179 … … 2223 2261 static NTSTATUS query_user(struct winbindd_domain *domain, 2224 2262 TALLOC_CTX *mem_ctx, 2225 const DOM_SID*user_sid,2263 const struct dom_sid *user_sid, 2226 2264 struct wbint_userinfo *info) 2227 2265 { … … 2332 2370 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, 2333 2371 TALLOC_CTX *mem_ctx, 2334 const DOM_SID*user_sid,2335 uint32 *num_groups, DOM_SID**user_gids)2372 const struct dom_sid *user_sid, 2373 uint32 *num_groups, struct dom_sid **user_gids) 2336 2374 { 2337 2375 struct cache_entry *centry = NULL; … … 2483 2521 static NTSTATUS lookup_useraliases(struct winbindd_domain *domain, 2484 2522 TALLOC_CTX *mem_ctx, 2485 uint32 num_sids, const DOM_SID*sids,2523 uint32 num_sids, const struct dom_sid *sids, 2486 2524 uint32 *num_aliases, uint32 **alias_rids) 2487 2525 { … … 2587 2625 } 2588 2626 2589 *sid_mem = talloc_array(mem_ctx, DOM_SID, *num_names);2627 *sid_mem = talloc_array(mem_ctx, struct dom_sid, *num_names); 2590 2628 *names = talloc_array(mem_ctx, char *, *num_names); 2591 2629 *name_types = talloc_array(mem_ctx, uint32, *num_names); … … 2616 2654 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, 2617 2655 TALLOC_CTX *mem_ctx, 2618 const DOM_SID*group_sid,2656 const struct dom_sid *group_sid, 2619 2657 enum lsa_SidType type, 2620 2658 uint32 *num_names, 2621 DOM_SID**sid_mem, char ***names,2659 struct dom_sid **sid_mem, char ***names, 2622 2660 uint32 **name_types) 2623 2661 { … … 2966 3004 2967 3005 void wcache_invalidate_samlogon(struct winbindd_domain *domain, 2968 struct netr_SamInfo3 *info3) 2969 { 2970 DOM_SID sid; 3006 const struct dom_sid *sid) 3007 { 2971 3008 fstring key_str, sid_string; 2972 3009 struct winbind_cache *cache; … … 2988 3025 } 2989 3026 2990 sid_copy(&sid, info3->base.domain_sid);2991 sid_append_rid(&sid, info3->base.rid);2992 2993 3027 /* Clear U/SID cache entry */ 2994 fstr_sprintf(key_str, "U/%s", sid_to_fstring(sid_string, &sid));3028 fstr_sprintf(key_str, "U/%s", sid_to_fstring(sid_string, sid)); 2995 3029 DEBUG(10, ("wcache_invalidate_samlogon: clearing %s\n", key_str)); 2996 3030 tdb_delete(cache->tdb, string_tdb_data(key_str)); 2997 3031 2998 3032 /* Clear UG/SID cache entry */ 2999 fstr_sprintf(key_str, "UG/%s", sid_to_fstring(sid_string, &sid));3033 fstr_sprintf(key_str, "UG/%s", sid_to_fstring(sid_string, sid)); 3000 3034 DEBUG(10, ("wcache_invalidate_samlogon: clearing %s\n", key_str)); 3001 3035 tdb_delete(cache->tdb, string_tdb_data(key_str)); 3002 3036 3003 3037 /* Samba/winbindd never needs this. */ 3004 netsamlogon_clear_cached_user( info3);3038 netsamlogon_clear_cached_user(sid); 3005 3039 } 3006 3040 … … 3025 3059 } 3026 3060 3061 bool wcache_invalidate_cache_noinit(void) 3062 { 3063 struct winbindd_domain *domain; 3064 3065 for (domain = domain_list(); domain; domain = domain->next) { 3066 struct winbind_cache *cache; 3067 3068 /* Skip uninitialized domains. */ 3069 if (!domain->initialized && !domain->internal) { 3070 continue; 3071 } 3072 3073 cache = get_cache(domain); 3074 3075 DEBUG(10, ("wcache_invalidate_cache: invalidating cache " 3076 "entries for %s\n", domain->name)); 3077 if (cache) { 3078 if (cache->tdb) { 3079 tdb_traverse(cache->tdb, traverse_fn, NULL); 3080 /* 3081 * Flushing cache has nothing to with domains. 3082 * return here if we successfully flushed once. 3083 * To avoid unnecessary traversing the cache. 3084 */ 3085 return true; 3086 } else { 3087 return false; 3088 } 3089 } 3090 } 3091 return true; 3092 } 3093 3027 3094 bool init_wcache(void) 3028 3095 { … … 3038 3105 wcache->tdb = tdb_open_log(cache_path("winbindd_cache.tdb"), 3039 3106 WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, 3040 lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST), 3107 TDB_INCOMPATIBLE_HASH | 3108 (lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST)), 3041 3109 O_RDWR|O_CREAT, 0600); 3042 3110 … … 3115 3183 } 3116 3184 3117 bool lookup_cached_sid(TALLOC_CTX *mem_ctx, const DOM_SID*sid,3185 bool lookup_cached_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, 3118 3186 char **domain_name, char **name, 3119 3187 enum lsa_SidType *type) … … 3131 3199 } 3132 3200 3133 bool lookup_cached_name(TALLOC_CTX *mem_ctx, 3134 const char *domain_name, 3201 bool lookup_cached_name(const char *domain_name, 3135 3202 const char *name, 3136 DOM_SID*sid,3203 struct dom_sid *sid, 3137 3204 enum lsa_SidType *type) 3138 3205 { … … 3159 3226 void cache_name2sid(struct winbindd_domain *domain, 3160 3227 const char *domain_name, const char *name, 3161 enum lsa_SidType type, const DOM_SID*sid)3228 enum lsa_SidType type, const struct dom_sid *sid) 3162 3229 { 3163 3230 refresh_sequence_number(domain, false); … … 3211 3278 wcache->tdb = tdb_open_log(cache_path("winbindd_cache.tdb"), 3212 3279 WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, 3213 lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST), 3280 TDB_INCOMPATIBLE_HASH | 3281 (lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST)), 3214 3282 O_RDWR|O_CREAT, 0600); 3215 3283 … … 3284 3352 } 3285 3353 3286 NTSTATUS wcache_remove_oldest_cached_creds(struct winbindd_domain *domain, const DOM_SID *sid)3354 NTSTATUS wcache_remove_oldest_cached_creds(struct winbindd_domain *domain, const struct dom_sid *sid) 3287 3355 { 3288 3356 struct winbind_cache *cache = get_cache(domain); … … 3449 3517 centry->ofs = 0; 3450 3518 3451 if (centry->len < 8) {3519 if (centry->len < 16) { 3452 3520 /* huh? corrupt cache? */ 3453 DEBUG(0,("create_centry_validate: Corrupt cache for key %s (len < 8) ?\n", kstr)); 3521 DEBUG(0,("create_centry_validate: Corrupt cache for key %s " 3522 "(len < 16) ?\n", kstr)); 3454 3523 centry_free(centry); 3455 3524 state->bad_entry = true; … … 3460 3529 centry->status = NT_STATUS(centry_uint32(centry)); 3461 3530 centry->sequence_number = centry_uint32(centry); 3531 centry->timeout = centry_uint64_t(centry); 3462 3532 return centry; 3463 3533 } … … 3485 3555 (void)centry_uint32(centry); 3486 3556 if (NT_STATUS_IS_OK(centry->status)) { 3487 DOM_SIDsid;3557 struct dom_sid sid; 3488 3558 (void)centry_sid(centry, &sid); 3489 3559 } … … 3525 3595 { 3526 3596 struct cache_entry *centry = create_centry_validate(keystr, dbuf, state); 3527 DOM_SIDsid;3597 struct dom_sid sid; 3528 3598 3529 3599 if (!centry) { … … 3633 3703 3634 3704 for (i=0; i< num_entries; i++) { 3635 DOM_SIDsid;3705 struct dom_sid sid; 3636 3706 (void)centry_string(centry, mem_ctx); 3637 3707 (void)centry_string(centry, mem_ctx); … … 3691 3761 3692 3762 for (i=0; i< num_groups; i++) { 3693 DOM_SIDsid;3763 struct dom_sid sid; 3694 3764 centry_sid(centry, &sid); 3695 3765 } … … 3742 3812 3743 3813 for (i=0; i< num_names; i++) { 3744 DOM_SIDsid;3814 struct dom_sid sid; 3745 3815 centry_sid(centry, &sid); 3746 3816 (void)centry_string(centry, mem_ctx); … … 4029 4099 tdb = tdb_open_log(tdb_path, 4030 4100 WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, 4101 TDB_INCOMPATIBLE_HASH | 4031 4102 ( lp_winbind_offline_logon() 4032 4103 ? TDB_DEFAULT … … 4473 4544 } 4474 4545 4475 4476 4546 /********************************************************************* 4477 4547 ********************************************************************/ 4478 4548 4549 struct winbindd_tdc_domain* 4550 wcache_tdc_fetch_domainbysid(TALLOC_CTX *ctx, 4551 const struct dom_sid *sid) 4552 { 4553 struct winbindd_tdc_domain *dom_list = NULL; 4554 size_t num_domains = 0; 4555 int i; 4556 struct winbindd_tdc_domain *d = NULL; 4557 4558 DEBUG(10,("wcache_tdc_fetch_domainbysid: Searching for domain %s\n", 4559 sid_string_dbg(sid))); 4560 4561 if (!init_wcache()) { 4562 return false; 4563 } 4564 4565 /* fetch the list */ 4566 4567 wcache_tdc_fetch_list(&dom_list, &num_domains); 4568 4569 for (i = 0; i<num_domains; i++) { 4570 if (sid_equal(sid, &(dom_list[i].sid))) { 4571 DEBUG(10, ("wcache_tdc_fetch_domainbysid: " 4572 "Found domain %s for SID %s\n", 4573 dom_list[i].domain_name, 4574 sid_string_dbg(sid))); 4575 4576 d = TALLOC_P(ctx, struct winbindd_tdc_domain); 4577 if (!d) 4578 break; 4579 4580 d->domain_name = talloc_strdup(d, 4581 dom_list[i].domain_name); 4582 4583 d->dns_name = talloc_strdup(d, dom_list[i].dns_name); 4584 sid_copy(&d->sid, &dom_list[i].sid); 4585 d->trust_flags = dom_list[i].trust_flags; 4586 d->trust_type = dom_list[i].trust_type; 4587 d->trust_attribs = dom_list[i].trust_attribs; 4588 4589 break; 4590 } 4591 } 4592 4593 TALLOC_FREE(dom_list); 4594 4595 return d; 4596 } 4597 4598 4599 /********************************************************************* 4600 ********************************************************************/ 4601 4479 4602 void wcache_tdc_clear( void ) 4480 4603 { … … 4493 4616 static void wcache_save_user_pwinfo(struct winbindd_domain *domain, 4494 4617 NTSTATUS status, 4495 const DOM_SID*user_sid,4618 const struct dom_sid *user_sid, 4496 4619 const char *homedir, 4497 4620 const char *shell, … … 4517 4640 } 4518 4641 4642 #ifdef HAVE_ADS 4643 4519 4644 NTSTATUS nss_get_info_cached( struct winbindd_domain *domain, 4520 const DOM_SID*user_sid,4645 const struct dom_sid *user_sid, 4521 4646 TALLOC_CTX *ctx, 4522 ADS_STRUCT *ads, LDAPMessage *msg,4523 4647 const char **homedir, const char **shell, 4524 4648 const char **gecos, gid_t *p_gid) … … 4552 4676 do_query: 4553 4677 4554 nt_status = nss_get_info( domain->name, user_sid, ctx, ads, msg,4678 nt_status = nss_get_info( domain->name, user_sid, ctx, 4555 4679 homedir, shell, gecos, p_gid ); 4556 4680 … … 4576 4700 } 4577 4701 4702 #endif 4578 4703 4579 4704 /* the cache backend methods are exposed via this structure */ … … 4641 4766 bool ret = false; 4642 4767 4643 if (!wcache_opnum_cacheable(opnum)) { 4768 if (!wcache_opnum_cacheable(opnum) || 4769 is_my_own_sam_domain(domain) || 4770 is_builtin_domain(domain)) { 4644 4771 return false; 4645 4772 } … … 4658 4785 return false; 4659 4786 } 4660 if (data.dsize < 4) {4787 if (data.dsize < 12) { 4661 4788 goto fail; 4662 4789 } … … 4664 4791 if (!is_domain_offline(domain)) { 4665 4792 uint32_t entry_seqnum, dom_seqnum, last_check; 4793 uint64_t entry_timeout; 4666 4794 4667 4795 if (!wcache_fetch_seqnum(domain->name, &dom_seqnum, … … 4675 4803 goto fail; 4676 4804 } 4677 } 4678 4679 resp->data = (uint8_t *)talloc_memdup(mem_ctx, data.dptr + 4, 4680 data.dsize - 4); 4805 entry_timeout = BVAL(data.dptr, 4); 4806 if (entry_timeout > time(NULL)) { 4807 DEBUG(10, ("Entry has timed out\n")); 4808 goto fail; 4809 } 4810 } 4811 4812 resp->data = (uint8_t *)talloc_memdup(mem_ctx, data.dptr + 12, 4813 data.dsize - 12); 4681 4814 if (resp->data == NULL) { 4682 4815 DEBUG(10, ("talloc failed\n")); 4683 4816 goto fail; 4684 4817 } 4685 resp->length = data.dsize - 4;4818 resp->length = data.dsize - 12; 4686 4819 4687 4820 ret = true; … … 4696 4829 TDB_DATA key, data; 4697 4830 uint32_t dom_seqnum, last_check; 4698 4699 if (!wcache_opnum_cacheable(opnum)) { 4831 uint64_t timeout; 4832 4833 if (!wcache_opnum_cacheable(opnum) || 4834 is_my_own_sam_domain(domain) || 4835 is_builtin_domain(domain)) { 4700 4836 return; 4701 4837 } … … 4715 4851 } 4716 4852 4717 data.dsize = resp->length + 4; 4853 timeout = time(NULL) + lp_winbind_cache_time(); 4854 4855 data.dsize = resp->length + 12; 4718 4856 data.dptr = talloc_array(key.dptr, uint8_t, data.dsize); 4719 4857 if (data.dptr == NULL) { … … 4722 4860 4723 4861 SIVAL(data.dptr, 0, dom_seqnum); 4724 memcpy(data.dptr+4, resp->data, resp->length); 4862 SBVAL(data.dptr, 4, timeout); 4863 memcpy(data.dptr + 12, resp->data, resp->length); 4725 4864 4726 4865 tdb_store(wcache->tdb, key, data, 0); -
vendor/current/source3/winbindd/winbindd_ccache_access.c
r414 r740 24 24 #include "includes.h" 25 25 #include "winbindd.h" 26 #include "../libcli/auth/ntlmssp.h" 26 27 27 28 #undef DBGC_CLASS … … 51 52 { 52 53 NTSTATUS status; 53 NTLMSSP_STATE*ntlmssp_state = NULL;54 struct ntlmssp_state *ntlmssp_state = NULL; 54 55 DATA_BLOB dummy_msg, reply; 55 56 56 status = ntlmssp_client_start(&ntlmssp_state); 57 status = ntlmssp_client_start(NULL, 58 global_myname(), 59 lp_workgroup(), 60 lp_client_ntlmv2_auth(), 61 &ntlmssp_state); 57 62 58 63 if (!NT_STATUS_IS_OK(status)) { … … 132 137 133 138 done: 134 ntlmssp_end(&ntlmssp_state);139 TALLOC_FREE(ntlmssp_state); 135 140 return status; 136 141 } … … 164 169 struct winbindd_domain *domain; 165 170 fstring name_domain, name_user; 171 NTSTATUS result = NT_STATUS_NOT_SUPPORTED; 172 struct WINBINDD_MEMORY_CREDS *entry; 173 DATA_BLOB initial, challenge, auth; 174 uint32 initial_blob_len, challenge_blob_len, extra_len; 166 175 167 176 /* Ensure null termination */ … … 195 204 return; 196 205 } 197 198 sendto_domain(state, domain);199 }200 201 enum winbindd_result winbindd_dual_ccache_ntlm_auth(struct winbindd_domain *domain,202 struct winbindd_cli_state *state)203 {204 NTSTATUS result = NT_STATUS_NOT_SUPPORTED;205 struct WINBINDD_MEMORY_CREDS *entry;206 DATA_BLOB initial, challenge, auth;207 fstring name_domain, name_user;208 uint32 initial_blob_len, challenge_blob_len, extra_len;209 210 /* Ensure null termination */211 state->request->data.ccache_ntlm_auth.user[212 sizeof(state->request->data.ccache_ntlm_auth.user)-1]='\0';213 214 DEBUG(3, ("winbindd_dual_ccache_ntlm_auth: [%5lu]: perform NTLM auth on "215 "behalf of user %s (dual)\n", (unsigned long)state->pid,216 state->request->data.ccache_ntlm_auth.user));217 206 218 207 /* validate blob lengths */ … … 263 252 } 264 253 265 initial = data_blob(state->request->extra_data.data, initial_blob_len); 266 challenge = data_blob(state->request->extra_data.data + initial_blob_len, 267 state->request->data.ccache_ntlm_auth.challenge_blob_len); 268 269 if (!initial.data || !challenge.data) { 270 result = NT_STATUS_NO_MEMORY; 271 } else { 272 result = do_ntlm_auth_with_hashes( 273 name_user, name_domain, entry->lm_hash, entry->nt_hash, 274 initial, challenge, &auth, 275 state->response->data.ccache_ntlm_auth.session_key); 276 } 277 278 data_blob_free(&initial); 279 data_blob_free(&challenge); 254 initial = data_blob_const(state->request->extra_data.data, 255 initial_blob_len); 256 challenge = data_blob_const( 257 state->request->extra_data.data + initial_blob_len, 258 state->request->data.ccache_ntlm_auth.challenge_blob_len); 259 260 result = do_ntlm_auth_with_hashes( 261 name_user, name_domain, entry->lm_hash, entry->nt_hash, 262 initial, challenge, &auth, 263 state->response->data.ccache_ntlm_auth.session_key); 280 264 281 265 if (!NT_STATUS_IS_OK(result)) { … … 295 279 296 280 process_result: 297 return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; 281 if (!NT_STATUS_IS_OK(result)) { 282 request_error(state); 283 return; 284 } 285 request_ok(state); 298 286 } 299 287 … … 302 290 struct winbindd_domain *domain; 303 291 fstring name_domain, name_user; 292 NTSTATUS status; 304 293 305 294 /* Ensure null termination */ … … 315 304 /* Parse domain and username */ 316 305 317 if (!canonicalize_username(state->request->data.ccache_ ntlm_auth.user,306 if (!canonicalize_username(state->request->data.ccache_save.user, 318 307 name_domain, name_user)) { 319 308 DEBUG(5,("winbindd_ccache_save: cannot parse domain and user " … … 324 313 } 325 314 315 /* 316 * The domain is checked here only for compatibility 317 * reasons. We used to do the winbindd memory ccache for 318 * ntlm_auth in the domain child. With that code, we had to 319 * make sure that we do have a domain around to send this 320 * to. Now we do the memory cache in the parent winbindd, 321 * where it would not matter if we have a domain or not. 322 */ 323 326 324 domain = find_auth_domain(state->request->flags, name_domain); 327 328 325 if (domain == NULL) { 329 326 DEBUG(5, ("winbindd_ccache_save: can't get domain [%s]\n", … … 337 334 return; 338 335 } 339 340 sendto_domain(state, domain);341 }342 343 enum winbindd_result winbindd_dual_ccache_save(344 struct winbindd_domain *domain, struct winbindd_cli_state *state)345 {346 NTSTATUS status = NT_STATUS_NOT_SUPPORTED;347 348 /* Ensure null termination */349 state->request->data.ccache_save.user[350 sizeof(state->request->data.ccache_save.user)-1]='\0';351 state->request->data.ccache_save.pass[352 sizeof(state->request->data.ccache_save.pass)-1]='\0';353 354 DEBUG(3, ("winbindd_dual_ccache_save: [%5lu]: save password of user "355 "%s\n", (unsigned long)state->pid,356 state->request->data.ccache_save.user));357 336 358 337 status = winbindd_add_memory_creds( … … 364 343 DEBUG(1, ("winbindd_add_memory_creds failed %s\n", 365 344 nt_errstr(status))); 366 re turn WINBINDD_ERROR;367 }368 369 re turn WINBINDD_OK;370 } 345 request_error(state); 346 return; 347 } 348 request_ok(state); 349 } -
vendor/current/source3/winbindd/winbindd_change_machine_acct.c
r414 r740 21 21 #include "includes.h" 22 22 #include "winbindd.h" 23 #include "librpc/gen_ndr/ cli_wbint.h"23 #include "librpc/gen_ndr/ndr_wbint_c.h" 24 24 25 25 struct winbindd_change_machine_acct_state { … … 58 58 } 59 59 60 subreq = rpccli_wbint_ChangeMachineAccount_send(state, ev,61 dom ain->child.rpccli);60 subreq = dcerpc_wbint_ChangeMachineAccount_send(state, ev, 61 dom_child_handle(domain)); 62 62 if (tevent_req_nomem(subreq, req)) { 63 63 return tevent_req_post(req, ev); … … 75 75 NTSTATUS status, result; 76 76 77 status = rpccli_wbint_ChangeMachineAccount_recv(subreq, state, &result);78 if ( !NT_STATUS_IS_OK(status)) {77 status = dcerpc_wbint_ChangeMachineAccount_recv(subreq, state, &result); 78 if (any_nt_status_not_ok(status, result, &status)) { 79 79 tevent_req_nterror(req, status); 80 return;81 }82 if (!NT_STATUS_IS_OK(result)) {83 tevent_req_nterror(req, result);84 80 return; 85 81 } -
vendor/current/source3/winbindd/winbindd_check_machine_acct.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ cli_wbint.h"22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 23 24 24 struct winbindd_check_machine_acct_state { … … 62 62 } 63 63 64 subreq = rpccli_wbint_CheckMachineAccount_send(state, ev,65 dom ain->child.rpccli);64 subreq = dcerpc_wbint_CheckMachineAccount_send(state, ev, 65 dom_child_handle(domain)); 66 66 if (tevent_req_nomem(subreq, req)) { 67 67 return tevent_req_post(req, ev); … … 79 79 NTSTATUS status, result; 80 80 81 status = rpccli_wbint_CheckMachineAccount_recv(subreq, state, &result);82 if ( !NT_STATUS_IS_OK(status)) {81 status = dcerpc_wbint_CheckMachineAccount_recv(subreq, state, &result); 82 if (any_nt_status_not_ok(status, result, &status)) { 83 83 tevent_req_nterror(req, status); 84 return;85 }86 if (!NT_STATUS_IS_OK(result)) {87 tevent_req_nterror(req, result);88 84 return; 89 85 } … … 94 90 struct winbindd_response *presp) 95 91 { 96 return tevent_req_simple_recv_ntstatus(req); 92 NTSTATUS status = tevent_req_simple_recv_ntstatus(req); 93 94 set_auth_errors(presp, status); 95 return status; 97 96 } -
vendor/current/source3/winbindd/winbindd_cm.c
r594 r740 62 62 #include "winbindd.h" 63 63 #include "../libcli/auth/libcli_auth.h" 64 #include "../librpc/gen_ndr/cli_netlogon.h" 65 #include "../librpc/gen_ndr/cli_samr.h" 66 #include "../librpc/gen_ndr/cli_lsa.h" 67 #include "../librpc/gen_ndr/cli_dssetup.h" 64 #include "../librpc/gen_ndr/ndr_netlogon_c.h" 65 #include "rpc_client/cli_pipe.h" 66 #include "rpc_client/cli_netlogon.h" 67 #include "../librpc/gen_ndr/ndr_samr_c.h" 68 #include "../librpc/gen_ndr/ndr_lsa_c.h" 69 #include "rpc_client/cli_lsarpc.h" 70 #include "../librpc/gen_ndr/ndr_dssetup_c.h" 71 #include "libads/sitename_cache.h" 72 #include "libsmb/libsmb.h" 73 #include "libsmb/clidgram.h" 74 #include "ads.h" 75 #include "secrets.h" 76 #include "../libcli/security/security.h" 77 #include "passdb.h" 78 #include "messages.h" 68 79 69 80 #undef DBGC_CLASS … … 179 190 pid_t parent_pid = sys_getpid(); 180 191 char *lfile = NULL; 192 NTSTATUS status; 181 193 182 194 if (domain->dc_probe_pid != (pid_t)-1) { … … 223 235 } 224 236 225 if (!winbindd_reinit_after_fork(lfile)) { 237 status = winbindd_reinit_after_fork(NULL, lfile); 238 if (!NT_STATUS_IS_OK(status)) { 239 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n", 240 nt_errstr(status))); 226 241 messaging_send_buf(winbind_messaging_context(), 227 242 pid_to_procid(parent_pid), … … 285 300 /* Are we still in "startup" mode ? */ 286 301 287 if (domain->startup && ( now.tv_sec> domain->startup_time + 30)) {302 if (domain->startup && (time_mono(NULL) > domain->startup_time + 30)) { 288 303 /* No longer in "startup" mode. */ 289 304 DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n", … … 502 517 503 518 /* Go into "startup" mode again. */ 504 domain->startup_time = t ev.tv_sec;519 domain->startup_time = time_mono(NULL); 505 520 domain->startup = True; 506 521 … … 535 550 ****************************************************************/ 536 551 537 void winbind_add_failed_connection_entry(const struct winbindd_domain *domain, 538 const char *server, 539 NTSTATUS result) 552 static void winbind_add_failed_connection_entry( 553 const struct winbindd_domain *domain, 554 const char *server, 555 NTSTATUS result) 540 556 { 541 557 add_failed_connection_entry(domain->name, server, result); … … 595 611 const char *tmp = NULL; 596 612 const char *p; 613 struct dcerpc_binding_handle *b; 597 614 598 615 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the … … 619 636 } 620 637 638 b = netlogon_pipe->binding_handle; 639 621 640 /* This call can take a long time - allow the server to time out. 622 641 35 seconds should do it. */ … … 627 646 struct netr_DsRGetDCNameInfo *domain_info = NULL; 628 647 629 result = rpccli_netr_DsRGetDCName(netlogon_pipe,648 result = dcerpc_netr_DsRGetDCName(b, 630 649 mem_ctx, 631 650 our_domain->dcname, … … 654 673 } 655 674 } else { 656 result = rpccli_netr_GetAnyDCName(netlogon_pipe, mem_ctx,675 result = dcerpc_netr_GetAnyDCName(b, mem_ctx, 657 676 our_domain->dcname, 658 677 domain->name, … … 665 684 666 685 if (!NT_STATUS_IS_OK(result)) { 667 DEBUG(10,(" rpccli_netr_GetAnyDCName failed: %s\n",686 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n", 668 687 nt_errstr(result))); 669 688 talloc_destroy(mem_ctx); … … 672 691 673 692 if (!W_ERROR_IS_OK(werr)) { 674 DEBUG(10,(" rpccli_netr_GetAnyDCName failed: %s\n",693 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n", 675 694 win_errstr(werr))); 676 695 talloc_destroy(mem_ctx); … … 678 697 } 679 698 680 /* rpccli_netr_GetAnyDCName gives us a name with \\ */699 /* dcerpc_netr_GetAnyDCName gives us a name with \\ */ 681 700 p = strip_hostname(tmp); 682 701 … … 685 704 talloc_destroy(mem_ctx); 686 705 687 DEBUG(10,(" rpccli_netr_GetAnyDCName returned %s\n", dcname));706 DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname)); 688 707 689 708 if (!resolve_name(dcname, dc_ss, 0x20, true)) { … … 802 821 (*cli)->timeout = 10000; /* 10 seconds */ 803 822 (*cli)->fd = sockfd; 804 fstrcpy((*cli)->desthost, controller); 823 (*cli)->desthost = talloc_strdup((*cli), controller); 824 if ((*cli)->desthost == NULL) { 825 result = NT_STATUS_NO_MEMORY; 826 goto done; 827 } 828 805 829 (*cli)->use_kerberos = True; 806 830 … … 1099 1123 struct ip_service ip_list; 1100 1124 uint32_t nt_version = NETLOGON_NT_VERSION_1; 1125 NTSTATUS status; 1126 const char *dc_name; 1101 1127 1102 1128 ip_list.ss = *pss; 1103 1129 ip_list.port = 0; 1104 1130 1105 #ifdef WITH_ADS1131 #ifdef HAVE_ADS 1106 1132 /* For active directory servers, try to get the ldap server name. 1107 1133 None of these failures should be considered critical for now */ … … 1163 1189 #endif 1164 1190 1165 /* try GETDC requests next */ 1166 1167 if (send_getdc_request(mem_ctx, winbind_messaging_context(), 1168 pss, domain->name, &domain->sid, 1169 nt_version)) { 1170 const char *dc_name = NULL; 1171 int i; 1172 smb_msleep(100); 1173 for (i=0; i<5; i++) { 1174 if (receive_getdc_response(mem_ctx, pss, domain->name, 1175 &nt_version, 1176 &dc_name, NULL)) { 1177 fstrcpy(name, dc_name); 1178 namecache_store(name, 0x20, 1, &ip_list); 1179 return True; 1180 } 1181 smb_msleep(500); 1182 } 1191 status = nbt_getdc(winbind_messaging_context(), pss, domain->name, 1192 &domain->sid, nt_version, mem_ctx, &nt_version, 1193 &dc_name, NULL); 1194 if (NT_STATUS_IS_OK(status)) { 1195 fstrcpy(name, dc_name); 1196 namecache_store(name, 0x20, 1, &ip_list); 1197 return True; 1183 1198 } 1184 1199 … … 1369 1384 return False; 1370 1385 1371 status = smbsock_any_connect(addrs, dcnames, num_addrs,1372 fd, &fd_index, NULL);1386 status = smbsock_any_connect(addrs, dcnames, NULL, NULL, NULL, 1387 num_addrs, 0, 10, fd, &fd_index, NULL); 1373 1388 if (!NT_STATUS_IS_OK(status)) { 1374 1389 for (i=0; i<num_dcs; i++) { … … 1417 1432 } 1418 1433 1434 static char *current_dc_key(TALLOC_CTX *mem_ctx, const char *domain_name) 1435 { 1436 return talloc_asprintf_strupper_m(mem_ctx, "CURRENT_DCNAME/%s", 1437 domain_name); 1438 } 1439 1440 static void store_current_dc_in_gencache(const char *domain_name, 1441 const char *dc_name, 1442 struct cli_state *cli) 1443 { 1444 char addr[INET6_ADDRSTRLEN]; 1445 char *key = NULL; 1446 char *value = NULL; 1447 1448 if (cli == NULL) { 1449 return; 1450 } 1451 if (cli->fd == -1) { 1452 return; 1453 } 1454 get_peer_addr(cli->fd, addr, sizeof(addr)); 1455 1456 key = current_dc_key(talloc_tos(), domain_name); 1457 if (key == NULL) { 1458 goto done; 1459 } 1460 1461 value = talloc_asprintf(talloc_tos(), "%s %s", addr, dc_name); 1462 if (value == NULL) { 1463 goto done; 1464 } 1465 1466 gencache_set(key, value, 0x7fffffff); 1467 done: 1468 TALLOC_FREE(value); 1469 TALLOC_FREE(key); 1470 } 1471 1472 bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx, 1473 const char *domain_name, 1474 char **p_dc_name, char **p_dc_ip) 1475 { 1476 char *key, *value, *p; 1477 bool ret = false; 1478 char *dc_name = NULL; 1479 char *dc_ip = NULL; 1480 1481 key = current_dc_key(talloc_tos(), domain_name); 1482 if (key == NULL) { 1483 goto done; 1484 } 1485 if (!gencache_get(key, &value, NULL)) { 1486 goto done; 1487 } 1488 p = strchr(value, ' '); 1489 if (p == NULL) { 1490 goto done; 1491 } 1492 dc_ip = talloc_strndup(mem_ctx, value, p - value); 1493 if (dc_ip == NULL) { 1494 goto done; 1495 } 1496 dc_name = talloc_strdup(mem_ctx, p+1); 1497 if (dc_name == NULL) { 1498 goto done; 1499 } 1500 1501 if (p_dc_ip != NULL) { 1502 *p_dc_ip = dc_ip; 1503 dc_ip = NULL; 1504 } 1505 if (p_dc_name != NULL) { 1506 *p_dc_name = dc_name; 1507 dc_name = NULL; 1508 } 1509 ret = true; 1510 done: 1511 TALLOC_FREE(dc_name); 1512 TALLOC_FREE(dc_ip); 1513 TALLOC_FREE(key); 1514 return ret; 1515 } 1516 1419 1517 static NTSTATUS cm_open_connection(struct winbindd_domain *domain, 1420 1518 struct winbindd_cm_conn *new_conn) … … 1432 1530 1433 1531 /* we have to check the server affinity cache here since 1434 later we select ea DC based on response time and not preference */1532 later we select a DC based on response time and not preference */ 1435 1533 1436 1534 /* Check the negative connection cache … … 1481 1579 NTSTATUS status; 1482 1580 1483 status = smbsock_connect(&domain->dcaddr, NULL, NULL, 1484 &fd, NULL); 1581 status = smbsock_connect(&domain->dcaddr, 0, 1582 NULL, -1, NULL, -1, 1583 &fd, NULL, 10); 1485 1584 if (!NT_STATUS_IS_OK(status)) { 1486 1585 fd = -1; … … 1517 1616 } 1518 1617 set_domain_online(domain); 1618 1619 /* 1620 * Much as I hate global state, this seems to be the point 1621 * where we can be certain that we have a proper connection to 1622 * a DC. wbinfo --dc-info needs that information, store it in 1623 * gencache with a looong timeout. This will need revisiting 1624 * once we start to connect to multiple DCs, wbcDcInfo is 1625 * already prepared for that. 1626 */ 1627 store_current_dc_in_gencache(domain->name, domain->dcname, 1628 new_conn->cli); 1519 1629 } else { 1520 1630 /* Ensure we setup the retry handler. */ … … 1530 1640 void invalidate_cm_connection(struct winbindd_cm_conn *conn) 1531 1641 { 1642 NTSTATUS result; 1643 1532 1644 /* We're closing down a possibly dead 1533 1645 connection. Don't have impossibly long (10s) timeouts. */ … … 1538 1650 1539 1651 if (conn->samr_pipe != NULL) { 1652 if (is_valid_policy_hnd(&conn->sam_connect_handle)) { 1653 dcerpc_samr_Close(conn->samr_pipe->binding_handle, 1654 talloc_tos(), 1655 &conn->sam_connect_handle, 1656 &result); 1657 } 1540 1658 TALLOC_FREE(conn->samr_pipe); 1541 1659 /* Ok, it must be dead. Drop timeout to 0.5 sec. */ … … 1546 1664 1547 1665 if (conn->lsa_pipe != NULL) { 1666 if (is_valid_policy_hnd(&conn->lsa_policy)) { 1667 dcerpc_lsa_Close(conn->lsa_pipe->binding_handle, 1668 talloc_tos(), 1669 &conn->lsa_policy, 1670 &result); 1671 } 1548 1672 TALLOC_FREE(conn->lsa_pipe); 1549 1673 /* Ok, it must be dead. Drop timeout to 0.5 sec. */ … … 1554 1678 1555 1679 if (conn->lsa_pipe_tcp != NULL) { 1680 if (is_valid_policy_hnd(&conn->lsa_policy)) { 1681 dcerpc_lsa_Close(conn->lsa_pipe_tcp->binding_handle, 1682 talloc_tos(), 1683 &conn->lsa_policy, 1684 &result); 1685 } 1556 1686 TALLOC_FREE(conn->lsa_pipe_tcp); 1557 1687 /* Ok, it must be dead. Drop timeout to 0.5 sec. */ … … 1579 1709 { 1580 1710 struct winbindd_domain *domain; 1711 struct winbindd_cli_state *cli_state; 1581 1712 1582 1713 for (domain = domain_list(); domain; domain = domain->next) { 1583 if (domain->conn.cli == NULL) 1584 continue; 1585 1586 if (domain->conn.cli->fd == -1) 1587 continue; 1588 1589 close(domain->conn.cli->fd); 1590 domain->conn.cli->fd = -1; 1714 struct cli_state *cli = domain->conn.cli; 1715 1716 /* 1717 * first close the low level SMB TCP connection 1718 * so that we don't generate any SMBclose 1719 * requests in invalidate_cm_connection() 1720 */ 1721 if (cli && cli->fd != -1) { 1722 close(domain->conn.cli->fd); 1723 domain->conn.cli->fd = -1; 1724 } 1725 1726 invalidate_cm_connection(&domain->conn); 1727 } 1728 1729 for (cli_state = winbindd_client_list(); 1730 cli_state != NULL; 1731 cli_state = cli_state->next) { 1732 if (cli_state->sock >= 0) { 1733 close(cli_state->sock); 1734 cli_state->sock = -1; 1735 } 1591 1736 } 1592 1737 } … … 1650 1795 NTSTATUS init_dc_connection(struct winbindd_domain *domain) 1651 1796 { 1797 if (domain->internal) { 1798 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 1799 } 1800 1652 1801 if (domain->initialized && !domain->online) { 1653 1802 /* We check for online status elsewhere. */ … … 1683 1832 struct winbindd_domain *our_domain; 1684 1833 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 1834 WERROR werr; 1685 1835 struct netr_DomainTrustList trusts; 1686 1836 int i; … … 1690 1840 struct rpc_pipe_client *cli; 1691 1841 TALLOC_CTX *mem_ctx = NULL; 1842 struct dcerpc_binding_handle *b; 1692 1843 1693 1844 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name )); … … 1724 1875 } 1725 1876 1877 b = cli->binding_handle; 1878 1726 1879 if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) { 1727 1880 DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n")); … … 1729 1882 } 1730 1883 1731 result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,1884 result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx, 1732 1885 cli->desthost, 1733 1886 flags, 1734 1887 &trusts, 1735 NULL);1888 &werr); 1736 1889 if (!NT_STATUS_IS_OK(result)) { 1737 1890 DEBUG(0,("set_dc_type_and_flags_trustinfo: " … … 1741 1894 return false; 1742 1895 } 1896 if (!W_ERROR_IS_OK(werr)) { 1897 DEBUG(0,("set_dc_type_and_flags_trustinfo: " 1898 "failed to query trusted domain list: %s\n", 1899 win_errstr(werr))); 1900 talloc_destroy(mem_ctx); 1901 return false; 1902 } 1743 1903 1744 1904 /* Now find the domain name and get the flags */ … … 1789 1949 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain ) 1790 1950 { 1791 NTSTATUS 1951 NTSTATUS status, result; 1792 1952 WERROR werr; 1793 1953 TALLOC_CTX *mem_ctx = NULL; … … 1810 1970 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name )); 1811 1971 1812 result= cli_rpc_pipe_open_noauth(domain->conn.cli,1972 status = cli_rpc_pipe_open_noauth(domain->conn.cli, 1813 1973 &ndr_table_dssetup.syntax_id, 1814 1974 &cli); 1815 1975 1816 if (!NT_STATUS_IS_OK( result)) {1976 if (!NT_STATUS_IS_OK(status)) { 1817 1977 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to " 1818 1978 "PI_DSSETUP on domain %s: (%s)\n", 1819 domain->name, nt_errstr( result)));1979 domain->name, nt_errstr(status))); 1820 1980 1821 1981 /* if this is just a non-AD domain we need to continue … … 1826 1986 } 1827 1987 1828 result = rpccli_dssetup_DsRoleGetPrimaryDomainInformation(cli, mem_ctx,1988 status = dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli->binding_handle, mem_ctx, 1829 1989 DS_ROLE_BASIC_INFORMATION, 1830 1990 &info, … … 1832 1992 TALLOC_FREE(cli); 1833 1993 1834 if (!NT_STATUS_IS_OK(result)) { 1994 if (NT_STATUS_IS_OK(status)) { 1995 result = werror_to_ntstatus(werr); 1996 } 1997 if (!NT_STATUS_IS_OK(status)) { 1835 1998 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo " 1836 1999 "on domain %s failed: (%s)\n", 1837 domain->name, nt_errstr( result)));2000 domain->name, nt_errstr(status))); 1838 2001 1839 2002 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for … … 1842 2005 * set - gd */ 1843 2006 1844 if (NT_STATUS_ V(result) == DCERPC_FAULT_OP_RNG_ERROR) {2007 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) { 1845 2008 goto no_dssetup; 1846 2009 } … … 1858 2021 1859 2022 no_dssetup: 1860 result= cli_rpc_pipe_open_noauth(domain->conn.cli,2023 status = cli_rpc_pipe_open_noauth(domain->conn.cli, 1861 2024 &ndr_table_lsarpc.syntax_id, &cli); 1862 2025 1863 if (!NT_STATUS_IS_OK( result)) {2026 if (!NT_STATUS_IS_OK(status)) { 1864 2027 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to " 1865 2028 "PI_LSARPC on domain %s: (%s)\n", 1866 domain->name, nt_errstr( result)));2029 domain->name, nt_errstr(status))); 1867 2030 TALLOC_FREE(cli); 1868 2031 TALLOC_FREE(mem_ctx); … … 1870 2033 } 1871 2034 1872 result = rpccli_lsa_open_policy2(cli, mem_ctx, True,2035 status = rpccli_lsa_open_policy2(cli, mem_ctx, True, 1873 2036 SEC_FLAG_MAXIMUM_ALLOWED, &pol); 1874 2037 1875 if (NT_STATUS_IS_OK( result)) {2038 if (NT_STATUS_IS_OK(status)) { 1876 2039 /* This particular query is exactly what Win2k clients use 1877 2040 to determine that the DC is active directory */ 1878 result = rpccli_lsa_QueryInfoPolicy2(cli, mem_ctx,2041 status = dcerpc_lsa_QueryInfoPolicy2(cli->binding_handle, mem_ctx, 1879 2042 &pol, 1880 2043 LSA_POLICY_INFO_DNS, 1881 &lsa_info); 1882 } 1883 1884 if (NT_STATUS_IS_OK(result)) { 2044 &lsa_info, 2045 &result); 2046 } 2047 2048 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) { 1885 2049 domain->active_directory = True; 1886 2050 … … 1912 2076 domain->active_directory = False; 1913 2077 1914 result = rpccli_lsa_open_policy(cli, mem_ctx, True,2078 status = rpccli_lsa_open_policy(cli, mem_ctx, True, 1915 2079 SEC_FLAG_MAXIMUM_ALLOWED, 1916 2080 &pol); 1917 2081 1918 if (!NT_STATUS_IS_OK( result)) {2082 if (!NT_STATUS_IS_OK(status)) { 1919 2083 goto done; 1920 2084 } 1921 2085 1922 result = rpccli_lsa_QueryInfoPolicy(cli, mem_ctx,2086 status = dcerpc_lsa_QueryInfoPolicy(cli->binding_handle, mem_ctx, 1923 2087 &pol, 1924 2088 LSA_POLICY_INFO_ACCOUNT_DOMAIN, 1925 &lsa_info );1926 1927 if (NT_STATUS_IS_OK( result)) {2089 &lsa_info, 2090 &result); 2091 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) { 1928 2092 1929 2093 if (lsa_info->account_domain.name.string) { … … 1993 2157 1994 2158 if (lp_client_schannel() == False) { 1995 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; ;2159 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 1996 2160 } 1997 2161 … … 2016 2180 { 2017 2181 struct winbindd_cm_conn *conn; 2018 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;2182 NTSTATUS status, result; 2019 2183 struct netlogon_creds_CredentialState *p_creds; 2020 2184 char *machine_password = NULL; … … 2022 2186 char *domain_name = NULL; 2023 2187 2024 result = init_dc_connection_rpc(domain); 2025 if (!NT_STATUS_IS_OK(result)) { 2026 return result; 2188 if (sid_check_is_domain(&domain->sid)) { 2189 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle); 2190 } 2191 2192 status = init_dc_connection_rpc(domain); 2193 if (!NT_STATUS_IS_OK(status)) { 2194 return status; 2027 2195 } 2028 2196 … … 2046 2214 (conn->cli->password == NULL || conn->cli->password[0] == '\0')) 2047 2215 { 2048 result= get_trust_creds(domain, &machine_password,2216 status = get_trust_creds(domain, &machine_password, 2049 2217 &machine_account, NULL); 2050 if (!NT_STATUS_IS_OK( result)) {2218 if (!NT_STATUS_IS_OK(status)) { 2051 2219 DEBUG(10, ("cm_connect_sam: No no user available for " 2052 2220 "domain %s, trying schannel\n", conn->cli->domain)); … … 2061 2229 2062 2230 if (!machine_password || !machine_account) { 2063 result= NT_STATUS_NO_MEMORY;2231 status = NT_STATUS_NO_MEMORY; 2064 2232 goto done; 2065 2233 } … … 2067 2235 /* We have an authenticated connection. Use a NTLMSSP SPNEGO 2068 2236 authenticated SAMR pipe with sign & seal. */ 2069 result= cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,2237 status = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli, 2070 2238 &ndr_table_samr.syntax_id, 2071 2239 NCACN_NP, … … 2076 2244 &conn->samr_pipe); 2077 2245 2078 if (!NT_STATUS_IS_OK( result)) {2246 if (!NT_STATUS_IS_OK(status)) { 2079 2247 DEBUG(10,("cm_connect_sam: failed to connect to SAMR " 2080 2248 "pipe for domain %s using NTLMSSP " 2081 2249 "authenticated pipe: user %s\\%s. Error was " 2082 2250 "%s\n", domain->name, domain_name, 2083 machine_account, nt_errstr( result)));2251 machine_account, nt_errstr(status))); 2084 2252 goto schannel; 2085 2253 } … … 2090 2258 domain_name, machine_account)); 2091 2259 2092 result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,2260 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx, 2093 2261 conn->samr_pipe->desthost, 2094 2262 SEC_FLAG_MAXIMUM_ALLOWED, 2095 &conn->sam_connect_handle); 2096 if (NT_STATUS_IS_OK(result)) { 2263 &conn->sam_connect_handle, 2264 &result); 2265 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) { 2097 2266 goto open_domain; 2098 2267 } 2099 DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_Connect2 " 2268 if (NT_STATUS_IS_OK(status)) { 2269 status = result; 2270 } 2271 2272 DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 " 2100 2273 "failed for domain %s, error was %s. Trying schannel\n", 2101 domain->name, nt_errstr( result) ));2274 domain->name, nt_errstr(status) )); 2102 2275 TALLOC_FREE(conn->samr_pipe); 2103 2276 … … 2106 2279 /* Fall back to schannel if it's a W2K pre-SP1 box. */ 2107 2280 2108 result= cm_get_schannel_creds(domain, &p_creds);2109 if (!NT_STATUS_IS_OK( result)) {2281 status = cm_get_schannel_creds(domain, &p_creds); 2282 if (!NT_STATUS_IS_OK(status)) { 2110 2283 /* If this call fails - conn->cli can now be NULL ! */ 2111 2284 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info " 2112 2285 "for domain %s (error %s), trying anon\n", 2113 2286 domain->name, 2114 nt_errstr( result) ));2287 nt_errstr(status) )); 2115 2288 goto anonymous; 2116 2289 } 2117 result= cli_rpc_pipe_open_schannel_with_key2290 status = cli_rpc_pipe_open_schannel_with_key 2118 2291 (conn->cli, &ndr_table_samr.syntax_id, NCACN_NP, 2119 2292 DCERPC_AUTH_LEVEL_PRIVACY, 2120 2293 domain->name, &p_creds, &conn->samr_pipe); 2121 2294 2122 if (!NT_STATUS_IS_OK( result)) {2295 if (!NT_STATUS_IS_OK(status)) { 2123 2296 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for " 2124 2297 "domain %s using schannel. Error was %s\n", 2125 domain->name, nt_errstr( result) ));2298 domain->name, nt_errstr(status) )); 2126 2299 goto anonymous; 2127 2300 } … … 2129 2302 "schannel.\n", domain->name )); 2130 2303 2131 result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,2304 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx, 2132 2305 conn->samr_pipe->desthost, 2133 2306 SEC_FLAG_MAXIMUM_ALLOWED, 2134 &conn->sam_connect_handle); 2135 if (NT_STATUS_IS_OK(result)) { 2307 &conn->sam_connect_handle, 2308 &result); 2309 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) { 2136 2310 goto open_domain; 2137 2311 } 2138 DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_Connect2 failed " 2312 if (NT_STATUS_IS_OK(status)) { 2313 status = result; 2314 } 2315 DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed " 2139 2316 "for domain %s, error was %s. Trying anonymous\n", 2140 domain->name, nt_errstr( result) ));2317 domain->name, nt_errstr(status) )); 2141 2318 TALLOC_FREE(conn->samr_pipe); 2142 2319 … … 2144 2321 2145 2322 /* Finally fall back to anonymous. */ 2146 result= cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,2323 status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id, 2147 2324 &conn->samr_pipe); 2148 2325 2149 if (!NT_STATUS_IS_OK( result)) {2326 if (!NT_STATUS_IS_OK(status)) { 2150 2327 goto done; 2151 2328 } 2152 2329 2153 result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,2330 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx, 2154 2331 conn->samr_pipe->desthost, 2155 2332 SEC_FLAG_MAXIMUM_ALLOWED, 2156 &conn->sam_connect_handle); 2157 if (!NT_STATUS_IS_OK(result)) { 2333 &conn->sam_connect_handle, 2334 &result); 2335 if (!NT_STATUS_IS_OK(status)) { 2158 2336 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed " 2159 2337 "for domain %s Error was %s\n", 2160 domain->name, nt_errstr( result) ));2338 domain->name, nt_errstr(status) )); 2161 2339 goto done; 2162 2340 } 2341 if (!NT_STATUS_IS_OK(result)) { 2342 status = result; 2343 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed " 2344 "for domain %s Error was %s\n", 2345 domain->name, nt_errstr(result))); 2346 goto done; 2347 } 2163 2348 2164 2349 open_domain: 2165 result = rpccli_samr_OpenDomain(conn->samr_pipe,2350 status = dcerpc_samr_OpenDomain(conn->samr_pipe->binding_handle, 2166 2351 mem_ctx, 2167 2352 &conn->sam_connect_handle, 2168 2353 SEC_FLAG_MAXIMUM_ALLOWED, 2169 2354 &domain->sid, 2170 &conn->sam_domain_handle); 2171 2355 &conn->sam_domain_handle, 2356 &result); 2357 if (!NT_STATUS_IS_OK(status)) { 2358 goto done; 2359 } 2360 2361 status = result; 2172 2362 done: 2173 2363 2174 if (NT_STATUS_EQUAL( result, NT_STATUS_ACCESS_DENIED)) {2364 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { 2175 2365 /* 2176 2366 * if we got access denied, we might just have no access rights … … 2182 2372 TALLOC_FREE(conn->samr_pipe); 2183 2373 ZERO_STRUCT(conn->sam_domain_handle); 2184 return result;2185 } else if (!NT_STATUS_IS_OK( result)) {2374 return status; 2375 } else if (!NT_STATUS_IS_OK(status)) { 2186 2376 invalidate_cm_connection(conn); 2187 return result;2377 return status; 2188 2378 } 2189 2379 … … 2192 2382 SAFE_FREE(machine_password); 2193 2383 SAFE_FREE(machine_account); 2194 return result;2384 return status; 2195 2385 } 2196 2386 … … 2504 2694 return NT_STATUS_OK; 2505 2695 } 2696 2697 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx, 2698 void *private_data, 2699 uint32_t msg_type, 2700 struct server_id server_id, 2701 DATA_BLOB *data) 2702 { 2703 struct winbindd_domain *domain; 2704 char *freeit = NULL; 2705 char *addr; 2706 2707 if ((data == NULL) 2708 || (data->data == NULL) 2709 || (data->length == 0) 2710 || (data->data[data->length-1] != '\0')) { 2711 DEBUG(1, ("invalid msg_ip_dropped message: not a valid " 2712 "string\n")); 2713 return; 2714 } 2715 2716 addr = (char *)data->data; 2717 DEBUG(10, ("IP %s dropped\n", addr)); 2718 2719 if (!is_ipaddress(addr)) { 2720 char *slash; 2721 /* 2722 * Some code sends us ip addresses with the /netmask 2723 * suffix 2724 */ 2725 slash = strchr(addr, '/'); 2726 if (slash == NULL) { 2727 DEBUG(1, ("invalid msg_ip_dropped message: %s", 2728 addr)); 2729 return; 2730 } 2731 freeit = talloc_strndup(talloc_tos(), addr, slash-addr); 2732 if (freeit == NULL) { 2733 DEBUG(1, ("talloc failed\n")); 2734 return; 2735 } 2736 addr = freeit; 2737 DEBUG(10, ("Stripped /netmask to IP %s\n", addr)); 2738 } 2739 2740 for (domain = domain_list(); domain != NULL; domain = domain->next) { 2741 char sockaddr[INET6_ADDRSTRLEN]; 2742 if (domain->conn.cli == NULL) { 2743 continue; 2744 } 2745 if (domain->conn.cli->fd == -1) { 2746 continue; 2747 } 2748 client_socket_addr(domain->conn.cli->fd, sockaddr, 2749 sizeof(sockaddr)); 2750 if (strequal(sockaddr, addr)) { 2751 close(domain->conn.cli->fd); 2752 domain->conn.cli->fd = -1; 2753 } 2754 } 2755 TALLOC_FREE(freeit); 2756 } -
vendor/current/source3/winbindd/winbindd_cred_cache.c
r414 r740 26 26 #include "../libcli/auth/libcli_auth.h" 27 27 #include "smb_krb5.h" 28 #include "libads/kerberos_proto.h" 28 29 29 30 #undef DBGC_CLASS … … 48 49 at one-half of the period from now till the tkt 49 50 expiration */ 50 #define KRB5_EVENT_REFRESH_TIME(x) ((x) - (((x) - time(NULL))/2)) 51 52 static time_t krb5_event_refresh_time(time_t end_time) 53 { 54 time_t rest = end_time - time(NULL); 55 return end_time - rest/2; 56 } 51 57 52 58 /**************************************************************** … … 184 190 from now to the expiration time */ 185 191 expire_time = entry->refresh_time; 186 new_start = KRB5_EVENT_REFRESH_TIME(entry->refresh_time);192 new_start = krb5_event_refresh_time(entry->refresh_time); 187 193 #endif 188 194 goto done; … … 208 214 #else 209 215 expire_time = new_start; 210 new_start = KRB5_EVENT_REFRESH_TIME(new_start);216 new_start = krb5_event_refresh_time(new_start); 211 217 #endif 212 218 … … 270 276 if (entry->renew_until && expire_time 271 277 && (entry->renew_until <= expire_time)) { 272 /* try to regain ticket 10 seconds befor re expiration */278 /* try to regain ticket 10 seconds before expiration */ 273 279 expire_time -= 10; 274 280 add_krb5_ticket_gain_handler_event(entry, … … 360 366 retry_later: 361 367 362 #if defined(DEBUG_KRB5_TKT_RE GAIN)368 #if defined(DEBUG_KRB5_TKT_RENEWAL) 363 369 t = timeval_set(time(NULL) + 30, 0); 364 370 #else … … 374 380 t = timeval_set(time(NULL) + 30, 0); 375 381 #else 376 t = timeval_set( KRB5_EVENT_REFRESH_TIME(entry->refresh_time), 0);382 t = timeval_set(krb5_event_refresh_time(entry->refresh_time), 0); 377 383 #endif 378 384 … … 524 530 error_message(ret))); 525 531 return krb5_to_nt_status(ret); 526 } else { 527 DEBUG(10, ("add_ccache_to_list: successfully destroyed " 528 "krb5 ccache %s for user %s\n", ccname, 529 username)); 530 } 532 } 533 DEBUG(10, ("add_ccache_to_list: successfully destroyed " 534 "krb5 ccache %s for user %s\n", ccname, 535 username)); 531 536 } 532 537 #endif … … 546 551 * event handler created - gd 547 552 * Add ticket refresh handler here */ 548 553 549 554 if (!lp_winbind_refresh_tickets() || renew_until <= 0) { 550 555 return NT_STATUS_OK; 551 556 } 552 557 553 558 if (!entry->event) { 554 559 if (postponed_request) { … … 560 565 t = timeval_set(time(NULL)+30, 0); 561 566 #else 562 t = timeval_set(KRB5_EVENT_REFRESH_TIME(ticket_end), 0); 567 t = timeval_set(krb5_event_refresh_time(ticket_end), 568 0); 563 569 #endif 564 570 if (!entry->refresh_time) { … … 587 593 DEBUG(10,("add_ccache_to_list: added krb5_ticket handler\n")); 588 594 } 589 595 590 596 return NT_STATUS_OK; 591 597 } … … 644 650 t = timeval_set(time(NULL)+30, 0); 645 651 #else 646 t = timeval_set( KRB5_EVENT_REFRESH_TIME(ticket_end), 0);652 t = timeval_set(krb5_event_refresh_time(ticket_end), 0); 647 653 #endif 648 654 if (entry->refresh_time == 0) { … … 687 693 struct WINBINDD_CCACHE_ENTRY *entry = get_ccache_by_username(username); 688 694 NTSTATUS status = NT_STATUS_OK; 689 695 #ifdef HAVE_KRB5 690 696 krb5_error_code ret; 691 697 #endif -
vendor/current/source3/winbindd/winbindd_creds.c
r414 r740 5 5 6 6 Copyright (C) Guenther Deschner 2005 7 7 8 8 This program is free software; you can redistribute it and/or modify 9 9 it under the terms of the GNU General Public License as published by 10 10 the Free Software Foundation; either version 3 of the License, or 11 11 (at your option) any later version. 12 12 13 13 This program is distributed in the hope that it will be useful, 14 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 16 GNU General Public License for more details. 17 17 18 18 You should have received a copy of the GNU General Public License 19 19 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 23 23 #include "winbindd.h" 24 24 #include "../libcli/auth/libcli_auth.h" 25 #include "../libcli/security/security.h" 25 26 #undef DBGC_CLASS 26 27 #define DBGC_CLASS DBGC_WINBIND … … 30 31 NTSTATUS winbindd_get_creds(struct winbindd_domain *domain, 31 32 TALLOC_CTX *mem_ctx, 32 const DOM_SID*sid,33 const struct dom_sid *sid, 33 34 struct netr_SamInfo3 **info3, 34 35 const uint8 *cached_nt_pass[NT_HASH_LEN], … … 55 56 56 57 NTSTATUS winbindd_store_creds(struct winbindd_domain *domain, 57 TALLOC_CTX *mem_ctx,58 58 const char *user, 59 59 const char *pass, 60 struct netr_SamInfo3 *info3, 61 const DOM_SID *user_sid) 60 struct netr_SamInfo3 *info3) 62 61 { 63 62 NTSTATUS status; 64 63 uchar nt_pass[NT_HASH_LEN]; 65 DOM_SIDcred_sid;64 struct dom_sid cred_sid; 66 65 67 66 if (info3 != NULL) { 68 67 69 DOM_SID sid; 70 sid_copy(&sid, info3->base.domain_sid); 71 sid_append_rid(&sid, info3->base.rid); 72 sid_copy(&cred_sid, &sid); 68 sid_compose(&cred_sid, info3->base.domain_sid, 69 info3->base.rid); 73 70 info3->base.user_flags |= NETLOGON_CACHED_ACCOUNT; 74 75 } else if (user_sid != NULL) {76 77 sid_copy(&cred_sid, user_sid);78 71 79 72 } else if (user != NULL) { … … 83 76 enum lsa_SidType type; 84 77 85 if (!lookup_cached_name(mem_ctx, 86 domain->name, 78 if (!lookup_cached_name(domain->name, 87 79 user, 88 80 &cred_sid, … … 121 113 dump_data_pw("nt_pass", nt_pass, NT_HASH_LEN); 122 114 123 status = wcache_save_creds(domain, mem_ctx,&cred_sid, nt_pass);115 status = wcache_save_creds(domain, &cred_sid, nt_pass); 124 116 if (!NT_STATUS_IS_OK(status)) { 125 117 return status; … … 137 129 138 130 NTSTATUS winbindd_update_creds_by_info3(struct winbindd_domain *domain, 139 TALLOC_CTX *mem_ctx,140 131 const char *user, 141 132 const char *pass, 142 133 struct netr_SamInfo3 *info3) 143 134 { 144 return winbindd_store_creds(domain, mem_ctx, user, pass, info3, NULL); 145 } 146 147 NTSTATUS winbindd_update_creds_by_sid(struct winbindd_domain *domain, 148 TALLOC_CTX *mem_ctx, 149 const DOM_SID *sid, 150 const char *pass) 151 { 152 return winbindd_store_creds(domain, mem_ctx, NULL, pass, NULL, sid); 135 return winbindd_store_creds(domain, user, pass, info3); 153 136 } 154 137 155 138 NTSTATUS winbindd_update_creds_by_name(struct winbindd_domain *domain, 156 TALLOC_CTX *mem_ctx,157 139 const char *user, 158 140 const char *pass) 159 141 { 160 return winbindd_store_creds(domain, mem_ctx, user, pass, NULL, NULL);142 return winbindd_store_creds(domain, user, pass, NULL); 161 143 } 162 144 -
vendor/current/source3/winbindd/winbindd_domain.c
r414 r740 40 40 .struct_fn = winbindd_dual_init_connection, 41 41 },{ 42 .name = "SHOW_SEQUENCE",43 .struct_cmd = WINBINDD_SHOW_SEQUENCE,44 .struct_fn = winbindd_dual_show_sequence,45 },{46 42 .name = "PAM_AUTH", 47 43 .struct_cmd = WINBINDD_PAM_AUTH, … … 64 60 .struct_fn = winbindd_dual_pam_chauthtok, 65 61 },{ 66 .name = "CCACHE_NTLM_AUTH",67 .struct_cmd = WINBINDD_CCACHE_NTLMAUTH,68 .struct_fn = winbindd_dual_ccache_ntlm_auth,69 },{70 .name = "CCACHE_SAVE",71 .struct_cmd = WINBINDD_CCACHE_SAVE,72 .struct_fn = winbindd_dual_ccache_save,73 },{74 62 .name = "NDRCMD", 75 63 .struct_cmd = WINBINDD_DUAL_NDRCMD, … … 80 68 }; 81 69 82 void setup_domain_child(struct winbindd_domain *domain, 83 struct winbindd_child *child) 70 void setup_domain_child(struct winbindd_domain *domain) 84 71 { 85 setup_child(domain, child, domain_dispatch_table, 86 "log.wb", domain->name); 72 int i; 73 74 for (i=0; i<lp_winbind_max_domain_connections(); i++) { 75 setup_child(domain, &domain->children[i], 76 domain_dispatch_table, 77 "log.wb", domain->name); 78 domain->children[i].domain = domain; 79 } 87 80 } -
vendor/current/source3/winbindd/winbindd_dsgetdcname.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ cli_wbint.h"22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 23 24 24 struct winbindd_dsgetdcname_state { … … 68 68 child = locator_child(); 69 69 70 subreq = rpccli_wbint_DsGetDcName_send(71 state, ev, child-> rpccli,70 subreq = dcerpc_wbint_DsGetDcName_send( 71 state, ev, child->binding_handle, 72 72 request->data.dsgetdcname.domain_name, guid_ptr, 73 73 request->data.dsgetdcname.site_name, … … 88 88 NTSTATUS status, result; 89 89 90 status = rpccli_wbint_DsGetDcName_recv(subreq, state, &result);90 status = dcerpc_wbint_DsGetDcName_recv(subreq, state, &result); 91 91 TALLOC_FREE(subreq); 92 if ( !NT_STATUS_IS_OK(status)) {92 if (any_nt_status_not_ok(status, result, &status)) { 93 93 tevent_req_nterror(req, status); 94 return;95 }96 if (!NT_STATUS_IS_OK(result)) {97 tevent_req_nterror(req, result);98 94 return; 99 95 } -
vendor/current/source3/winbindd/winbindd_dual.c
r591 r740 30 30 #include "includes.h" 31 31 #include "winbindd.h" 32 #include "../../nsswitch/libwbclient/wbc_async.h" 32 #include "nsswitch/wb_reqtrans.h" 33 #include "secrets.h" 34 #include "../lib/util/select.h" 35 #include "../libcli/security/security.h" 36 #include "system/select.h" 37 #include "messages.h" 38 #include "../lib/util/tevent_unix.h" 33 39 34 40 #undef DBGC_CLASS … … 135 141 struct tevent_req *subreq; 136 142 137 if ((state->child-> pid == 0) && (!fork_domain_child(state->child))) {143 if ((state->child->sock == -1) && (!fork_domain_child(state->child))) { 138 144 tevent_req_error(req, errno); 139 145 return; … … 146 152 } 147 153 tevent_req_set_callback(subreq, wb_child_request_done, req); 148 149 if (!tevent_req_set_endtime(req, state->ev, 150 timeval_current_ofs(300, 0))) { 151 tevent_req_nomem(NULL, req); 152 return; 153 } 154 tevent_req_set_endtime(req, state->ev, timeval_current_ofs(300, 0)); 154 155 } 155 156 … … 165 166 TALLOC_FREE(subreq); 166 167 if (ret == -1) { 168 /* 169 * The basic parent/child communication broke, close 170 * our socket 171 */ 172 close(state->child->sock); 173 state->child->sock = -1; 167 174 tevent_req_error(req, err); 168 175 return; … … 182 189 *presponse = talloc_move(mem_ctx, &state->response); 183 190 return 0; 191 } 192 193 static bool winbindd_child_busy(struct winbindd_child *child) 194 { 195 return tevent_queue_length(child->queue) > 0; 196 } 197 198 static struct winbindd_child *find_idle_child(struct winbindd_domain *domain) 199 { 200 int i; 201 202 for (i=0; i<lp_winbind_max_domain_connections(); i++) { 203 if (!winbindd_child_busy(&domain->children[i])) { 204 return &domain->children[i]; 205 } 206 } 207 208 return NULL; 209 } 210 211 struct winbindd_child *choose_domain_child(struct winbindd_domain *domain) 212 { 213 struct winbindd_child *result; 214 215 result = find_idle_child(domain); 216 if (result != NULL) { 217 return result; 218 } 219 return &domain->children[rand() % lp_winbind_max_domain_connections()]; 220 } 221 222 struct dcerpc_binding_handle *dom_child_handle(struct winbindd_domain *domain) 223 { 224 struct winbindd_child *child; 225 226 child = choose_domain_child(domain); 227 return child->binding_handle; 184 228 } 185 229 … … 187 231 struct tevent_context *ev; 188 232 struct winbindd_domain *domain; 233 struct winbindd_child *child; 189 234 struct winbindd_request *request; 190 235 struct winbindd_request *init_req; … … 210 255 } 211 256 257 state->child = choose_domain_child(domain); 258 212 259 if (domain->initialized) { 213 subreq = wb_child_request_send(state, ev, &domain->child,260 subreq = wb_child_request_send(state, ev, state->child, 214 261 request); 215 262 if (tevent_req_nomem(subreq, req)) { … … 233 280 state->init_req->cmd = WINBINDD_INIT_CONNECTION; 234 281 fstrcpy(state->init_req->domain_name, domain->name); 235 state->init_req->data.init_conn.is_primary = 236 domain->primary ? true : false; 282 state->init_req->data.init_conn.is_primary = domain->primary; 237 283 fstrcpy(state->init_req->data.init_conn.dcname, ""); 238 284 239 subreq = wb_child_request_send(state, ev, &domain->child,285 subreq = wb_child_request_send(state, ev, state->child, 240 286 state->init_req); 241 287 if (tevent_req_nomem(subreq, req)) { … … 258 304 fstrcpy(state->init_req->domain_name, domain->name); 259 305 260 subreq = wb_child_request_send(state, ev, &domain->child, request);306 subreq = wb_child_request_send(state, ev, state->child, request); 261 307 if (tevent_req_nomem(subreq, req)) { 262 308 return tevent_req_post(req, ev); … … 289 335 TALLOC_FREE(response); 290 336 291 subreq = wb_child_request_send(state, state->ev, &state->domain->child,337 subreq = wb_child_request_send(state, state->ev, state->child, 292 338 state->init_req); 293 339 if (tevent_req_nomem(subreq, req)) { … … 329 375 TALLOC_FREE(response); 330 376 331 subreq = wb_child_request_send(state, state->ev, &state->domain->child,377 subreq = wb_child_request_send(state, state->ev, state->child, 332 378 state->request); 333 379 if (tevent_req_nomem(subreq, req)) { … … 366 412 *presponse = talloc_move(mem_ctx, &state->response); 367 413 return 0; 368 }369 370 struct domain_request_state {371 struct winbindd_domain *domain;372 struct winbindd_request *request;373 struct winbindd_response *response;374 void (*continuation)(void *private_data_data, bool success);375 void *private_data_data;376 };377 378 static void async_domain_request_done(struct tevent_req *req);379 380 void async_domain_request(TALLOC_CTX *mem_ctx,381 struct winbindd_domain *domain,382 struct winbindd_request *request,383 struct winbindd_response *response,384 void (*continuation)(void *private_data_data, bool success),385 void *private_data_data)386 {387 struct tevent_req *subreq;388 struct domain_request_state *state;389 390 state = TALLOC_P(mem_ctx, struct domain_request_state);391 if (state == NULL) {392 DEBUG(0, ("talloc failed\n"));393 continuation(private_data_data, False);394 return;395 }396 397 state->domain = domain;398 state->request = request;399 state->response = response;400 state->continuation = continuation;401 state->private_data_data = private_data_data;402 403 subreq = wb_domain_request_send(state, winbind_event_context(),404 domain, request);405 if (subreq == NULL) {406 DEBUG(5, ("wb_domain_request_send failed\n"));407 continuation(private_data_data, false);408 return;409 }410 tevent_req_set_callback(subreq, async_domain_request_done, state);411 }412 413 static void async_domain_request_done(struct tevent_req *req)414 {415 struct domain_request_state *state = tevent_req_callback_data(416 req, struct domain_request_state);417 struct winbindd_response *response;418 int ret, err;419 420 ret = wb_domain_request_recv(req, state, &response, &err);421 TALLOC_FREE(req);422 if (ret == -1) {423 DEBUG(5, ("wb_domain_request returned %s\n", strerror(err)));424 state->continuation(state->private_data_data, false);425 return;426 }427 *(state->response) = *response;428 state->continuation(state->private_data_data, true);429 }430 431 static void recvfrom_child(void *private_data_data, bool success)432 {433 struct winbindd_cli_state *state =434 talloc_get_type_abort(private_data_data, struct winbindd_cli_state);435 enum winbindd_result result = state->response->result;436 437 /* This is an optimization: The child has written directly to the438 * response buffer. The request itself is still in pending state,439 * state that in the result code. */440 441 state->response->result = WINBINDD_PENDING;442 443 if ((!success) || (result != WINBINDD_OK)) {444 request_error(state);445 return;446 }447 448 request_ok(state);449 }450 451 void sendto_domain(struct winbindd_cli_state *state,452 struct winbindd_domain *domain)453 {454 async_domain_request(state->mem_ctx, domain,455 state->request, state->response,456 recvfrom_child, state);457 414 } 458 415 … … 483 440 } 484 441 485 DEBUG(1 ,("child_process_request: unknown request fn number %d\n",442 DEBUG(1, ("child_process_request: unknown request fn number %d\n", 486 443 (int)state->request->cmd)); 487 444 state->response->result = WINBINDD_ERROR; … … 494 451 { 495 452 if (logprefix && logname) { 453 char *logbase = NULL; 454 455 if (*lp_logfile()) { 456 char *end = NULL; 457 458 if (asprintf(&logbase, "%s", lp_logfile()) < 0) { 459 smb_panic("Internal error: asprintf failed"); 460 } 461 462 if ((end = strrchr_m(logbase, '/'))) { 463 *end = '\0'; 464 } 465 } else { 466 if (asprintf(&logbase, "%s", get_dyn_LOGFILEBASE()) < 0) { 467 smb_panic("Internal error: asprintf failed"); 468 } 469 } 470 496 471 if (asprintf(&child->logfilename, "%s/%s-%s", 497 get_dyn_LOGFILEBASE(), logprefix, logname) < 0) { 472 logbase, logprefix, logname) < 0) { 473 SAFE_FREE(logbase); 498 474 smb_panic("Internal error: asprintf failed"); 499 475 } 476 477 SAFE_FREE(logbase); 500 478 } else { 501 479 smb_panic("Internal error: logprefix == NULL && " … … 503 481 } 504 482 483 child->sock = -1; 505 484 child->domain = domain; 506 485 child->table = table; 507 486 child->queue = tevent_queue_create(NULL, "winbind_child"); 508 487 SMB_ASSERT(child->queue != NULL); 509 child-> rpccli = wbint_rpccli_create(NULL, domain, child);510 SMB_ASSERT(child-> rpccli!= NULL);511 } 512 513 st ruct winbindd_child *children = NULL;488 child->binding_handle = wbint_binding_handle(NULL, domain, child); 489 SMB_ASSERT(child->binding_handle != NULL); 490 } 491 492 static struct winbindd_child *winbindd_children = NULL; 514 493 515 494 void winbind_child_died(pid_t pid) … … 517 496 struct winbindd_child *child; 518 497 519 for (child = children; child != NULL; child = child->next) {498 for (child = winbindd_children; child != NULL; child = child->next) { 520 499 if (child->pid == pid) { 521 500 break; … … 530 509 /* This will be re-added in fork_domain_child() */ 531 510 532 DLIST_REMOVE(children, child); 533 534 close(child->sock); 535 child->sock = -1; 511 DLIST_REMOVE(winbindd_children, child); 536 512 child->pid = 0; 513 514 if (child->sock != -1) { 515 close(child->sock); 516 child->sock = -1; 517 } 537 518 } 538 519 … … 565 546 debug_message(msg_ctx, private_data, MSG_DEBUG, server_id, data); 566 547 567 for (child = children; child != NULL; child = child->next) {548 for (child = winbindd_children; child != NULL; child = child->next) { 568 549 569 550 DEBUG(10,("winbind_msg_debug: sending message to pid %u.\n", … … 610 591 } 611 592 612 for (child = children; child != NULL; child = child->next) {613 /* Don't send message to internal child s. We've already593 for (child = winbindd_children; child != NULL; child = child->next) { 594 /* Don't send message to internal children. We've already 614 595 done so above. */ 615 596 if (!child->domain || winbindd_internal_child(child)) { … … 685 666 } 686 667 687 for (child = children; child != NULL; child = child->next) {668 for (child = winbindd_children; child != NULL; child = child->next) { 688 669 /* Don't send message to internal childs. */ 689 670 if (!child->domain || winbindd_internal_child(child)) { … … 783 764 dump_event_list(winbind_event_context()); 784 765 785 for (child = children; child != NULL; child = child->next) {766 for (child = winbindd_children; child != NULL; child = child->next) { 786 767 787 768 DEBUG(10,("winbind_msg_dump_event_list: sending message to pid %u\n", … … 1191 1172 } 1192 1173 1193 bool winbindd_reinit_after_fork(const char *logfilename) 1174 NTSTATUS winbindd_reinit_after_fork(const struct winbindd_child *myself, 1175 const char *logfilename) 1194 1176 { 1195 1177 struct winbindd_domain *domain; 1196 1178 struct winbindd_child *cl; 1197 1198 if (!NT_STATUS_IS_OK(reinit_after_fork(winbind_messaging_context(), 1199 winbind_event_context(), 1200 true))) { 1179 NTSTATUS status; 1180 1181 status = reinit_after_fork( 1182 winbind_messaging_context(), 1183 winbind_event_context(), 1184 procid_self(), 1185 true); 1186 if (!NT_STATUS_IS_OK(status)) { 1201 1187 DEBUG(0,("reinit_after_fork() failed\n")); 1202 return false;1188 return status; 1203 1189 } 1204 1190 … … 1211 1197 1212 1198 if (!winbindd_setup_sig_term_handler(false)) 1213 return false;1199 return NT_STATUS_NO_MEMORY; 1214 1200 if (!winbindd_setup_sig_hup_handler(override_logfile ? NULL : 1215 1201 logfilename)) 1216 return false;1202 return NT_STATUS_NO_MEMORY; 1217 1203 1218 1204 /* Stop zombies in children */ … … 1253 1239 1254 1240 /* Destroy all possible events in child list. */ 1255 for (cl = children; cl != NULL; cl = cl->next) {1241 for (cl = winbindd_children; cl != NULL; cl = cl->next) { 1256 1242 TALLOC_FREE(cl->lockout_policy_event); 1257 1243 TALLOC_FREE(cl->machine_password_change_event); … … 1262 1248 */ 1263 1249 cl->pid = (pid_t)0; 1250 1251 /* 1252 * Close service sockets to all other children 1253 */ 1254 if ((cl != myself) && (cl->sock != -1)) { 1255 close(cl->sock); 1256 cl->sock = -1; 1257 } 1264 1258 } 1265 1259 /* … … 1282 1276 cl->pid = (pid_t)0; 1283 1277 1284 return true;1278 return NT_STATUS_OK; 1285 1279 } 1286 1280 … … 1302 1296 struct winbindd_response response; 1303 1297 struct winbindd_domain *primary_domain = NULL; 1298 NTSTATUS status; 1299 ssize_t nwritten; 1304 1300 1305 1301 if (child->domain) { … … 1309 1305 DEBUG(10, ("fork_domain_child called without domain.\n")); 1310 1306 } 1311 child_domain = child->domain;1312 1307 1313 1308 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fdpair) != 0) { … … 1331 1326 if (child->pid != 0) { 1332 1327 /* Parent */ 1328 ssize_t nread; 1329 1333 1330 close(fdpair[0]); 1331 1332 nread = read(fdpair[1], &status, sizeof(status)); 1333 if (nread != sizeof(status)) { 1334 DEBUG(1, ("fork_domain_child: Could not read child status: " 1335 "nread=%d, error=%s\n", (int)nread, 1336 strerror(errno))); 1337 close(fdpair[1]); 1338 return false; 1339 } 1340 if (!NT_STATUS_IS_OK(status)) { 1341 DEBUG(1, ("fork_domain_child: Child status is %s\n", 1342 nt_errstr(status))); 1343 close(fdpair[1]); 1344 return false; 1345 } 1346 1334 1347 child->next = child->prev = NULL; 1335 DLIST_ADD( children, child);1348 DLIST_ADD(winbindd_children, child); 1336 1349 child->sock = fdpair[1]; 1337 1350 return True; … … 1339 1352 1340 1353 /* Child */ 1354 child_domain = child->domain; 1341 1355 1342 1356 DEBUG(10, ("Child process %d\n", (int)sys_getpid())); … … 1345 1359 close(fdpair[1]); 1346 1360 1347 if (!winbindd_reinit_after_fork(child->logfilename)) { 1361 status = winbindd_reinit_after_fork(child, child->logfilename); 1362 1363 nwritten = write(state.sock, &status, sizeof(status)); 1364 if (nwritten != sizeof(status)) { 1365 DEBUG(1, ("fork_domain_child: Could not write status: " 1366 "nwritten=%d, error=%s\n", (int)nwritten, 1367 strerror(errno))); 1368 _exit(0); 1369 } 1370 if (!NT_STATUS_IS_OK(status)) { 1371 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n", 1372 nt_errstr(status))); 1348 1373 _exit(0); 1349 1374 } … … 1358 1383 messaging_register(winbind_messaging_context(), NULL, 1359 1384 MSG_DEBUG, debug_message); 1385 messaging_register(winbind_messaging_context(), NULL, 1386 MSG_WINBIND_IP_DROPPED, 1387 winbind_msg_ip_dropped); 1388 1360 1389 1361 1390 primary_domain = find_our_domain(); … … 1369 1398 if ( child->domain ) { 1370 1399 child->domain->startup = True; 1371 child->domain->startup_time = time (NULL);1400 child->domain->startup_time = time_mono(NULL); 1372 1401 /* we can be in primary domain or in trusted domain 1373 1402 * If we are in trusted domain, set the primary domain … … 1377 1406 if (!(child->domain->primary)) { 1378 1407 primary_domain->startup = True; 1379 primary_domain->startup_time = time (NULL);1408 primary_domain->startup_time = time_mono(NULL); 1380 1409 set_domain_online_request(primary_domain); 1381 1410 } … … 1433 1462 1434 1463 int ret; 1435 fd_set r_fds;1436 fd_set w_fds;1437 int maxfd;1464 struct pollfd *pfds; 1465 int num_pfds; 1466 int timeout; 1438 1467 struct timeval t; 1439 1468 struct timeval *tp; 1440 struct timeval now;1441 1469 TALLOC_CTX *frame = talloc_stackframe(); 1442 1470 struct iovec iov[2]; 1443 1471 int iov_count; 1444 NTSTATUS status; 1445 1446 if (run_events(winbind_event_context(), 0, NULL, NULL)) { 1472 1473 if (run_events_poll(winbind_event_context(), 0, NULL, 0)) { 1447 1474 TALLOC_FREE(frame); 1448 1475 continue; 1449 1476 } 1450 1477 1451 GetTimeOfDay(&now);1452 1453 1478 if (child->domain && child->domain->startup && 1454 ( now.tv_sec> child->domain->startup_time + 30)) {1479 (time_mono(NULL) > child->domain->startup_time + 30)) { 1455 1480 /* No longer in "startup" mode. */ 1456 1481 DEBUG(10,("fork_domain_child: domain %s no longer in 'startup' mode.\n", … … 1459 1484 } 1460 1485 1461 FD_ZERO(&r_fds); 1462 FD_ZERO(&w_fds); 1463 1464 if (state.sock < 0 || state.sock >= FD_SETSIZE) { 1465 TALLOC_FREE(frame); 1466 perror("EBADF"); 1486 pfds = TALLOC_ZERO_P(talloc_tos(), struct pollfd); 1487 if (pfds == NULL) { 1488 DEBUG(1, ("talloc failed\n")); 1467 1489 _exit(1); 1468 1490 } 1469 1491 1470 FD_SET(state.sock, &r_fds); 1471 maxfd = state.sock; 1472 1473 /* 1474 * Initialize this high as event_add_to_select_args() 1475 * uses a timeval_min() on this and next_event. Fix 1476 * from Roel van Meer <rolek@alt001.com>. 1477 */ 1478 t.tv_sec = 999999; 1479 t.tv_usec = 0; 1480 1481 event_add_to_select_args(winbind_event_context(), &now, 1482 &r_fds, &w_fds, &t, &maxfd); 1492 pfds->fd = state.sock; 1493 pfds->events = POLLIN|POLLHUP; 1494 num_pfds = 1; 1495 1496 timeout = INT_MAX; 1497 1498 if (!event_add_to_poll_args( 1499 winbind_event_context(), talloc_tos(), 1500 &pfds, &num_pfds, &timeout)) { 1501 DEBUG(1, ("event_add_to_poll_args failed\n")); 1502 _exit(1); 1503 } 1483 1504 tp = get_timed_events_timeout(winbind_event_context(), &t); 1484 1505 if (tp) { … … 1487 1508 } 1488 1509 1489 ret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, tp); 1490 1491 if (run_events(winbind_event_context(), ret, &r_fds, &w_fds)) { 1510 ret = sys_poll(pfds, num_pfds, timeout); 1511 1512 if (run_events_poll(winbind_event_context(), ret, 1513 pfds, num_pfds)) { 1492 1514 /* We got a signal - continue. */ 1493 1515 TALLOC_FREE(frame); 1494 1516 continue; 1495 1517 } 1518 1519 TALLOC_FREE(pfds); 1496 1520 1497 1521 if (ret == 0) { … … 1508 1532 1509 1533 if (ret == -1 && errno != EINTR) { 1510 DEBUG(0,(" selecterror occured\n"));1534 DEBUG(0,("poll error occured\n")); 1511 1535 TALLOC_FREE(frame); 1512 perror(" select");1536 perror("poll"); 1513 1537 _exit(1); 1514 1538 } … … 1556 1580 } 1557 1581 } 1582 1583 void winbind_msg_ip_dropped_parent(struct messaging_context *msg_ctx, 1584 void *private_data, 1585 uint32_t msg_type, 1586 struct server_id server_id, 1587 DATA_BLOB *data) 1588 { 1589 struct winbindd_child *child; 1590 1591 winbind_msg_ip_dropped(msg_ctx, private_data, msg_type, 1592 server_id, data); 1593 1594 1595 for (child = winbindd_children; child != NULL; child = child->next) { 1596 messaging_send_buf(msg_ctx, pid_to_procid(child->pid), 1597 msg_type, data->data, data->length); 1598 } 1599 } -
vendor/current/source3/winbindd/winbindd_dual_ndr.c
r414 r740 30 30 #include "winbindd/winbindd.h" 31 31 #include "winbindd/winbindd_proto.h" 32 #include "ntdomain.h" 32 33 #include "librpc/gen_ndr/srv_wbint.h" 33 34 34 struct wb _ndr_transport_priv{35 struct wbint_bh_state { 35 36 struct winbindd_domain *domain; 36 37 struct winbindd_child *child; 37 38 }; 38 39 39 struct wb_ndr_dispatch_state { 40 struct wb_ndr_transport_priv *transport; 40 static bool wbint_bh_is_connected(struct dcerpc_binding_handle *h) 41 { 42 struct wbint_bh_state *hs = dcerpc_binding_handle_data(h, 43 struct wbint_bh_state); 44 45 if (!hs->child) { 46 return false; 47 } 48 49 return true; 50 } 51 52 static uint32_t wbint_bh_set_timeout(struct dcerpc_binding_handle *h, 53 uint32_t timeout) 54 { 55 /* TODO: implement timeouts */ 56 return UINT32_MAX; 57 } 58 59 struct wbint_bh_raw_call_state { 60 struct winbindd_domain *domain; 41 61 uint32_t opnum; 42 const struct ndr_interface_call *call; 43 void *r; 44 DATA_BLOB req_blob, resp_blob; 62 DATA_BLOB in_data; 45 63 struct winbindd_request request; 46 64 struct winbindd_response *response; 65 DATA_BLOB out_data; 47 66 }; 48 67 49 static void wb_ndr_dispatch_done(struct tevent_req *subreq); 50 51 static struct tevent_req *wb_ndr_dispatch_send(TALLOC_CTX *mem_ctx, 52 struct tevent_context *ev, 53 struct rpc_pipe_client *cli, 54 const struct ndr_interface_table *table, 55 uint32_t opnum, 56 void *r) 57 { 58 struct tevent_req *req, *subreq; 59 struct wb_ndr_dispatch_state *state; 60 struct wb_ndr_transport_priv *transport = talloc_get_type_abort( 61 cli->transport->priv, struct wb_ndr_transport_priv); 62 struct ndr_push *push; 63 enum ndr_err_code ndr_err; 68 static void wbint_bh_raw_call_done(struct tevent_req *subreq); 69 70 static struct tevent_req *wbint_bh_raw_call_send(TALLOC_CTX *mem_ctx, 71 struct tevent_context *ev, 72 struct dcerpc_binding_handle *h, 73 const struct GUID *object, 74 uint32_t opnum, 75 uint32_t in_flags, 76 const uint8_t *in_data, 77 size_t in_length) 78 { 79 struct wbint_bh_state *hs = 80 dcerpc_binding_handle_data(h, 81 struct wbint_bh_state); 82 struct tevent_req *req; 83 struct wbint_bh_raw_call_state *state; 84 bool ok; 85 struct tevent_req *subreq; 64 86 65 87 req = tevent_req_create(mem_ctx, &state, 66 struct wb _ndr_dispatch_state);88 struct wbint_bh_raw_call_state); 67 89 if (req == NULL) { 68 90 return NULL; 69 91 } 70 71 state->r = r; 72 state->call = &table->calls[opnum]; 73 state->transport = transport; 92 state->domain = hs->domain; 74 93 state->opnum = opnum; 75 76 push = ndr_push_init_ctx(state, NULL); 77 if (tevent_req_nomem(push, req)) { 94 state->in_data.data = discard_const_p(uint8_t, in_data); 95 state->in_data.length = in_length; 96 97 ok = wbint_bh_is_connected(h); 98 if (!ok) { 99 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION); 78 100 return tevent_req_post(req, ev); 79 101 } 80 102 81 ndr_err = state->call->ndr_push(push, NDR_IN, r); 82 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 83 tevent_req_nterror(req, ndr_map_error2ntstatus(ndr_err)); 84 TALLOC_FREE(push); 85 return tevent_req_post(req, ev); 86 } 87 88 state->req_blob = ndr_push_blob(push); 89 90 if ((transport->domain != NULL) 91 && wcache_fetch_ndr(state, transport->domain, opnum, 92 &state->req_blob, &state->resp_blob)) { 103 if ((state->domain != NULL) 104 && wcache_fetch_ndr(state, state->domain, state->opnum, 105 &state->in_data, &state->out_data)) { 93 106 tevent_req_done(req); 94 107 return tevent_req_post(req, ev); … … 96 109 97 110 state->request.cmd = WINBINDD_DUAL_NDRCMD; 98 state->request.data.ndrcmd = opnum;99 state->request.extra_data.data = (char *)state-> req_blob.data;100 state->request.extra_len = state-> req_blob.length;101 102 subreq = wb_child_request_send(state, ev, transport->child,111 state->request.data.ndrcmd = state->opnum; 112 state->request.extra_data.data = (char *)state->in_data.data; 113 state->request.extra_len = state->in_data.length; 114 115 subreq = wb_child_request_send(state, ev, hs->child, 103 116 &state->request); 104 117 if (tevent_req_nomem(subreq, req)) { 105 118 return tevent_req_post(req, ev); 106 119 } 107 tevent_req_set_callback(subreq, wb_ndr_dispatch_done, req); 120 tevent_req_set_callback(subreq, wbint_bh_raw_call_done, req); 121 108 122 return req; 109 123 } 110 124 111 static void wb_ndr_dispatch_done(struct tevent_req *subreq) 112 { 113 struct tevent_req *req = tevent_req_callback_data( 114 subreq, struct tevent_req); 115 struct wb_ndr_dispatch_state *state = tevent_req_data( 116 req, struct wb_ndr_dispatch_state); 125 static void wbint_bh_raw_call_done(struct tevent_req *subreq) 126 { 127 struct tevent_req *req = 128 tevent_req_callback_data(subreq, 129 struct tevent_req); 130 struct wbint_bh_raw_call_state *state = 131 tevent_req_data(req, 132 struct wbint_bh_raw_call_state); 117 133 int ret, err; 118 134 … … 120 136 TALLOC_FREE(subreq); 121 137 if (ret == -1) { 122 tevent_req_nterror(req, map_nt_error_from_unix(err)); 138 NTSTATUS status = map_nt_error_from_unix(err); 139 tevent_req_nterror(req, status); 123 140 return; 124 141 } 125 142 126 state-> resp_blob = data_blob_const(143 state->out_data = data_blob_talloc(state, 127 144 state->response->extra_data.data, 128 state->response->length - sizeof(struct winbindd_response)); 129 130 if (state->transport->domain != NULL) { 131 wcache_store_ndr(state->transport->domain, state->opnum, 132 &state->req_blob, &state->resp_blob); 145 state->response->length - sizeof(struct winbindd_response)); 146 if (state->response->extra_data.data && !state->out_data.data) { 147 tevent_req_nomem(NULL, req); 148 return; 149 } 150 151 if (state->domain != NULL) { 152 wcache_store_ndr(state->domain, state->opnum, 153 &state->in_data, &state->out_data); 133 154 } 134 155 … … 136 157 } 137 158 138 static NTSTATUS wb_ndr_dispatch_recv(struct tevent_req *req, 139 TALLOC_CTX *mem_ctx) 140 { 141 struct wb_ndr_dispatch_state *state = tevent_req_data( 142 req, struct wb_ndr_dispatch_state); 159 static NTSTATUS wbint_bh_raw_call_recv(struct tevent_req *req, 160 TALLOC_CTX *mem_ctx, 161 uint8_t **out_data, 162 size_t *out_length, 163 uint32_t *out_flags) 164 { 165 struct wbint_bh_raw_call_state *state = 166 tevent_req_data(req, 167 struct wbint_bh_raw_call_state); 143 168 NTSTATUS status; 144 struct ndr_pull *pull;145 enum ndr_err_code ndr_err;146 169 147 170 if (tevent_req_is_nterror(req, &status)) { 171 tevent_req_received(req); 148 172 return status; 149 173 } 150 174 151 pull = ndr_pull_init_blob(&state->resp_blob, mem_ctx, NULL); 152 if (pull == NULL) { 153 return NT_STATUS_NO_MEMORY; 154 } 155 156 /* have the ndr parser alloc memory for us */ 157 pull->flags |= LIBNDR_FLAG_REF_ALLOC; 158 ndr_err = state->call->ndr_pull(pull, NDR_OUT, state->r); 159 TALLOC_FREE(pull); 160 161 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 162 return ndr_map_error2ntstatus(ndr_err); 163 } 164 175 *out_data = talloc_move(mem_ctx, &state->out_data.data); 176 *out_length = state->out_data.length; 177 *out_flags = 0; 178 tevent_req_received(req); 165 179 return NT_STATUS_OK; 166 180 } 167 181 168 static NTSTATUS wb_ndr_dispatch(struct rpc_pipe_client *cli, 169 TALLOC_CTX *mem_ctx, 170 const struct ndr_interface_table *table, 171 uint32_t opnum, void *r) 172 { 173 TALLOC_CTX *frame = talloc_stackframe(); 174 struct event_context *ev; 182 struct wbint_bh_disconnect_state { 183 uint8_t _dummy; 184 }; 185 186 static struct tevent_req *wbint_bh_disconnect_send(TALLOC_CTX *mem_ctx, 187 struct tevent_context *ev, 188 struct dcerpc_binding_handle *h) 189 { 190 struct wbint_bh_state *hs = dcerpc_binding_handle_data(h, 191 struct wbint_bh_state); 175 192 struct tevent_req *req; 176 NTSTATUS status = NT_STATUS_OK; 177 178 ev = event_context_init(frame); 179 if (ev == NULL) { 180 status = NT_STATUS_NO_MEMORY; 181 goto fail; 182 } 183 184 req = wb_ndr_dispatch_send(frame, ev, cli, table, opnum, r); 193 struct wbint_bh_disconnect_state *state; 194 bool ok; 195 196 req = tevent_req_create(mem_ctx, &state, 197 struct wbint_bh_disconnect_state); 185 198 if (req == NULL) { 186 status = NT_STATUS_NO_MEMORY;187 goto fail;188 }189 190 if (!tevent_req_poll(req, ev)) {191 status = map_nt_error_from_unix(errno);192 goto fail;193 }194 195 status = wb_ndr_dispatch_recv(req, mem_ctx);196 fail:197 TALLOC_FREE(frame);198 return status;199 }200 201 struct rpc_pipe_client *wbint_rpccli_create(TALLOC_CTX *mem_ctx,202 struct winbindd_domain *domain,203 struct winbindd_child *child)204 {205 struct rpc_pipe_client *result;206 struct wb_ndr_transport_priv *transp;207 208 result = talloc(mem_ctx, struct rpc_pipe_client);209 if (result == NULL) {210 199 return NULL; 211 200 } 212 result->abstract_syntax = ndr_table_wbint.syntax_id; 213 result->transfer_syntax = ndr_transfer_syntax; 214 result->dispatch = wb_ndr_dispatch; 215 result->dispatch_send = wb_ndr_dispatch_send; 216 result->dispatch_recv = wb_ndr_dispatch_recv; 217 result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; 218 result->max_recv_frag = RPC_MAX_PDU_FRAG_LEN; 219 result->desthost = NULL; 220 result->srv_name_slash = NULL; 201 202 ok = wbint_bh_is_connected(h); 203 if (!ok) { 204 tevent_req_nterror(req, NT_STATUS_INVALID_CONNECTION); 205 return tevent_req_post(req, ev); 206 } 221 207 222 208 /* 223 * Initialize a fake transport. Due to our own wb_ndr_dispatch 224 * function we don't use all the fragmentation engine in 225 * cli_pipe, which would use all the _read and _write 226 * functions in rpc_cli_transport. But we need a place to 227 * store the child struct in, and we're re-using 228 * result->transport->priv for that. 209 * TODO: do a real async disconnect ... 210 * 211 * For now the caller needs to free rpc_cli 229 212 */ 230 231 result->transport = talloc_zero(result, struct rpc_cli_transport); 232 if (result->transport == NULL) { 233 TALLOC_FREE(result); 213 hs->child = NULL; 214 215 tevent_req_done(req); 216 return tevent_req_post(req, ev); 217 } 218 219 static NTSTATUS wbint_bh_disconnect_recv(struct tevent_req *req) 220 { 221 NTSTATUS status; 222 223 if (tevent_req_is_nterror(req, &status)) { 224 tevent_req_received(req); 225 return status; 226 } 227 228 tevent_req_received(req); 229 return NT_STATUS_OK; 230 } 231 232 static bool wbint_bh_ref_alloc(struct dcerpc_binding_handle *h) 233 { 234 return true; 235 } 236 237 static void wbint_bh_do_ndr_print(struct dcerpc_binding_handle *h, 238 int ndr_flags, 239 const void *_struct_ptr, 240 const struct ndr_interface_call *call) 241 { 242 void *struct_ptr = discard_const(_struct_ptr); 243 244 if (DEBUGLEVEL < 10) { 245 return; 246 } 247 248 if (ndr_flags & NDR_IN) { 249 ndr_print_function_debug(call->ndr_print, 250 call->name, 251 ndr_flags, 252 struct_ptr); 253 } 254 if (ndr_flags & NDR_OUT) { 255 ndr_print_function_debug(call->ndr_print, 256 call->name, 257 ndr_flags, 258 struct_ptr); 259 } 260 } 261 262 static const struct dcerpc_binding_handle_ops wbint_bh_ops = { 263 .name = "wbint", 264 .is_connected = wbint_bh_is_connected, 265 .set_timeout = wbint_bh_set_timeout, 266 .raw_call_send = wbint_bh_raw_call_send, 267 .raw_call_recv = wbint_bh_raw_call_recv, 268 .disconnect_send = wbint_bh_disconnect_send, 269 .disconnect_recv = wbint_bh_disconnect_recv, 270 271 .ref_alloc = wbint_bh_ref_alloc, 272 .do_ndr_print = wbint_bh_do_ndr_print, 273 }; 274 275 /* initialise a wbint binding handle */ 276 struct dcerpc_binding_handle *wbint_binding_handle(TALLOC_CTX *mem_ctx, 277 struct winbindd_domain *domain, 278 struct winbindd_child *child) 279 { 280 struct dcerpc_binding_handle *h; 281 struct wbint_bh_state *hs; 282 283 h = dcerpc_binding_handle_create(mem_ctx, 284 &wbint_bh_ops, 285 NULL, 286 &ndr_table_wbint, 287 &hs, 288 struct wbint_bh_state, 289 __location__); 290 if (h == NULL) { 234 291 return NULL; 235 292 } 236 transp = talloc(result->transport, struct wb_ndr_transport_priv); 237 if (transp == NULL) { 238 TALLOC_FREE(result); 239 return NULL; 240 } 241 transp->domain = domain; 242 transp->child = child; 243 result->transport->priv = transp; 244 return result; 293 hs->domain = domain; 294 hs->child = child; 295 296 return h; 245 297 } 246 298 … … 248 300 struct winbindd_cli_state *state) 249 301 { 250 pipes_struct p;302 struct pipes_struct p; 251 303 struct api_struct *fns; 252 304 int num_fns; … … 265 317 ZERO_STRUCT(p); 266 318 p.mem_ctx = talloc_stackframe(); 267 p.in_data.data.buffer_size = state->request->extra_len; 268 p.in_data.data.data_p = state->request->extra_data.data; 269 prs_init(&p.out_data.rdata, 0, state->mem_ctx, false); 319 p.in_data.data = data_blob_const(state->request->extra_data.data, 320 state->request->extra_len); 270 321 271 322 ret = fns[state->request->data.ndrcmd].fn(&p); 323 if (!ret) { 324 TALLOC_FREE(p.mem_ctx); 325 return WINBINDD_ERROR; 326 } 327 328 state->response->extra_data.data = 329 talloc_move(state->mem_ctx, &p.out_data.rdata.data); 330 state->response->length += p.out_data.rdata.length; 331 p.out_data.rdata.length = 0; 332 272 333 TALLOC_FREE(p.mem_ctx); 273 if (!ret) { 274 return WINBINDD_ERROR; 275 } 276 277 state->response->extra_data.data = 278 talloc_memdup(state->mem_ctx, p.out_data.rdata.data_p, 279 p.out_data.rdata.data_offset); 280 state->response->length += p.out_data.rdata.data_offset; 281 prs_mem_free(&p.out_data.rdata); 334 282 335 if (state->response->extra_data.data == NULL) { 283 336 return WINBINDD_ERROR; … … 285 338 return WINBINDD_OK; 286 339 } 287 288 /*289 * Just a dummy to make srv_wbint.c happy290 */291 NTSTATUS rpc_srv_register(int version, const char *clnt, const char *srv,292 const struct ndr_interface_table *iface,293 const struct api_struct *cmds, int size)294 {295 return NT_STATUS_OK;296 } -
vendor/current/source3/winbindd/winbindd_dual_srv.c
r618 r740 24 24 #include "winbindd/winbindd.h" 25 25 #include "winbindd/winbindd_proto.h" 26 #include "rpc_client/cli_pipe.h" 27 #include "ntdomain.h" 26 28 #include "librpc/gen_ndr/srv_wbint.h" 27 #include "../librpc/gen_ndr/cli_netlogon.h" 28 29 void _wbint_Ping(pipes_struct *p, struct wbint_Ping *r) 29 #include "../librpc/gen_ndr/ndr_netlogon_c.h" 30 #include "idmap.h" 31 #include "../libcli/security/security.h" 32 33 void _wbint_Ping(struct pipes_struct *p, struct wbint_Ping *r) 30 34 { 31 35 *r->out.out_data = r->in.in_data; 32 36 } 33 37 34 NTSTATUS _wbint_LookupSid(pipes_struct *p, struct wbint_LookupSid *r) 38 static bool reset_cm_connection_on_error(struct winbindd_domain *domain, 39 NTSTATUS status) 40 { 41 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { 42 invalidate_cm_connection(&domain->conn); 43 /* We invalidated the connection. */ 44 return true; 45 } 46 return false; 47 } 48 49 NTSTATUS _wbint_LookupSid(struct pipes_struct *p, struct wbint_LookupSid *r) 35 50 { 36 51 struct winbindd_domain *domain = wb_child_domain(); … … 46 61 status = domain->methods->sid_to_name(domain, p->mem_ctx, r->in.sid, 47 62 &dom_name, &name, &type); 63 reset_cm_connection_on_error(domain, status); 48 64 if (!NT_STATUS_IS_OK(status)) { 49 65 return status; … … 56 72 } 57 73 58 NTSTATUS _wbint_LookupName(pipes_struct *p, struct wbint_LookupName *r) 59 { 60 struct winbindd_domain *domain = wb_child_domain(); 61 62 if (domain == NULL) { 63 return NT_STATUS_REQUEST_NOT_ACCEPTED; 64 } 65 66 return domain->methods->name_to_sid( 74 NTSTATUS _wbint_LookupSids(struct pipes_struct *p, struct wbint_LookupSids *r) 75 { 76 struct winbindd_domain *domain = wb_child_domain(); 77 NTSTATUS status; 78 79 if (domain == NULL) { 80 return NT_STATUS_REQUEST_NOT_ACCEPTED; 81 } 82 83 /* 84 * This breaks the winbindd_domain->methods abstraction: This 85 * is only called for remote domains, and both winbindd_msrpc 86 * and winbindd_ad call into lsa_lookupsids anyway. Caching is 87 * done at the wbint RPC layer. 88 */ 89 status = rpc_lookup_sids(p->mem_ctx, domain, r->in.sids, 90 &r->out.domains, &r->out.names); 91 reset_cm_connection_on_error(domain, status); 92 return status; 93 } 94 95 NTSTATUS _wbint_LookupName(struct pipes_struct *p, struct wbint_LookupName *r) 96 { 97 struct winbindd_domain *domain = wb_child_domain(); 98 NTSTATUS status; 99 100 if (domain == NULL) { 101 return NT_STATUS_REQUEST_NOT_ACCEPTED; 102 } 103 104 status = domain->methods->name_to_sid( 67 105 domain, p->mem_ctx, r->in.domain, r->in.name, r->in.flags, 68 106 r->out.sid, r->out.type); 69 } 70 71 NTSTATUS _wbint_Sid2Uid(pipes_struct *p, struct wbint_Sid2Uid *r) 107 reset_cm_connection_on_error(domain, status); 108 return status; 109 } 110 111 NTSTATUS _wbint_Sid2Uid(struct pipes_struct *p, struct wbint_Sid2Uid *r) 72 112 { 73 113 uid_t uid; … … 83 123 } 84 124 85 NTSTATUS _wbint_Sid2Gid( pipes_struct *p, struct wbint_Sid2Gid *r)125 NTSTATUS _wbint_Sid2Gid(struct pipes_struct *p, struct wbint_Sid2Gid *r) 86 126 { 87 127 gid_t gid; … … 97 137 } 98 138 99 NTSTATUS _wbint_Uid2Sid(pipes_struct *p, struct wbint_Uid2Sid *r) 139 NTSTATUS _wbint_Sids2UnixIDs(struct pipes_struct *p, 140 struct wbint_Sids2UnixIDs *r) 141 { 142 uint32_t i, j; 143 struct id_map *ids = NULL; 144 struct id_map **id_ptrs = NULL; 145 struct dom_sid *sids = NULL; 146 uint32_t *id_idx = NULL; 147 NTSTATUS status = NT_STATUS_NO_MEMORY; 148 149 for (i=0; i<r->in.domains->count; i++) { 150 struct lsa_DomainInfo *d = &r->in.domains->domains[i]; 151 struct idmap_domain *dom; 152 uint32_t num_ids; 153 154 dom = idmap_find_domain(d->name.string); 155 if (dom == NULL) { 156 DEBUG(10, ("idmap domain %s not found\n", 157 d->name.string)); 158 continue; 159 } 160 161 num_ids = 0; 162 163 for (j=0; j<r->in.ids->num_ids; j++) { 164 if (r->in.ids->ids[j].domain_index == i) { 165 num_ids += 1; 166 } 167 } 168 169 ids = TALLOC_REALLOC_ARRAY(talloc_tos(), ids, 170 struct id_map, num_ids); 171 if (ids == NULL) { 172 goto nomem; 173 } 174 id_ptrs = TALLOC_REALLOC_ARRAY(talloc_tos(), id_ptrs, 175 struct id_map *, num_ids+1); 176 if (id_ptrs == NULL) { 177 goto nomem; 178 } 179 id_idx = TALLOC_REALLOC_ARRAY(talloc_tos(), id_idx, 180 uint32_t, num_ids); 181 if (id_idx == NULL) { 182 goto nomem; 183 } 184 sids = TALLOC_REALLOC_ARRAY(talloc_tos(), sids, 185 struct dom_sid, num_ids); 186 if (sids == NULL) { 187 goto nomem; 188 } 189 190 num_ids = 0; 191 192 for (j=0; j<r->in.ids->num_ids; j++) { 193 struct wbint_TransID *id = &r->in.ids->ids[j]; 194 195 if (id->domain_index != i) { 196 continue; 197 } 198 id_idx[num_ids] = j; 199 id_ptrs[num_ids] = &ids[num_ids]; 200 201 ids[num_ids].sid = &sids[num_ids]; 202 sid_compose(ids[num_ids].sid, d->sid, id->rid); 203 ids[num_ids].xid.type = id->type; 204 ids[num_ids].status = ID_UNKNOWN; 205 num_ids += 1; 206 } 207 id_ptrs[num_ids] = NULL; 208 209 status = dom->methods->sids_to_unixids(dom, id_ptrs); 210 DEBUG(10, ("sids_to_unixids returned %s\n", 211 nt_errstr(status))); 212 213 for (j=0; j<num_ids; j++) { 214 struct wbint_TransID *id = &r->in.ids->ids[id_idx[j]]; 215 216 if (ids[j].status != ID_MAPPED) { 217 continue; 218 } 219 id->unix_id = ids[j].xid.id; 220 } 221 } 222 status = NT_STATUS_OK; 223 nomem: 224 TALLOC_FREE(ids); 225 TALLOC_FREE(id_ptrs); 226 TALLOC_FREE(id_idx); 227 TALLOC_FREE(sids); 228 return status; 229 } 230 231 NTSTATUS _wbint_Uid2Sid(struct pipes_struct *p, struct wbint_Uid2Sid *r) 100 232 { 101 233 return idmap_uid_to_sid(r->in.dom_name ? r->in.dom_name : "", … … 103 235 } 104 236 105 NTSTATUS _wbint_Gid2Sid( pipes_struct *p, struct wbint_Gid2Sid *r)237 NTSTATUS _wbint_Gid2Sid(struct pipes_struct *p, struct wbint_Gid2Sid *r) 106 238 { 107 239 return idmap_gid_to_sid(r->in.dom_name ? r->in.dom_name : "", … … 109 241 } 110 242 111 NTSTATUS _wbint_AllocateUid( pipes_struct *p, struct wbint_AllocateUid *r)243 NTSTATUS _wbint_AllocateUid(struct pipes_struct *p, struct wbint_AllocateUid *r) 112 244 { 113 245 struct unixid xid; … … 122 254 } 123 255 124 NTSTATUS _wbint_AllocateGid( pipes_struct *p, struct wbint_AllocateGid *r)256 NTSTATUS _wbint_AllocateGid(struct pipes_struct *p, struct wbint_AllocateGid *r) 125 257 { 126 258 struct unixid xid; … … 135 267 } 136 268 137 NTSTATUS _wbint_QueryUser(pipes_struct *p, struct wbint_QueryUser *r) 138 { 139 struct winbindd_domain *domain = wb_child_domain(); 140 141 if (domain == NULL) { 142 return NT_STATUS_REQUEST_NOT_ACCEPTED; 143 } 144 145 return domain->methods->query_user(domain, p->mem_ctx, r->in.sid, 146 r->out.info); 147 } 148 149 NTSTATUS _wbint_LookupUserAliases(pipes_struct *p, 269 NTSTATUS _wbint_QueryUser(struct pipes_struct *p, struct wbint_QueryUser *r) 270 { 271 struct winbindd_domain *domain = wb_child_domain(); 272 NTSTATUS status; 273 274 if (domain == NULL) { 275 return NT_STATUS_REQUEST_NOT_ACCEPTED; 276 } 277 278 status = domain->methods->query_user(domain, p->mem_ctx, r->in.sid, 279 r->out.info); 280 reset_cm_connection_on_error(domain, status); 281 return status; 282 } 283 284 NTSTATUS _wbint_LookupUserAliases(struct pipes_struct *p, 150 285 struct wbint_LookupUserAliases *r) 151 286 { 152 287 struct winbindd_domain *domain = wb_child_domain(); 153 154 if (domain == NULL) { 155 return NT_STATUS_REQUEST_NOT_ACCEPTED; 156 } 157 158 return domain->methods->lookup_useraliases( 288 NTSTATUS status; 289 290 if (domain == NULL) { 291 return NT_STATUS_REQUEST_NOT_ACCEPTED; 292 } 293 294 status = domain->methods->lookup_useraliases( 159 295 domain, p->mem_ctx, r->in.sids->num_sids, r->in.sids->sids, 160 296 &r->out.rids->num_rids, &r->out.rids->rids); 161 } 162 163 NTSTATUS _wbint_LookupUserGroups(pipes_struct *p, 297 reset_cm_connection_on_error(domain, status); 298 return status; 299 } 300 301 NTSTATUS _wbint_LookupUserGroups(struct pipes_struct *p, 164 302 struct wbint_LookupUserGroups *r) 165 303 { 166 304 struct winbindd_domain *domain = wb_child_domain(); 167 168 if (domain == NULL) { 169 return NT_STATUS_REQUEST_NOT_ACCEPTED; 170 } 171 172 return domain->methods->lookup_usergroups( 305 NTSTATUS status; 306 307 if (domain == NULL) { 308 return NT_STATUS_REQUEST_NOT_ACCEPTED; 309 } 310 311 status = domain->methods->lookup_usergroups( 173 312 domain, p->mem_ctx, r->in.sid, 174 313 &r->out.sids->num_sids, &r->out.sids->sids); 175 } 176 177 NTSTATUS _wbint_QuerySequenceNumber(pipes_struct *p, 314 reset_cm_connection_on_error(domain, status); 315 return status; 316 } 317 318 NTSTATUS _wbint_QuerySequenceNumber(struct pipes_struct *p, 178 319 struct wbint_QuerySequenceNumber *r) 179 320 { 180 321 struct winbindd_domain *domain = wb_child_domain(); 181 182 if (domain == NULL) { 183 return NT_STATUS_REQUEST_NOT_ACCEPTED; 184 } 185 186 return domain->methods->sequence_number(domain, r->out.sequence); 187 } 188 189 NTSTATUS _wbint_LookupGroupMembers(pipes_struct *p, 322 NTSTATUS status; 323 324 if (domain == NULL) { 325 return NT_STATUS_REQUEST_NOT_ACCEPTED; 326 } 327 328 status = domain->methods->sequence_number(domain, r->out.sequence); 329 reset_cm_connection_on_error(domain, status); 330 return status; 331 } 332 333 NTSTATUS _wbint_LookupGroupMembers(struct pipes_struct *p, 190 334 struct wbint_LookupGroupMembers *r) 191 335 { … … 204 348 domain, p->mem_ctx, r->in.sid, r->in.type, 205 349 &num_names, &sid_mem, &names, &name_types); 350 reset_cm_connection_on_error(domain, status); 206 351 if (!NT_STATUS_IS_OK(status)) { 207 352 return status; … … 225 370 } 226 371 227 NTSTATUS _wbint_QueryUserList(pipes_struct *p, struct wbint_QueryUserList *r) 228 { 229 struct winbindd_domain *domain = wb_child_domain(); 230 231 if (domain == NULL) { 232 return NT_STATUS_REQUEST_NOT_ACCEPTED; 233 } 234 235 return domain->methods->query_user_list( 372 NTSTATUS _wbint_QueryUserList(struct pipes_struct *p, 373 struct wbint_QueryUserList *r) 374 { 375 struct winbindd_domain *domain = wb_child_domain(); 376 NTSTATUS status; 377 378 if (domain == NULL) { 379 return NT_STATUS_REQUEST_NOT_ACCEPTED; 380 } 381 382 status = domain->methods->query_user_list( 236 383 domain, p->mem_ctx, &r->out.users->num_userinfos, 237 384 &r->out.users->userinfos); 238 } 239 240 NTSTATUS _wbint_QueryGroupList(pipes_struct *p, struct wbint_QueryGroupList *r) 385 reset_cm_connection_on_error(domain, status); 386 return status; 387 } 388 389 NTSTATUS _wbint_QueryGroupList(struct pipes_struct *p, 390 struct wbint_QueryGroupList *r) 241 391 { 242 392 struct winbindd_domain *domain = wb_child_domain(); 243 393 uint32_t i, num_groups; 244 struct acct_info *groups;394 struct wb_acct_info *groups; 245 395 struct wbint_Principal *result; 246 396 NTSTATUS status; … … 252 402 status = domain->methods->enum_dom_groups(domain, talloc_tos(), 253 403 &num_groups, &groups); 404 reset_cm_connection_on_error(domain, status); 254 405 if (!NT_STATUS_IS_OK(status)) { 255 406 return status; … … 275 426 r->out.groups->num_principals = num_groups; 276 427 r->out.groups->principals = result; 277 return NT_STATUS_OK; 278 } 279 280 NTSTATUS _wbint_DsGetDcName(pipes_struct *p, struct wbint_DsGetDcName *r) 428 429 TALLOC_FREE(groups); 430 return NT_STATUS_OK; 431 } 432 433 NTSTATUS _wbint_DsGetDcName(struct pipes_struct *p, struct wbint_DsGetDcName *r) 281 434 { 282 435 struct winbindd_domain *domain = wb_child_domain(); … … 286 439 WERROR werr; 287 440 unsigned int orig_timeout; 441 struct dcerpc_binding_handle *b; 288 442 289 443 if (domain == NULL) { … … 297 451 status = cm_connect_netlogon(domain, &netlogon_pipe); 298 452 453 reset_cm_connection_on_error(domain, status); 299 454 if (!NT_STATUS_IS_OK(status)) { 300 455 DEBUG(10, ("Can't contact the NETLOGON pipe\n")); 301 456 return status; 302 457 } 458 459 b = netlogon_pipe->binding_handle; 303 460 304 461 /* This call can take a long time - allow the server to time out. … … 308 465 309 466 if (domain->active_directory) { 310 status = rpccli_netr_DsRGetDCName(311 netlogon_pipe,p->mem_ctx, domain->dcname,467 status = dcerpc_netr_DsRGetDCName(b, 468 p->mem_ctx, domain->dcname, 312 469 r->in.domain_name, NULL, r->in.domain_guid, 313 470 r->in.flags, r->out.dc_info, &werr); … … 315 472 goto done; 316 473 } 474 if (reset_cm_connection_on_error(domain, status)) { 475 /* Re-initialize. */ 476 status = cm_connect_netlogon(domain, &netlogon_pipe); 477 478 reset_cm_connection_on_error(domain, status); 479 if (!NT_STATUS_IS_OK(status)) { 480 DEBUG(10, ("Can't contact the NETLOGON pipe\n")); 481 return status; 482 } 483 484 b = netlogon_pipe->binding_handle; 485 486 /* This call can take a long time - allow the server to time out. 487 35 seconds should do it. */ 488 489 orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000); 490 } 317 491 } 318 492 … … 328 502 329 503 if (r->in.flags & DS_PDC_REQUIRED) { 330 status = rpccli_netr_GetDcName(331 netlogon_pipe,p->mem_ctx, domain->dcname,504 status = dcerpc_netr_GetDcName(b, 505 p->mem_ctx, domain->dcname, 332 506 r->in.domain_name, &dc_info->dc_unc, &werr); 333 507 } else { 334 status = rpccli_netr_GetAnyDCName(335 netlogon_pipe,p->mem_ctx, domain->dcname,508 status = dcerpc_netr_GetAnyDCName(b, 509 p->mem_ctx, domain->dcname, 336 510 r->in.domain_name, &dc_info->dc_unc, &werr); 337 511 } 338 512 339 if (!NT_STATUS_IS_OK(status)) { 340 DEBUG(10, ("rpccli_netr_Get[Any]DCName failed: %s\n", 513 reset_cm_connection_on_error(domain, status); 514 if (!NT_STATUS_IS_OK(status)) { 515 DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n", 341 516 nt_errstr(status))); 342 517 goto done; 343 518 } 344 519 if (!W_ERROR_IS_OK(werr)) { 345 DEBUG(10, (" rpccli_netr_Get[Any]DCName failed: %s\n",520 DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n", 346 521 win_errstr(werr))); 347 522 status = werror_to_ntstatus(werr); … … 359 534 } 360 535 361 NTSTATUS _wbint_LookupRids( pipes_struct *p, struct wbint_LookupRids *r)536 NTSTATUS _wbint_LookupRids(struct pipes_struct *p, struct wbint_LookupRids *r) 362 537 { 363 538 struct winbindd_domain *domain = wb_child_domain(); … … 376 551 domain, talloc_tos(), r->in.domain_sid, r->in.rids->rids, 377 552 r->in.rids->num_rids, &domain_name, &names, &types); 553 reset_cm_connection_on_error(domain, status); 378 554 if (!NT_STATUS_IS_OK(status)) { 379 555 return status; … … 402 578 } 403 579 404 NTSTATUS _wbint_CheckMachineAccount( pipes_struct *p,580 NTSTATUS _wbint_CheckMachineAccount(struct pipes_struct *p, 405 581 struct wbint_CheckMachineAccount *r) 406 582 { … … 454 630 } 455 631 456 NTSTATUS _wbint_ChangeMachineAccount( pipes_struct *p,632 NTSTATUS _wbint_ChangeMachineAccount(struct pipes_struct *p, 457 633 struct wbint_ChangeMachineAccount *r) 458 634 { … … 514 690 } 515 691 516 NTSTATUS _wbint_PingDc( pipes_struct *p, struct wbint_PingDc *r)692 NTSTATUS _wbint_PingDc(struct pipes_struct *p, struct wbint_PingDc *r) 517 693 { 518 694 NTSTATUS status; … … 522 698 WERROR werr; 523 699 fstring logon_server; 700 struct dcerpc_binding_handle *b; 524 701 525 702 domain = wb_child_domain(); … … 529 706 530 707 status = cm_connect_netlogon(domain, &netlogon_pipe); 708 reset_cm_connection_on_error(domain, status); 531 709 if (!NT_STATUS_IS_OK(status)) { 532 710 DEBUG(3, ("could not open handle to NETLOGON pipe\n")); 533 711 return status; 534 712 } 713 714 b = netlogon_pipe->binding_handle; 535 715 536 716 fstr_sprintf(logon_server, "\\\\%s", domain->dcname); … … 542 722 * netlogon pipe works. 543 723 */ 544 status = rpccli_netr_LogonControl(netlogon_pipe, p->mem_ctx,724 status = dcerpc_netr_LogonControl(b, p->mem_ctx, 545 725 logon_server, NETLOGON_CONTROL_QUERY, 546 726 2, &info, &werr); 547 727 548 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { 549 DEBUG(2, ("rpccli_netr_LogonControl timed out\n")); 550 invalidate_cm_connection(&domain->conn); 551 return status; 552 } 553 554 if (!NT_STATUS_EQUAL(status, NT_STATUS_CTL_FILE_NOT_SUPPORTED)) { 555 DEBUG(2, ("rpccli_netr_LogonControl returned %s, expected " 556 "NT_STATUS_CTL_FILE_NOT_SUPPORTED\n", 557 nt_errstr(status))); 558 return status; 728 reset_cm_connection_on_error(domain, status); 729 if (!NT_STATUS_IS_OK(status)) { 730 DEBUG(2, ("dcerpc_netr_LogonControl failed: %s\n", 731 nt_errstr(status))); 732 return status; 733 } 734 735 if (!W_ERROR_EQUAL(werr, WERR_NOT_SUPPORTED)) { 736 DEBUG(2, ("dcerpc_netr_LogonControl returned %s, expected " 737 "WERR_NOT_SUPPORTED\n", 738 win_errstr(werr))); 739 return werror_to_ntstatus(werr); 559 740 } 560 741 … … 562 743 return NT_STATUS_OK; 563 744 } 564 565 NTSTATUS _wbint_SetMapping(pipes_struct *p, struct wbint_SetMapping *r)566 {567 struct id_map map;568 569 map.sid = r->in.sid;570 map.xid.id = r->in.id;571 map.status = ID_MAPPED;572 573 switch (r->in.type) {574 case WBINT_ID_TYPE_UID:575 map.xid.type = ID_TYPE_UID;576 break;577 case WBINT_ID_TYPE_GID:578 map.xid.type = ID_TYPE_GID;579 break;580 default:581 return NT_STATUS_INVALID_PARAMETER;582 }583 584 return idmap_set_mapping(&map);585 }586 587 NTSTATUS _wbint_RemoveMapping(pipes_struct *p, struct wbint_RemoveMapping *r)588 {589 struct id_map map;590 591 map.sid = r->in.sid;592 map.xid.id = r->in.id;593 map.status = ID_MAPPED;594 595 switch (r->in.type) {596 case WBINT_ID_TYPE_UID:597 map.xid.type = ID_TYPE_UID;598 break;599 case WBINT_ID_TYPE_GID:600 map.xid.type = ID_TYPE_GID;601 break;602 default:603 return NT_STATUS_INVALID_PARAMETER;604 }605 606 return idmap_remove_mapping(&map);607 }608 609 NTSTATUS _wbint_SetHWM(pipes_struct *p, struct wbint_SetHWM *r)610 {611 struct unixid id;612 NTSTATUS status;613 614 id.id = r->in.id;615 616 switch (r->in.type) {617 case WBINT_ID_TYPE_UID:618 id.type = ID_TYPE_UID;619 status = idmap_set_uid_hwm(&id);620 break;621 case WBINT_ID_TYPE_GID:622 id.type = ID_TYPE_GID;623 status = idmap_set_gid_hwm(&id);624 break;625 default:626 status = NT_STATUS_INVALID_PARAMETER;627 break;628 }629 return status;630 } -
vendor/current/source3/winbindd/winbindd_getdcname.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ cli_wbint.h"22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 23 24 24 struct winbindd_getdcname_state { … … 66 66 status = wb_dsgetdcname_recv(subreq, state, &state->dcinfo); 67 67 TALLOC_FREE(subreq); 68 if (!NT_STATUS_IS_OK(status)) { 69 tevent_req_nterror(req, status); 68 if (tevent_req_nterror(req, status)) { 70 69 return; 71 70 } -
vendor/current/source3/winbindd/winbindd_getgrgid.c
r414 r740 69 69 status = wb_gid2sid_recv(subreq, &state->sid); 70 70 TALLOC_FREE(subreq); 71 if (!NT_STATUS_IS_OK(status)) { 72 tevent_req_nterror(req, status); 71 if (tevent_req_nterror(req, status)) { 73 72 return; 74 73 } … … 93 92 &state->gid, &state->members); 94 93 TALLOC_FREE(subreq); 95 if (!NT_STATUS_IS_OK(status)) { 96 tevent_req_nterror(req, status); 94 if (tevent_req_nterror(req, status)) { 97 95 return; 98 96 } -
vendor/current/source3/winbindd/winbindd_getgrnam.c
r414 r740 98 98 status = wb_lookupname_recv(subreq, &state->sid, &type); 99 99 TALLOC_FREE(subreq); 100 if (!NT_STATUS_IS_OK(status)) { 101 tevent_req_nterror(req, status); 100 if (tevent_req_nterror(req, status)) { 102 101 return; 103 102 } … … 128 127 &state->gid, &state->members); 129 128 TALLOC_FREE(subreq); 130 if (!NT_STATUS_IS_OK(status)) { 131 tevent_req_nterror(req, status); 129 if (tevent_req_nterror(req, status)) { 132 130 return; 133 131 } -
vendor/current/source3/winbindd/winbindd_getgroups.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "passdb/lookup_sid.h" /* only for LOOKUP_NAME_NO_NSS flag */ 22 23 23 24 struct winbindd_getgroups_state { … … 96 97 status = wb_lookupname_recv(subreq, &state->sid, &state->type); 97 98 TALLOC_FREE(subreq); 98 if (!NT_STATUS_IS_OK(status)) { 99 tevent_req_nterror(req, status); 99 if (tevent_req_nterror(req, status)) { 100 100 return; 101 101 } … … 119 119 &state->sids); 120 120 TALLOC_FREE(subreq); 121 if (!NT_STATUS_IS_OK(status)) { 122 tevent_req_nterror(req, status); 121 if (tevent_req_nterror(req, status)) { 123 122 return; 124 123 } -
vendor/current/source3/winbindd/winbindd_getpwent.c
r414 r740 98 98 return; 99 99 } 100 if (!NT_STATUS_IS_OK(status)) { 101 tevent_req_nterror(req, status); 100 if (tevent_req_nterror(req, status)) { 102 101 return; 103 102 } -
vendor/current/source3/winbindd/winbindd_getpwnam.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "passdb/lookup_sid.h" /* only for LOOKUP_NAME_NO_NSS flag */ 22 23 23 24 struct winbindd_getpwnam_state { … … 100 101 status = wb_lookupname_recv(subreq, &state->sid, &state->type); 101 102 TALLOC_FREE(subreq); 102 if (!NT_STATUS_IS_OK(status)) { 103 tevent_req_nterror(req, status); 103 if (tevent_req_nterror(req, status)) { 104 104 return; 105 105 } … … 120 120 status = wb_getpwsid_recv(subreq); 121 121 TALLOC_FREE(subreq); 122 if (!NT_STATUS_IS_OK(status)) { 123 tevent_req_nterror(req, status); 122 if (tevent_req_nterror(req, status)) { 124 123 return; 125 124 } -
vendor/current/source3/winbindd/winbindd_getpwsid.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "../libcli/security/security.h" 22 23 23 24 struct winbindd_getpwsid_state { … … 70 71 status = wb_getpwsid_recv(subreq); 71 72 TALLOC_FREE(subreq); 72 if (!NT_STATUS_IS_OK(status)) { 73 tevent_req_nterror(req, status); 73 if (tevent_req_nterror(req, status)) { 74 74 return; 75 75 } -
vendor/current/source3/winbindd/winbindd_getpwuid.c
r414 r740 66 66 status = wb_uid2sid_recv(subreq, &state->sid); 67 67 TALLOC_FREE(subreq); 68 if (!NT_STATUS_IS_OK(status)) { 69 tevent_req_nterror(req, status); 68 if (tevent_req_nterror(req, status)) { 70 69 return; 71 70 } … … 86 85 status = wb_getpwsid_recv(subreq); 87 86 TALLOC_FREE(subreq); 88 if (!NT_STATUS_IS_OK(status)) { 89 tevent_req_nterror(req, status); 87 if (tevent_req_nterror(req, status)) { 90 88 return; 91 89 } -
vendor/current/source3/winbindd/winbindd_getsidaliases.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "../libcli/security/security.h" 22 23 23 24 struct winbindd_getsidaliases_state { … … 37 38 struct winbindd_getsidaliases_state *state; 38 39 struct winbindd_domain *domain; 39 size_t num_sids;40 uint32_t num_sids; 40 41 struct dom_sid *sids; 41 42 … … 69 70 sids = NULL; 70 71 71 if ((request->extra_data.data != NULL) 72 && !parse_sidlist(state, request->extra_data.data, 73 &sids, &num_sids)) { 74 DEBUG(1, ("Could not parse SID list: %s\n", 75 request->extra_data.data)); 76 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 77 return tevent_req_post(req, ev); 72 if (request->extra_data.data != NULL) { 73 if (request->extra_data.data[request->extra_len-1] != '\0') { 74 DEBUG(1, ("Got non-NULL terminated sidlist\n")); 75 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 76 return tevent_req_post(req, ev); 77 } 78 if (!parse_sidlist(state, request->extra_data.data, 79 &sids, &num_sids)) { 80 DEBUG(1, ("Could not parse SID list: %s\n", 81 request->extra_data.data)); 82 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 83 return tevent_req_post(req, ev); 84 } 85 } 86 87 if (DEBUGLEVEL >= 10) { 88 size_t i; 89 for (i=0; i<num_sids; i++) { 90 fstring sidstr; 91 sid_to_fstring(sidstr, &sids[i]); 92 DEBUGADD(10, ("%s\n", sidstr)); 93 } 78 94 } 79 95 … … 97 113 &state->aliases); 98 114 TALLOC_FREE(subreq); 99 if (!NT_STATUS_IS_OK(status)) { 100 tevent_req_nterror(req, status); 115 if (tevent_req_nterror(req, status)) { 101 116 return; 102 117 } -
vendor/current/source3/winbindd/winbindd_getuserdomgroups.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "../libcli/security/security.h" 22 23 23 24 struct winbindd_getuserdomgroups_state { … … 83 84 &state->sids); 84 85 TALLOC_FREE(subreq); 85 if (!NT_STATUS_IS_OK(status)) { 86 tevent_req_nterror(req, status); 86 if (tevent_req_nterror(req, status)) { 87 87 return; 88 88 } -
vendor/current/source3/winbindd/winbindd_getusersids.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "../libcli/security/security.h" 22 23 23 24 struct winbindd_getusersids_state { … … 74 75 &state->sids); 75 76 TALLOC_FREE(subreq); 76 if (!NT_STATUS_IS_OK(status)) { 77 tevent_req_nterror(req, status); 77 if (tevent_req_nterror(req, status)) { 78 78 return; 79 79 } -
vendor/current/source3/winbindd/winbindd_gid_to_sid.c
r414 r740 64 64 status = wb_gid2sid_recv(subreq, &state->sid); 65 65 TALLOC_FREE(subreq); 66 if (!NT_STATUS_IS_OK(status)) { 67 tevent_req_nterror(req, status); 66 if (tevent_req_nterror(req, status)) { 68 67 return; 69 68 } -
vendor/current/source3/winbindd/winbindd_list_groups.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ cli_wbint.h"22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 23 24 24 struct winbindd_list_groups_domstate { … … 91 91 struct winbindd_list_groups_domstate *d = &state->domains[i]; 92 92 93 d->subreq = rpccli_wbint_QueryGroupList_send(94 state->domains, ev, d ->domain->child.rpccli,93 d->subreq = dcerpc_wbint_QueryGroupList_send( 94 state->domains, ev, dom_child_handle(d->domain), 95 95 &d->groups); 96 96 if (tevent_req_nomem(d->subreq, req)) { … … 114 114 int i; 115 115 116 status = rpccli_wbint_QueryGroupList_recv(subreq, state->domains,116 status = dcerpc_wbint_QueryGroupList_recv(subreq, state->domains, 117 117 &result); 118 118 … … 125 125 struct winbindd_list_groups_domstate *d = &state->domains[i]; 126 126 127 DEBUG(10, ("Domain %s returned %d users\n", d->domain->name,127 DEBUG(10, ("Domain %s returned %d groups\n", d->domain->name, 128 128 d->groups.num_principals)); 129 129 … … 154 154 char *result; 155 155 int i; 156 uint32_t j ;156 uint32_t j, num_entries = 0; 157 157 size_t len; 158 158 … … 162 162 163 163 len = 0; 164 response->data.num_entries = 0; 164 165 for (i=0; i<state->num_domains; i++) { 165 166 struct winbindd_list_groups_domstate *d = &state->domains[i]; … … 172 173 len += strlen(name)+1; 173 174 } 175 response->data.num_entries += d->groups.num_principals; 174 176 } 175 177 … … 194 196 result[len] = ','; 195 197 len += 1; 198 num_entries++; 196 199 } 197 200 } 198 201 result[len-1] = '\0'; 199 202 203 response->data.num_entries = num_entries; 200 204 response->extra_data.data = result; 201 205 response->length += len; -
vendor/current/source3/winbindd/winbindd_list_users.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ cli_wbint.h"22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 23 24 24 struct winbindd_list_users_domstate { … … 91 91 struct winbindd_list_users_domstate *d = &state->domains[i]; 92 92 93 d->subreq = rpccli_wbint_QueryUserList_send(94 state->domains, ev, d ->domain->child.rpccli,93 d->subreq = dcerpc_wbint_QueryUserList_send( 94 state->domains, ev, dom_child_handle(d->domain), 95 95 &d->users); 96 96 if (tevent_req_nomem(d->subreq, req)) { … … 114 114 int i; 115 115 116 status = rpccli_wbint_QueryUserList_recv(subreq, state->domains,116 status = dcerpc_wbint_QueryUserList_recv(subreq, state->domains, 117 117 &result); 118 118 … … 162 162 163 163 len = 0; 164 response->data.num_entries = 0; 164 165 for (i=0; i<state->num_domains; i++) { 165 166 struct winbindd_list_users_domstate *d = &state->domains[i]; … … 172 173 len += strlen(name)+1; 173 174 } 175 response->data.num_entries += d->users.num_userinfos; 174 176 } 175 177 -
vendor/current/source3/winbindd/winbindd_lookupname.c
r414 r740 87 87 status = wb_lookupname_recv(subreq, &state->sid, &state->type); 88 88 TALLOC_FREE(subreq); 89 if (!NT_STATUS_IS_OK(status)) { 90 tevent_req_nterror(req, status); 89 if (tevent_req_nterror(req, status)) { 91 90 return; 92 91 } -
vendor/current/source3/winbindd/winbindd_lookuprids.c
r618 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/cli_wbint.h" 22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 #include "../libcli/security/security.h" 23 24 24 25 struct winbindd_lookuprids_state { … … 83 84 } 84 85 85 subreq = rpccli_wbint_LookupRids_send(86 state, ev, dom ain->child.rpccli, &state->domain_sid,86 subreq = dcerpc_wbint_LookupRids_send( 87 state, ev, dom_child_handle(domain), &state->domain_sid, 87 88 &state->rids, &state->domain_name, &state->names); 88 89 if (tevent_req_nomem(subreq, req)) { … … 101 102 NTSTATUS status, result; 102 103 103 status = rpccli_wbint_LookupRids_recv(subreq, state, &result);104 status = dcerpc_wbint_LookupRids_recv(subreq, state, &result); 104 105 TALLOC_FREE(subreq); 105 if ( !NT_STATUS_IS_OK(status)) {106 if (any_nt_status_not_ok(status, result, &status)) { 106 107 tevent_req_nterror(req, status); 107 return;108 }109 if (!NT_STATUS_IS_OK(result)) {110 tevent_req_nterror(req, result);111 108 return; 112 109 } -
vendor/current/source3/winbindd/winbindd_lookupsid.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "../libcli/security/security.h" 22 23 23 24 struct winbindd_lookupsid_state { 24 struct tevent_context *ev;25 25 struct dom_sid sid; 26 26 enum lsa_SidType type; … … 44 44 return NULL; 45 45 } 46 state->ev = ev;47 46 48 47 /* Ensure null termination */ … … 54 53 DEBUG(5, ("%s not a SID\n", request->data.sid)); 55 54 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 56 return tevent_req_post(req, ev); ;55 return tevent_req_post(req, ev); 57 56 } 58 57 -
vendor/current/source3/winbindd/winbindd_misc.c
r414 r740 23 23 #include "includes.h" 24 24 #include "winbindd.h" 25 #include "../librpc/gen_ndr/cli_netlogon.h"26 25 27 26 #undef DBGC_CLASS … … 131 130 } 132 131 132 state->response->data.num_entries = num_domains; 133 133 134 extra_data_len = strlen(extra_data); 134 135 if (extra_data_len > 0) { … … 204 205 state->response->length += extra_data_len+1; 205 206 } 206 207 return WINBINDD_OK;208 }209 210 /* This is the child-only version of --sequence. It only allows for a single211 * domain (ie "our" one) to be displayed. */212 213 enum winbindd_result winbindd_dual_show_sequence(struct winbindd_domain *domain,214 struct winbindd_cli_state *state)215 {216 DEBUG(3, ("[%5lu]: show sequence\n", (unsigned long)state->pid));217 218 /* Ensure null termination */219 state->request->domain_name[sizeof(state->request->domain_name)-1]='\0';220 221 domain->methods->sequence_number(domain, &domain->sequence_number);222 223 state->response->data.sequence_number =224 domain->sequence_number;225 207 226 208 return WINBINDD_OK; … … 333 315 } 334 316 317 void winbindd_dc_info(struct winbindd_cli_state *cli) 318 { 319 struct winbindd_domain *domain; 320 char *dc_name, *dc_ip; 321 322 cli->request->domain_name[sizeof(cli->request->domain_name)-1] = '\0'; 323 324 DEBUG(3, ("[%5lu]: domain_info [%s]\n", (unsigned long)cli->pid, 325 cli->request->domain_name)); 326 327 if (cli->request->domain_name[0] != '\0') { 328 domain = find_domain_from_name_noinit( 329 cli->request->domain_name); 330 DEBUG(10, ("Could not find domain %s\n", 331 cli->request->domain_name)); 332 if (domain == NULL) { 333 request_error(cli); 334 return; 335 } 336 } else { 337 domain = find_our_domain(); 338 } 339 340 if (!fetch_current_dc_from_gencache( 341 talloc_tos(), domain->name, &dc_name, &dc_ip)) { 342 DEBUG(10, ("fetch_current_dc_from_gencache(%s) failed\n", 343 domain->name)); 344 request_error(cli); 345 return; 346 } 347 348 cli->response->data.num_entries = 1; 349 cli->response->extra_data.data = talloc_asprintf( 350 cli->mem_ctx, "%s\n%s\n", dc_name, dc_ip); 351 352 TALLOC_FREE(dc_name); 353 TALLOC_FREE(dc_ip); 354 355 if (cli->response->extra_data.data == NULL) { 356 request_error(cli); 357 return; 358 } 359 360 /* must add one to length to copy the 0 for string termination */ 361 cli->response->length += 362 strlen((char *)cli->response->extra_data.data) + 1; 363 364 request_ok(cli); 365 } 366 335 367 /* List various tidbits of information */ 336 368 -
vendor/current/source3/winbindd/winbindd_ndr.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "../librpc/gen_ndr/ndr_netlogon.h" 23 #include "../librpc/gen_ndr/ndr_security.h" 24 #include "librpc/ndr/util.h" 22 25 23 26 #undef DBGC_CLASS … … 119 122 const struct winbindd_domain *r) 120 123 { 124 int i; 121 125 if (!r) { 122 126 return; … … 149 153 ndr_print_NTSTATUS(ndr, "last_status", r->last_status); 150 154 ndr_print_winbindd_cm_conn(ndr, "conn", &r->conn); 151 ndr_print_winbindd_child(ndr, "child", &r->child); 155 for (i=0; i<lp_winbind_max_domain_connections(); i++) { 156 ndr_print_winbindd_child(ndr, "children", &r->children[i]); 157 } 152 158 ndr_print_uint32(ndr, "check_online_timeout", r->check_online_timeout); 153 159 ndr_print_ptr(ndr, "check_online_event", r->check_online_event); -
vendor/current/source3/winbindd/winbindd_pam.c
r597 r740 26 26 #include "winbindd.h" 27 27 #include "../libcli/auth/libcli_auth.h" 28 #include "../librpc/gen_ndr/cli_samr.h" 28 #include "../librpc/gen_ndr/ndr_samr_c.h" 29 #include "rpc_client/cli_pipe.h" 30 #include "rpc_client/cli_samr.h" 31 #include "../librpc/gen_ndr/ndr_netlogon.h" 32 #include "rpc_client/cli_netlogon.h" 29 33 #include "smb_krb5.h" 34 #include "../lib/crypto/arcfour.h" 35 #include "../libcli/security/security.h" 36 #include "ads.h" 37 #include "../librpc/gen_ndr/krb5pac.h" 38 #include "passdb/machine_sid.h" 39 #include "auth.h" 30 40 31 41 #undef DBGC_CLASS … … 35 45 36 46 static NTSTATUS append_info3_as_txt(TALLOC_CTX *mem_ctx, 37 struct winbindd_ cli_state *state,47 struct winbindd_response *resp, 38 48 struct netr_SamInfo3 *info3) 39 49 { … … 41 51 uint32_t i; 42 52 43 state->response->data.auth.info3.logon_time =53 resp->data.auth.info3.logon_time = 44 54 nt_time_to_unix(info3->base.last_logon); 45 state->response->data.auth.info3.logoff_time =55 resp->data.auth.info3.logoff_time = 46 56 nt_time_to_unix(info3->base.last_logoff); 47 state->response->data.auth.info3.kickoff_time =57 resp->data.auth.info3.kickoff_time = 48 58 nt_time_to_unix(info3->base.acct_expiry); 49 state->response->data.auth.info3.pass_last_set_time =59 resp->data.auth.info3.pass_last_set_time = 50 60 nt_time_to_unix(info3->base.last_password_change); 51 state->response->data.auth.info3.pass_can_change_time =61 resp->data.auth.info3.pass_can_change_time = 52 62 nt_time_to_unix(info3->base.allow_password_change); 53 state->response->data.auth.info3.pass_must_change_time =63 resp->data.auth.info3.pass_must_change_time = 54 64 nt_time_to_unix(info3->base.force_password_change); 55 65 56 state->response->data.auth.info3.logon_count = info3->base.logon_count;57 state->response->data.auth.info3.bad_pw_count = info3->base.bad_password_count;58 59 state->response->data.auth.info3.user_rid = info3->base.rid;60 state->response->data.auth.info3.group_rid = info3->base.primary_gid;61 sid_to_fstring( state->response->data.auth.info3.dom_sid, info3->base.domain_sid);62 63 state->response->data.auth.info3.num_groups = info3->base.groups.count;64 state->response->data.auth.info3.user_flgs = info3->base.user_flags;65 66 state->response->data.auth.info3.acct_flags = info3->base.acct_flags;67 state->response->data.auth.info3.num_other_sids = info3->sidcount;68 69 fstrcpy( state->response->data.auth.info3.user_name,66 resp->data.auth.info3.logon_count = info3->base.logon_count; 67 resp->data.auth.info3.bad_pw_count = info3->base.bad_password_count; 68 69 resp->data.auth.info3.user_rid = info3->base.rid; 70 resp->data.auth.info3.group_rid = info3->base.primary_gid; 71 sid_to_fstring(resp->data.auth.info3.dom_sid, info3->base.domain_sid); 72 73 resp->data.auth.info3.num_groups = info3->base.groups.count; 74 resp->data.auth.info3.user_flgs = info3->base.user_flags; 75 76 resp->data.auth.info3.acct_flags = info3->base.acct_flags; 77 resp->data.auth.info3.num_other_sids = info3->sidcount; 78 79 fstrcpy(resp->data.auth.info3.user_name, 70 80 info3->base.account_name.string); 71 fstrcpy( state->response->data.auth.info3.full_name,81 fstrcpy(resp->data.auth.info3.full_name, 72 82 info3->base.full_name.string); 73 fstrcpy( state->response->data.auth.info3.logon_script,83 fstrcpy(resp->data.auth.info3.logon_script, 74 84 info3->base.logon_script.string); 75 fstrcpy( state->response->data.auth.info3.profile_path,85 fstrcpy(resp->data.auth.info3.profile_path, 76 86 info3->base.profile_path.string); 77 fstrcpy( state->response->data.auth.info3.home_dir,87 fstrcpy(resp->data.auth.info3.home_dir, 78 88 info3->base.home_directory.string); 79 fstrcpy( state->response->data.auth.info3.dir_drive,89 fstrcpy(resp->data.auth.info3.dir_drive, 80 90 info3->base.home_drive.string); 81 91 82 fstrcpy( state->response->data.auth.info3.logon_srv,92 fstrcpy(resp->data.auth.info3.logon_srv, 83 93 info3->base.logon_server.string); 84 fstrcpy( state->response->data.auth.info3.logon_dom,94 fstrcpy(resp->data.auth.info3.logon_dom, 85 95 info3->base.domain.string); 86 96 87 ex = talloc_strdup( state->mem_ctx, "");97 ex = talloc_strdup(mem_ctx, ""); 88 98 NT_STATUS_HAVE_NO_MEMORY(ex); 89 99 … … 109 119 } 110 120 111 state->response->extra_data.data = ex;112 state->response->length += talloc_get_size(ex);121 resp->extra_data.data = ex; 122 resp->length += talloc_get_size(ex); 113 123 114 124 return NT_STATUS_OK; … … 116 126 117 127 static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx, 118 struct winbindd_ cli_state *state,128 struct winbindd_response *resp, 119 129 struct netr_SamInfo3 *info3) 120 130 { … … 122 132 enum ndr_err_code ndr_err; 123 133 124 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL,info3,134 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, info3, 125 135 (ndr_push_flags_fn_t)ndr_push_netr_SamInfo3); 126 136 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 129 139 } 130 140 131 state->response->extra_data.data = blob.data;132 state->response->length += blob.length;141 resp->extra_data.data = blob.data; 142 resp->length += blob.length; 133 143 134 144 return NT_STATUS_OK; … … 136 146 137 147 static NTSTATUS append_unix_username(TALLOC_CTX *mem_ctx, 138 struct winbindd_ cli_state *state,148 struct winbindd_response *resp, 139 149 const struct netr_SamInfo3 *info3, 140 150 const char *name_domain, … … 160 170 } 161 171 162 fill_domain_username( state->response->data.auth.unix_username,172 fill_domain_username(resp->data.auth.unix_username, 163 173 nt_domain, nt_username, true); 164 174 165 DEBUG(5, ("Setting unix username to [%s]\n",166 state->response->data.auth.unix_username));175 DEBUG(5, ("Setting unix username to [%s]\n", 176 resp->data.auth.unix_username)); 167 177 168 178 return NT_STATUS_OK; … … 170 180 171 181 static NTSTATUS append_afs_token(TALLOC_CTX *mem_ctx, 172 struct winbindd_ cli_state *state,182 struct winbindd_response *resp, 173 183 const struct netr_SamInfo3 *info3, 174 184 const char *name_domain, … … 193 203 194 204 { 195 DOM_SIDuser_sid;205 struct dom_sid user_sid; 196 206 fstring sidstr; 197 207 198 sid_co py(&user_sid, info3->base.domain_sid);199 sid_append_rid(&user_sid,info3->base.rid);208 sid_compose(&user_sid, info3->base.domain_sid, 209 info3->base.rid); 200 210 sid_to_fstring(sidstr, &user_sid); 201 211 afsname = talloc_string_sub(mem_ctx, afsname, … … 224 234 return NT_STATUS_OK; 225 235 } 226 state->response->extra_data.data = talloc_strdup(state->mem_ctx, 227 token); 228 if (state->response->extra_data.data == NULL) { 236 resp->extra_data.data = talloc_strdup(mem_ctx, token); 237 if (resp->extra_data.data == NULL) { 229 238 return NT_STATUS_NO_MEMORY; 230 239 } 231 state->response->length += 232 strlen((const char *)state->response->extra_data.data)+1; 240 resp->length += strlen((const char *)resp->extra_data.data)+1; 233 241 234 242 return NT_STATUS_OK; 235 243 } 236 244 237 NTSTATUS check_info3_in_group(struct netr_SamInfo3 *info3,238 245 static NTSTATUS check_info3_in_group(struct netr_SamInfo3 *info3, 246 const char *group_sid) 239 247 /** 240 248 * Check whether a user belongs to a group or list of groups. … … 249 257 */ 250 258 { 251 DOM_SID*require_membership_of_sid;252 size_t num_require_membership_of_sid;259 struct dom_sid *require_membership_of_sid; 260 uint32_t num_require_membership_of_sid; 253 261 char *req_sid; 254 262 const char *p; 255 DOM_SIDsid;263 struct dom_sid sid; 256 264 size_t i; 257 struct nt_user_token *token;265 struct security_token *token; 258 266 TALLOC_CTX *frame = talloc_stackframe(); 259 267 NTSTATUS status; … … 266 274 } 267 275 268 token = talloc_zero(talloc_tos(), struct nt_user_token);276 token = talloc_zero(talloc_tos(), struct security_token); 269 277 if (token == NULL) { 270 278 DEBUG(0, ("talloc failed\n")); … … 297 305 298 306 status = sid_array_from_info3(talloc_tos(), info3, 299 &token-> user_sids,307 &token->sids, 300 308 &token->num_sids, 301 309 true, false); … … 315 323 } 316 324 317 debug_nt_user_token(DBGC_CLASS, 10, token);325 security_token_debug(DBGC_CLASS, 10, token); 318 326 319 327 for (i=0; i<num_require_membership_of_sid; i++) { … … 349 357 } 350 358 351 if (is_myname(domain_name)) { 352 DEBUG(3, ("Authentication for domain %s (local domain " 353 "to this server) not supported at this " 354 "stage\n", domain_name)); 355 return NULL; 359 if (strequal(domain_name, get_global_sam_name())) { 360 return find_domain_from_name_noinit(domain_name); 356 361 } 357 362 … … 387 392 388 393 static NTSTATUS fillup_password_policy(struct winbindd_domain *domain, 389 struct winbindd_cli_state *state) 394 struct winbindd_response *response) 395 { 396 TALLOC_CTX *frame = talloc_stackframe(); 397 struct winbindd_methods *methods; 398 NTSTATUS status; 399 struct samr_DomInfo1 password_policy; 400 401 if ( !winbindd_can_contact_domain( domain ) ) { 402 DEBUG(5,("fillup_password_policy: No inbound trust to " 403 "contact domain %s\n", domain->name)); 404 status = NT_STATUS_NOT_SUPPORTED; 405 goto done; 406 } 407 408 methods = domain->methods; 409 410 status = methods->password_policy(domain, talloc_tos(), &password_policy); 411 if (NT_STATUS_IS_ERR(status)) { 412 goto done; 413 } 414 415 fill_in_password_policy(response, &password_policy); 416 417 done: 418 TALLOC_FREE(frame); 419 return NT_STATUS_OK; 420 } 421 422 static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain *domain, 423 TALLOC_CTX *mem_ctx, 424 uint16 *lockout_threshold) 425 { 426 struct winbindd_methods *methods; 427 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 428 struct samr_DomInfo12 lockout_policy; 429 430 *lockout_threshold = 0; 431 432 methods = domain->methods; 433 434 status = methods->lockout_policy(domain, mem_ctx, &lockout_policy); 435 if (NT_STATUS_IS_ERR(status)) { 436 return status; 437 } 438 439 *lockout_threshold = lockout_policy.lockout_threshold; 440 441 return NT_STATUS_OK; 442 } 443 444 static NTSTATUS get_pwd_properties(struct winbindd_domain *domain, 445 TALLOC_CTX *mem_ctx, 446 uint32 *password_properties) 390 447 { 391 448 struct winbindd_methods *methods; … … 393 450 struct samr_DomInfo1 password_policy; 394 451 395 if ( !winbindd_can_contact_domain( domain ) ) {396 DEBUG(5,("fillup_password_policy: No inbound trust to "397 "contact domain %s\n", domain->name));398 return NT_STATUS_NOT_SUPPORTED;399 }400 401 methods = domain->methods;402 403 status = methods->password_policy(domain, state->mem_ctx, &password_policy);404 if (NT_STATUS_IS_ERR(status)) {405 return status;406 }407 408 fill_in_password_policy(state->response, &password_policy);409 410 return NT_STATUS_OK;411 }412 413 static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain *domain,414 TALLOC_CTX *mem_ctx,415 uint16 *lockout_threshold)416 {417 struct winbindd_methods *methods;418 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;419 struct samr_DomInfo12 lockout_policy;420 421 *lockout_threshold = 0;422 423 methods = domain->methods;424 425 status = methods->lockout_policy(domain, mem_ctx, &lockout_policy);426 if (NT_STATUS_IS_ERR(status)) {427 return status;428 }429 430 *lockout_threshold = lockout_policy.lockout_threshold;431 432 return NT_STATUS_OK;433 }434 435 static NTSTATUS get_pwd_properties(struct winbindd_domain *domain,436 TALLOC_CTX *mem_ctx,437 uint32 *password_properties)438 {439 struct winbindd_methods *methods;440 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;441 struct samr_DomInfo1 password_policy;442 443 452 *password_properties = 0; 444 453 … … 460 469 const char *type, 461 470 uid_t uid, 462 bool *internal_ccache)471 const char **user_ccache_file) 463 472 { 464 473 /* accept FILE and WRFILE as krb5_cc_type from the client and then … … 468 477 const char *gen_cc = NULL; 469 478 470 *internal_ccache = true; 471 472 if (uid == -1) { 473 goto memory_ccache; 474 } 475 476 if (!type || type[0] == '\0') { 477 goto memory_ccache; 478 } 479 480 if (strequal(type, "FILE")) { 481 gen_cc = talloc_asprintf(mem_ctx, "FILE:/tmp/krb5cc_%d", uid); 482 } else if (strequal(type, "WRFILE")) { 483 gen_cc = talloc_asprintf(mem_ctx, "WRFILE:/tmp/krb5cc_%d", uid); 484 } else { 485 DEBUG(10,("we don't allow to set a %s type ccache\n", type)); 486 goto memory_ccache; 487 } 488 489 *internal_ccache = false; 490 goto done; 491 492 memory_ccache: 493 gen_cc = talloc_strdup(mem_ctx, "MEMORY:winbindd_pam_ccache"); 494 495 done: 479 if (uid != -1) { 480 if (strequal(type, "FILE")) { 481 gen_cc = talloc_asprintf( 482 mem_ctx, "FILE:/tmp/krb5cc_%d", uid); 483 } 484 if (strequal(type, "WRFILE")) { 485 gen_cc = talloc_asprintf( 486 mem_ctx, "WRFILE:/tmp/krb5cc_%d", uid); 487 } 488 } 489 490 *user_ccache_file = gen_cc; 491 492 if (gen_cc == NULL) { 493 gen_cc = talloc_strdup(mem_ctx, "MEMORY:winbindd_pam_ccache"); 494 } 496 495 if (gen_cc == NULL) { 497 496 DEBUG(0,("out of memory\n")); … … 499 498 } 500 499 501 DEBUG(10,("using ccache: %s %s\n", gen_cc, *internal_ccache ? "(internal)":"")); 500 DEBUG(10, ("using ccache: %s%s\n", gen_cc, 501 (*user_ccache_file == NULL) ? " (internal)":"")); 502 502 503 503 return gen_cc; 504 504 } 505 505 506 static void setup_return_cc_name(struct winbindd_cli_state *state, const char *cc)507 {508 const char *type = state->request->data.auth.krb5_cc_type;509 510 state->response->data.auth.krb5ccname[0] = '\0';511 512 if (type[0] == '\0') {513 return;514 }515 516 if (!strequal(type, "FILE") &&517 !strequal(type, "WRFILE")) {518 DEBUG(10,("won't return krbccname for a %s type ccache\n",519 type));520 return;521 }522 523 fstrcpy(state->response->data.auth.krb5ccname, cc);524 }525 526 506 #endif 527 507 528 static uid_t get_uid_from_state(struct winbindd_cli_state *state)508 uid_t get_uid_from_request(struct winbindd_request *request) 529 509 { 530 510 uid_t uid; 531 511 532 uid = state->request->data.auth.uid;512 uid = request->data.auth.uid; 533 513 534 514 if (uid < 0) { … … 544 524 **********************************************************************/ 545 525 546 static NTSTATUS winbindd_raw_kerberos_login(struct winbindd_domain *domain, 547 struct winbindd_cli_state *state, 548 struct netr_SamInfo3 **info3) 526 static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx, 527 struct winbindd_domain *domain, 528 const char *user, 529 const char *pass, 530 const char *krb5_cc_type, 531 uid_t uid, 532 struct netr_SamInfo3 **info3, 533 fstring krb5ccname) 549 534 { 550 535 #ifdef HAVE_KRB5 … … 558 543 time_t ticket_lifetime = 0; 559 544 time_t renewal_until = 0; 560 uid_t uid = -1;561 545 ADS_STRUCT *ads; 562 546 time_t time_offset = 0; 563 bool internal_ccache = true; 564 565 ZERO_STRUCTP(info3); 547 const char *user_ccache_file; 548 struct PAC_LOGON_INFO *logon_info = NULL; 566 549 567 550 *info3 = NULL; … … 570 553 * prepare a krb5_cc_cache string for the user */ 571 554 572 uid = get_uid_from_state(state);573 555 if (uid == -1) { 574 556 DEBUG(0,("no valid uid\n")); 575 557 } 576 558 577 cc = generate_krb5_ccache( state->mem_ctx,578 state->request->data.auth.krb5_cc_type,579 state->request->data.auth.uid,580 & internal_ccache);559 cc = generate_krb5_ccache(mem_ctx, 560 krb5_cc_type, 561 uid, 562 &user_ccache_file); 581 563 if (cc == NULL) { 582 564 return NT_STATUS_NO_MEMORY; … … 596 578 * do kerberos auth and setup ccache as the user */ 597 579 598 parse_domain_user( state->request->data.auth.user, name_domain, name_user);580 parse_domain_user(user, name_domain, name_user); 599 581 600 582 realm = domain->alt_name; 601 583 strupper_m(realm); 602 584 603 principal_s = talloc_asprintf( state->mem_ctx, "%s@%s", name_user, realm);585 principal_s = talloc_asprintf(mem_ctx, "%s@%s", name_user, realm); 604 586 if (principal_s == NULL) { 605 587 return NT_STATUS_NO_MEMORY; 606 588 } 607 589 608 service = talloc_asprintf( state->mem_ctx, "%s/%s@%s", KRB5_TGS_NAME, realm, realm);590 service = talloc_asprintf(mem_ctx, "%s/%s@%s", KRB5_TGS_NAME, realm, realm); 609 591 if (service == NULL) { 610 592 return NT_STATUS_NO_MEMORY; … … 616 598 /************************ ENTERING NON-ROOT **********************/ 617 599 618 if ( !internal_ccache) {600 if (user_ccache_file != NULL) { 619 601 set_effective_uid(uid); 620 602 DEBUG(10,("winbindd_raw_kerberos_login: uid is %d\n", uid)); 621 603 } 622 604 623 result = kerberos_return_ info3_from_pac(state->mem_ctx,624 625 state->request->data.auth.pass,626 627 628 629 630 631 632 633 634 info3);635 if ( !internal_ccache) {605 result = kerberos_return_pac(mem_ctx, 606 principal_s, 607 pass, 608 time_offset, 609 &ticket_lifetime, 610 &renewal_until, 611 cc, 612 true, 613 true, 614 WINBINDD_PAM_AUTH_KRB5_RENEW_TIME, 615 NULL, 616 &logon_info); 617 if (user_ccache_file != NULL) { 636 618 gain_root_privilege(); 637 619 } … … 643 625 } 644 626 627 *info3 = &logon_info->info3; 628 645 629 DEBUG(10,("winbindd_raw_kerberos_login: winbindd validated ticket of %s\n", 646 630 principal_s)); … … 649 633 * environment */ 650 634 651 if ( !internal_ccache) {652 653 setup_return_cc_name(state, cc);635 if (user_ccache_file != NULL) { 636 637 fstrcpy(krb5ccname, user_ccache_file); 654 638 655 639 result = add_ccache_to_list(principal_s, 656 640 cc, 657 641 service, 658 state->request->data.auth.user,642 user, 659 643 realm, 660 644 uid, … … 697 681 } 698 682 699 if (!NT_STATUS_IS_OK(remove_ccache( state->request->data.auth.user))) {683 if (!NT_STATUS_IS_OK(remove_ccache(user))) { 700 684 DEBUG(3,("winbindd_raw_kerberos_login: " 701 685 "could not remove ccache for user %s\n", 702 state->request->data.auth.user));686 user)); 703 687 } 704 688 … … 734 718 ****************************************************************/ 735 719 736 NTSTATUS append_auth_data(struct winbindd_cli_state *state, 737 struct netr_SamInfo3 *info3, 738 const char *name_domain, 739 const char *name_user) 720 static NTSTATUS append_auth_data(TALLOC_CTX *mem_ctx, 721 struct winbindd_response *resp, 722 uint32_t request_flags, 723 struct netr_SamInfo3 *info3, 724 const char *name_domain, 725 const char *name_user) 740 726 { 741 727 NTSTATUS result; 742 uint32_t flags = state->request->flags; 743 744 if (flags & WBFLAG_PAM_USER_SESSION_KEY) { 745 memcpy(state->response->data.auth.user_session_key, 728 729 if (request_flags & WBFLAG_PAM_USER_SESSION_KEY) { 730 memcpy(resp->data.auth.user_session_key, 746 731 info3->base.key.key, 747 sizeof( state->response->data.auth.user_session_key)732 sizeof(resp->data.auth.user_session_key) 748 733 /* 16 */); 749 734 } 750 735 751 if ( flags & WBFLAG_PAM_LMKEY) {752 memcpy( state->response->data.auth.first_8_lm_hash,736 if (request_flags & WBFLAG_PAM_LMKEY) { 737 memcpy(resp->data.auth.first_8_lm_hash, 753 738 info3->base.LMSessKey.key, 754 sizeof( state->response->data.auth.first_8_lm_hash)739 sizeof(resp->data.auth.first_8_lm_hash) 755 740 /* 8 */); 756 741 } 757 742 758 if (flags & WBFLAG_PAM_INFO3_TEXT) { 759 result = append_info3_as_txt(state->mem_ctx, state, info3); 743 if (request_flags & WBFLAG_PAM_UNIX_NAME) { 744 result = append_unix_username(mem_ctx, resp, 745 info3, name_domain, name_user); 746 if (!NT_STATUS_IS_OK(result)) { 747 DEBUG(10,("Failed to append Unix Username: %s\n", 748 nt_errstr(result))); 749 return result; 750 } 751 } 752 753 /* currently, anything from here on potentially overwrites extra_data. */ 754 755 if (request_flags & WBFLAG_PAM_INFO3_NDR) { 756 result = append_info3_as_ndr(mem_ctx, resp, info3); 757 if (!NT_STATUS_IS_OK(result)) { 758 DEBUG(10,("Failed to append INFO3 (NDR): %s\n", 759 nt_errstr(result))); 760 return result; 761 } 762 } 763 764 if (request_flags & WBFLAG_PAM_INFO3_TEXT) { 765 result = append_info3_as_txt(mem_ctx, resp, info3); 760 766 if (!NT_STATUS_IS_OK(result)) { 761 767 DEBUG(10,("Failed to append INFO3 (TXT): %s\n", … … 765 771 } 766 772 767 /* currently, anything from here on potentially overwrites extra_data. */ 768 769 if (flags & WBFLAG_PAM_INFO3_NDR) { 770 result = append_info3_as_ndr(state->mem_ctx, state, info3); 771 if (!NT_STATUS_IS_OK(result)) { 772 DEBUG(10,("Failed to append INFO3 (NDR): %s\n", 773 nt_errstr(result))); 774 return result; 775 } 776 } 777 778 if (flags & WBFLAG_PAM_UNIX_NAME) { 779 result = append_unix_username(state->mem_ctx, state, info3, 780 name_domain, name_user); 781 if (!NT_STATUS_IS_OK(result)) { 782 DEBUG(10,("Failed to append Unix Username: %s\n", 783 nt_errstr(result))); 784 return result; 785 } 786 } 787 788 if (flags & WBFLAG_PAM_AFS_TOKEN) { 789 result = append_afs_token(state->mem_ctx, state, info3, 790 name_domain, name_user); 773 if (request_flags & WBFLAG_PAM_AFS_TOKEN) { 774 result = append_afs_token(mem_ctx, resp, 775 info3, name_domain, name_user); 791 776 if (!NT_STATUS_IS_OK(result)) { 792 777 DEBUG(10,("Failed to append AFS token: %s\n", … … 799 784 } 800 785 801 void winbindd_pam_auth(struct winbindd_cli_state *state)802 {803 struct winbindd_domain *domain;804 fstring name_domain, name_user;805 char *mapped = NULL;806 NTSTATUS result;807 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;808 809 /* Ensure null termination */810 state->request->data.auth.user811 [sizeof(state->request->data.auth.user)-1]='\0';812 813 /* Ensure null termination */814 state->request->data.auth.pass815 [sizeof(state->request->data.auth.pass)-1]='\0';816 817 DEBUG(3, ("[%5lu]: pam auth %s\n", (unsigned long)state->pid,818 state->request->data.auth.user));819 820 if (!check_request_flags(state->request->flags)) {821 result = NT_STATUS_INVALID_PARAMETER_MIX;822 goto done;823 }824 825 /* Parse domain and username */826 827 name_map_status = normalize_name_unmap(state->mem_ctx,828 state->request->data.auth.user,829 &mapped);830 831 /* Update the auth name if we did any mapping */832 833 if (NT_STATUS_IS_OK(name_map_status) ||834 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED))835 {836 fstrcpy(state->request->data.auth.user, mapped);837 }838 839 if (!canonicalize_username(state->request->data.auth.user, name_domain, name_user)) {840 result = NT_STATUS_NO_SUCH_USER;841 goto done;842 }843 844 domain = find_auth_domain(state->request->flags, name_domain);845 846 if (domain == NULL) {847 result = NT_STATUS_NO_SUCH_USER;848 goto done;849 }850 851 sendto_domain(state, domain);852 return;853 done:854 set_auth_errors(state->response, result);855 DEBUG(5, ("Plain text authentication for %s returned %s "856 "(PAM: %d)\n",857 state->request->data.auth.user,858 state->response->data.auth.nt_status_string,859 state->response->data.auth.pam_error));860 request_error(state);861 }862 863 786 static NTSTATUS winbindd_dual_pam_auth_cached(struct winbindd_domain *domain, 864 787 struct winbindd_cli_state *state, … … 868 791 uint16 max_allowed_bad_attempts; 869 792 fstring name_domain, name_user; 870 DOM_SIDsid;793 struct dom_sid sid; 871 794 enum lsa_SidType type; 872 795 uchar new_nt_pass[NT_HASH_LEN]; … … 891 814 892 815 893 if (!lookup_cached_name(state->mem_ctx, 894 name_domain, 816 if (!lookup_cached_name(name_domain, 895 817 name_user, 896 818 &sid, … … 998 920 const char *principal_s = NULL; 999 921 const char *service = NULL; 1000 bool internal_ccache = false;1001 1002 uid = get_uid_from_ state(state);922 const char *user_ccache_file; 923 924 uid = get_uid_from_request(state->request); 1003 925 if (uid == -1) { 1004 926 DEBUG(0,("winbindd_dual_pam_auth_cached: invalid uid\n")); … … 1009 931 state->request->data.auth.krb5_cc_type, 1010 932 state->request->data.auth.uid, 1011 & internal_ccache);933 &user_ccache_file); 1012 934 if (cc == NULL) { 1013 935 return NT_STATUS_NO_MEMORY; … … 1027 949 } 1028 950 1029 if (!internal_ccache) { 1030 1031 setup_return_cc_name(state, cc); 951 if (user_ccache_file != NULL) { 952 953 fstrcpy(state->response->data.auth.krb5ccname, 954 user_ccache_file); 1032 955 1033 956 result = add_ccache_to_list(principal_s, … … 1058 981 1059 982 result = winbindd_update_creds_by_info3(domain, 1060 state->mem_ctx,1061 983 state->request->data.auth.user, 1062 984 state->request->data.auth.pass, … … 1101 1023 } 1102 1024 1103 if ((my_info3->base.rid != DOMAIN_ USER_RID_ADMIN) ||1025 if ((my_info3->base.rid != DOMAIN_RID_ADMINISTRATOR) || 1104 1026 (password_properties & DOMAIN_PASSWORD_LOCKOUT_ADMINS)) { 1105 1027 my_info3->base.acct_flags |= ACB_AUTOLOCK; … … 1109 1031 failed: 1110 1032 result = winbindd_update_creds_by_info3(domain, 1111 state->mem_ctx,1112 1033 state->request->data.auth.user, 1113 1034 NULL, … … 1176 1097 } 1177 1098 try_login: 1178 result = winbindd_raw_kerberos_login(contact_domain, state, info3); 1099 result = winbindd_raw_kerberos_login( 1100 state->mem_ctx, contact_domain, 1101 state->request->data.auth.user, 1102 state->request->data.auth.pass, 1103 state->request->data.auth.krb5_cc_type, 1104 get_uid_from_request(state->request), 1105 info3, state->response->data.auth.krb5ccname); 1179 1106 done: 1180 1107 return result; 1181 1108 } 1182 1109 1183 typedef NTSTATUS (*netlogon_fn_t)(struct rpc_pipe_client *cli, 1184 TALLOC_CTX *mem_ctx, 1185 uint32 logon_parameters, 1186 const char *server, 1187 const char *username, 1188 const char *domain, 1189 const char *workstation, 1190 const uint8 chal[8], 1191 uint16_t validation_level, 1192 DATA_BLOB lm_response, 1193 DATA_BLOB nt_response, 1194 struct netr_SamInfo3 **info3); 1195 1196 static NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, 1197 struct winbindd_cli_state *state, 1198 struct netr_SamInfo3 **info3) 1199 { 1200 1201 struct rpc_pipe_client *netlogon_pipe; 1202 uchar chal[8]; 1203 DATA_BLOB lm_resp; 1204 DATA_BLOB nt_resp; 1110 static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx, 1111 const char *domain, const char *user, 1112 const DATA_BLOB *challenge, 1113 const DATA_BLOB *lm_resp, 1114 const DATA_BLOB *nt_resp, 1115 struct netr_SamInfo3 **pinfo3) 1116 { 1117 struct auth_usersupplied_info *user_info = NULL; 1118 NTSTATUS status; 1119 1120 status = make_user_info(&user_info, user, user, domain, domain, 1121 global_myname(), lm_resp, nt_resp, NULL, NULL, 1122 NULL, AUTH_PASSWORD_RESPONSE); 1123 if (!NT_STATUS_IS_OK(status)) { 1124 DEBUG(10, ("make_user_info failed: %s\n", nt_errstr(status))); 1125 return status; 1126 } 1127 1128 /* We don't want any more mapping of the username */ 1129 user_info->mapped_state = True; 1130 1131 status = check_sam_security_info3(challenge, talloc_tos(), user_info, 1132 pinfo3); 1133 free_user_info(&user_info); 1134 DEBUG(10, ("Authenticaticating user %s\\%s returned %s\n", domain, 1135 user, nt_errstr(status))); 1136 return status; 1137 } 1138 1139 static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain, 1140 TALLOC_CTX *mem_ctx, 1141 uint32_t logon_parameters, 1142 const char *server, 1143 const char *username, 1144 const char *domainname, 1145 const char *workstation, 1146 const uint8_t chal[8], 1147 DATA_BLOB lm_response, 1148 DATA_BLOB nt_response, 1149 struct netr_SamInfo3 **info3) 1150 { 1205 1151 int attempts = 0; 1206 unsigned char local_lm_response[24]; 1207 unsigned char local_nt_response[24]; 1208 struct winbindd_domain *contact_domain; 1209 fstring name_domain, name_user; 1210 bool retry; 1152 bool retry = false; 1211 1153 NTSTATUS result; 1212 struct netr_SamInfo3 *my_info3 = NULL;1213 1214 *info3 = NULL;1215 1216 DEBUG(10,("winbindd_dual_pam_auth_samlogon\n"));1217 1218 /* Parse domain and username */1219 1220 parse_domain_user(state->request->data.auth.user, name_domain, name_user);1221 1222 /* do password magic */1223 1224 1225 generate_random_buffer(chal, 8);1226 if (lp_client_ntlmv2_auth()) {1227 DATA_BLOB server_chal;1228 DATA_BLOB names_blob;1229 DATA_BLOB nt_response;1230 DATA_BLOB lm_response;1231 server_chal = data_blob_talloc(state->mem_ctx, chal, 8);1232 1233 /* note that the 'workgroup' here is a best guess - we don't know1234 the server's domain at this point. The 'server name' is also1235 dodgy...1236 */1237 names_blob = NTLMv2_generate_names_blob(state->mem_ctx, global_myname(), lp_workgroup());1238 1239 if (!SMBNTLMv2encrypt(NULL, name_user, name_domain,1240 state->request->data.auth.pass,1241 &server_chal,1242 &names_blob,1243 &lm_response, &nt_response, NULL, NULL)) {1244 data_blob_free(&names_blob);1245 data_blob_free(&server_chal);1246 DEBUG(0, ("winbindd_pam_auth: SMBNTLMv2encrypt() failed!\n"));1247 result = NT_STATUS_NO_MEMORY;1248 goto done;1249 }1250 data_blob_free(&names_blob);1251 data_blob_free(&server_chal);1252 lm_resp = data_blob_talloc(state->mem_ctx, lm_response.data,1253 lm_response.length);1254 nt_resp = data_blob_talloc(state->mem_ctx, nt_response.data,1255 nt_response.length);1256 data_blob_free(&lm_response);1257 data_blob_free(&nt_response);1258 1259 } else {1260 if (lp_client_lanman_auth()1261 && SMBencrypt(state->request->data.auth.pass,1262 chal,1263 local_lm_response)) {1264 lm_resp = data_blob_talloc(state->mem_ctx,1265 local_lm_response,1266 sizeof(local_lm_response));1267 } else {1268 lm_resp = data_blob_null;1269 }1270 SMBNTencrypt(state->request->data.auth.pass,1271 chal,1272 local_nt_response);1273 1274 nt_resp = data_blob_talloc(state->mem_ctx,1275 local_nt_response,1276 sizeof(local_nt_response));1277 }1278 1279 /* what domain should we contact? */1280 1281 if ( IS_DC ) {1282 if (!(contact_domain = find_domain_from_name(name_domain))) {1283 DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",1284 state->request->data.auth.user, name_domain, name_user, name_domain));1285 result = NT_STATUS_NO_SUCH_USER;1286 goto done;1287 }1288 1289 } else {1290 if (is_myname(name_domain)) {1291 DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain));1292 result = NT_STATUS_NO_SUCH_USER;1293 goto done;1294 }1295 1296 contact_domain = find_our_domain();1297 }1298 1299 /* check authentication loop */1300 1154 1301 1155 do { 1302 netlogon_fn_t logon_fn;1303 const struct cli_pipe_auth_data *auth;1156 struct rpc_pipe_client *netlogon_pipe; 1157 const struct pipe_auth_data *auth; 1304 1158 uint32_t neg_flags = 0; 1305 1159 1306 ZERO_STRUCTP( my_info3);1160 ZERO_STRUCTP(info3); 1307 1161 retry = false; 1308 1162 1309 result = cm_connect_netlogon( contact_domain, &netlogon_pipe);1163 result = cm_connect_netlogon(domain, &netlogon_pipe); 1310 1164 1311 1165 if (!NT_STATUS_IS_OK(result)) { 1312 DEBUG(3, ("could not open handle to NETLOGON pipe\n")); 1313 goto done; 1166 DEBUG(3,("could not open handle to NETLOGON pipe (error: %s)\n", 1167 nt_errstr(result))); 1168 return result; 1314 1169 } 1315 1170 auth = netlogon_pipe->auth; … … 1348 1203 * NETLOGON_NEG_AUTHENTICATED_RPC set together 1349 1204 * are the indication that the server supports 1350 * NetlogonValidationSamInfo4 (6). And must only1205 * NetlogonValidationSamInfo4 (6). And it must only 1351 1206 * be used if "SealSecureChannel" is used. 1352 1207 * … … 1356 1211 if (auth == NULL) { 1357 1212 domain->can_do_validation6 = false; 1358 } else if (auth->auth_type != PIPE_AUTH_TYPE_SCHANNEL) {1213 } else if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { 1359 1214 domain->can_do_validation6 = false; 1360 1215 } else if (auth->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { … … 1366 1221 } 1367 1222 1368 logon_fn = contact_domain->can_do_samlogon_ex 1369 ? rpccli_netlogon_sam_network_logon_ex 1370 : rpccli_netlogon_sam_network_logon; 1371 1372 result = logon_fn(netlogon_pipe, 1373 state->mem_ctx, 1374 0, 1375 contact_domain->dcname, /* server name */ 1376 name_user, /* user name */ 1377 name_domain, /* target domain */ 1378 global_myname(), /* workstation */ 1379 chal, 1380 domain->can_do_validation6 ? 6 : 3, 1381 lm_resp, 1382 nt_resp, 1383 &my_info3); 1384 1385 if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR) 1386 && contact_domain->can_do_samlogon_ex) { 1387 DEBUG(3, ("Got a DC that can not do NetSamLogonEx, " 1388 "retrying with NetSamLogon\n")); 1389 contact_domain->can_do_samlogon_ex = false; 1223 if (domain->can_do_samlogon_ex) { 1224 result = rpccli_netlogon_sam_network_logon_ex( 1225 netlogon_pipe, 1226 mem_ctx, 1227 0, 1228 server, /* server name */ 1229 username, /* user name */ 1230 domainname, /* target domain */ 1231 workstation, /* workstation */ 1232 chal, 1233 domain->can_do_validation6 ? 6 : 3, 1234 lm_response, 1235 nt_response, 1236 info3); 1237 } else { 1238 result = rpccli_netlogon_sam_network_logon( 1239 netlogon_pipe, 1240 mem_ctx, 1241 0, 1242 server, /* server name */ 1243 username, /* user name */ 1244 domainname, /* target domain */ 1245 workstation, /* workstation */ 1246 chal, 1247 domain->can_do_validation6 ? 6 : 3, 1248 lm_response, 1249 nt_response, 1250 info3); 1251 } 1252 1253 if (NT_STATUS_EQUAL(result, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) { 1254 1390 1255 /* 1391 1256 * It's likely that the server also does not support … … 1393 1258 */ 1394 1259 domain->can_do_validation6 = false; 1395 retry = true; 1396 continue; 1260 1261 if (domain->can_do_samlogon_ex) { 1262 DEBUG(3, ("Got a DC that can not do NetSamLogonEx, " 1263 "retrying with NetSamLogon\n")); 1264 domain->can_do_samlogon_ex = false; 1265 retry = true; 1266 continue; 1267 } 1268 1269 1270 /* Got DCERPC_FAULT_OP_RNG_ERROR for SamLogon 1271 * (no Ex). This happens against old Samba 1272 * DCs. Drop the connection. 1273 */ 1274 invalidate_cm_connection(&domain->conn); 1275 result = NT_STATUS_LOGON_FAILURE; 1276 break; 1397 1277 } 1398 1278 … … 1433 1313 "password was changed and we didn't know it. " 1434 1314 "Killing connections to domain %s\n", 1435 name_domain));1436 invalidate_cm_connection(& contact_domain->conn);1315 domainname)); 1316 invalidate_cm_connection(&domain->conn); 1437 1317 retry = true; 1438 1318 } 1439 1319 1440 1320 } while ( (attempts < 2) && retry ); 1321 1322 return result; 1323 } 1324 1325 static NTSTATUS winbindd_dual_pam_auth_samlogon(TALLOC_CTX *mem_ctx, 1326 struct winbindd_domain *domain, 1327 const char *user, 1328 const char *pass, 1329 uint32_t request_flags, 1330 struct netr_SamInfo3 **info3) 1331 { 1332 1333 uchar chal[8]; 1334 DATA_BLOB lm_resp; 1335 DATA_BLOB nt_resp; 1336 unsigned char local_nt_response[24]; 1337 fstring name_domain, name_user; 1338 NTSTATUS result; 1339 struct netr_SamInfo3 *my_info3 = NULL; 1340 1341 *info3 = NULL; 1342 1343 DEBUG(10,("winbindd_dual_pam_auth_samlogon\n")); 1344 1345 /* Parse domain and username */ 1346 1347 parse_domain_user(user, name_domain, name_user); 1348 1349 /* do password magic */ 1350 1351 generate_random_buffer(chal, sizeof(chal)); 1352 1353 if (lp_client_ntlmv2_auth()) { 1354 DATA_BLOB server_chal; 1355 DATA_BLOB names_blob; 1356 server_chal = data_blob_const(chal, 8); 1357 1358 /* note that the 'workgroup' here is for the local 1359 machine. The 'server name' must match the 1360 'workstation' passed to the actual SamLogon call. 1361 */ 1362 names_blob = NTLMv2_generate_names_blob( 1363 mem_ctx, global_myname(), lp_workgroup()); 1364 1365 if (!SMBNTLMv2encrypt(mem_ctx, name_user, name_domain, 1366 pass, 1367 &server_chal, 1368 &names_blob, 1369 &lm_resp, &nt_resp, NULL, NULL)) { 1370 data_blob_free(&names_blob); 1371 DEBUG(0, ("winbindd_pam_auth: SMBNTLMv2encrypt() failed!\n")); 1372 result = NT_STATUS_NO_MEMORY; 1373 goto done; 1374 } 1375 data_blob_free(&names_blob); 1376 } else { 1377 lm_resp = data_blob_null; 1378 SMBNTencrypt(pass, chal, local_nt_response); 1379 1380 nt_resp = data_blob_talloc(mem_ctx, local_nt_response, 1381 sizeof(local_nt_response)); 1382 } 1383 1384 if (strequal(name_domain, get_global_sam_name())) { 1385 DATA_BLOB chal_blob = data_blob_const(chal, sizeof(chal)); 1386 1387 result = winbindd_dual_auth_passdb( 1388 mem_ctx, name_domain, name_user, 1389 &chal_blob, &lm_resp, &nt_resp, info3); 1390 goto done; 1391 } 1392 1393 /* check authentication loop */ 1394 1395 result = winbind_samlogon_retry_loop(domain, 1396 mem_ctx, 1397 0, 1398 domain->dcname, 1399 name_user, 1400 name_domain, 1401 global_myname(), 1402 chal, 1403 lm_resp, 1404 nt_resp, 1405 &my_info3); 1406 if (!NT_STATUS_IS_OK(result)) { 1407 goto done; 1408 } 1441 1409 1442 1410 /* handle the case where a NT4 DC does not fill in the acct_flags in … … 1444 1412 * caller, we look up the account flags ourselve - gd */ 1445 1413 1446 if (( state->request->flags & WBFLAG_PAM_INFO3_TEXT) &&1414 if ((request_flags & WBFLAG_PAM_INFO3_TEXT) && 1447 1415 NT_STATUS_IS_OK(result) && (my_info3->base.acct_flags == 0)) { 1448 1416 … … 1450 1418 struct policy_handle samr_domain_handle, user_pol; 1451 1419 union samr_UserInfo *info = NULL; 1452 NTSTATUS status_tmp ;1420 NTSTATUS status_tmp, result_tmp; 1453 1421 uint32 acct_flags; 1454 1455 status_tmp = cm_connect_sam(contact_domain, state->mem_ctx, 1422 struct dcerpc_binding_handle *b; 1423 1424 status_tmp = cm_connect_sam(domain, mem_ctx, 1456 1425 &samr_pipe, &samr_domain_handle); 1457 1426 … … 1462 1431 } 1463 1432 1464 status_tmp = rpccli_samr_OpenUser(samr_pipe, state->mem_ctx, 1433 b = samr_pipe->binding_handle; 1434 1435 status_tmp = dcerpc_samr_OpenUser(b, mem_ctx, 1465 1436 &samr_domain_handle, 1466 1437 MAXIMUM_ALLOWED_ACCESS, 1467 1438 my_info3->base.rid, 1468 &user_pol); 1439 &user_pol, 1440 &result_tmp); 1469 1441 1470 1442 if (!NT_STATUS_IS_OK(status_tmp)) { … … 1473 1445 goto done; 1474 1446 } 1475 1476 status_tmp = rpccli_samr_QueryUserInfo(samr_pipe, state->mem_ctx, 1447 if (!NT_STATUS_IS_OK(result_tmp)) { 1448 DEBUG(3, ("could not open user handle on SAMR pipe: %s\n", 1449 nt_errstr(result_tmp))); 1450 goto done; 1451 } 1452 1453 status_tmp = dcerpc_samr_QueryUserInfo(b, mem_ctx, 1477 1454 &user_pol, 1478 1455 16, 1479 &info); 1456 &info, 1457 &result_tmp); 1480 1458 1481 1459 if (!NT_STATUS_IS_OK(status_tmp)) { 1482 1460 DEBUG(3, ("could not query user info on SAMR pipe: %s\n", 1483 1461 nt_errstr(status_tmp))); 1484 rpccli_samr_Close(samr_pipe, state->mem_ctx, &user_pol);1462 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result_tmp); 1485 1463 goto done; 1486 1464 } 1465 if (!NT_STATUS_IS_OK(result_tmp)) { 1466 DEBUG(3, ("could not query user info on SAMR pipe: %s\n", 1467 nt_errstr(result_tmp))); 1468 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result_tmp); 1469 goto done; 1470 } 1487 1471 1488 1472 acct_flags = info->info16.acct_flags; 1489 1473 1490 1474 if (acct_flags == 0) { 1491 rpccli_samr_Close(samr_pipe, state->mem_ctx, &user_pol);1475 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result_tmp); 1492 1476 goto done; 1493 1477 } … … 1497 1481 DEBUG(10,("successfully retrieved acct_flags 0x%x\n", acct_flags)); 1498 1482 1499 rpccli_samr_Close(samr_pipe, state->mem_ctx, &user_pol);1483 dcerpc_samr_Close(b, mem_ctx, &user_pol, &result_tmp); 1500 1484 } 1501 1485 … … 1525 1509 state->request->data.auth.user)); 1526 1510 1527 if (!check_request_flags(state->request->flags)) {1528 result = NT_STATUS_INVALID_PARAMETER_MIX;1529 goto done;1530 }1531 1532 1511 /* Parse domain and username */ 1533 1512 … … 1548 1527 1549 1528 if ( mapped_user != state->request->data.auth.user ) { 1550 fstr_sprintf( domain_user, "%s\\%s", name_domain, name_user ); 1529 fstr_sprintf( domain_user, "%s%c%s", name_domain, 1530 *lp_winbind_separator(), 1531 name_user ); 1551 1532 safe_strcpy( state->request->data.auth.user, domain_user, 1552 1533 sizeof(state->request->data.auth.user)-1 ); 1553 1534 } 1554 1535 1555 if ( domain->online == false) {1536 if (!domain->online) { 1556 1537 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; 1557 1538 if (domain->startup) { … … 1607 1588 NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_MUST_CHANGE) || 1608 1589 NT_STATUS_EQUAL(result, NT_STATUS_WRONG_PASSWORD)) { 1609 goto process_result;1590 goto done; 1610 1591 } 1611 1592 … … 1621 1602 /* Check for Samlogon authentication */ 1622 1603 if (domain->online) { 1623 result = winbindd_dual_pam_auth_samlogon(domain, state, &info3); 1604 result = winbindd_dual_pam_auth_samlogon( 1605 state->mem_ctx, domain, 1606 state->request->data.auth.user, 1607 state->request->data.auth.pass, 1608 state->request->flags, 1609 &info3); 1624 1610 1625 1611 if (NT_STATUS_IS_OK(result)) { … … 1670 1656 if (NT_STATUS_IS_OK(result)) { 1671 1657 1672 DOM_SIDuser_sid;1658 struct dom_sid user_sid; 1673 1659 1674 1660 /* In all codepaths where result == NT_STATUS_OK info3 must have … … 1679 1665 } 1680 1666 1681 wcache_invalidate_samlogon(find_domain_from_name(name_domain), info3); 1667 sid_compose(&user_sid, info3->base.domain_sid, 1668 info3->base.rid); 1669 1670 wcache_invalidate_samlogon(find_domain_from_name(name_domain), 1671 &user_sid); 1682 1672 netsamlogon_cache_store(name_user, info3); 1683 1673 … … 1687 1677 domain). */ 1688 1678 if ( domain->primary ) { 1689 sid_compose(&user_sid, info3->base.domain_sid,1690 info3->base.rid);1691 1679 cache_name2sid(domain, name_domain, name_user, 1692 1680 SID_NAME_USER, &user_sid); … … 1705 1693 } 1706 1694 1707 result = append_auth_data(state, info3, name_domain, 1708 name_user); 1695 result = append_auth_data(state->mem_ctx, state->response, 1696 state->request->flags, info3, 1697 name_domain, name_user); 1709 1698 if (!NT_STATUS_IS_OK(result)) { 1710 1699 goto done; 1711 1700 } 1712 1701 1713 if ((state->request->flags & WBFLAG_PAM_CACHED_LOGIN)) { 1714 1715 /* Store in-memory creds for single-signon using ntlm_auth. */ 1716 result = winbindd_add_memory_creds(state->request->data.auth.user, 1717 get_uid_from_state(state), 1718 state->request->data.auth.pass); 1719 1720 if (!NT_STATUS_IS_OK(result)) { 1721 DEBUG(10,("Failed to store memory creds: %s\n", nt_errstr(result))); 1722 goto done; 1723 } 1724 1725 if (lp_winbind_offline_logon()) { 1726 result = winbindd_store_creds(domain, 1727 state->mem_ctx, 1702 if ((state->request->flags & WBFLAG_PAM_CACHED_LOGIN) 1703 && lp_winbind_offline_logon()) { 1704 1705 result = winbindd_store_creds(domain, 1728 1706 state->request->data.auth.user, 1729 1707 state->request->data.auth.pass, 1730 info3, NULL); 1731 if (!NT_STATUS_IS_OK(result)) { 1732 1733 /* Release refcount. */ 1734 winbindd_delete_memory_creds(state->request->data.auth.user); 1735 1736 DEBUG(10,("Failed to store creds: %s\n", nt_errstr(result))); 1737 goto done; 1738 } 1739 } 1740 } 1741 1708 info3); 1709 } 1742 1710 1743 1711 if (state->request->flags & WBFLAG_PAM_GET_PWD_POLICY) { … … 1752 1720 result = NT_STATUS_NOT_SUPPORTED; 1753 1721 if (our_domain == domain ) { 1754 result = fillup_password_policy(our_domain, state); 1722 result = fillup_password_policy( 1723 our_domain, state->response); 1755 1724 } 1756 1725 … … 1784 1753 } 1785 1754 1786 1787 /**********************************************************************1788 Challenge Response Authentication Protocol1789 **********************************************************************/1790 1791 void winbindd_pam_auth_crap(struct winbindd_cli_state *state)1792 {1793 struct winbindd_domain *domain = NULL;1794 const char *domain_name = NULL;1795 NTSTATUS result;1796 1797 if (!check_request_flags(state->request->flags)) {1798 result = NT_STATUS_INVALID_PARAMETER_MIX;1799 goto done;1800 }1801 1802 if (!state->privileged) {1803 DEBUG(2, ("winbindd_pam_auth_crap: non-privileged access "1804 "denied. !\n"));1805 DEBUGADD(2, ("winbindd_pam_auth_crap: Ensure permissions "1806 "on %s are set correctly.\n",1807 get_winbind_priv_pipe_dir()));1808 /* send a better message than ACCESS_DENIED */1809 fstr_sprintf(state->response->data.auth.error_string,1810 "winbind client not authorized to use "1811 "winbindd_pam_auth_crap. Ensure permissions on "1812 "%s are set correctly.",1813 get_winbind_priv_pipe_dir());1814 result = NT_STATUS_ACCESS_DENIED;1815 goto done;1816 }1817 1818 /* Ensure null termination */1819 state->request->data.auth_crap.user1820 [sizeof(state->request->data.auth_crap.user)-1]=0;1821 state->request->data.auth_crap.domain1822 [sizeof(state->request->data.auth_crap.domain)-1]=0;1823 1824 DEBUG(3, ("[%5lu]: pam auth crap domain: [%s] user: %s\n",1825 (unsigned long)state->pid,1826 state->request->data.auth_crap.domain,1827 state->request->data.auth_crap.user));1828 1829 if (*state->request->data.auth_crap.domain != '\0') {1830 domain_name = state->request->data.auth_crap.domain;1831 } else if (lp_winbind_use_default_domain()) {1832 domain_name = lp_workgroup();1833 }1834 1835 if (domain_name != NULL)1836 domain = find_auth_domain(state->request->flags, domain_name);1837 1838 if (domain != NULL) {1839 sendto_domain(state, domain);1840 return;1841 }1842 1843 result = NT_STATUS_NO_SUCH_USER;1844 1845 done:1846 set_auth_errors(state->response, result);1847 DEBUG(5, ("CRAP authentication for %s\\%s returned %s (PAM: %d)\n",1848 state->request->data.auth_crap.domain,1849 state->request->data.auth_crap.user,1850 state->response->data.auth.nt_status_string,1851 state->response->data.auth.pam_error));1852 request_error(state);1853 return;1854 }1855 1856 1857 1755 enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, 1858 1756 struct winbindd_cli_state *state) … … 1860 1758 NTSTATUS result; 1861 1759 struct netr_SamInfo3 *info3 = NULL; 1862 struct rpc_pipe_client *netlogon_pipe;1863 1760 const char *name_user = NULL; 1864 1761 const char *name_domain = NULL; 1865 1762 const char *workstation; 1866 struct winbindd_domain *contact_domain;1867 int attempts = 0;1868 bool retry;1869 1763 1870 1764 DATA_BLOB lm_resp, nt_resp; … … 1877 1771 state->request->data.auth_crap.domain[sizeof(state->request->data.auth_crap.domain)-1]=0; 1878 1772 1879 if (!check_request_flags(state->request->flags)) {1880 result = NT_STATUS_INVALID_PARAMETER_MIX;1881 goto done;1882 }1883 1884 1773 name_user = state->request->data.auth_crap.user; 1885 1886 if (*state->request->data.auth_crap.domain) { 1887 name_domain = state->request->data.auth_crap.domain; 1888 } else if (lp_winbind_use_default_domain()) { 1889 name_domain = lp_workgroup(); 1890 } else { 1891 DEBUG(5,("no domain specified with username (%s) - failing auth\n", 1892 name_user)); 1893 result = NT_STATUS_NO_SUCH_USER; 1894 goto done; 1895 } 1774 name_domain = state->request->data.auth_crap.domain; 1775 workstation = state->request->data.auth_crap.workstation; 1896 1776 1897 1777 DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n", (unsigned long)state->pid, 1898 1778 name_domain, name_user)); 1899 1900 if (*state->request->data.auth_crap.workstation) {1901 workstation = state->request->data.auth_crap.workstation;1902 } else {1903 workstation = global_myname();1904 }1905 1779 1906 1780 if (state->request->data.auth_crap.lm_resp_len > sizeof(state->request->data.auth_crap.lm_resp) … … 1929 1803 } 1930 1804 1931 /* what domain should we contact? */ 1932 1933 if ( IS_DC ) { 1934 if (!(contact_domain = find_domain_from_name(name_domain))) { 1935 DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", 1936 state->request->data.auth_crap.user, name_domain, name_user, name_domain)); 1937 result = NT_STATUS_NO_SUCH_USER; 1938 goto done; 1939 } 1940 } else { 1941 if (is_myname(name_domain)) { 1942 DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain)); 1943 result = NT_STATUS_NO_SUCH_USER; 1944 goto done; 1945 } 1946 contact_domain = find_our_domain(); 1947 } 1948 1949 do { 1950 netlogon_fn_t logon_fn; 1951 const struct cli_pipe_auth_data *auth; 1952 uint32_t neg_flags = 0; 1953 1954 retry = false; 1955 1956 netlogon_pipe = NULL; 1957 result = cm_connect_netlogon(contact_domain, &netlogon_pipe); 1958 1959 if (!NT_STATUS_IS_OK(result)) { 1960 DEBUG(3, ("could not open handle to NETLOGON pipe (error: %s)\n", 1961 nt_errstr(result))); 1962 goto done; 1963 } 1964 auth = netlogon_pipe->auth; 1965 if (netlogon_pipe->dc) { 1966 neg_flags = netlogon_pipe->dc->negotiate_flags; 1967 } 1968 1969 if (auth == NULL) { 1970 domain->can_do_validation6 = false; 1971 } else if (auth->auth_type != PIPE_AUTH_TYPE_SCHANNEL) { 1972 domain->can_do_validation6 = false; 1973 } else if (auth->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { 1974 domain->can_do_validation6 = false; 1975 } else if (!(neg_flags & NETLOGON_NEG_CROSS_FOREST_TRUSTS)) { 1976 domain->can_do_validation6 = false; 1977 } else if (!(neg_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) { 1978 domain->can_do_validation6 = false; 1979 } 1980 1981 logon_fn = contact_domain->can_do_samlogon_ex 1982 ? rpccli_netlogon_sam_network_logon_ex 1983 : rpccli_netlogon_sam_network_logon; 1984 1985 result = logon_fn(netlogon_pipe, 1986 state->mem_ctx, 1987 state->request->data.auth_crap.logon_parameters, 1988 contact_domain->dcname, 1989 name_user, 1990 name_domain, 1991 /* Bug #3248 - found by Stefan Burkei. */ 1992 workstation, /* We carefully set this above so use it... */ 1993 state->request->data.auth_crap.chal, 1994 domain->can_do_validation6 ? 6 : 3, 1995 lm_resp, 1996 nt_resp, 1997 &info3); 1998 1999 if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR) 2000 && contact_domain->can_do_samlogon_ex) { 2001 DEBUG(3, ("Got a DC that can not do NetSamLogonEx, " 2002 "retrying with NetSamLogon\n")); 2003 contact_domain->can_do_samlogon_ex = false; 2004 /* 2005 * It's likely that the server also does not support 2006 * validation level 6 2007 */ 2008 domain->can_do_validation6 = false; 2009 retry = true; 2010 continue; 2011 } 2012 2013 if (domain->can_do_validation6 && 2014 (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_INFO_CLASS) || 2015 NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PARAMETER) || 2016 NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL))) { 2017 DEBUG(3,("Got a DC that can not do validation level 6, " 2018 "retrying with level 3\n")); 2019 domain->can_do_validation6 = false; 2020 retry = true; 2021 continue; 2022 } 2023 2024 /* 2025 * we increment this after the "feature negotiation" 2026 * for can_do_samlogon_ex and can_do_validation6 2027 */ 2028 attempts += 1; 2029 2030 /* We have to try a second time as cm_connect_netlogon 2031 might not yet have noticed that the DC has killed 2032 our connection. */ 2033 2034 if (!rpccli_is_connected(netlogon_pipe)) { 2035 retry = true; 2036 continue; 2037 } 2038 2039 /* if we get access denied, a possible cause was that we had and open 2040 connection to the DC, but someone changed our machine account password 2041 out from underneath us using 'net rpc changetrustpw' */ 2042 2043 if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) ) { 2044 DEBUG(3,("winbindd_pam_auth: sam_logon returned " 2045 "ACCESS_DENIED. Maybe the trust account " 2046 "password was changed and we didn't know it. " 2047 "Killing connections to domain %s\n", 2048 name_domain)); 2049 invalidate_cm_connection(&contact_domain->conn); 2050 retry = true; 2051 } 2052 2053 } while ( (attempts < 2) && retry ); 1805 if (strequal(name_domain, get_global_sam_name())) { 1806 DATA_BLOB chal_blob = data_blob_const( 1807 state->request->data.auth_crap.chal, 1808 sizeof(state->request->data.auth_crap.chal)); 1809 1810 result = winbindd_dual_auth_passdb( 1811 state->mem_ctx, name_domain, name_user, 1812 &chal_blob, &lm_resp, &nt_resp, &info3); 1813 goto process_result; 1814 } 1815 1816 result = winbind_samlogon_retry_loop(domain, 1817 state->mem_ctx, 1818 state->request->data.auth_crap.logon_parameters, 1819 domain->dcname, 1820 name_user, 1821 name_domain, 1822 /* Bug #3248 - found by Stefan Burkei. */ 1823 workstation, /* We carefully set this above so use it... */ 1824 state->request->data.auth_crap.chal, 1825 lm_resp, 1826 nt_resp, 1827 &info3); 1828 if (!NT_STATUS_IS_OK(result)) { 1829 goto done; 1830 } 1831 1832 process_result: 2054 1833 2055 1834 if (NT_STATUS_IS_OK(result)) { 2056 2057 wcache_invalidate_samlogon(find_domain_from_name(name_domain), info3); 1835 struct dom_sid user_sid; 1836 1837 sid_compose(&user_sid, info3->base.domain_sid, 1838 info3->base.rid); 1839 wcache_invalidate_samlogon(find_domain_from_name(name_domain), 1840 &user_sid); 2058 1841 netsamlogon_cache_store(name_user, info3); 2059 1842 … … 2071 1854 } 2072 1855 2073 result = append_auth_data(state, info3, name_domain, 2074 name_user); 1856 result = append_auth_data(state->mem_ctx, state->response, 1857 state->request->flags, info3, 1858 name_domain, name_user); 2075 1859 if (!NT_STATUS_IS_OK(result)) { 2076 1860 goto done; … … 2102 1886 } 2103 1887 2104 /* Change a user password */2105 2106 void winbindd_pam_chauthtok(struct winbindd_cli_state *state)2107 {2108 fstring domain, user;2109 char *mapped_user;2110 struct winbindd_domain *contact_domain;2111 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;2112 2113 DEBUG(3, ("[%5lu]: pam chauthtok %s\n", (unsigned long)state->pid,2114 state->request->data.chauthtok.user));2115 2116 /* Setup crap */2117 2118 nt_status = normalize_name_unmap(state->mem_ctx,2119 state->request->data.chauthtok.user,2120 &mapped_user);2121 2122 /* Update the chauthtok name if we did any mapping */2123 2124 if (NT_STATUS_IS_OK(nt_status) ||2125 NT_STATUS_EQUAL(nt_status, NT_STATUS_FILE_RENAMED))2126 {2127 fstrcpy(state->request->data.chauthtok.user, mapped_user);2128 }2129 2130 /* Must pass in state->...chauthtok.user because2131 canonicalize_username() assumes an fstring(). Since2132 we have already copied it (if necessary), this is ok. */2133 2134 if (!canonicalize_username(state->request->data.chauthtok.user, domain, user)) {2135 set_auth_errors(state->response, NT_STATUS_NO_SUCH_USER);2136 DEBUG(5, ("winbindd_pam_chauthtok: canonicalize_username %s failed with %s"2137 "(PAM: %d)\n",2138 state->request->data.auth.user,2139 state->response->data.auth.nt_status_string,2140 state->response->data.auth.pam_error));2141 request_error(state);2142 return;2143 }2144 2145 contact_domain = find_domain_from_name(domain);2146 if (!contact_domain) {2147 set_auth_errors(state->response, NT_STATUS_NO_SUCH_USER);2148 DEBUG(3, ("Cannot change password for [%s] -> [%s]\\[%s] as %s is not a trusted domain\n",2149 state->request->data.chauthtok.user, domain, user, domain));2150 request_error(state);2151 return;2152 }2153 2154 sendto_domain(state, contact_domain);2155 }2156 2157 1888 enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact_domain, 2158 1889 struct winbindd_cli_state *state) … … 2161 1892 char *newpass = NULL; 2162 1893 struct policy_handle dom_pol; 2163 struct rpc_pipe_client *cli ;1894 struct rpc_pipe_client *cli = NULL; 2164 1895 bool got_info = false; 2165 1896 struct samr_DomInfo1 *info = NULL; 2166 struct samr_ChangeReject*reject = NULL;1897 struct userPwdChangeFailureInformation *reject = NULL; 2167 1898 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 2168 1899 fstring domain, user; 1900 struct dcerpc_binding_handle *b = NULL; 1901 1902 ZERO_STRUCT(dom_pol); 2169 1903 2170 1904 DEBUG(3, ("[%5lu]: dual pam chauthtok %s\n", (unsigned long)state->pid, … … 2191 1925 goto done; 2192 1926 } 1927 1928 b = cli->binding_handle; 2193 1929 2194 1930 result = rpccli_samr_chgpasswd_user3(cli, state->mem_ctx, … … 2206 1942 2207 1943 state->response->data.auth.reject_reason = 2208 reject-> reason;1944 reject->extendedFailureReason; 2209 1945 2210 1946 got_info = true; … … 2217 1953 2218 1954 /* only fallback when the chgpasswd_user3 call is not supported */ 2219 if ( (NT_STATUS_EQUAL(result, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR))) ||2220 (NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED)) ||2221 (NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL)) ||2222 (NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED))) {1955 if (NT_STATUS_EQUAL(result, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE) || 1956 NT_STATUS_EQUAL(result, NT_STATUS_NOT_SUPPORTED) || 1957 NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL) || 1958 NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) { 2223 1959 2224 1960 DEBUG(10,("Password change with chgpasswd_user3 failed with: %s, retrying chgpasswd_user2\n", … … 2237 1973 done: 2238 1974 2239 if (NT_STATUS_IS_OK(result) && (state->request->flags & WBFLAG_PAM_CACHED_LOGIN)) {2240 2241 /* Update the single sign-on memory creds. */2242 result = winbindd_ replace_memory_creds(state->request->data.chauthtok.user,2243 2244 2245 /* When we login from gdm or xdm and password expires,2246 * we change password, but there are no memory crendentials2247 * So, winbindd_replace_memory_creds() returns2248 * NT_STATUS_OBJECT_NAME_NOT_FOUND.This is not a failure.1975 if (NT_STATUS_IS_OK(result) 1976 && (state->request->flags & WBFLAG_PAM_CACHED_LOGIN) 1977 && lp_winbind_offline_logon()) { 1978 result = winbindd_update_creds_by_name(contact_domain, user, 1979 newpass); 1980 /* Again, this happens when we login from gdm or xdm 1981 * and the password expires, *BUT* cached crendentials 1982 * doesn't exist. winbindd_update_creds_by_name() 1983 * returns NT_STATUS_NO_SUCH_USER. 1984 * This is not a failure. 2249 1985 * --- BoYang 2250 1986 * */ 2251 if (NT_STATUS_EQUAL(result, NT_STATUS_ OBJECT_NAME_NOT_FOUND)) {1987 if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER)) { 2252 1988 result = NT_STATUS_OK; 2253 1989 } 2254 1990 2255 1991 if (!NT_STATUS_IS_OK(result)) { 2256 DEBUG(10,("Failed to replace memory creds: %s\n", nt_errstr(result))); 1992 DEBUG(10, ("Failed to store creds: %s\n", 1993 nt_errstr(result))); 2257 1994 goto process_result; 2258 1995 } 2259 2260 if (lp_winbind_offline_logon()) {2261 result = winbindd_update_creds_by_name(contact_domain,2262 state->mem_ctx, user,2263 newpass);2264 /* Again, this happens when we login from gdm or xdm2265 * and the password expires, *BUT* cached crendentials2266 * doesn't exist. winbindd_update_creds_by_name()2267 * returns NT_STATUS_NO_SUCH_USER.2268 * This is not a failure.2269 * --- BoYang2270 * */2271 if (NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_USER)) {2272 result = NT_STATUS_OK;2273 }2274 2275 if (!NT_STATUS_IS_OK(result)) {2276 DEBUG(10,("Failed to store creds: %s\n", nt_errstr(result)));2277 goto process_result;2278 }2279 }2280 1996 } 2281 1997 … … 2284 2000 NTSTATUS policy_ret; 2285 2001 2286 policy_ret = fillup_password_policy(contact_domain, state); 2002 policy_ret = fillup_password_policy( 2003 contact_domain, state->response); 2287 2004 2288 2005 /* failure of this is non critical, it will just provide no … … 2297 2014 2298 2015 process_result: 2016 2017 if (strequal(contact_domain->name, get_global_sam_name())) { 2018 /* FIXME: internal rpc pipe does not cache handles yet */ 2019 if (b) { 2020 if (is_valid_policy_hnd(&dom_pol)) { 2021 NTSTATUS _result; 2022 dcerpc_samr_Close(b, state->mem_ctx, &dom_pol, &_result); 2023 } 2024 TALLOC_FREE(cli); 2025 } 2026 } 2299 2027 2300 2028 set_auth_errors(state->response, result); … … 2310 2038 } 2311 2039 2312 void winbindd_pam_logoff(struct winbindd_cli_state *state)2313 {2314 struct winbindd_domain *domain;2315 fstring name_domain, user;2316 uid_t caller_uid = (uid_t)-1;2317 uid_t request_uid = state->request->data.logoff.uid;2318 2319 DEBUG(3, ("[%5lu]: pam logoff %s\n", (unsigned long)state->pid,2320 state->request->data.logoff.user));2321 2322 /* Ensure null termination */2323 state->request->data.logoff.user2324 [sizeof(state->request->data.logoff.user)-1]='\0';2325 2326 state->request->data.logoff.krb5ccname2327 [sizeof(state->request->data.logoff.krb5ccname)-1]='\0';2328 2329 if (request_uid == (gid_t)-1) {2330 goto failed;2331 }2332 2333 if (!canonicalize_username(state->request->data.logoff.user, name_domain, user)) {2334 goto failed;2335 }2336 2337 if ((domain = find_auth_domain(state->request->flags,2338 name_domain)) == NULL) {2339 goto failed;2340 }2341 2342 if ((sys_getpeereid(state->sock, &caller_uid)) != 0) {2343 DEBUG(1,("winbindd_pam_logoff: failed to check peerid: %s\n",2344 strerror(errno)));2345 goto failed;2346 }2347 2348 switch (caller_uid) {2349 case -1:2350 goto failed;2351 case 0:2352 /* root must be able to logoff any user - gd */2353 state->request->data.logoff.uid = request_uid;2354 break;2355 default:2356 if (caller_uid != request_uid) {2357 DEBUG(1,("winbindd_pam_logoff: caller requested invalid uid\n"));2358 goto failed;2359 }2360 state->request->data.logoff.uid = caller_uid;2361 break;2362 }2363 2364 sendto_domain(state, domain);2365 return;2366 2367 failed:2368 set_auth_errors(state->response, NT_STATUS_NO_SUCH_USER);2369 DEBUG(5, ("Pam Logoff for %s returned %s "2370 "(PAM: %d)\n",2371 state->request->data.logoff.user,2372 state->response->data.auth.nt_status_string,2373 state->response->data.auth.pam_error));2374 request_error(state);2375 return;2376 }2377 2378 2040 enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain, 2379 2041 struct winbindd_cli_state *state) … … 2430 2092 process_result: 2431 2093 2432 winbindd_delete_memory_creds(state->request->data.logoff.user);2433 2094 2434 2095 set_auth_errors(state->response, result); … … 2438 2099 2439 2100 /* Change user password with auth crap*/ 2440 2441 void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state)2442 {2443 struct winbindd_domain *domain = NULL;2444 const char *domain_name = NULL;2445 2446 /* Ensure null termination */2447 state->request->data.chng_pswd_auth_crap.user[2448 sizeof(state->request->data.chng_pswd_auth_crap.user)-1]=0;2449 state->request->data.chng_pswd_auth_crap.domain[2450 sizeof(state->request->data.chng_pswd_auth_crap.domain)-1]=0;2451 2452 DEBUG(3, ("[%5lu]: pam change pswd auth crap domain: %s user: %s\n",2453 (unsigned long)state->pid,2454 state->request->data.chng_pswd_auth_crap.domain,2455 state->request->data.chng_pswd_auth_crap.user));2456 2457 if (*state->request->data.chng_pswd_auth_crap.domain != '\0') {2458 domain_name = state->request->data.chng_pswd_auth_crap.domain;2459 } else if (lp_winbind_use_default_domain()) {2460 domain_name = lp_workgroup();2461 }2462 2463 if (domain_name != NULL)2464 domain = find_domain_from_name(domain_name);2465 2466 if (domain != NULL) {2467 DEBUG(7, ("[%5lu]: pam auth crap changing pswd in domain: "2468 "%s\n", (unsigned long)state->pid,domain->name));2469 sendto_domain(state, domain);2470 return;2471 }2472 2473 set_auth_errors(state->response, NT_STATUS_NO_SUCH_USER);2474 DEBUG(5, ("CRAP change password for %s\\%s returned %s (PAM: %d)\n",2475 state->request->data.chng_pswd_auth_crap.domain,2476 state->request->data.chng_pswd_auth_crap.user,2477 state->response->data.auth.nt_status_string,2478 state->response->data.auth.pam_error));2479 request_error(state);2480 return;2481 }2482 2101 2483 2102 enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state) … … 2491 2110 struct policy_handle dom_pol; 2492 2111 struct winbindd_domain *contact_domain = domainSt; 2493 struct rpc_pipe_client *cli; 2112 struct rpc_pipe_client *cli = NULL; 2113 struct dcerpc_binding_handle *b = NULL; 2114 2115 ZERO_STRUCT(dom_pol); 2494 2116 2495 2117 /* Ensure null termination */ … … 2540 2162 2541 2163 /* Change password */ 2542 new_nt_password = data_blob_talloc( 2543 state->mem_ctx, 2164 new_nt_password = data_blob_const( 2544 2165 state->request->data.chng_pswd_auth_crap.new_nt_pswd, 2545 2166 state->request->data.chng_pswd_auth_crap.new_nt_pswd_len); 2546 2167 2547 old_nt_hash_enc = data_blob_talloc( 2548 state->mem_ctx, 2168 old_nt_hash_enc = data_blob_const( 2549 2169 state->request->data.chng_pswd_auth_crap.old_nt_hash_enc, 2550 2170 state->request->data.chng_pswd_auth_crap.old_nt_hash_enc_len); 2551 2171 2552 2172 if(state->request->data.chng_pswd_auth_crap.new_lm_pswd_len > 0) { 2553 new_lm_password = data_blob_talloc( 2554 state->mem_ctx, 2173 new_lm_password = data_blob_const( 2555 2174 state->request->data.chng_pswd_auth_crap.new_lm_pswd, 2556 2175 state->request->data.chng_pswd_auth_crap.new_lm_pswd_len); 2557 2176 2558 old_lm_hash_enc = data_blob_talloc( 2559 state->mem_ctx, 2177 old_lm_hash_enc = data_blob_const( 2560 2178 state->request->data.chng_pswd_auth_crap.old_lm_hash_enc, 2561 2179 state->request->data.chng_pswd_auth_crap.old_lm_hash_enc_len); … … 2573 2191 } 2574 2192 2193 b = cli->binding_handle; 2194 2575 2195 result = rpccli_samr_chng_pswd_auth_crap( 2576 2196 cli, state->mem_ctx, user, new_nt_password, old_nt_hash_enc, … … 2578 2198 2579 2199 done: 2200 2201 if (strequal(contact_domain->name, get_global_sam_name())) { 2202 /* FIXME: internal rpc pipe does not cache handles yet */ 2203 if (b) { 2204 if (is_valid_policy_hnd(&dom_pol)) { 2205 NTSTATUS _result; 2206 dcerpc_samr_Close(b, state->mem_ctx, &dom_pol, &_result); 2207 } 2208 TALLOC_FREE(cli); 2209 } 2210 } 2580 2211 2581 2212 set_auth_errors(state->response, result); -
vendor/current/source3/winbindd/winbindd_ping_dc.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ cli_wbint.h"22 #include "librpc/gen_ndr/ndr_wbint_c.h" 23 23 24 24 struct winbindd_ping_dc_state { … … 62 62 } 63 63 64 subreq = rpccli_wbint_PingDc_send(state, ev, domain->child.rpccli);64 subreq = dcerpc_wbint_PingDc_send(state, ev, dom_child_handle(domain)); 65 65 if (tevent_req_nomem(subreq, req)) { 66 66 return tevent_req_post(req, ev); … … 78 78 NTSTATUS status, result; 79 79 80 status = rpccli_wbint_PingDc_recv(subreq, state, &result);81 if ( !NT_STATUS_IS_OK(status)) {80 status = dcerpc_wbint_PingDc_recv(subreq, state, &result); 81 if (any_nt_status_not_ok(status, result, &status)) { 82 82 tevent_req_nterror(req, status); 83 return;84 }85 if (!NT_STATUS_IS_OK(result)) {86 tevent_req_nterror(req, result);87 83 return; 88 84 } -
vendor/current/source3/winbindd/winbindd_proto.h
r414 r740 24 24 #define _WINBINDD_PROTO_H_ 25 25 26 27 /* The following definitions come from auth/token_util.c */28 29 bool nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token );30 bool nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid );31 NT_USER_TOKEN *get_root_nt_token( void );32 NTSTATUS add_aliases(const DOM_SID *domain_sid,33 struct nt_user_token *token);34 struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx,35 const DOM_SID *user_sid,36 bool is_guest,37 int num_groupsids,38 const DOM_SID *groupsids);39 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token);40 void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid,41 int n_groups, gid_t *groups);42 43 /* The following definitions come from smbd/connection.c */44 45 bool yield_connection(connection_struct *conn, const char *name);46 int count_current_connections( const char *sharename, bool clear );47 int count_all_current_connections(void);48 bool claim_connection(connection_struct *conn, const char *name,49 uint32 msg_flags);50 bool register_message_flags(bool doreg, uint32 msg_flags);51 52 26 /* The following definitions come from winbindd/winbindd.c */ 53 54 struct event_context *winbind_event_context(void);55 27 struct messaging_context *winbind_messaging_context(void); 56 28 void request_error(struct winbindd_cli_state *state); … … 60 32 bool winbindd_use_idmap_cache(void); 61 33 bool winbindd_use_cache(void); 34 void winbindd_register_handlers(void); 35 const char *get_winbind_pipe_dir(void); 36 char *get_winbind_priv_pipe_dir(void); 62 37 int main(int argc, char **argv, char **envp); 63 38 … … 80 55 struct dom_sid **sids, 81 56 enum lsa_SidType **types); 82 83 /* The following definitions come from winbindd/winbindd_async.c */ 84 85 bool print_sidlist(TALLOC_CTX *mem_ctx, const DOM_SID *sids, 86 size_t num_sids, char **result, ssize_t *len); 87 bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr, 88 DOM_SID **sids, size_t *num_sids); 57 NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx, 58 struct winbindd_domain *domain, 59 struct lsa_SidArray *sids, 60 struct lsa_RefDomainList **pdomains, 61 struct lsa_TransNameArray **pnames); 89 62 90 63 /* The following definitions come from winbindd/winbindd_cache.c */ 91 64 92 void winbindd_check_cache_size(time_t t);93 65 struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status); 94 NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const DOM_SID*sid);66 NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const struct dom_sid *sid); 95 67 NTSTATUS wcache_get_creds(struct winbindd_domain *domain, 96 68 TALLOC_CTX *mem_ctx, 97 const DOM_SID*sid,69 const struct dom_sid *sid, 98 70 const uint8 **cached_nt_pass, 99 71 const uint8 **cached_salt); 100 72 NTSTATUS wcache_save_creds(struct winbindd_domain *domain, 101 TALLOC_CTX *mem_ctx, 102 const DOM_SID *sid, 73 const struct dom_sid *sid, 103 74 const uint8 nt_pass[NT_HASH_LEN]); 104 75 void wcache_invalidate_samlogon(struct winbindd_domain *domain, 105 struct netr_SamInfo3 *info3);76 const struct dom_sid *user_sid); 106 77 bool wcache_invalidate_cache(void); 78 bool wcache_invalidate_cache_noinit(void); 107 79 bool init_wcache(void); 108 80 bool initialize_winbindd_cache(void); … … 120 92 struct dom_sid **sid_mem, char ***names, 121 93 uint32_t **name_types); 122 bool lookup_cached_sid(TALLOC_CTX *mem_ctx, const DOM_SID*sid,94 bool lookup_cached_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, 123 95 char **domain_name, char **name, 124 96 enum lsa_SidType *type); 125 bool lookup_cached_name(TALLOC_CTX *mem_ctx, 126 const char *domain_name, 97 bool lookup_cached_name(const char *domain_name, 127 98 const char *name, 128 DOM_SID*sid,99 struct dom_sid *sid, 129 100 enum lsa_SidType *type); 130 101 void cache_name2sid(struct winbindd_domain *domain, 131 102 const char *domain_name, const char *name, 132 enum lsa_SidType type, const DOM_SID*sid);103 enum lsa_SidType type, const struct dom_sid *sid); 133 104 NTSTATUS wcache_name_to_sid(struct winbindd_domain *domain, 134 105 const char *domain_name, … … 142 113 NTSTATUS wcache_lookup_useraliases(struct winbindd_domain *domain, 143 114 TALLOC_CTX *mem_ctx, 144 uint32 num_sids, const DOM_SID*sids,115 uint32 num_sids, const struct dom_sid *sids, 145 116 uint32 *pnum_aliases, uint32 **paliases); 146 117 NTSTATUS wcache_lookup_usergroups(struct winbindd_domain *domain, … … 152 123 void wcache_flush_cache(void); 153 124 NTSTATUS wcache_count_cached_creds(struct winbindd_domain *domain, int *count); 154 NTSTATUS wcache_remove_oldest_cached_creds(struct winbindd_domain *domain, const DOM_SID*sid) ;125 NTSTATUS wcache_remove_oldest_cached_creds(struct winbindd_domain *domain, const struct dom_sid *sid) ; 155 126 bool set_global_winbindd_state_offline(void); 156 127 void set_global_winbindd_state_online(void); … … 162 133 bool wcache_tdc_add_domain( struct winbindd_domain *domain ); 163 134 struct winbindd_tdc_domain * wcache_tdc_fetch_domain( TALLOC_CTX *ctx, const char *name ); 135 struct winbindd_tdc_domain* wcache_tdc_fetch_domainbysid(TALLOC_CTX *ctx, const struct dom_sid *sid); 164 136 void wcache_tdc_clear( void ); 137 #ifdef HAVE_ADS 138 struct ads_struct; 165 139 NTSTATUS nss_get_info_cached( struct winbindd_domain *domain, 166 const DOM_SID*user_sid,140 const struct dom_sid *user_sid, 167 141 TALLOC_CTX *ctx, 168 ADS_STRUCT *ads, LDAPMessage *msg,169 142 const char **homedir, const char **shell, 170 143 const char **gecos, gid_t *p_gid); 144 #endif 171 145 bool wcache_store_seqnum(const char *domain_name, uint32_t seqnum, 172 146 time_t last_seq_check); … … 182 156 struct winbindd_cli_state *state); 183 157 void winbindd_ccache_save(struct winbindd_cli_state *state); 184 enum winbindd_result winbindd_dual_ccache_save(185 struct winbindd_domain *domain, struct winbindd_cli_state *state);186 158 187 159 /* The following definitions come from winbindd/winbindd_cm.c */ … … 189 161 void set_domain_offline(struct winbindd_domain *domain); 190 162 void set_domain_online_request(struct winbindd_domain *domain); 191 void winbind_add_failed_connection_entry(const struct winbindd_domain *domain,192 const char *server,193 NTSTATUS result);194 163 void invalidate_cm_connection(struct winbindd_cm_conn *conn); 195 164 void close_conns_after_fork(void); … … 204 173 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, 205 174 struct rpc_pipe_client **cli); 175 bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx, 176 const char *domain_name, 177 char **p_dc_name, char **p_dc_ip); 206 178 207 179 /* The following definitions come from winbindd/winbindd_cred_cache.c */ … … 236 208 NTSTATUS winbindd_get_creds(struct winbindd_domain *domain, 237 209 TALLOC_CTX *mem_ctx, 238 const DOM_SID*sid,210 const struct dom_sid *sid, 239 211 struct netr_SamInfo3 **info3, 240 212 const uint8 *cached_nt_pass[NT_HASH_LEN], 241 213 const uint8 *cred_salt[NT_HASH_LEN]); 242 214 NTSTATUS winbindd_store_creds(struct winbindd_domain *domain, 243 TALLOC_CTX *mem_ctx,244 215 const char *user, 245 216 const char *pass, 246 struct netr_SamInfo3 *info3, 247 const DOM_SID *user_sid); 217 struct netr_SamInfo3 *info3); 248 218 NTSTATUS winbindd_update_creds_by_info3(struct winbindd_domain *domain, 249 TALLOC_CTX *mem_ctx,250 219 const char *user, 251 220 const char *pass, 252 221 struct netr_SamInfo3 *info3); 253 NTSTATUS winbindd_update_creds_by_sid(struct winbindd_domain *domain,254 TALLOC_CTX *mem_ctx,255 const DOM_SID *sid,256 const char *pass);257 222 NTSTATUS winbindd_update_creds_by_name(struct winbindd_domain *domain, 258 TALLOC_CTX *mem_ctx,259 223 const char *user, 260 224 const char *pass); … … 262 226 /* The following definitions come from winbindd/winbindd_domain.c */ 263 227 264 void setup_domain_child(struct winbindd_domain *domain, 265 struct winbindd_child *child); 228 void setup_domain_child(struct winbindd_domain *domain); 266 229 267 230 /* The following definitions come from winbindd/winbindd_dual.c */ 231 232 struct dcerpc_binding_handle *dom_child_handle(struct winbindd_domain *domain); 233 struct winbindd_child *choose_domain_child(struct winbindd_domain *domain); 268 234 269 235 struct tevent_req *wb_child_request_send(TALLOC_CTX *mem_ctx, … … 280 246 struct winbindd_response **presponse, int *err); 281 247 282 void async_domain_request(TALLOC_CTX *mem_ctx,283 struct winbindd_domain *domain,284 struct winbindd_request *request,285 struct winbindd_response *response,286 void (*continuation)(void *private_data_data, bool success),287 void *private_data_data);288 void sendto_domain(struct winbindd_cli_state *state,289 struct winbindd_domain *domain);290 248 void setup_child(struct winbindd_domain *domain, struct winbindd_child *child, 291 249 const struct winbindd_child_dispatch_table *table, … … 324 282 struct server_id server_id, 325 283 DATA_BLOB *data); 326 bool winbindd_reinit_after_fork(const char *logfilename); 284 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx, 285 void *private_data, 286 uint32_t msg_type, 287 struct server_id server_id, 288 DATA_BLOB *data); 289 void winbind_msg_ip_dropped_parent(struct messaging_context *msg_ctx, 290 void *private_data, 291 uint32_t msg_type, 292 struct server_id server_id, 293 DATA_BLOB *data); 294 NTSTATUS winbindd_reinit_after_fork(const struct winbindd_child *myself, 295 const char *logfilename); 327 296 struct winbindd_domain *wb_child_domain(void); 328 297 … … 350 319 void init_idmap_child(void); 351 320 struct winbindd_child *idmap_child(void); 321 struct idmap_domain *idmap_find_domain(const char *domname); 352 322 353 323 /* The following definitions come from winbindd/winbindd_locator.c */ … … 362 332 struct winbindd_cli_state *state); 363 333 void winbindd_show_sequence(struct winbindd_cli_state *state); 364 enum winbindd_result winbindd_dual_show_sequence(struct winbindd_domain *domain,365 struct winbindd_cli_state *state);366 334 void winbindd_domain_info(struct winbindd_cli_state *state); 335 void winbindd_dc_info(struct winbindd_cli_state *state); 367 336 void winbindd_ping(struct winbindd_cli_state *state); 368 337 void winbindd_info(struct winbindd_cli_state *state); … … 373 342 374 343 /* The following definitions come from winbindd/winbindd_ndr.c */ 375 344 struct ndr_print; 376 345 void ndr_print_winbindd_child(struct ndr_print *ndr, 377 346 const char *name, … … 390 359 391 360 bool check_request_flags(uint32_t flags); 361 uid_t get_uid_from_request(struct winbindd_request *request); 392 362 struct winbindd_domain *find_auth_domain(uint8_t flags, 393 363 const char *domain_name); 394 NTSTATUS check_info3_in_group(struct netr_SamInfo3 *info3,395 const char *group_sid);396 NTSTATUS append_auth_data(struct winbindd_cli_state *state,397 struct netr_SamInfo3 *info3,398 const char *name_domain,399 const char *name_user);400 void winbindd_pam_auth(struct winbindd_cli_state *state);401 364 enum winbindd_result winbindd_dual_pam_auth(struct winbindd_domain *domain, 402 365 struct winbindd_cli_state *state) ; 403 void winbindd_pam_auth_crap(struct winbindd_cli_state *state);404 366 enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, 405 367 struct winbindd_cli_state *state) ; 406 void winbindd_pam_chauthtok(struct winbindd_cli_state *state);407 368 enum winbindd_result winbindd_dual_pam_chauthtok(struct winbindd_domain *contact_domain, 408 369 struct winbindd_cli_state *state); 409 void winbindd_pam_logoff(struct winbindd_cli_state *state);410 370 enum winbindd_result winbindd_dual_pam_logoff(struct winbindd_domain *domain, 411 371 struct winbindd_cli_state *state) ; 412 void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state);413 372 enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state); 414 373 … … 416 375 417 376 struct winbindd_domain *domain_list(void); 418 void free_domain_list(void);377 bool domain_is_forest_root(const struct winbindd_domain *domain); 419 378 void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te, 420 379 struct timeval now, void *private_data); … … 422 381 struct winbindd_cli_state *state); 423 382 bool init_domain_list(void); 424 void check_domain_trusted( const char *name, const DOM_SID *user_sid );425 383 struct winbindd_domain *find_domain_from_name_noinit(const char *domain_name); 426 384 struct winbindd_domain *find_domain_from_name(const char *domain_name); 427 struct winbindd_domain *find_domain_from_sid_noinit(const DOM_SID*sid);428 struct winbindd_domain *find_domain_from_sid(const DOM_SID*sid);385 struct winbindd_domain *find_domain_from_sid_noinit(const struct dom_sid *sid); 386 struct winbindd_domain *find_domain_from_sid(const struct dom_sid *sid); 429 387 struct winbindd_domain *find_our_domain(void); 430 388 struct winbindd_domain *find_root_domain(void); 431 389 struct winbindd_domain *find_builtin_domain(void); 432 struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID*sid);390 struct winbindd_domain *find_lookup_domain_from_sid(const struct dom_sid *sid); 433 391 struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name); 434 392 bool parse_domain_user(const char *domuser, fstring domain, fstring user); 435 393 bool parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser, 436 394 char **domain, char **user); 437 void parse_add_domuser(void *buf, char *domuser, int *len);438 395 bool canonicalize_username(fstring username_inout, fstring domain, fstring user); 439 396 void fill_domain_username(fstring name, const char *domain, const char *user, bool can_assume); … … 442 399 const char *user, 443 400 bool can_assume); 444 const char *get_winbind_pipe_dir(void) ;445 char *get_winbind_priv_pipe_dir(void) ;446 int open_winbindd_socket(void);447 int open_winbindd_priv_socket(void);448 401 struct winbindd_cli_state *winbindd_client_list(void); 449 402 void winbindd_add_client(struct winbindd_cli_state *cli); 450 403 void winbindd_remove_client(struct winbindd_cli_state *cli); 451 void winbindd_kill_all_clients(void);452 404 int winbindd_num_clients(void); 453 405 NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, 454 406 TALLOC_CTX *mem_ctx, 455 const DOM_SID*user_sid,456 uint32 *p_num_groups, DOM_SID**user_sids);407 const struct dom_sid *user_sid, 408 uint32 *p_num_groups, struct dom_sid **user_sids); 457 409 458 410 NTSTATUS normalize_name_map(TALLOC_CTX *mem_ctx, … … 479 431 void set_auth_errors(struct winbindd_response *resp, NTSTATUS result); 480 432 bool is_domain_offline(const struct winbindd_domain *domain); 433 bool is_domain_online(const struct winbindd_domain *domain); 434 bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr, 435 struct dom_sid **sids, uint32_t *num_sids); 481 436 482 437 /* The following definitions come from winbindd/winbindd_wins.c */ … … 494 449 struct winbindd_cli_state *state); 495 450 496 struct rpc_pipe_client *wbint_rpccli_create(TALLOC_CTX *mem_ctx,497 498 451 struct dcerpc_binding_handle *wbint_binding_handle(TALLOC_CTX *mem_ctx, 452 struct winbindd_domain *domain, 453 struct winbindd_child *child); 499 454 enum winbindd_result winbindd_dual_ndrcmd(struct winbindd_domain *domain, 500 455 struct winbindd_cli_state *state); … … 513 468 NTSTATUS winbindd_lookupsid_recv(struct tevent_req *req, 514 469 struct winbindd_response *response); 470 471 struct tevent_req *winbindd_lookupsids_send(TALLOC_CTX *mem_ctx, 472 struct tevent_context *ev, 473 struct winbindd_cli_state *cli, 474 struct winbindd_request *request); 475 NTSTATUS winbindd_lookupsids_recv(struct tevent_req *req, 476 struct winbindd_response *response); 515 477 516 478 struct tevent_req *wb_lookupname_send(TALLOC_CTX *mem_ctx, … … 847 809 struct winbindd_response *presp); 848 810 849 struct tevent_req *winbindd_set_mapping_send(TALLOC_CTX *mem_ctx, 850 struct tevent_context *ev, 851 struct winbindd_cli_state *cli, 852 struct winbindd_request *request); 853 NTSTATUS winbindd_set_mapping_recv(struct tevent_req *req, 854 struct winbindd_response *response); 855 856 struct tevent_req *winbindd_remove_mapping_send(TALLOC_CTX *mem_ctx, 857 struct tevent_context *ev, 858 struct winbindd_cli_state *cli, 859 struct winbindd_request *request); 860 NTSTATUS winbindd_remove_mapping_recv(struct tevent_req *req, 861 struct winbindd_response *response); 862 863 struct tevent_req *winbindd_set_hwm_send(TALLOC_CTX *mem_ctx, 864 struct tevent_context *ev, 865 struct winbindd_cli_state *cli, 866 struct winbindd_request *request); 867 NTSTATUS winbindd_set_hwm_recv(struct tevent_req *req, 868 struct winbindd_response *response); 811 struct tevent_req *winbindd_pam_auth_send(TALLOC_CTX *mem_ctx, 812 struct tevent_context *ev, 813 struct winbindd_cli_state *cli, 814 struct winbindd_request *request); 815 NTSTATUS winbindd_pam_auth_recv(struct tevent_req *req, 816 struct winbindd_response *response); 817 818 struct tevent_req *winbindd_pam_auth_crap_send( 819 TALLOC_CTX *mem_ctx, 820 struct tevent_context *ev, 821 struct winbindd_cli_state *cli, 822 struct winbindd_request *request); 823 NTSTATUS winbindd_pam_auth_crap_recv(struct tevent_req *req, 824 struct winbindd_response *response); 825 826 struct tevent_req *winbindd_pam_chauthtok_send( 827 TALLOC_CTX *mem_ctx, 828 struct tevent_context *ev, 829 struct winbindd_cli_state *cli, 830 struct winbindd_request *request); 831 NTSTATUS winbindd_pam_chauthtok_recv(struct tevent_req *req, 832 struct winbindd_response *response); 833 834 struct tevent_req *winbindd_pam_logoff_send(TALLOC_CTX *mem_ctx, 835 struct tevent_context *ev, 836 struct winbindd_cli_state *cli, 837 struct winbindd_request *request); 838 NTSTATUS winbindd_pam_logoff_recv(struct tevent_req *req, 839 struct winbindd_response *response); 840 841 struct tevent_req *winbindd_pam_chng_pswd_auth_crap_send( 842 TALLOC_CTX *mem_ctx, 843 struct tevent_context *ev, 844 struct winbindd_cli_state *cli, 845 struct winbindd_request *request); 846 NTSTATUS winbindd_pam_chng_pswd_auth_crap_recv( 847 struct tevent_req *req, 848 struct winbindd_response *response); 849 850 struct tevent_req *wb_lookupsids_send(TALLOC_CTX *mem_ctx, 851 struct tevent_context *ev, 852 struct dom_sid *sids, 853 uint32_t num_sids); 854 NTSTATUS wb_lookupsids_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 855 struct lsa_RefDomainList **domains, 856 struct lsa_TransNameArray **names); 857 858 struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx, 859 struct tevent_context *ev, 860 struct winbindd_cli_state *cli, 861 struct winbindd_request *request); 862 NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req, 863 struct winbindd_response *response); 864 865 866 /* The following definitions come from winbindd/winbindd_samr.c */ 867 868 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx, 869 struct winbindd_domain *domain, 870 struct rpc_pipe_client **samr_pipe, 871 struct policy_handle *samr_domain_hnd); 869 872 870 873 #endif /* _WINBINDD_PROTO_H_ */ -
vendor/current/source3/winbindd/winbindd_reconnect.c
r427 r740 94 94 TALLOC_CTX *mem_ctx, 95 95 uint32 *num_entries, 96 struct acct_info **info)96 struct wb_acct_info **info) 97 97 { 98 98 NTSTATUS result; … … 112 112 TALLOC_CTX *mem_ctx, 113 113 uint32 *num_entries, 114 struct acct_info **info)114 struct wb_acct_info **info) 115 115 { 116 116 NTSTATUS result; … … 132 132 const char *name, 133 133 uint32_t flags, 134 DOM_SID*sid,134 struct dom_sid *sid, 135 135 enum lsa_SidType *type) 136 136 { … … 153 153 static NTSTATUS sid_to_name(struct winbindd_domain *domain, 154 154 TALLOC_CTX *mem_ctx, 155 const DOM_SID*sid,155 const struct dom_sid *sid, 156 156 char **domain_name, 157 157 char **name, … … 172 172 static NTSTATUS rids_to_names(struct winbindd_domain *domain, 173 173 TALLOC_CTX *mem_ctx, 174 const DOM_SID*sid,174 const struct dom_sid *sid, 175 175 uint32 *rids, 176 176 size_t num_rids, … … 197 197 static NTSTATUS query_user(struct winbindd_domain *domain, 198 198 TALLOC_CTX *mem_ctx, 199 const DOM_SID*user_sid,199 const struct dom_sid *user_sid, 200 200 struct wbint_userinfo *user_info) 201 201 { … … 215 215 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, 216 216 TALLOC_CTX *mem_ctx, 217 const DOM_SID*user_sid,218 uint32 *num_groups, DOM_SID**user_gids)217 const struct dom_sid *user_sid, 218 uint32 *num_groups, struct dom_sid **user_gids) 219 219 { 220 220 NTSTATUS result; … … 234 234 static NTSTATUS lookup_useraliases(struct winbindd_domain *domain, 235 235 TALLOC_CTX *mem_ctx, 236 uint32 num_sids, const DOM_SID*sids,236 uint32 num_sids, const struct dom_sid *sids, 237 237 uint32 *num_aliases, uint32 **alias_rids) 238 238 { … … 256 256 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, 257 257 TALLOC_CTX *mem_ctx, 258 const DOM_SID*group_sid,258 const struct dom_sid *group_sid, 259 259 enum lsa_SidType type, 260 260 uint32 *num_names, 261 DOM_SID **sid_mem, char ***names,261 struct dom_sid **sid_mem, char ***names, 262 262 uint32 **name_types) 263 263 { -
vendor/current/source3/winbindd/winbindd_rpc.c
r594 r740 1 /* 2 Unix SMB/CIFS implementation. 3 4 Winbind rpc backend functions 5 6 Copyright (C) Tim Potter 2000-2001,2003 7 Copyright (C) Andrew Tridgell 2001 8 Copyright (C) Volker Lendecke 2005 9 Copyright (C) Guenther Deschner 2008 (pidl conversion) 10 11 This program is free software; you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation; either version 3 of the License, or 14 (at your option) any later version. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program. If not, see <http://www.gnu.org/licenses/>. 23 */ 1 /* 2 * Unix SMB/CIFS implementation. 3 * 4 * Winbind rpc backend functions 5 * 6 * Copyright (c) 2000-2003 Tim Potter 7 * Copyright (c) 2001 Andrew Tridgell 8 * Copyright (c) 2005 Volker Lendecke 9 * Copyright (c) 2008 Guenther Deschner (pidl conversion) 10 * Copyright (c) 2010 Andreas Schneider <asn@samba.org> 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 3 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program. If not, see <http://www.gnu.org/licenses/>. 24 */ 24 25 25 26 #include "includes.h" 26 27 #include "winbindd.h" 27 #include "../librpc/gen_ndr/cli_samr.h" 28 #include "../librpc/gen_ndr/cli_lsa.h" 29 30 #undef DBGC_CLASS 31 #define DBGC_CLASS DBGC_WINBIND 32 33 34 /* Query display info for a domain. This returns enough information plus a 35 bit extra to give an overview of domain users for the User Manager 36 application. */ 37 static NTSTATUS query_user_list(struct winbindd_domain *domain, 38 TALLOC_CTX *mem_ctx, 39 uint32 *num_entries, 40 struct wbint_userinfo **info) 41 { 42 NTSTATUS result; 43 struct policy_handle dom_pol; 44 unsigned int i, start_idx; 45 uint32 loop_count; 46 struct rpc_pipe_client *cli; 47 48 DEBUG(3,("rpc: query_user_list\n")); 49 50 *num_entries = 0; 51 *info = NULL; 52 53 if ( !winbindd_can_contact_domain( domain ) ) { 54 DEBUG(10,("query_user_list: No incoming trust for domain %s\n", 55 domain->name)); 56 return NT_STATUS_OK; 57 } 58 59 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 60 if (!NT_STATUS_IS_OK(result)) 61 return result; 62 63 i = start_idx = 0; 64 loop_count = 0; 28 #include "winbindd_rpc.h" 29 #include "rpc_client/rpc_client.h" 30 #include "librpc/gen_ndr/ndr_samr_c.h" 31 #include "librpc/gen_ndr/ndr_lsa_c.h" 32 #include "rpc_client/cli_samr.h" 33 #include "rpc_client/cli_lsarpc.h" 34 #include "../libcli/security/security.h" 35 36 /* Query display info for a domain */ 37 NTSTATUS rpc_query_user_list(TALLOC_CTX *mem_ctx, 38 struct rpc_pipe_client *samr_pipe, 39 struct policy_handle *samr_policy, 40 const struct dom_sid *domain_sid, 41 uint32_t *pnum_info, 42 struct wbint_userinfo **pinfo) 43 { 44 struct wbint_userinfo *info = NULL; 45 uint32_t num_info = 0; 46 uint32_t loop_count = 0; 47 uint32_t start_idx = 0; 48 uint32_t i = 0; 49 NTSTATUS status, result; 50 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 51 52 *pnum_info = 0; 65 53 66 54 do { 67 uint32 num_dom_users, j; 68 uint32 max_entries, max_size; 55 uint32_t j; 56 uint32_t num_dom_users; 57 uint32_t max_entries, max_size; 69 58 uint32_t total_size, returned_size; 70 71 59 union samr_DispInfo disp_info; 72 60 73 /* this next bit is copied from net_user_list_internal() */74 75 get_query_dispinfo_params(loop_count, &max_entries,76 &max_size); 77 78 result = rpccli_samr_QueryDisplayInfo(cli,mem_ctx,79 &dom_pol,80 1, 61 dcerpc_get_query_dispinfo_params(loop_count, 62 &max_entries, 63 &max_size); 64 65 status = dcerpc_samr_QueryDisplayInfo(b, 66 mem_ctx, 67 samr_policy, 68 1, /* level */ 81 69 start_idx, 82 70 max_entries, … … 84 72 &total_size, 85 73 &returned_size, 86 &disp_info); 87 74 &disp_info, 75 &result); 76 if (!NT_STATUS_IS_OK(status)) { 77 return status; 78 } 88 79 if (!NT_STATUS_IS_OK(result)) { 89 90 91 92 } 93 94 num_dom_users = disp_info.info1.count;80 if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 81 return result; 82 } 83 } 84 85 /* increment required start query values */ 95 86 start_idx += disp_info.info1.count; 96 87 loop_count++; 97 98 *num_entries += num_dom_users; 99 100 *info = TALLOC_REALLOC_ARRAY(mem_ctx, *info, 101 struct wbint_userinfo, 102 *num_entries); 103 104 if (!(*info)) { 88 num_dom_users = disp_info.info1.count; 89 90 num_info += num_dom_users; 91 92 info = TALLOC_REALLOC_ARRAY(mem_ctx, 93 info, 94 struct wbint_userinfo, 95 num_info); 96 if (info == NULL) { 105 97 return NT_STATUS_NO_MEMORY; 106 98 } 107 99 108 100 for (j = 0; j < num_dom_users; i++, j++) { 109 110 101 uint32_t rid = disp_info.info1.entries[j].rid; 111 112 (*info)[i].acct_name = talloc_strdup(mem_ctx, 113 disp_info.info1.entries[j].account_name.string); 114 (*info)[i].full_name = talloc_strdup(mem_ctx, 115 disp_info.info1.entries[j].full_name.string); 116 (*info)[i].homedir = NULL; 117 (*info)[i].shell = NULL; 118 sid_compose(&(*info)[i].user_sid, &domain->sid, rid); 102 struct samr_DispEntryGeneral *src; 103 struct wbint_userinfo *dst; 104 105 src = &(disp_info.info1.entries[j]); 106 dst = &(info[i]); 107 108 dst->acct_name = talloc_strdup(info, 109 src->account_name.string); 110 if (dst->acct_name == NULL) { 111 return NT_STATUS_NO_MEMORY; 112 } 113 114 dst->full_name = talloc_strdup(info, src->full_name.string); 115 if ((src->full_name.string != NULL) && 116 (dst->full_name == NULL)) 117 { 118 return NT_STATUS_NO_MEMORY; 119 } 120 121 dst->homedir = NULL; 122 dst->shell = NULL; 123 124 sid_compose(&dst->user_sid, domain_sid, rid); 119 125 120 126 /* For the moment we set the primary group for … … 125 131 force group' smb.conf parameter or 126 132 something like that. */ 127 128 sid_compose(&(*info)[i].group_sid, &domain->sid, 129 DOMAIN_GROUP_RID_USERS); 130 } 131 133 sid_compose(&dst->group_sid, domain_sid, 134 DOMAIN_RID_USERS); 135 } 132 136 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 133 137 134 return result; 135 } 136 137 /* list all domain groups */ 138 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, 139 TALLOC_CTX *mem_ctx, 140 uint32 *num_entries, 141 struct acct_info **info) 142 { 143 struct policy_handle dom_pol; 144 NTSTATUS status; 145 uint32 start = 0; 146 struct rpc_pipe_client *cli; 147 148 *num_entries = 0; 149 *info = NULL; 150 151 DEBUG(3,("rpc: enum_dom_groups\n")); 152 153 if ( !winbindd_can_contact_domain( domain ) ) { 154 DEBUG(10,("enum_domain_groups: No incoming trust for domain %s\n", 155 domain->name)); 156 return NT_STATUS_OK; 157 } 158 159 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 160 if (!NT_STATUS_IS_OK(status)) 161 return status; 138 *pnum_info = num_info; 139 *pinfo = info; 140 141 return NT_STATUS_OK; 142 } 143 144 /* List all domain groups */ 145 NTSTATUS rpc_enum_dom_groups(TALLOC_CTX *mem_ctx, 146 struct rpc_pipe_client *samr_pipe, 147 struct policy_handle *samr_policy, 148 uint32_t *pnum_info, 149 struct wb_acct_info **pinfo) 150 { 151 struct wb_acct_info *info = NULL; 152 uint32_t start = 0; 153 uint32_t num_info = 0; 154 NTSTATUS status, result; 155 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 156 157 *pnum_info = 0; 162 158 163 159 do { 164 160 struct samr_SamArray *sam_array = NULL; 165 uint32 count = 0; 166 TALLOC_CTX *mem_ctx2; 167 int g; 168 169 mem_ctx2 = talloc_init("enum_dom_groups[rpc]"); 161 uint32_t count = 0; 162 uint32_t g; 170 163 171 164 /* start is updated by this call. */ 172 status = rpccli_samr_EnumDomainGroups(cli, mem_ctx2, 173 &dom_pol, 165 status = dcerpc_samr_EnumDomainGroups(b, 166 mem_ctx, 167 samr_policy, 174 168 &start, 175 169 &sam_array, 176 170 0xFFFF, /* buffer size? */ 177 &count); 178 179 if (!NT_STATUS_IS_OK(status) && 180 !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { 181 talloc_destroy(mem_ctx2); 182 break; 183 } 184 185 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info, 186 struct acct_info, 187 (*num_entries) + count); 188 if (! *info) { 189 talloc_destroy(mem_ctx2); 171 &count, 172 &result); 173 if (!NT_STATUS_IS_OK(status)) { 174 return status; 175 } 176 if (!NT_STATUS_IS_OK(result)) { 177 if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 178 DEBUG(2,("query_user_list: failed to enum domain groups: %s\n", 179 nt_errstr(result))); 180 return result; 181 } 182 } 183 184 info = TALLOC_REALLOC_ARRAY(mem_ctx, 185 info, 186 struct wb_acct_info, 187 num_info + count); 188 if (info == NULL) { 190 189 return NT_STATUS_NO_MEMORY; 191 190 } 192 191 193 for (g=0; g < count; g++) { 194 195 fstrcpy((*info)[*num_entries + g].acct_name, 192 for (g = 0; g < count; g++) { 193 fstrcpy(info[num_info + g].acct_name, 196 194 sam_array->entries[g].name.string); 197 (*info)[*num_entries + g].rid = sam_array->entries[g].idx; 198 } 199 200 (*num_entries) += count; 201 talloc_destroy(mem_ctx2); 202 } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)); 203 204 return status; 205 } 206 207 /* List all domain groups */ 208 209 static NTSTATUS enum_local_groups(struct winbindd_domain *domain, 210 TALLOC_CTX *mem_ctx, 211 uint32 *num_entries, 212 struct acct_info **info) 213 { 214 struct policy_handle dom_pol; 215 NTSTATUS result; 216 struct rpc_pipe_client *cli; 217 218 *num_entries = 0; 219 *info = NULL; 220 221 DEBUG(3,("rpc: enum_local_groups\n")); 222 223 if ( !winbindd_can_contact_domain( domain ) ) { 224 DEBUG(10,("enum_local_groups: No incoming trust for domain %s\n", 225 domain->name)); 226 return NT_STATUS_OK; 227 } 228 229 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 230 if (!NT_STATUS_IS_OK(result)) 231 return result; 195 196 info[num_info + g].rid = sam_array->entries[g].idx; 197 } 198 199 num_info += count; 200 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 201 202 *pnum_info = num_info; 203 *pinfo = info; 204 205 return NT_STATUS_OK; 206 } 207 208 NTSTATUS rpc_enum_local_groups(TALLOC_CTX *mem_ctx, 209 struct rpc_pipe_client *samr_pipe, 210 struct policy_handle *samr_policy, 211 uint32_t *pnum_info, 212 struct wb_acct_info **pinfo) 213 { 214 struct wb_acct_info *info = NULL; 215 uint32_t num_info = 0; 216 NTSTATUS status, result; 217 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 218 219 *pnum_info = 0; 232 220 233 221 do { 234 222 struct samr_SamArray *sam_array = NULL; 235 uint32 count = 0, start = *num_entries; 236 TALLOC_CTX *mem_ctx2; 237 int g; 238 239 mem_ctx2 = talloc_init("enum_dom_local_groups[rpc]"); 240 241 result = rpccli_samr_EnumDomainAliases(cli, mem_ctx2, 242 &dom_pol, 223 uint32_t count = 0; 224 uint32_t start = num_info; 225 uint32_t g; 226 227 status = dcerpc_samr_EnumDomainAliases(b, 228 mem_ctx, 229 samr_policy, 243 230 &start, 244 231 &sam_array, 245 232 0xFFFF, /* buffer size? */ 246 &count); 247 if (!NT_STATUS_IS_OK(result) && 248 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES) ) 249 { 250 talloc_destroy(mem_ctx2); 251 return result; 252 } 253 254 (*info) = TALLOC_REALLOC_ARRAY(mem_ctx, *info, 255 struct acct_info, 256 (*num_entries) + count); 257 if (! *info) { 258 talloc_destroy(mem_ctx2); 259 return NT_STATUS_NO_MEMORY; 260 } 261 262 for (g=0; g < count; g++) { 263 264 fstrcpy((*info)[*num_entries + g].acct_name, 233 &count, 234 &result); 235 if (!NT_STATUS_IS_OK(status)) { 236 return status; 237 } 238 if (!NT_STATUS_IS_OK(result)) { 239 if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 240 return result; 241 } 242 } 243 244 info = TALLOC_REALLOC_ARRAY(mem_ctx, 245 info, 246 struct wb_acct_info, 247 num_info + count); 248 if (info == NULL) { 249 return NT_STATUS_NO_MEMORY; 250 } 251 252 for (g = 0; g < count; g++) { 253 fstrcpy(info[num_info + g].acct_name, 265 254 sam_array->entries[g].name.string); 266 (*info)[*num_entries + g].rid = sam_array->entries[g].idx; 267 } 268 269 (*num_entries) += count; 270 talloc_destroy(mem_ctx2); 271 255 info[num_info + g].rid = sam_array->entries[g].idx; 256 } 257 258 num_info += count; 272 259 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 273 260 274 return result; 261 *pnum_info = num_info; 262 *pinfo = info; 263 264 return NT_STATUS_OK; 275 265 } 276 266 277 267 /* convert a single name to a sid in a domain */ 278 static NTSTATUS msrpc_name_to_sid(struct winbindd_domain *domain, 279 TALLOC_CTX *mem_ctx, 280 const char *domain_name, 281 const char *name, 282 uint32_t flags, 283 DOM_SID *sid, 284 enum lsa_SidType *type) 285 { 286 NTSTATUS result; 287 DOM_SID *sids = NULL; 268 NTSTATUS rpc_name_to_sid(TALLOC_CTX *mem_ctx, 269 struct rpc_pipe_client *lsa_pipe, 270 struct policy_handle *lsa_policy, 271 const char *domain_name, 272 const char *name, 273 uint32_t flags, 274 struct dom_sid *sid, 275 enum lsa_SidType *type) 276 { 288 277 enum lsa_SidType *types = NULL; 278 struct dom_sid *sids = NULL; 289 279 char *full_name = NULL; 290 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL;291 280 char *mapped_name = NULL; 292 293 if (name == NULL || *name=='\0') { 281 NTSTATUS status; 282 283 if (name == NULL || name[0] == '\0') { 294 284 full_name = talloc_asprintf(mem_ctx, "%s", domain_name); 295 } else if (domain_name == NULL || *domain_name== '\0') {285 } else if (domain_name == NULL || domain_name[0] == '\0') { 296 286 full_name = talloc_asprintf(mem_ctx, "%s", name); 297 287 } else { 298 288 full_name = talloc_asprintf(mem_ctx, "%s\\%s", domain_name, name); 299 289 } 300 if (!full_name) { 301 DEBUG(0, ("talloc_asprintf failed!\n"));290 291 if (full_name == NULL) { 302 292 return NT_STATUS_NO_MEMORY; 303 293 } 304 294 305 DEBUG(3,("rpc: name_to_sid name=%s\n", full_name)); 306 307 name_map_status = normalize_name_unmap(mem_ctx, full_name, 308 &mapped_name); 309 310 /* Reset the full_name pointer if we mapped anytthing */ 311 312 if (NT_STATUS_IS_OK(name_map_status) || 313 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED)) 314 { 295 status = normalize_name_unmap(mem_ctx, full_name, &mapped_name); 296 /* Reset the full_name pointer if we mapped anything */ 297 if (NT_STATUS_IS_OK(status) || 298 NT_STATUS_EQUAL(status, NT_STATUS_FILE_RENAMED)) { 315 299 full_name = mapped_name; 316 300 } 317 301 318 DEBUG(3,("name_to_sid [rpc] %s for domain %s\n", 319 full_name?full_name:"", domain_name )); 320 321 result = winbindd_lookup_names(mem_ctx, domain, 1, 322 (const char **)&full_name, NULL, 323 &sids, &types); 324 if (!NT_STATUS_IS_OK(result)) 325 return result; 326 327 /* Return rid and type if lookup successful */ 302 DEBUG(3,("name_to_sid: %s for domain %s\n", 303 full_name ? full_name : "", domain_name )); 304 305 /* 306 * We don't run into deadlocks here, cause winbind_off() is 307 * called in the main function. 308 */ 309 status = rpccli_lsa_lookup_names(lsa_pipe, 310 mem_ctx, 311 lsa_policy, 312 1, /* num_names */ 313 (const char **) &full_name, 314 NULL, /* domains */ 315 1, /* level */ 316 &sids, 317 &types); 318 if (!NT_STATUS_IS_OK(status)) { 319 DEBUG(2,("name_to_sid: failed to lookup name: %s\n", 320 nt_errstr(status))); 321 return status; 322 } 328 323 329 324 sid_copy(sid, &sids[0]); … … 333 328 } 334 329 335 /* 336 convert a domain SID to a user or group name 337 */ 338 static NTSTATUS msrpc_sid_to_name(struct winbindd_domain *domain, 339 TALLOC_CTX *mem_ctx, 340 const DOM_SID *sid, 341 char **domain_name, 342 char **name, 343 enum lsa_SidType *type) 344 { 345 char **domains; 346 char **names; 330 /* Convert a domain SID to a user or group name */ 331 NTSTATUS rpc_sid_to_name(TALLOC_CTX *mem_ctx, 332 struct rpc_pipe_client *lsa_pipe, 333 struct policy_handle *lsa_policy, 334 struct winbindd_domain *domain, 335 const struct dom_sid *sid, 336 char **pdomain_name, 337 char **pname, 338 enum lsa_SidType *ptype) 339 { 340 char *mapped_name = NULL; 341 char **domains = NULL; 342 char **names = NULL; 347 343 enum lsa_SidType *types = NULL; 348 NTSTATUS result; 349 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL; 350 char *mapped_name = NULL; 351 352 DEBUG(3,("sid_to_name [rpc] %s for domain %s\n", sid_string_dbg(sid), 353 domain->name )); 354 355 result = winbindd_lookup_sids(mem_ctx, 356 domain, 357 1, 358 sid, 359 &domains, 360 &names, 361 &types); 362 if (!NT_STATUS_IS_OK(result)) { 363 DEBUG(2,("msrpc_sid_to_name: failed to lookup sids: %s\n", 364 nt_errstr(result))); 365 return result; 366 } 367 368 369 *type = (enum lsa_SidType)types[0]; 370 *domain_name = domains[0]; 371 *name = names[0]; 372 373 DEBUG(5,("Mapped sid to [%s]\\[%s]\n", domains[0], *name)); 374 375 name_map_status = normalize_name_map(mem_ctx, domain, *name, 376 &mapped_name); 377 if (NT_STATUS_IS_OK(name_map_status) || 378 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED)) 379 { 380 *name = mapped_name; 381 DEBUG(5,("returning mapped name -- %s\n", *name)); 344 NTSTATUS map_status; 345 NTSTATUS status; 346 347 status = rpccli_lsa_lookup_sids(lsa_pipe, 348 mem_ctx, 349 lsa_policy, 350 1, /* num_sids */ 351 sid, 352 &domains, 353 &names, 354 &types); 355 if (!NT_STATUS_IS_OK(status)) { 356 DEBUG(2,("sid_to_name: failed to lookup sids: %s\n", 357 nt_errstr(status))); 358 return status; 359 } 360 361 *ptype = (enum lsa_SidType) types[0]; 362 363 map_status = normalize_name_map(mem_ctx, 364 domain, 365 *pname, 366 &mapped_name); 367 if (NT_STATUS_IS_OK(map_status) || 368 NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) { 369 *pname = talloc_strdup(mem_ctx, mapped_name); 370 DEBUG(5,("returning mapped name -- %s\n", *pname)); 371 } else { 372 *pname = talloc_strdup(mem_ctx, names[0]); 373 } 374 if (*pname == NULL) { 375 return NT_STATUS_NO_MEMORY; 376 } 377 378 *pdomain_name = talloc_strdup(mem_ctx, domains[0]); 379 if (*pdomain_name == NULL) { 380 return NT_STATUS_NO_MEMORY; 382 381 } 383 382 … … 385 384 } 386 385 387 static NTSTATUS msrpc_rids_to_names(struct winbindd_domain *domain, 388 TALLOC_CTX *mem_ctx, 389 const DOM_SID *sid, 390 uint32 *rids, 391 size_t num_rids, 392 char **domain_name, 393 char ***names, 394 enum lsa_SidType **types) 395 { 396 char **domains; 397 NTSTATUS result; 398 DOM_SID *sids; 386 /* Convert a bunch of rids to user or group names */ 387 NTSTATUS rpc_rids_to_names(TALLOC_CTX *mem_ctx, 388 struct rpc_pipe_client *lsa_pipe, 389 struct policy_handle *lsa_policy, 390 struct winbindd_domain *domain, 391 const struct dom_sid *sid, 392 uint32_t *rids, 393 size_t num_rids, 394 char **pdomain_name, 395 char ***pnames, 396 enum lsa_SidType **ptypes) 397 { 398 enum lsa_SidType *types = NULL; 399 char *domain_name = NULL; 400 char **domains = NULL; 401 char **names = NULL; 402 struct dom_sid *sids; 399 403 size_t i; 400 char **ret_names; 401 402 DEBUG(3, ("rids_to_names [rpc] for domain %s\n", domain->name )); 403 404 if (num_rids) { 405 sids = TALLOC_ARRAY(mem_ctx, DOM_SID, num_rids); 404 NTSTATUS status; 405 406 if (num_rids > 0) { 407 sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids); 406 408 if (sids == NULL) { 407 409 return NT_STATUS_NO_MEMORY; … … 411 413 } 412 414 413 for (i =0; i<num_rids; i++) {415 for (i = 0; i < num_rids; i++) { 414 416 if (!sid_compose(&sids[i], sid, rids[i])) { 415 417 return NT_STATUS_INTERNAL_ERROR; … … 417 419 } 418 420 419 result = winbindd_lookup_sids(mem_ctx, 420 domain, 421 num_rids, 422 sids, 423 &domains, 424 names, 425 types); 426 427 if (!NT_STATUS_IS_OK(result) && 428 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) { 421 status = rpccli_lsa_lookup_sids(lsa_pipe, 422 mem_ctx, 423 lsa_policy, 424 num_rids, 425 sids, 426 &domains, 427 &names, 428 &types); 429 if (!NT_STATUS_IS_OK(status) && 430 !NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) { 431 DEBUG(2,("rids_to_names: failed to lookup sids: %s\n", 432 nt_errstr(status))); 433 return status; 434 } 435 436 for (i = 0; i < num_rids; i++) { 437 char *mapped_name = NULL; 438 NTSTATUS map_status; 439 440 if (types[i] != SID_NAME_UNKNOWN) { 441 map_status = normalize_name_map(mem_ctx, 442 domain, 443 names[i], 444 &mapped_name); 445 if (NT_STATUS_IS_OK(map_status) || 446 NT_STATUS_EQUAL(map_status, NT_STATUS_FILE_RENAMED)) { 447 TALLOC_FREE(names[i]); 448 names[i] = talloc_strdup(names, mapped_name); 449 if (names[i] == NULL) { 450 return NT_STATUS_NO_MEMORY; 451 } 452 } 453 454 domain_name = domains[i]; 455 } 456 } 457 458 *pdomain_name = domain_name; 459 *ptypes = types; 460 *pnames = names; 461 462 return NT_STATUS_OK; 463 } 464 465 /* Lookup user information from a rid or username. */ 466 NTSTATUS rpc_query_user(TALLOC_CTX *mem_ctx, 467 struct rpc_pipe_client *samr_pipe, 468 struct policy_handle *samr_policy, 469 const struct dom_sid *domain_sid, 470 const struct dom_sid *user_sid, 471 struct wbint_userinfo *user_info) 472 { 473 struct policy_handle user_policy; 474 union samr_UserInfo *info = NULL; 475 uint32_t user_rid; 476 NTSTATUS status, result; 477 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 478 479 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) { 480 return NT_STATUS_UNSUCCESSFUL; 481 } 482 483 /* Get user handle */ 484 status = dcerpc_samr_OpenUser(b, 485 mem_ctx, 486 samr_policy, 487 SEC_FLAG_MAXIMUM_ALLOWED, 488 user_rid, 489 &user_policy, 490 &result); 491 if (!NT_STATUS_IS_OK(status)) { 492 return status; 493 } 494 if (!NT_STATUS_IS_OK(result)) { 429 495 return result; 430 496 } 431 497 432 ret_names = *names; 433 for (i=0; i<num_rids; i++) { 434 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL; 435 char *mapped_name = NULL; 436 437 if ((*types)[i] != SID_NAME_UNKNOWN) { 438 name_map_status = normalize_name_map(mem_ctx, 439 domain, 440 ret_names[i], 441 &mapped_name); 442 if (NT_STATUS_IS_OK(name_map_status) || 443 NT_STATUS_EQUAL(name_map_status, NT_STATUS_FILE_RENAMED)) 444 { 445 ret_names[i] = mapped_name; 446 } 447 448 *domain_name = domains[i]; 449 } 450 } 451 452 return result; 453 } 454 455 /* Lookup user information from a rid or username. */ 456 static NTSTATUS query_user(struct winbindd_domain *domain, 457 TALLOC_CTX *mem_ctx, 458 const DOM_SID *user_sid, 459 struct wbint_userinfo *user_info) 460 { 461 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 462 struct policy_handle dom_pol, user_pol; 463 union samr_UserInfo *info = NULL; 464 uint32 user_rid; 465 struct netr_SamInfo3 *user; 466 struct rpc_pipe_client *cli; 467 468 DEBUG(3,("rpc: query_user sid=%s\n", sid_string_dbg(user_sid))); 469 470 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) 471 return NT_STATUS_UNSUCCESSFUL; 498 /* Get user info */ 499 status = dcerpc_samr_QueryUserInfo(b, 500 mem_ctx, 501 &user_policy, 502 0x15, 503 &info, 504 &result); 505 { 506 NTSTATUS _result; 507 dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result); 508 } 509 if (!NT_STATUS_IS_OK(status)) { 510 return status; 511 } 512 if (!NT_STATUS_IS_OK(result)) { 513 return result; 514 } 515 516 sid_compose(&user_info->user_sid, domain_sid, user_rid); 517 sid_compose(&user_info->group_sid, domain_sid, 518 info->info21.primary_gid); 519 520 user_info->acct_name = talloc_strdup(user_info, 521 info->info21.account_name.string); 522 if (user_info->acct_name == NULL) { 523 return NT_STATUS_NO_MEMORY; 524 } 525 526 user_info->full_name = talloc_strdup(user_info, 527 info->info21.full_name.string); 528 if ((info->info21.full_name.string != NULL) && 529 (user_info->acct_name == NULL)) 530 { 531 return NT_STATUS_NO_MEMORY; 532 } 472 533 473 534 user_info->homedir = NULL; … … 475 536 user_info->primary_gid = (gid_t)-1; 476 537 477 /* try netsamlogon cache first */ 478 479 if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL ) 480 { 481 482 DEBUG(5,("query_user: Cache lookup succeeded for %s\n", 483 sid_string_dbg(user_sid))); 484 485 sid_compose(&user_info->user_sid, &domain->sid, user->base.rid); 486 sid_compose(&user_info->group_sid, &domain->sid, 487 user->base.primary_gid); 488 489 user_info->acct_name = talloc_strdup(mem_ctx, 490 user->base.account_name.string); 491 user_info->full_name = talloc_strdup(mem_ctx, 492 user->base.full_name.string); 493 494 TALLOC_FREE(user); 495 496 return NT_STATUS_OK; 497 } 498 499 if ( !winbindd_can_contact_domain( domain ) ) { 500 DEBUG(10,("query_user: No incoming trust for domain %s\n", 501 domain->name)); 502 return NT_STATUS_OK; 503 } 504 505 /* no cache; hit the wire */ 506 507 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 508 if (!NT_STATUS_IS_OK(result)) 509 return result; 538 return NT_STATUS_OK; 539 } 540 541 /* Lookup groups a user is a member of. */ 542 NTSTATUS rpc_lookup_usergroups(TALLOC_CTX *mem_ctx, 543 struct rpc_pipe_client *samr_pipe, 544 struct policy_handle *samr_policy, 545 const struct dom_sid *domain_sid, 546 const struct dom_sid *user_sid, 547 uint32_t *pnum_groups, 548 struct dom_sid **puser_grpsids) 549 { 550 struct policy_handle user_policy; 551 struct samr_RidWithAttributeArray *rid_array = NULL; 552 struct dom_sid *user_grpsids = NULL; 553 uint32_t num_groups = 0, i; 554 uint32_t user_rid; 555 NTSTATUS status, result; 556 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 557 558 if (!sid_peek_check_rid(domain_sid, user_sid, &user_rid)) { 559 return NT_STATUS_UNSUCCESSFUL; 560 } 510 561 511 562 /* Get user handle */ 512 result = rpccli_samr_OpenUser(cli, mem_ctx, 513 &dom_pol, 563 status = dcerpc_samr_OpenUser(b, 564 mem_ctx, 565 samr_policy, 514 566 SEC_FLAG_MAXIMUM_ALLOWED, 515 567 user_rid, 516 &user_pol); 517 518 if (!NT_STATUS_IS_OK(result)) 568 &user_policy, 569 &result); 570 if (!NT_STATUS_IS_OK(status)) { 571 return status; 572 } 573 if (!NT_STATUS_IS_OK(result)) { 519 574 return result; 520 521 /* Get user info */ 522 result = rpccli_samr_QueryUserInfo(cli, mem_ctx, 523 &user_pol, 524 0x15, 525 &info); 526 527 rpccli_samr_Close(cli, mem_ctx, &user_pol); 528 529 if (!NT_STATUS_IS_OK(result)) 575 } 576 577 /* Query user rids */ 578 status = dcerpc_samr_GetGroupsForUser(b, 579 mem_ctx, 580 &user_policy, 581 &rid_array, 582 &result); 583 num_groups = rid_array->count; 584 585 { 586 NTSTATUS _result; 587 dcerpc_samr_Close(b, mem_ctx, &user_policy, &_result); 588 } 589 590 if (!NT_STATUS_IS_OK(status)) { 591 return status; 592 } 593 if (!NT_STATUS_IS_OK(result) || num_groups == 0) { 530 594 return result; 531 532 sid_compose(&user_info->user_sid, &domain->sid, user_rid); 533 sid_compose(&user_info->group_sid, &domain->sid, 534 info->info21.primary_gid); 535 user_info->acct_name = talloc_strdup(mem_ctx, 536 info->info21.account_name.string); 537 user_info->full_name = talloc_strdup(mem_ctx, 538 info->info21.full_name.string); 539 user_info->homedir = NULL; 540 user_info->shell = NULL; 541 user_info->primary_gid = (gid_t)-1; 595 } 596 597 user_grpsids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_groups); 598 if (user_grpsids == NULL) { 599 status = NT_STATUS_NO_MEMORY; 600 return status; 601 } 602 603 for (i = 0; i < num_groups; i++) { 604 sid_compose(&(user_grpsids[i]), domain_sid, 605 rid_array->rids[i].rid); 606 } 607 608 *pnum_groups = num_groups; 609 610 *puser_grpsids = user_grpsids; 542 611 543 612 return NT_STATUS_OK; 544 } 545 546 /* Lookup groups a user is a member of. I wish Unix had a call like this! */ 547 static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, 548 TALLOC_CTX *mem_ctx, 549 const DOM_SID *user_sid, 550 uint32 *num_groups, DOM_SID **user_grpsids) 551 { 552 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 553 struct policy_handle dom_pol, user_pol; 554 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED; 555 struct samr_RidWithAttributeArray *rid_array = NULL; 556 unsigned int i; 557 uint32 user_rid; 558 struct rpc_pipe_client *cli; 559 560 DEBUG(3,("rpc: lookup_usergroups sid=%s\n", sid_string_dbg(user_sid))); 561 562 if (!sid_peek_check_rid(&domain->sid, user_sid, &user_rid)) 563 return NT_STATUS_UNSUCCESSFUL; 564 565 *num_groups = 0; 566 *user_grpsids = NULL; 567 568 /* so lets see if we have a cached user_info_3 */ 569 result = lookup_usergroups_cached(domain, mem_ctx, user_sid, 570 num_groups, user_grpsids); 571 572 if (NT_STATUS_IS_OK(result)) { 573 return NT_STATUS_OK; 574 } 575 576 if ( !winbindd_can_contact_domain( domain ) ) { 577 DEBUG(10,("lookup_usergroups: No incoming trust for domain %s\n", 578 domain->name)); 579 580 /* Tell the cache manager not to remember this one */ 581 582 return NT_STATUS_SYNCHRONIZATION_REQUIRED; 583 } 584 585 /* no cache; hit the wire */ 586 587 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 588 if (!NT_STATUS_IS_OK(result)) 589 return result; 590 591 /* Get user handle */ 592 result = rpccli_samr_OpenUser(cli, mem_ctx, 593 &dom_pol, 594 des_access, 595 user_rid, 596 &user_pol); 597 598 if (!NT_STATUS_IS_OK(result)) 599 return result; 600 601 /* Query user rids */ 602 result = rpccli_samr_GetGroupsForUser(cli, mem_ctx, 603 &user_pol, 604 &rid_array); 605 *num_groups = rid_array->count; 606 607 rpccli_samr_Close(cli, mem_ctx, &user_pol); 608 609 if (!NT_STATUS_IS_OK(result) || (*num_groups) == 0) 610 return result; 611 612 (*user_grpsids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups); 613 if (!(*user_grpsids)) 614 return NT_STATUS_NO_MEMORY; 615 616 for (i=0;i<(*num_groups);i++) { 617 sid_copy(&((*user_grpsids)[i]), &domain->sid); 618 sid_append_rid(&((*user_grpsids)[i]), 619 rid_array->rids[i].rid); 620 } 621 622 return NT_STATUS_OK; 623 } 624 613 } 614 615 NTSTATUS rpc_lookup_useraliases(TALLOC_CTX *mem_ctx, 616 struct rpc_pipe_client *samr_pipe, 617 struct policy_handle *samr_policy, 618 uint32_t num_sids, 619 const struct dom_sid *sids, 620 uint32_t *pnum_aliases, 621 uint32_t **palias_rids) 622 { 625 623 #define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */ 626 627 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain, 628 TALLOC_CTX *mem_ctx, 629 uint32 num_sids, const DOM_SID *sids, 630 uint32 *num_aliases, 631 uint32 **alias_rids) 632 { 633 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 634 struct policy_handle dom_pol; 635 uint32 num_query_sids = 0; 636 int i; 637 struct rpc_pipe_client *cli; 624 uint32_t num_query_sids = 0; 625 uint32_t num_queries = 1; 626 uint32_t num_aliases = 0; 627 uint32_t total_sids = 0; 628 uint32_t *alias_rids = NULL; 629 uint32_t rangesize = MAX_SAM_ENTRIES_W2K; 630 uint32_t i; 638 631 struct samr_Ids alias_rids_query; 639 int rangesize = MAX_SAM_ENTRIES_W2K; 640 uint32 total_sids = 0; 641 int num_queries = 1; 642 643 *num_aliases = 0; 644 *alias_rids = NULL; 645 646 DEBUG(3,("rpc: lookup_useraliases\n")); 647 648 if ( !winbindd_can_contact_domain( domain ) ) { 649 DEBUG(10,("msrpc_lookup_useraliases: No incoming trust for domain %s\n", 650 domain->name)); 651 return NT_STATUS_OK; 652 } 653 654 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 655 if (!NT_STATUS_IS_OK(result)) 656 return result; 632 NTSTATUS status, result; 633 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 657 634 658 635 do { … … 664 641 num_query_sids = MIN(num_sids - total_sids, rangesize); 665 642 666 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n", 667 num_queries, num_query_sids)); 643 DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n", 644 num_queries, num_query_sids)); 668 645 669 646 if (num_query_sids) { … … 676 653 } 677 654 678 for (i=0; i<num_query_sids; i++) { 679 sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]); 680 if (!sid_array.sids[i].sid) { 681 TALLOC_FREE(sid_array.sids); 655 for (i = 0; i < num_query_sids; i++) { 656 sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[total_sids++]); 657 if (sid_array.sids[i].sid == NULL) { 682 658 return NT_STATUS_NO_MEMORY; 683 659 } … … 686 662 687 663 /* do request */ 688 result = rpccli_samr_GetAliasMembership(cli, mem_ctx, 689 &dom_pol, 664 status = dcerpc_samr_GetAliasMembership(b, 665 mem_ctx, 666 samr_policy, 690 667 &sid_array, 691 &alias_rids_query); 692 668 &alias_rids_query, 669 &result); 670 if (!NT_STATUS_IS_OK(status)) { 671 return status; 672 } 693 673 if (!NT_STATUS_IS_OK(result)) { 694 *num_aliases = 0; 695 *alias_rids = NULL; 696 TALLOC_FREE(sid_array.sids); 697 goto done; 674 return result; 698 675 } 699 676 700 677 /* process output */ 701 702 for (i=0; i<alias_rids_query.count; i++) {703 size_t na = *num_aliases; 704 if (!add_rid_to_array_unique(mem_ctx, alias_rids_query.ids[i],705 alias_rids, &na)) {706 return NT_STATUS_NO_MEMORY;707 }708 *num_aliases = na;709 }710 711 TALLOC_FREE(sid_array.sids);678 for (i = 0; i < alias_rids_query.count; i++) { 679 size_t na = num_aliases; 680 681 if (!add_rid_to_array_unique(mem_ctx, 682 alias_rids_query.ids[i], 683 &alias_rids, 684 &na)) { 685 return NT_STATUS_NO_MEMORY; 686 } 687 num_aliases = na; 688 } 712 689 713 690 num_queries++; … … 715 692 } while (total_sids < num_sids); 716 693 717 done: 718 DEBUG(10,("rpc: lookup_useraliases: got %d aliases in %d queries " 719 "(rangesize: %d)\n", *num_aliases, num_queries, rangesize)); 720 721 return result; 722 } 723 694 DEBUG(10,("rpc: rpc_lookup_useraliases: got %d aliases in %d queries " 695 "(rangesize: %d)\n", num_aliases, num_queries, rangesize)); 696 697 *pnum_aliases = num_aliases; 698 *palias_rids = alias_rids; 699 700 return NT_STATUS_OK; 701 #undef MAX_SAM_ENTRIES_W2K 702 } 724 703 725 704 /* Lookup group membership given a rid. */ 726 static NTSTATUS lookup_groupmem(struct winbindd_domain *domain, 727 TALLOC_CTX *mem_ctx, 728 const DOM_SID *group_sid, 729 enum lsa_SidType type, 730 uint32 *num_names, 731 DOM_SID **sid_mem, char ***names, 732 uint32 **name_types) 733 { 734 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 735 uint32 i, total_names = 0; 736 struct policy_handle dom_pol, group_pol; 737 uint32 des_access = SEC_FLAG_MAXIMUM_ALLOWED; 738 uint32 *rid_mem = NULL; 739 uint32 group_rid; 740 unsigned int j, r; 741 struct rpc_pipe_client *cli; 742 unsigned int orig_timeout; 743 struct samr_RidTypeArray *rids = NULL; 744 745 DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name, 746 sid_string_dbg(group_sid))); 747 748 if ( !winbindd_can_contact_domain( domain ) ) { 749 DEBUG(10,("lookup_groupmem: No incoming trust for domain %s\n", 750 domain->name)); 751 return NT_STATUS_OK; 752 } 753 754 if (!sid_peek_check_rid(&domain->sid, group_sid, &group_rid)) 705 NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx, 706 struct rpc_pipe_client *samr_pipe, 707 struct policy_handle *samr_policy, 708 const char *domain_name, 709 const struct dom_sid *domain_sid, 710 const struct dom_sid *group_sid, 711 enum lsa_SidType type, 712 uint32_t *pnum_names, 713 struct dom_sid **psid_mem, 714 char ***pnames, 715 uint32_t **pname_types) 716 { 717 struct policy_handle group_policy; 718 uint32_t group_rid; 719 uint32_t *rid_mem = NULL; 720 721 uint32_t num_names = 0; 722 uint32_t total_names = 0; 723 struct dom_sid *sid_mem = NULL; 724 char **names = NULL; 725 uint32_t *name_types = NULL; 726 727 struct lsa_Strings tmp_names; 728 struct samr_Ids tmp_types; 729 730 uint32_t j, r; 731 NTSTATUS status, result; 732 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 733 734 if (!sid_peek_check_rid(domain_sid, group_sid, &group_rid)) { 755 735 return NT_STATUS_UNSUCCESSFUL; 756 757 *num_names = 0; 758 759 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 760 if (!NT_STATUS_IS_OK(result)) 761 return result; 762 763 result = rpccli_samr_OpenGroup(cli, mem_ctx, 764 &dom_pol, 765 des_access, 766 group_rid, 767 &group_pol); 768 769 if (!NT_STATUS_IS_OK(result)) 770 return result; 771 772 /* Step #1: Get a list of user rids that are the members of the 773 group. */ 774 775 /* This call can take a long time - allow the server to time out. 776 35 seconds should do it. */ 777 778 orig_timeout = rpccli_set_timeout(cli, 35000); 779 780 result = rpccli_samr_QueryGroupMember(cli, mem_ctx, 781 &group_pol, 782 &rids); 783 784 /* And restore our original timeout. */ 785 rpccli_set_timeout(cli, orig_timeout); 786 787 rpccli_samr_Close(cli, mem_ctx, &group_pol); 788 789 if (!NT_STATUS_IS_OK(result)) 790 return result; 791 792 if (!rids || !rids->count) { 793 names = NULL; 794 name_types = NULL; 795 sid_mem = NULL; 796 return NT_STATUS_OK; 797 } 798 799 *num_names = rids->count; 800 rid_mem = rids->rids; 801 802 /* Step #2: Convert list of rids into list of usernames. Do this 803 in bunches of ~1000 to avoid crashing NT4. It looks like there 804 is a buffer overflow or something like that lurking around 805 somewhere. */ 806 807 #define MAX_LOOKUP_RIDS 900 808 809 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names); 810 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names); 811 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_names); 812 813 for (j=0;j<(*num_names);j++) 814 sid_compose(&(*sid_mem)[j], &domain->sid, rid_mem[j]); 815 816 if (*num_names>0 && (!*names || !*name_types)) 817 return NT_STATUS_NO_MEMORY; 818 819 for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) { 820 int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS); 821 struct lsa_Strings tmp_names; 822 struct samr_Ids tmp_types; 823 824 /* Lookup a chunk of rids */ 825 826 result = rpccli_samr_LookupRids(cli, mem_ctx, 827 &dom_pol, 828 num_lookup_rids, 829 &rid_mem[i], 830 &tmp_names, 831 &tmp_types); 832 833 /* see if we have a real error (and yes the 834 STATUS_SOME_UNMAPPED is the one returned from 2k) */ 835 836 if (!NT_STATUS_IS_OK(result) && 837 !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) 736 } 737 738 switch(type) { 739 case SID_NAME_DOM_GRP: 740 { 741 struct samr_RidAttrArray *rids = NULL; 742 743 status = dcerpc_samr_OpenGroup(b, 744 mem_ctx, 745 samr_policy, 746 SEC_FLAG_MAXIMUM_ALLOWED, 747 group_rid, 748 &group_policy, 749 &result); 750 if (!NT_STATUS_IS_OK(status)) { 751 return status; 752 } 753 if (!NT_STATUS_IS_OK(result)) { 838 754 return result; 839 840 /* Copy result into array. The talloc system will take 841 care of freeing the temporary arrays later on. */ 842 843 if (tmp_names.count != tmp_types.count) { 844 return NT_STATUS_UNSUCCESSFUL; 845 } 846 847 for (r=0; r<tmp_names.count; r++) { 848 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) { 849 continue; 850 } 851 (*names)[total_names] = fill_domain_username_talloc( 852 mem_ctx, domain->name, 853 tmp_names.names[r].string, true); 854 (*name_types)[total_names] = tmp_types.ids[r]; 855 total_names += 1; 856 } 857 } 858 859 *num_names = total_names; 755 } 756 757 /* 758 * Step #1: Get a list of user rids that are the members of the group. 759 */ 760 status = dcerpc_samr_QueryGroupMember(b, 761 mem_ctx, 762 &group_policy, 763 &rids, 764 &result); 765 { 766 NTSTATUS _result; 767 dcerpc_samr_Close(b, mem_ctx, &group_policy, &_result); 768 } 769 770 if (!NT_STATUS_IS_OK(status)) { 771 return status; 772 } 773 if (!NT_STATUS_IS_OK(result)) { 774 return result; 775 } 776 777 778 if (rids == NULL || rids->count == 0) { 779 pnum_names = 0; 780 pnames = NULL; 781 pname_types = NULL; 782 psid_mem = NULL; 783 784 return NT_STATUS_OK; 785 } 786 787 num_names = rids->count; 788 rid_mem = rids->rids; 789 790 break; 791 } 792 case SID_NAME_WKN_GRP: 793 case SID_NAME_ALIAS: 794 { 795 struct lsa_SidArray sid_array; 796 struct lsa_SidPtr sid_ptr; 797 struct samr_Ids rids_query; 798 799 sid_ptr.sid = dom_sid_dup(mem_ctx, group_sid); 800 if (sid_ptr.sid == NULL) { 801 return NT_STATUS_NO_MEMORY; 802 } 803 804 sid_array.num_sids = 1; 805 sid_array.sids = &sid_ptr; 806 807 status = dcerpc_samr_GetAliasMembership(b, 808 mem_ctx, 809 samr_policy, 810 &sid_array, 811 &rids_query, 812 &result); 813 if (!NT_STATUS_IS_OK(status)) { 814 return status; 815 } 816 if (!NT_STATUS_IS_OK(result)) { 817 return result; 818 } 819 820 if (rids_query.count == 0) { 821 pnum_names = 0; 822 pnames = NULL; 823 pname_types = NULL; 824 psid_mem = NULL; 825 826 return NT_STATUS_OK; 827 } 828 829 num_names = rids_query.count; 830 rid_mem = rids_query.ids; 831 832 break; 833 } 834 default: 835 return NT_STATUS_UNSUCCESSFUL; 836 } 837 838 /* 839 * Step #2: Convert list of rids into list of usernames. 840 */ 841 if (num_names > 0) { 842 names = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_names); 843 name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32_t, num_names); 844 sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_names); 845 if (names == NULL || name_types == NULL || sid_mem == NULL) { 846 return NT_STATUS_NO_MEMORY; 847 } 848 } 849 850 for (j = 0; j < num_names; j++) { 851 sid_compose(&sid_mem[j], domain_sid, rid_mem[j]); 852 } 853 854 status = dcerpc_samr_LookupRids(b, 855 mem_ctx, 856 samr_policy, 857 num_names, 858 rid_mem, 859 &tmp_names, 860 &tmp_types, 861 &result); 862 if (!NT_STATUS_IS_OK(status)) { 863 return status; 864 } 865 866 if (!NT_STATUS_IS_OK(result)) { 867 if (!NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) { 868 return result; 869 } 870 } 871 872 /* Copy result into array. The talloc system will take 873 care of freeing the temporary arrays later on. */ 874 if (tmp_names.count != tmp_types.count) { 875 return NT_STATUS_UNSUCCESSFUL; 876 } 877 878 for (r = 0; r < tmp_names.count; r++) { 879 if (tmp_types.ids[r] == SID_NAME_UNKNOWN) { 880 continue; 881 } 882 names[total_names] = fill_domain_username_talloc(names, 883 domain_name, 884 tmp_names.names[r].string, 885 true); 886 if (names[total_names] == NULL) { 887 return NT_STATUS_NO_MEMORY; 888 } 889 name_types[total_names] = tmp_types.ids[r]; 890 total_names++; 891 } 892 893 *pnum_names = total_names; 894 *pnames = names; 895 *pname_types = name_types; 896 *psid_mem = sid_mem; 860 897 861 898 return NT_STATUS_OK; 862 899 } 863 900 864 #ifdef HAVE_LDAP 865 866 #include <ldap.h> 867 868 static int get_ldap_seq(const char *server, int port, uint32 *seq) 869 { 870 int ret = -1; 871 struct timeval to; 872 const char *attrs[] = {"highestCommittedUSN", NULL}; 873 LDAPMessage *res = NULL; 874 char **values = NULL; 875 LDAP *ldp = NULL; 876 877 *seq = DOM_SEQUENCE_NONE; 878 879 /* 880 * Parameterised (5) second timeout on open. This is needed as the 881 * search timeout doesn't seem to apply to doing an open as well. JRA. 882 */ 883 884 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout()); 885 if (ldp == NULL) 886 return -1; 887 888 /* Timeout if no response within 20 seconds. */ 889 to.tv_sec = 10; 890 to.tv_usec = 0; 891 892 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)", 893 CONST_DISCARD(char **, attrs), 0, &to, &res)) 894 goto done; 895 896 if (ldap_count_entries(ldp, res) != 1) 897 goto done; 898 899 values = ldap_get_values(ldp, res, "highestCommittedUSN"); 900 if (!values || !values[0]) 901 goto done; 902 903 *seq = atoi(values[0]); 904 ret = 0; 905 906 done: 907 908 if (values) 909 ldap_value_free(values); 910 if (res) 911 ldap_msgfree(res); 912 if (ldp) 913 ldap_unbind(ldp); 914 return ret; 915 } 916 917 /********************************************************************** 918 Get the sequence number for a Windows AD native mode domain using 919 LDAP queries. 920 **********************************************************************/ 921 922 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq) 923 { 924 int ret = -1; 925 char addr[INET6_ADDRSTRLEN]; 926 927 print_sockaddr(addr, sizeof(addr), &domain->dcaddr); 928 if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) { 929 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence " 930 "number for Domain (%s) from DC (%s)\n", 931 domain->name, addr)); 932 } 933 return ret; 934 } 935 936 #endif /* HAVE_LDAP */ 937 938 /* find the sequence number for a domain */ 939 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq) 940 { 941 TALLOC_CTX *mem_ctx; 901 /* Find the sequence number for a domain */ 902 NTSTATUS rpc_sequence_number(TALLOC_CTX *mem_ctx, 903 struct rpc_pipe_client *samr_pipe, 904 struct policy_handle *samr_policy, 905 const char *domain_name, 906 uint32_t *pseq) 907 { 942 908 union samr_DomainInfo *info = NULL; 943 NTSTATUS result; 944 struct policy_handle dom_pol; 945 bool got_seq_num = False; 946 struct rpc_pipe_client *cli; 947 948 DEBUG(10,("rpc: fetch sequence_number for %s\n", domain->name)); 949 950 if ( !winbindd_can_contact_domain( domain ) ) { 951 DEBUG(10,("sequence_number: No incoming trust for domain %s\n", 952 domain->name)); 953 *seq = time(NULL); 954 return NT_STATUS_OK; 955 } 956 957 *seq = DOM_SEQUENCE_NONE; 958 959 if (!(mem_ctx = talloc_init("sequence_number[rpc]"))) 960 return NT_STATUS_NO_MEMORY; 961 962 #ifdef HAVE_LDAP 963 if ( domain->active_directory ) 964 { 965 int res; 966 967 DEBUG(8,("using get_ldap_seq() to retrieve the " 968 "sequence number\n")); 969 970 res = get_ldap_sequence_number( domain, seq ); 971 if (res == 0) 972 { 973 result = NT_STATUS_OK; 974 DEBUG(10,("domain_sequence_number: LDAP for " 975 "domain %s is %u\n", 976 domain->name, *seq)); 977 goto done; 978 } 979 980 DEBUG(10,("domain_sequence_number: failed to get LDAP " 981 "sequence number for domain %s\n", 982 domain->name )); 983 } 984 #endif /* HAVE_LDAP */ 985 986 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 987 if (!NT_STATUS_IS_OK(result)) { 988 goto done; 989 } 990 991 /* Query domain info */ 992 993 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx, 994 &dom_pol, 909 bool got_seq_num = false; 910 NTSTATUS status, result; 911 struct dcerpc_binding_handle *b = samr_pipe->binding_handle; 912 913 /* query domain info */ 914 status = dcerpc_samr_QueryDomainInfo(b, 915 mem_ctx, 916 samr_policy, 995 917 8, 996 &info );997 998 if (NT_STATUS_IS_OK( result)) {999 * seq = info->info8.sequence_num;1000 got_seq_num = True;918 &info, 919 &result); 920 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) { 921 *pseq = info->info8.sequence_num; 922 got_seq_num = true; 1001 923 goto seq_num; 1002 924 } … … 1004 926 /* retry with info-level 2 in case the dc does not support info-level 8 1005 927 * (like all older samba2 and samba3 dc's) - Guenther */ 1006 1007 result = rpccli_samr_QueryDomainInfo(cli,mem_ctx,1008 &dom_pol,928 status = dcerpc_samr_QueryDomainInfo(b, 929 mem_ctx, 930 samr_policy, 1009 931 2, 1010 &info); 1011 1012 if (NT_STATUS_IS_OK(result)) { 1013 *seq = info->general.sequence_num; 1014 got_seq_num = True; 1015 } 1016 1017 seq_num: 932 &info, 933 &result); 934 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) { 935 *pseq = info->general.sequence_num; 936 got_seq_num = true; 937 goto seq_num; 938 } 939 940 if (!NT_STATUS_IS_OK(status)) { 941 goto seq_num; 942 } 943 944 status = result; 945 946 seq_num: 1018 947 if (got_seq_num) { 1019 948 DEBUG(10,("domain_sequence_number: for domain %s is %u\n", 1020 domain ->name, (unsigned)*seq));949 domain_name, (unsigned) *pseq)); 1021 950 } else { 1022 951 DEBUG(10,("domain_sequence_number: failed to get sequence " 1023 952 "number (%u) for domain %s\n", 1024 (unsigned)*seq, domain->name )); 1025 } 1026 1027 done: 1028 1029 talloc_destroy(mem_ctx); 1030 1031 return result; 1032 } 1033 1034 /* get a list of trusted domains */ 1035 static NTSTATUS trusted_domains(struct winbindd_domain *domain, 1036 TALLOC_CTX *mem_ctx, 1037 struct netr_DomainTrustList *trusts) 1038 { 1039 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 1040 uint32 enum_ctx = 0; 1041 struct rpc_pipe_client *cli; 1042 struct policy_handle lsa_policy; 1043 1044 DEBUG(3,("rpc: trusted_domains\n")); 1045 1046 ZERO_STRUCTP(trusts); 1047 1048 result = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); 1049 if (!NT_STATUS_IS_OK(result)) 1050 return result; 1051 1052 result = STATUS_MORE_ENTRIES; 1053 1054 while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 1055 uint32 start_idx; 1056 int i; 953 (unsigned) *pseq, domain_name )); 954 status = NT_STATUS_OK; 955 } 956 957 return status; 958 } 959 960 /* Get a list of trusted domains */ 961 NTSTATUS rpc_trusted_domains(TALLOC_CTX *mem_ctx, 962 struct rpc_pipe_client *lsa_pipe, 963 struct policy_handle *lsa_policy, 964 uint32_t *pnum_trusts, 965 struct netr_DomainTrust **ptrusts) 966 { 967 struct netr_DomainTrust *array = NULL; 968 uint32_t enum_ctx = 0; 969 uint32_t count = 0; 970 NTSTATUS status, result; 971 struct dcerpc_binding_handle *b = lsa_pipe->binding_handle; 972 973 do { 1057 974 struct lsa_DomainList dom_list; 1058 1059 result = rpccli_lsa_EnumTrustDom(cli, mem_ctx, 1060 &lsa_policy, 975 uint32_t start_idx; 976 uint32_t i; 977 978 /* 979 * We don't run into deadlocks here, cause winbind_off() is 980 * called in the main function. 981 */ 982 status = dcerpc_lsa_EnumTrustDom(b, 983 mem_ctx, 984 lsa_policy, 1061 985 &enum_ctx, 1062 986 &dom_list, 1063 (uint32_t)-1); 1064 1065 if (!NT_STATUS_IS_OK(result) && 1066 !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) 1067 break; 1068 1069 start_idx = trusts->count; 1070 trusts->count += dom_list.count; 1071 1072 trusts->array = talloc_realloc( 1073 mem_ctx, trusts->array, struct netr_DomainTrust, 1074 trusts->count); 1075 if (trusts->array == NULL) { 987 (uint32_t) -1, 988 &result); 989 if (!NT_STATUS_IS_OK(status)) { 990 return status; 991 } 992 if (!NT_STATUS_IS_OK(result)) { 993 if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 994 return result; 995 } 996 } 997 998 start_idx = count; 999 count += dom_list.count; 1000 1001 array = talloc_realloc(mem_ctx, 1002 array, 1003 struct netr_DomainTrust, 1004 count); 1005 if (array == NULL) { 1076 1006 return NT_STATUS_NO_MEMORY; 1077 1007 } 1078 1008 1079 for (i =0; i<dom_list.count; i++) {1080 struct netr_DomainTrust *trust = & trusts->array[i];1009 for (i = 0; i < dom_list.count; i++) { 1010 struct netr_DomainTrust *trust = &array[i]; 1081 1011 struct dom_sid *sid; 1082 1012 1083 1013 ZERO_STRUCTP(trust); 1084 1014 1085 trust->netbios_name = talloc_move( 1086 trusts->array, 1087 &dom_list.domains[i].name.string); 1015 trust->netbios_name = talloc_move(array, 1016 &dom_list.domains[i].name.string); 1088 1017 trust->dns_name = NULL; 1089 1018 1090 sid = talloc( trusts->array, struct dom_sid);1019 sid = talloc(array, struct dom_sid); 1091 1020 if (sid == NULL) { 1092 1021 return NT_STATUS_NO_MEMORY; … … 1095 1024 trust->sid = sid; 1096 1025 } 1097 } 1026 } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); 1027 1028 *pnum_trusts = count; 1029 *ptrusts = array; 1030 1031 return NT_STATUS_OK; 1032 } 1033 1034 static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx, 1035 struct winbindd_domain *domain, 1036 struct lsa_SidArray *sids, 1037 struct lsa_RefDomainList **pdomains, 1038 struct lsa_TransNameArray **pnames) 1039 { 1040 struct lsa_TransNameArray2 lsa_names2; 1041 struct lsa_TransNameArray *names; 1042 uint32_t i, count; 1043 struct rpc_pipe_client *cli; 1044 NTSTATUS status, result; 1045 1046 status = cm_connect_lsa_tcp(domain, talloc_tos(), &cli); 1047 if (!NT_STATUS_IS_OK(status)) { 1048 domain->can_do_ncacn_ip_tcp = false; 1049 return status; 1050 } 1051 1052 ZERO_STRUCT(lsa_names2); 1053 status = dcerpc_lsa_LookupSids3(cli->binding_handle, 1054 mem_ctx, 1055 sids, 1056 pdomains, 1057 &lsa_names2, 1058 LSA_LOOKUP_NAMES_ALL, 1059 &count, 1060 LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES, 1061 LSA_CLIENT_REVISION_2, 1062 &result); 1063 if (!NT_STATUS_IS_OK(status)) { 1064 return status; 1065 } 1066 if (NT_STATUS_IS_ERR(result)) { 1067 return result; 1068 } 1069 names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray); 1070 if (names == NULL) { 1071 return NT_STATUS_NO_MEMORY; 1072 } 1073 names->count = lsa_names2.count; 1074 names->names = talloc_array(names, struct lsa_TranslatedName, 1075 names->count); 1076 if (names->names == NULL) { 1077 return NT_STATUS_NO_MEMORY; 1078 } 1079 for (i=0; i<names->count; i++) { 1080 names->names[i].sid_type = lsa_names2.names[i].sid_type; 1081 names->names[i].name.string = talloc_move( 1082 names->names, &lsa_names2.names[i].name.string); 1083 names->names[i].sid_index = lsa_names2.names[i].sid_index; 1084 } 1085 *pnames = names; 1098 1086 return result; 1099 1087 } 1100 1088 1101 /* find the lockout policy for a domain */ 1102 static NTSTATUS msrpc_lockout_policy(struct winbindd_domain *domain, 1103 TALLOC_CTX *mem_ctx, 1104 struct samr_DomInfo12 *lockout_policy) 1105 { 1106 NTSTATUS result; 1107 struct rpc_pipe_client *cli; 1108 struct policy_handle dom_pol; 1109 union samr_DomainInfo *info = NULL; 1110 1111 DEBUG(10,("rpc: fetch lockout policy for %s\n", domain->name)); 1112 1113 if ( !winbindd_can_contact_domain( domain ) ) { 1114 DEBUG(10,("msrpc_lockout_policy: No incoming trust for domain %s\n", 1115 domain->name)); 1116 return NT_STATUS_NOT_SUPPORTED; 1117 } 1118 1119 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 1120 if (!NT_STATUS_IS_OK(result)) { 1121 goto done; 1122 } 1123 1124 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx, 1125 &dom_pol, 1126 12, 1127 &info); 1128 if (!NT_STATUS_IS_OK(result)) { 1129 goto done; 1130 } 1131 1132 *lockout_policy = info->info12; 1133 1134 DEBUG(10,("msrpc_lockout_policy: lockout_threshold %d\n", 1135 info->info12.lockout_threshold)); 1136 1137 done: 1138 1139 return result; 1140 } 1141 1142 /* find the password policy for a domain */ 1143 static NTSTATUS msrpc_password_policy(struct winbindd_domain *domain, 1144 TALLOC_CTX *mem_ctx, 1145 struct samr_DomInfo1 *password_policy) 1146 { 1147 NTSTATUS result; 1148 struct rpc_pipe_client *cli; 1149 struct policy_handle dom_pol; 1150 union samr_DomainInfo *info = NULL; 1151 1152 DEBUG(10,("rpc: fetch password policy for %s\n", domain->name)); 1153 1154 if ( !winbindd_can_contact_domain( domain ) ) { 1155 DEBUG(10,("msrpc_password_policy: No incoming trust for domain %s\n", 1156 domain->name)); 1157 return NT_STATUS_NOT_SUPPORTED; 1158 } 1159 1160 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol); 1161 if (!NT_STATUS_IS_OK(result)) { 1162 goto done; 1163 } 1164 1165 result = rpccli_samr_QueryDomainInfo(cli, mem_ctx, 1166 &dom_pol, 1167 1, 1168 &info); 1169 if (!NT_STATUS_IS_OK(result)) { 1170 goto done; 1171 } 1172 1173 *password_policy = info->info1; 1174 1175 DEBUG(10,("msrpc_password_policy: min_length_password %d\n", 1176 info->info1.min_password_length)); 1177 1178 done: 1179 1180 return result; 1181 } 1182 1183 typedef NTSTATUS (*lookup_sids_fn_t)(struct rpc_pipe_client *cli, 1184 TALLOC_CTX *mem_ctx, 1185 struct policy_handle *pol, 1186 int num_sids, 1187 const DOM_SID *sids, 1188 char ***pdomains, 1189 char ***pnames, 1190 enum lsa_SidType **ptypes); 1191 1192 NTSTATUS winbindd_lookup_sids(TALLOC_CTX *mem_ctx, 1193 struct winbindd_domain *domain, 1194 uint32_t num_sids, 1195 const struct dom_sid *sids, 1196 char ***domains, 1197 char ***names, 1198 enum lsa_SidType **types) 1199 { 1200 NTSTATUS status; 1089 NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx, 1090 struct winbindd_domain *domain, 1091 struct lsa_SidArray *sids, 1092 struct lsa_RefDomainList **pdomains, 1093 struct lsa_TransNameArray **pnames) 1094 { 1095 struct lsa_TransNameArray *names; 1201 1096 struct rpc_pipe_client *cli = NULL; 1202 1097 struct policy_handle lsa_policy; 1203 u nsigned int orig_timeout;1204 lookup_sids_fn_t lookup_sids_fn = rpccli_lsa_lookup_sids;1098 uint32_t count; 1099 NTSTATUS status, result; 1205 1100 1206 1101 if (domain->can_do_ncacn_ip_tcp) { 1207 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli);1208 if (NT_STATUS_IS_OK(status)) {1209 lookup_sids_fn = rpccli_lsa_lookup_sids3;1210 goto lookup;1211 } 1212 domain->can_do_ncacn_ip_tcp = false;1213 } 1102 status = rpc_try_lookup_sids3(mem_ctx, domain, sids, 1103 pdomains, pnames); 1104 if (!NT_STATUS_IS_ERR(status)) { 1105 return status; 1106 } 1107 } 1108 1214 1109 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); 1215 1216 1110 if (!NT_STATUS_IS_OK(status)) { 1217 1111 return status; 1218 1112 } 1219 1113 1220 lookup: 1221 /* 1222 * This call can take a long time 1223 * allow the server to time out. 1224 * 35 seconds should do it. 1225 */ 1226 orig_timeout = rpccli_set_timeout(cli, 35000); 1227 1228 status = lookup_sids_fn(cli, 1229 mem_ctx, 1230 &lsa_policy, 1231 num_sids, 1232 sids, 1233 domains, 1234 names, 1235 types); 1236 1237 /* And restore our original timeout. */ 1238 rpccli_set_timeout(cli, orig_timeout); 1239 1240 if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED || 1241 NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) { 1242 /* 1243 * This can happen if the schannel key is not 1244 * valid anymore, we need to invalidate the 1245 * all connections to the dc and reestablish 1246 * a netlogon connection first. 1247 */ 1248 invalidate_cm_connection(&domain->conn); 1249 status = NT_STATUS_ACCESS_DENIED; 1250 } 1251 1114 names = TALLOC_ZERO_P(mem_ctx, struct lsa_TransNameArray); 1115 if (names == NULL) { 1116 return NT_STATUS_NO_MEMORY; 1117 } 1118 status = dcerpc_lsa_LookupSids(cli->binding_handle, mem_ctx, 1119 &lsa_policy, sids, pdomains, 1120 names, LSA_LOOKUP_NAMES_ALL, 1121 &count, &result); 1252 1122 if (!NT_STATUS_IS_OK(status)) { 1253 1123 return status; 1254 1124 } 1255 1256 return status; 1257 } 1258 1259 typedef NTSTATUS (*lookup_names_fn_t)(struct rpc_pipe_client *cli, 1260 TALLOC_CTX *mem_ctx, 1261 struct policy_handle *pol, 1262 int num_names, 1263 const char **names, 1264 const char ***dom_names, 1265 int level, 1266 struct dom_sid **sids, 1267 enum lsa_SidType **types); 1268 1269 NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, 1270 struct winbindd_domain *domain, 1271 uint32_t num_names, 1272 const char **names, 1273 const char ***domains, 1274 struct dom_sid **sids, 1275 enum lsa_SidType **types) 1276 { 1277 NTSTATUS status; 1278 struct rpc_pipe_client *cli = NULL; 1279 struct policy_handle lsa_policy; 1280 unsigned int orig_timeout = 0; 1281 lookup_names_fn_t lookup_names_fn = rpccli_lsa_lookup_names; 1282 1283 if (domain->can_do_ncacn_ip_tcp) { 1284 status = cm_connect_lsa_tcp(domain, mem_ctx, &cli); 1285 if (NT_STATUS_IS_OK(status)) { 1286 lookup_names_fn = rpccli_lsa_lookup_names4; 1287 goto lookup; 1288 } 1289 domain->can_do_ncacn_ip_tcp = false; 1290 } 1291 status = cm_connect_lsa(domain, mem_ctx, &cli, &lsa_policy); 1292 1293 if (!NT_STATUS_IS_OK(status)) { 1294 return status; 1295 } 1296 1297 lookup: 1298 1299 /* 1300 * This call can take a long time 1301 * allow the server to time out. 1302 * 35 seconds should do it. 1303 */ 1304 orig_timeout = rpccli_set_timeout(cli, 35000); 1305 1306 status = lookup_names_fn(cli, 1307 mem_ctx, 1308 &lsa_policy, 1309 num_names, 1310 (const char **) names, 1311 domains, 1312 1, 1313 sids, 1314 types); 1315 1316 /* And restore our original timeout. */ 1317 rpccli_set_timeout(cli, orig_timeout); 1318 1319 if (NT_STATUS_V(status) == DCERPC_FAULT_ACCESS_DENIED || 1320 NT_STATUS_V(status) == DCERPC_FAULT_SEC_PKG_ERROR) { 1321 /* 1322 * This can happen if the schannel key is not 1323 * valid anymore, we need to invalidate the 1324 * all connections to the dc and reestablish 1325 * a netlogon connection first. 1326 */ 1327 invalidate_cm_connection(&domain->conn); 1328 status = NT_STATUS_ACCESS_DENIED; 1329 } 1330 1331 if (!NT_STATUS_IS_OK(status)) { 1332 return status; 1333 } 1334 1335 return status; 1336 } 1337 1338 /* the rpc backend methods are exposed via this structure */ 1339 struct winbindd_methods msrpc_methods = { 1340 False, 1341 query_user_list, 1342 enum_dom_groups, 1343 enum_local_groups, 1344 msrpc_name_to_sid, 1345 msrpc_sid_to_name, 1346 msrpc_rids_to_names, 1347 query_user, 1348 lookup_usergroups, 1349 msrpc_lookup_useraliases, 1350 lookup_groupmem, 1351 sequence_number, 1352 msrpc_lockout_policy, 1353 msrpc_password_policy, 1354 trusted_domains, 1355 }; 1125 if (NT_STATUS_IS_ERR(result)) { 1126 return result; 1127 } 1128 *pnames = names; 1129 return result; 1130 } -
vendor/current/source3/winbindd/winbindd_show_sequence.c
r414 r740 98 98 status = wb_seqnum_recv(subreq, &state->seqnum); 99 99 TALLOC_FREE(subreq); 100 if (!NT_STATUS_IS_OK(status)) { 101 tevent_req_nterror(req, status); 100 if (tevent_req_nterror(req, status)) { 102 101 return; 103 102 } … … 117 116 &state->seqnums); 118 117 TALLOC_FREE(subreq); 119 if (!NT_STATUS_IS_OK(status)) { 120 tevent_req_nterror(req, status); 118 if (tevent_req_nterror(req, status)) { 121 119 return; 122 120 } -
vendor/current/source3/winbindd/winbindd_sid_to_gid.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "../libcli/security/security.h" 22 23 23 24 struct winbindd_sid_to_gid_state { … … 72 73 status = wb_sid2gid_recv(subreq, &state->gid); 73 74 TALLOC_FREE(subreq); 74 if (!NT_STATUS_IS_OK(status)) { 75 tevent_req_nterror(req, status); 75 if (tevent_req_nterror(req, status)) { 76 76 return; 77 77 } -
vendor/current/source3/winbindd/winbindd_sid_to_uid.c
r414 r740 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "../libcli/security/security.h" 22 23 23 24 struct winbindd_sid_to_uid_state { … … 72 73 status = wb_sid2uid_recv(subreq, &state->uid); 73 74 TALLOC_FREE(subreq); 74 if (!NT_STATUS_IS_OK(status)) { 75 tevent_req_nterror(req, status); 75 if (tevent_req_nterror(req, status)) { 76 76 return; 77 77 } -
vendor/current/source3/winbindd/winbindd_uid_to_sid.c
r414 r740 64 64 status = wb_uid2sid_recv(subreq, &state->sid); 65 65 TALLOC_FREE(subreq); 66 if (!NT_STATUS_IS_OK(status)) { 67 tevent_req_nterror(req, status); 66 if (tevent_req_nterror(req, status)) { 68 67 return; 69 68 } -
vendor/current/source3/winbindd/winbindd_util.c
r478 r740 23 23 #include "includes.h" 24 24 #include "winbindd.h" 25 #include "secrets.h" 26 #include "../libcli/security/security.h" 27 #include "../libcli/auth/pam_errors.h" 28 #include "passdb/machine_sid.h" 25 29 26 30 #undef DBGC_CLASS … … 28 32 29 33 extern struct winbindd_methods cache_methods; 30 extern struct winbindd_methods builtin_passdb_methods;31 extern struct winbindd_methods sam_passdb_methods;32 33 34 34 35 /** 35 * @file winbindd_util.c 36 * @file winbindd_util.cq 36 37 * 37 38 * Winbind daemon for NT domain authentication nss module. … … 59 60 /* Free all entries in the trusted domain list */ 60 61 61 void free_domain_list(void)62 static void free_domain_list(void) 62 63 { 63 64 struct winbindd_domain *domain = _domain_list; … … 72 73 } 73 74 74 static bool is_internal_domain(const DOM_SID*sid)75 static bool is_internal_domain(const struct dom_sid *sid) 75 76 { 76 77 if (sid == NULL) … … 80 81 } 81 82 82 static bool is_in_internal_domain(const DOM_SID*sid)83 static bool is_in_internal_domain(const struct dom_sid *sid) 83 84 { 84 85 if (sid == NULL) … … 92 93 static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name, 93 94 struct winbindd_methods *methods, 94 const DOM_SID*sid)95 const struct dom_sid *sid) 95 96 { 96 97 struct winbindd_domain *domain; … … 138 139 } 139 140 140 if ( sid_equal(sid, &domain->sid)) {141 if (dom_sid_equal(sid, &domain->sid)) { 141 142 break; 142 143 } … … 144 145 } 145 146 146 /* See if we found a match. Check if we need to update the 147 SID. */ 148 149 if ( domain && sid) { 150 if ( sid_equal( &domain->sid, &global_sid_NULL ) ) 147 if (domain != NULL) { 148 /* 149 * We found a match. Possibly update the SID 150 */ 151 if ((sid != NULL) 152 && dom_sid_equal(&domain->sid, &global_sid_NULL)) { 151 153 sid_copy( &domain->sid, sid ); 152 154 } 153 155 return domain; 154 156 } … … 162 164 163 165 ZERO_STRUCTP(domain); 166 167 domain->children = SMB_MALLOC_ARRAY( 168 struct winbindd_child, lp_winbind_max_domain_connections()); 169 if (domain->children == NULL) { 170 SAFE_FREE(domain); 171 return NULL; 172 } 173 memset(domain->children, 0, 174 sizeof(struct winbindd_child) 175 * lp_winbind_max_domain_connections()); 164 176 165 177 fstrcpy(domain->name, domain_name); … … 224 236 } 225 237 238 bool domain_is_forest_root(const struct winbindd_domain *domain) 239 { 240 const uint32_t fr_flags = 241 (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST); 242 243 return ((domain->domain_flags & fr_flags) == fr_flags); 244 } 245 226 246 /******************************************************************** 227 247 rescan our domains looking for new trusted domains … … 229 249 230 250 struct trustdom_state { 231 TALLOC_CTX *mem_ctx; 232 bool primary; 233 bool forest_root; 234 struct winbindd_response *response; 251 struct winbindd_domain *domain; 252 struct winbindd_request request; 235 253 }; 236 254 237 static void trustdom_ recv(void *private_data, bool success);255 static void trustdom_list_done(struct tevent_req *req); 238 256 static void rescan_forest_root_trusts( void ); 239 257 static void rescan_forest_trusts( void ); … … 241 259 static void add_trusted_domains( struct winbindd_domain *domain ) 242 260 { 243 TALLOC_CTX *mem_ctx; 244 struct winbindd_request *request; 261 struct trustdom_state *state; 262 struct tevent_req *req; 263 264 state = TALLOC_ZERO_P(NULL, struct trustdom_state); 265 if (state == NULL) { 266 DEBUG(0, ("talloc failed\n")); 267 return; 268 } 269 state->domain = domain; 270 271 state->request.length = sizeof(state->request); 272 state->request.cmd = WINBINDD_LIST_TRUSTDOM; 273 274 req = wb_domain_request_send(state, winbind_event_context(), 275 domain, &state->request); 276 if (req == NULL) { 277 DEBUG(1, ("wb_domain_request_send failed\n")); 278 TALLOC_FREE(state); 279 return; 280 } 281 tevent_req_set_callback(req, trustdom_list_done, state); 282 } 283 284 static void trustdom_list_done(struct tevent_req *req) 285 { 286 struct trustdom_state *state = tevent_req_callback_data( 287 req, struct trustdom_state); 245 288 struct winbindd_response *response; 246 uint32 fr_flags = (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST); 247 248 struct trustdom_state *state; 249 250 mem_ctx = talloc_init("add_trusted_domains"); 251 if (mem_ctx == NULL) { 252 DEBUG(0, ("talloc_init failed\n")); 253 return; 254 } 255 256 request = TALLOC_ZERO_P(mem_ctx, struct winbindd_request); 257 response = TALLOC_P(mem_ctx, struct winbindd_response); 258 state = TALLOC_P(mem_ctx, struct trustdom_state); 259 260 if ((request == NULL) || (response == NULL) || (state == NULL)) { 261 DEBUG(0, ("talloc failed\n")); 262 talloc_destroy(mem_ctx); 263 return; 264 } 265 266 state->mem_ctx = mem_ctx; 267 state->response = response; 268 269 /* Flags used to know how to continue the forest trust search */ 270 271 state->primary = domain->primary; 272 state->forest_root = ((domain->domain_flags & fr_flags) == fr_flags ); 273 274 request->length = sizeof(*request); 275 request->cmd = WINBINDD_LIST_TRUSTDOM; 276 277 async_domain_request(mem_ctx, domain, request, response, 278 trustdom_recv, state); 279 } 280 281 static void trustdom_recv(void *private_data, bool success) 282 { 283 struct trustdom_state *state = 284 talloc_get_type_abort(private_data, struct trustdom_state); 285 struct winbindd_response *response = state->response; 289 int res, err; 286 290 char *p; 287 291 288 if ((!success) || (response->result != WINBINDD_OK)) { 292 res = wb_domain_request_recv(req, state, &response, &err); 293 if ((res == -1) || (response->result != WINBINDD_OK)) { 289 294 DEBUG(1, ("Could not receive trustdoms\n")); 290 talloc_destroy(state->mem_ctx);295 TALLOC_FREE(state); 291 296 return; 292 297 } … … 296 301 while ((p != NULL) && (*p != '\0')) { 297 302 char *q, *sidstr, *alt_name; 298 DOM_SIDsid;303 struct dom_sid sid; 299 304 struct winbindd_domain *domain; 300 305 char *alternate_name = NULL; … … 346 351 &sid); 347 352 if (domain) { 348 setup_domain_child(domain, 349 &domain->child); 353 setup_domain_child(domain); 350 354 } 351 355 } … … 363 367 */ 364 368 365 if ( state->primary) {369 if (state->domain->primary) { 366 370 /* If this is our primary domain and we are not in the 367 371 forest root, we have to scan the root trusts first */ 368 372 369 if ( !state->forest_root)373 if (!domain_is_forest_root(state->domain)) 370 374 rescan_forest_root_trusts(); 371 375 else 372 376 rescan_forest_trusts(); 373 377 374 } else if ( state->forest_root) {378 } else if (domain_is_forest_root(state->domain)) { 375 379 /* Once we have done root forest trust search, we can 376 380 go on to search the trusted forests */ … … 379 383 } 380 384 381 talloc_destroy(state->mem_ctx);385 TALLOC_FREE(state); 382 386 383 387 return; … … 424 428 &dom_list[i].sid ); 425 429 if (d != NULL) { 426 setup_domain_child(d , &d->child);430 setup_domain_child(d); 427 431 } 428 432 } … … 496 500 &dom_list[i].sid ); 497 501 if (d != NULL) { 498 setup_domain_child(d , &d->child);502 setup_domain_child(d); 499 503 } 500 504 } … … 606 610 /* BUILTIN domain */ 607 611 608 domain = add_trusted_domain("BUILTIN", NULL, & builtin_passdb_methods,612 domain = add_trusted_domain("BUILTIN", NULL, &cache_methods, 609 613 &global_sid_Builtin); 610 614 if (domain) { 611 setup_domain_child(domain, 612 &domain->child); 615 setup_domain_child(domain); 613 616 } 614 617 … … 616 619 617 620 domain = add_trusted_domain(get_global_sam_name(), NULL, 618 & sam_passdb_methods, get_global_sam_sid());621 &cache_methods, get_global_sam_sid()); 619 622 if (domain) { 620 623 if ( role != ROLE_DOMAIN_MEMBER ) { 621 624 domain->primary = True; 622 625 } 623 setup_domain_child(domain, 624 &domain->child); 626 setup_domain_child(domain); 625 627 } 626 628 … … 628 630 629 631 if ( role == ROLE_DOMAIN_MEMBER ) { 630 DOM_SIDour_sid;632 struct dom_sid our_sid; 631 633 632 634 if (!secrets_fetch_domain_sid(lp_workgroup(), &our_sid)) { … … 639 641 if (domain) { 640 642 domain->primary = True; 641 setup_domain_child(domain, 642 &domain->child); 643 setup_domain_child(domain); 643 644 644 645 /* Even in the parent winbindd we'll need to … … 653 654 654 655 return True; 655 }656 657 void check_domain_trusted( const char *name, const DOM_SID *user_sid )658 {659 struct winbindd_domain *domain;660 DOM_SID dom_sid;661 uint32 rid;662 663 /* Check if we even care */664 665 if (!lp_allow_trusted_domains())666 return;667 668 domain = find_domain_from_name_noinit( name );669 if ( domain )670 return;671 672 sid_copy( &dom_sid, user_sid );673 if ( !sid_split_rid( &dom_sid, &rid ) )674 return;675 676 /* add the newly discovered trusted domain */677 678 domain = add_trusted_domain( name, NULL, &cache_methods,679 &dom_sid);680 681 if ( !domain )682 return;683 684 /* assume this is a trust from a one-way transitive685 forest trust */686 687 domain->active_directory = True;688 domain->domain_flags = NETR_TRUST_FLAG_OUTBOUND;689 domain->domain_type = NETR_TRUST_TYPE_UPLEVEL;690 domain->internal = False;691 domain->online = True;692 693 setup_domain_child(domain,694 &domain->child);695 696 wcache_tdc_add_domain( domain );697 698 return;699 656 } 700 657 … … 747 704 /* Given a domain sid, return the struct winbindd domain info for it */ 748 705 749 struct winbindd_domain *find_domain_from_sid_noinit(const DOM_SID*sid)706 struct winbindd_domain *find_domain_from_sid_noinit(const struct dom_sid *sid) 750 707 { 751 708 struct winbindd_domain *domain; … … 754 711 755 712 for (domain = domain_list(); domain != NULL; domain = domain->next) { 756 if ( sid_compare_domain(sid, &domain->sid) == 0)713 if (dom_sid_compare_domain(sid, &domain->sid) == 0) 757 714 return domain; 758 715 } … … 765 722 /* Given a domain sid, return the struct winbindd domain info for it */ 766 723 767 struct winbindd_domain *find_domain_from_sid(const DOM_SID*sid)724 struct winbindd_domain *find_domain_from_sid(const struct dom_sid *sid) 768 725 { 769 726 struct winbindd_domain *domain; … … 799 756 struct winbindd_domain *ours = find_our_domain(); 800 757 801 if ( !ours )758 if (ours->forest_name[0] == '\0') { 802 759 return NULL; 803 804 if ( strlen(ours->forest_name) == 0 ) 805 return NULL; 760 } 806 761 807 762 return find_domain_from_name( ours->forest_name ); … … 810 765 struct winbindd_domain *find_builtin_domain(void) 811 766 { 812 DOM_SID sid;813 767 struct winbindd_domain *domain; 814 768 815 string_to_sid(&sid, "S-1-5-32"); 816 domain = find_domain_from_sid(&sid); 817 769 domain = find_domain_from_sid(&global_sid_Builtin); 818 770 if (domain == NULL) { 819 771 smb_panic("Could not find BUILTIN domain"); … … 825 777 /* Find the appropriate domain to lookup a name or SID */ 826 778 827 struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID*sid)779 struct winbindd_domain *find_lookup_domain_from_sid(const struct dom_sid *sid) 828 780 { 829 781 /* SIDs in the S-1-22-{1,2} domain should be handled by our passdb */ … … 943 895 } 944 896 945 /* add a domain user name to a buffer */946 void parse_add_domuser(void *buf, char *domuser, int *len)947 {948 fstring domain;949 char *p, *user;950 951 user = domuser;952 p = strchr(domuser, *lp_winbind_separator());953 954 if (p) {955 956 fstrcpy(domain, domuser);957 domain[PTR_DIFF(p, domuser)] = 0;958 p++;959 960 if (assume_domain(domain)) {961 962 user = p;963 *len -= (PTR_DIFF(p, domuser));964 }965 }966 967 safe_strcpy((char *)buf, user, *len);968 }969 970 897 /* Ensure an incoming username from NSS is fully qualified. Replace the 971 898 incoming fstring with DOMAIN <separator> user. Returns the same … … 1046 973 1047 974 /* 1048 * Winbindd socket accessor functions1049 */1050 1051 const char *get_winbind_pipe_dir(void)1052 {1053 return lp_parm_const_string(-1, "winbindd", "socket dir", WINBINDD_SOCKET_DIR);1054 }1055 1056 char *get_winbind_priv_pipe_dir(void)1057 {1058 return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR);1059 }1060 1061 /* Open the winbindd socket */1062 1063 static int _winbindd_socket = -1;1064 static int _winbindd_priv_socket = -1;1065 1066 int open_winbindd_socket(void)1067 {1068 if (_winbindd_socket == -1) {1069 _winbindd_socket = create_pipe_sock(1070 get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME, 0755);1071 DEBUG(10, ("open_winbindd_socket: opened socket fd %d\n",1072 _winbindd_socket));1073 }1074 1075 return _winbindd_socket;1076 }1077 1078 int open_winbindd_priv_socket(void)1079 {1080 if (_winbindd_priv_socket == -1) {1081 _winbindd_priv_socket = create_pipe_sock(1082 get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);1083 DEBUG(10, ("open_winbindd_priv_socket: opened socket fd %d\n",1084 _winbindd_priv_socket));1085 }1086 1087 return _winbindd_priv_socket;1088 }1089 1090 /*1091 975 * Client list accessor functions 1092 976 */ … … 1118 1002 } 1119 1003 1120 /* Close all open clients */1121 1122 void winbindd_kill_all_clients(void)1123 {1124 struct winbindd_cli_state *cl = winbindd_client_list();1125 1126 DEBUG(10, ("winbindd_kill_all_clients: going postal\n"));1127 1128 while (cl) {1129 struct winbindd_cli_state *next;1130 1131 next = cl->next;1132 winbindd_remove_client(cl);1133 cl = next;1134 }1135 }1136 1137 1004 /* Return number of open clients */ 1138 1005 … … 1144 1011 NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, 1145 1012 TALLOC_CTX *mem_ctx, 1146 const DOM_SID*user_sid,1147 uint32 *p_num_groups, DOM_SID**user_sids)1013 const struct dom_sid *user_sid, 1014 uint32_t *p_num_groups, struct dom_sid **user_sids) 1148 1015 { 1149 1016 struct netr_SamInfo3 *info3 = NULL; 1150 1017 NTSTATUS status = NT_STATUS_NO_MEMORY; 1151 size_t num_groups = 0;1018 uint32_t num_groups = 0; 1152 1019 1153 1020 DEBUG(3,(": lookup_usergroups_cached\n")); … … 1479 1346 return !domain->online; 1480 1347 } 1348 1349 bool is_domain_online(const struct winbindd_domain *domain) 1350 { 1351 return !is_domain_offline(domain); 1352 } 1353 1354 bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr, 1355 struct dom_sid **sids, uint32_t *num_sids) 1356 { 1357 const char *p; 1358 1359 p = sidstr; 1360 if (p == NULL) 1361 return False; 1362 1363 while (p[0] != '\0') { 1364 struct dom_sid sid; 1365 const char *q = NULL; 1366 1367 if (!dom_sid_parse_endp(p, &sid, &q)) { 1368 DEBUG(1, ("Could not parse sid %s\n", p)); 1369 return false; 1370 } 1371 if ((q == NULL) || (q[0] != '\n')) { 1372 DEBUG(1, ("Got invalid sidstr: %s\n", p)); 1373 return false; 1374 } 1375 if (!NT_STATUS_IS_OK(add_sid_to_array(mem_ctx, &sid, sids, 1376 num_sids))) 1377 { 1378 return False; 1379 } 1380 p = q+1; 1381 } 1382 return True; 1383 } -
vendor/current/source3/winbindd/winbindd_wins.c
r414 r740 23 23 #include "includes.h" 24 24 #include "winbindd.h" 25 #include "libsmb/nmblib.h" 25 26 26 27 #undef DBGC_CLASS 27 28 #define DBGC_CLASS DBGC_WINBIND 28 29 29 /* Use our own create socket code so we don't recurse.... */ 30 31 static int wins_lookup_open_socket_in(void) 32 { 33 struct sockaddr_in sock; 34 int val=1; 35 int res; 36 37 memset((char *)&sock,'\0',sizeof(sock)); 38 39 #ifdef HAVE_SOCK_SIN_LEN 40 sock.sin_len = sizeof(sock); 41 #endif 42 sock.sin_port = 0; 43 sock.sin_family = AF_INET; 44 sock.sin_addr.s_addr = interpret_addr("0.0.0.0"); 45 res = socket(AF_INET, SOCK_DGRAM, 0); 46 if (res == -1) 47 return -1; 48 49 if (setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))) { 50 close(res); 51 return -1; 52 } 53 #ifdef SO_REUSEPORT 54 if (setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val))) { 55 close(res); 56 return -1; 57 } 58 #endif /* SO_REUSEPORT */ 59 60 /* now we've got a socket - we need to bind it */ 61 62 if (bind(res, (struct sockaddr *)(void *)&sock, sizeof(sock)) < 0) { 63 close(res); 64 return(-1); 65 } 66 67 set_socket_options(res,"SO_BROADCAST"); 68 69 return res; 70 } 71 72 73 static NODE_STATUS_STRUCT *lookup_byaddr_backend(const char *addr, int *count) 74 { 75 int fd; 30 static struct node_status *lookup_byaddr_backend(TALLOC_CTX *mem_ctx, 31 const char *addr, int *count) 32 { 76 33 struct sockaddr_storage ss; 77 34 struct nmb_name nname; 78 NODE_STATUS_STRUCT *status; 79 80 fd = wins_lookup_open_socket_in(); 81 if (fd == -1) 82 return NULL; 35 struct node_status *result; 36 NTSTATUS status; 83 37 84 38 make_nmb_name(&nname, "*", 0); … … 86 40 return NULL; 87 41 } 88 status = node_status_query(fd, &nname, &ss, count, NULL); 89 90 close(fd); 91 return status; 92 } 93 94 static struct sockaddr_storage *lookup_byname_backend(const char *name, 95 int *count) 96 { 97 int fd; 42 status = node_status_query(mem_ctx, &nname, &ss, 43 &result, count, NULL); 44 if (!NT_STATUS_IS_OK(status)) { 45 return NULL; 46 } 47 return result; 48 } 49 50 static struct sockaddr_storage *lookup_byname_backend(TALLOC_CTX *mem_ctx, 51 const char *name, 52 int *count) 53 { 98 54 struct ip_service *ret = NULL; 99 55 struct sockaddr_storage *return_ss = NULL; 100 int j, i, flags = 0; 56 int j, i; 57 NTSTATUS status; 101 58 102 59 *count = 0; … … 106 63 if ( *count == 0 ) 107 64 return NULL; 108 if ( (return_ss = SMB_MALLOC_ARRAY(struct sockaddr_storage, *count)) == NULL ) { 65 return_ss = TALLOC_ARRAY(mem_ctx, struct sockaddr_storage, 66 *count); 67 if (return_ss == NULL ) { 109 68 free( ret ); 110 69 return NULL; … … 117 76 free( ret ); 118 77 return return_ss; 119 }120 121 fd = wins_lookup_open_socket_in();122 if (fd == -1) {123 return NULL;124 78 } 125 79 … … 132 86 continue; 133 87 } 134 return_ss = name_query(fd,name,0x20,True,True,bcast_ss,count, &flags, NULL); 135 if (return_ss) { 88 status = name_query(name, 0x20, True, True,bcast_ss, 89 mem_ctx, &return_ss, count, NULL); 90 if (NT_STATUS_IS_OK(status)) { 136 91 break; 137 92 } 138 93 } 139 94 140 close(fd);141 95 return return_ss; 142 96 } … … 148 102 fstring response; 149 103 int i, count, maxlen, size; 150 NODE_STATUS_STRUCT*status;104 struct node_status *status; 151 105 152 106 /* Ensure null termination */ … … 159 113 maxlen = sizeof(response) - 1; 160 114 161 if ((status = lookup_byaddr_backend(state->request->data.winsreq, &count))){ 115 if ((status = lookup_byaddr_backend( 116 state->mem_ctx, state->request->data.winsreq, &count))) { 162 117 size = strlen(state->request->data.winsreq); 163 118 if (size > maxlen) { 164 SAFE_FREE(status);119 TALLOC_FREE(status); 165 120 request_error(state); 166 121 return; … … 174 129 size = sizeof(status[i].name) + strlen(response); 175 130 if (size > maxlen) { 176 SAFE_FREE(status);131 TALLOC_FREE(status); 177 132 request_error(state); 178 133 return; … … 184 139 /* make last character a newline */ 185 140 response[strlen(response)-1] = '\n'; 186 SAFE_FREE(status);141 TALLOC_FREE(status); 187 142 } 188 143 fstrcpy(state->response->data.winsresp,response); … … 208 163 maxlen = sizeof(response) - 1; 209 164 210 if ((ip_list = lookup_byname_backend(state->request->data.winsreq,&count))){ 165 ip_list = lookup_byname_backend( 166 state->mem_ctx, state->request->data.winsreq, &count); 167 if (ip_list != NULL){ 211 168 for (i = count; i ; i--) { 212 169 print_sockaddr(addr, sizeof(addr), &ip_list[i-1]); 213 170 size = strlen(addr); 214 171 if (size > maxlen) { 215 SAFE_FREE(ip_list);172 TALLOC_FREE(ip_list); 216 173 request_error(state); 217 174 return; … … 230 187 size = strlen(state->request->data.winsreq) + strlen(response); 231 188 if (size > maxlen) { 232 SAFE_FREE(ip_list);189 TALLOC_FREE(ip_list); 233 190 request_error(state); 234 191 return; … … 236 193 fstrcat(response,state->request->data.winsreq); 237 194 fstrcat(response,"\n"); 238 SAFE_FREE(ip_list);195 TALLOC_FREE(ip_list); 239 196 } else { 240 197 request_error(state);
Note:
See TracChangeset
for help on using the changeset viewer.