Changeset 988 for vendor/current/source3/winbindd
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source3/winbindd
- Files:
-
- 11 added
- 4 deleted
- 74 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/winbindd/idmap.c
r740 r988 25 25 #include "winbindd.h" 26 26 #include "idmap.h" 27 #include "passdb/machine_sid.h" 27 #include "lib/util_sid_passdb.h" 28 #include "passdb.h" 28 29 29 30 #undef DBGC_CLASS … … 31 32 32 33 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 }48 34 49 35 /** … … 78 64 static struct idmap_domain **idmap_domains = NULL; 79 65 static int num_domains = 0; 66 67 static struct idmap_domain *idmap_init_named_domain(TALLOC_CTX *mem_ctx, 68 const char *domname); 69 static struct idmap_domain *idmap_init_domain(TALLOC_CTX *mem_ctx, 70 const char *domainname, 71 const char *modulename, 72 bool check_range); 73 static bool idmap_found_domain_backend( 74 const char *string, regmatch_t matches[], void *private_data); 75 76 static bool idmap_init(void) 77 { 78 static bool initialized; 79 int ret; 80 81 if (initialized) { 82 return true; 83 } 84 85 DEBUG(10, ("idmap_init(): calling static_init_idmap\n")); 86 87 static_init_idmap; 88 89 initialized = true; 90 91 if (!pdb_is_responsible_for_everything_else()) { 92 default_idmap_domain = idmap_init_named_domain(NULL, "*"); 93 if (default_idmap_domain == NULL) { 94 return false; 95 } 96 } 97 98 passdb_idmap_domain = idmap_init_domain( 99 NULL, get_global_sam_name(), "passdb", false); 100 if (passdb_idmap_domain == NULL) { 101 TALLOC_FREE(default_idmap_domain); 102 return false; 103 } 104 105 idmap_domains = talloc_array(NULL, struct idmap_domain *, 0); 106 if (idmap_domains == NULL) { 107 TALLOC_FREE(passdb_idmap_domain); 108 TALLOC_FREE(default_idmap_domain); 109 return false; 110 } 111 112 ret = lp_wi_scan_global_parametrics( 113 "idmapconfig\\(.*\\):backend", 2, 114 idmap_found_domain_backend, NULL); 115 if (ret != 0) { 116 DBG_WARNING("wi_scan_global_parametrics returned %d\n", ret); 117 return false; 118 } 119 120 return true; 121 } 122 123 bool domain_has_idmap_config(const char *domname) 124 { 125 int i; 126 char *config_option; 127 const char *range = NULL; 128 const char *backend = NULL; 129 bool ok; 130 131 ok = idmap_init(); 132 if (!ok) { 133 return false; 134 } 135 136 for (i=0; i<num_domains; i++) { 137 if (strequal(idmap_domains[i]->name, domname)) { 138 return true; 139 } 140 } 141 142 /* fallback: also check loadparm */ 143 144 config_option = talloc_asprintf(talloc_tos(), "idmap config %s", 145 domname); 146 if (config_option == NULL) { 147 DEBUG(0, ("out of memory\n")); 148 return false; 149 } 150 151 range = lp_parm_const_string(-1, config_option, "range", NULL); 152 backend = lp_parm_const_string(-1, config_option, "backend", NULL); 153 if (range != NULL && backend != NULL) { 154 DEBUG(5, ("idmap configuration specified for domain '%s'\n", 155 domname)); 156 TALLOC_FREE(config_option); 157 return true; 158 } 159 160 TALLOC_FREE(config_option); 161 return false; 162 } 163 164 static bool idmap_found_domain_backend( 165 const char *string, regmatch_t matches[], void *private_data) 166 { 167 if (matches[1].rm_so == -1) { 168 DBG_WARNING("Found match, but no name??\n"); 169 return false; 170 } 171 172 { 173 struct idmap_domain *dom, **tmp; 174 regoff_t len = matches[1].rm_eo - matches[1].rm_so; 175 char domname[len+1]; 176 177 memcpy(domname, string + matches[1].rm_so, len); 178 domname[len] = '\0'; 179 180 DBG_DEBUG("Found idmap domain \"%s\"\n", domname); 181 182 if (strcmp(domname, "*") == 0) { 183 return false; 184 } 185 186 dom = idmap_init_named_domain(idmap_domains, domname); 187 if (dom == NULL) { 188 DBG_NOTICE("Could not init idmap domain %s\n", 189 domname); 190 return false; 191 } 192 193 tmp = talloc_realloc(idmap_domains, idmap_domains, 194 struct idmap_domain *, num_domains + 1); 195 if (tmp == NULL) { 196 DBG_WARNING("talloc_realloc failed\n"); 197 TALLOC_FREE(dom); 198 return false; 199 } 200 idmap_domains = tmp; 201 idmap_domains[num_domains] = dom; 202 num_domains += 1; 203 } 204 205 return false; 206 } 80 207 81 208 static struct idmap_methods *get_methods(const char *name) … … 130 257 for (entry = backends; entry != NULL; entry = entry->next) { 131 258 if (strequal(entry->name, name)) { 132 DEBUG( 0,("Idmap module %s already registered!\n",259 DEBUG(5,("Idmap module %s already registered!\n", 133 260 name)); 134 261 return NT_STATUS_OBJECT_NAME_COLLISION; … … 172 299 char *config_option = NULL; 173 300 const char *range; 301 unsigned low_id = 0; 302 unsigned high_id = 0; 174 303 175 304 result = talloc_zero(mem_ctx, struct idmap_domain); … … 186 315 187 316 /* 317 * Check whether the requested backend module exists and 318 * load the methods. 319 */ 320 321 result->methods = get_methods(modulename); 322 if (result->methods == NULL) { 323 DEBUG(3, ("idmap backend %s not found\n", modulename)); 324 325 status = smb_probe_module("idmap", modulename); 326 if (!NT_STATUS_IS_OK(status)) { 327 DEBUG(3, ("Could not probe idmap module %s\n", 328 modulename)); 329 goto fail; 330 } 331 332 result->methods = get_methods(modulename); 333 } 334 if (result->methods == NULL) { 335 DEBUG(1, ("idmap backend %s not found\n", modulename)); 336 goto fail; 337 } 338 339 /* 188 340 * load ranges and read only information from the config 189 341 */ … … 196 348 } 197 349 350 result->read_only = lp_parm_bool(-1, config_option, "read only", false); 198 351 range = lp_parm_const_string(-1, config_option, "range", NULL); 352 353 talloc_free(config_option); 354 199 355 if (range == NULL) { 200 DEBUG(1, ("idmap range not specified for domain %s\n",201 result->name));202 356 if (check_range) { 357 DEBUG(1, ("idmap range not specified for domain %s\n", 358 result->name)); 203 359 goto fail; 204 360 } 205 } else if (sscanf(range, "%u - %u", &result->low_id, 206 &result->high_id) != 2) 361 } else if (sscanf(range, "%u - %u", &low_id, &high_id) != 2) 207 362 { 208 363 DEBUG(1, ("invalid range '%s' specified for domain " … … 211 366 goto fail; 212 367 } 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)); 368 } else if (low_id > high_id) { 369 DEBUG(1, ("Error: invalid idmap range detected: %u - %u\n", 370 low_id, high_id)); 223 371 if (check_range) { 224 372 goto fail; … … 226 374 } 227 375 228 result->methods = get_methods(modulename); 229 if (result->methods == NULL) { 230 DEBUG(3, ("idmap backend %s not found\n", modulename)); 231 232 status = smb_probe_module("idmap", modulename); 233 if (!NT_STATUS_IS_OK(status)) { 234 DEBUG(3, ("Could not probe idmap module %s\n", 235 modulename)); 236 goto fail; 237 } 238 239 result->methods = get_methods(modulename); 240 } 241 if (result->methods == NULL) { 242 DEBUG(1, ("idmap backend %s not found\n", modulename)); 243 goto fail; 244 } 376 result->low_id = low_id; 377 result->high_id = high_id; 245 378 246 379 status = result->methods->init(result); … … 274 407 char *config_option; 275 408 const char *backend; 276 277 idmap_init(); 409 bool ok; 410 411 ok = idmap_init(); 412 if (!ok) { 413 return NULL; 414 } 278 415 279 416 config_option = talloc_asprintf(talloc_tos(), "idmap config %s", … … 286 423 backend = lp_parm_const_string(-1, config_option, "backend", NULL); 287 424 if (backend == NULL) { 288 DEBUG(1, ("no backend defined for %s\n", config_option)); 425 DEBUG(10, ("no idmap backend configured for domain '%s'\n", 426 domname)); 289 427 goto fail; 290 428 } … … 302 440 TALLOC_FREE(result); 303 441 return NULL; 304 }305 306 /**307 * Initialize the default domain structure308 * @param[in] mem_ctx memory context for the result309 * @result The default domain structure310 *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, "*");318 }319 320 /**321 * Initialize the passdb domain structure322 * @param[in] mem_ctx memory context for the result323 * @result The default domain structure324 *325 * No config, passdb has its own configuration.326 */327 328 static struct idmap_domain *idmap_init_passdb_domain(TALLOC_CTX *mem_ctx)329 {330 idmap_init();331 332 /*333 * Always init the default domain, we can't go without one334 */335 if (default_idmap_domain == NULL) {336 default_idmap_domain = idmap_init_default_domain(NULL);337 }338 if (default_idmap_domain == NULL) {339 return NULL;340 }341 342 if (passdb_idmap_domain != NULL) {343 return passdb_idmap_domain;344 }345 346 passdb_idmap_domain = idmap_init_domain(NULL, get_global_sam_name(),347 "passdb", false);348 if (passdb_idmap_domain == NULL) {349 DEBUG(1, ("Could not init passdb idmap domain\n"));350 }351 352 return passdb_idmap_domain;353 442 } 354 443 … … 368 457 */ 369 458 370 st ruct idmap_domain *idmap_find_domain(const char *domname)371 { 372 struct idmap_domain *result;459 static struct idmap_domain *idmap_find_domain(const char *domname) 460 { 461 bool ok; 373 462 int i; 374 463 … … 376 465 domname?domname:"NULL")); 377 466 378 idmap_init(); 379 380 /* 381 * Always init the default domain, we can't go without one 382 */ 383 if (default_idmap_domain == NULL) { 384 default_idmap_domain = idmap_init_default_domain(NULL); 385 } 386 if (default_idmap_domain == NULL) { 467 ok = idmap_init(); 468 if (!ok) { 387 469 return NULL; 388 470 } … … 398 480 } 399 481 400 if (idmap_domains == NULL) { 401 /* 402 * talloc context for all idmap domains 403 */ 404 idmap_domains = TALLOC_ARRAY(NULL, struct idmap_domain *, 1); 405 } 406 407 if (idmap_domains == NULL) { 408 DEBUG(0, ("talloc failed\n")); 482 return default_idmap_domain; 483 } 484 485 struct idmap_domain *idmap_find_domain_with_sid(const char *domname, 486 const struct dom_sid *sid) 487 { 488 bool ok; 489 490 ok = idmap_init(); 491 if (!ok) { 409 492 return NULL; 410 493 } 411 494 412 result = idmap_init_named_domain(idmap_domains, domname); 413 if (result == NULL) { 414 /* 415 * Could not init that domain -- try the default one 416 */ 417 return default_idmap_domain; 418 } 419 420 ADD_TO_ARRAY(idmap_domains, struct idmap_domain *, result, 421 &idmap_domains, &num_domains); 422 return result; 495 if (sid_check_is_for_passdb(sid)) { 496 return passdb_idmap_domain; 497 } 498 499 return idmap_find_domain(domname); 423 500 } 424 501 … … 468 545 } 469 546 470 NTSTATUS idmap_backends_unixid_to_sid( const char *domname,struct id_map *id)547 NTSTATUS idmap_backends_unixid_to_sid(struct id_map *id) 471 548 { 472 549 struct idmap_domain *dom; 473 550 struct id_map *maps[2]; 474 475 DEBUG(10, ("idmap_backend_unixid_to_sid: domain = '%s', xid = %d " 476 "(type %d)\n", 477 domname?domname:"NULL", id->xid.id, id->xid.type)); 551 bool ok; 552 int i; 553 554 ok = idmap_init(); 555 if (!ok) { 556 return NT_STATUS_NONE_MAPPED; 557 } 558 559 DEBUG(10, ("idmap_backend_unixid_to_sid: xid = %d (type %d)\n", 560 id->xid.id, id->xid.type)); 478 561 479 562 maps[0] = id; … … 484 567 */ 485 568 486 dom = idmap_init_passdb_domain(NULL);569 dom = passdb_idmap_domain; 487 570 if ((dom != NULL) 488 571 && NT_STATUS_IS_OK(dom->methods->unixids_to_sids(dom, maps)) … … 491 574 } 492 575 493 dom = idmap_find_domain(domname); 576 dom = default_idmap_domain; 577 578 for (i=0; i<num_domains; i++) { 579 if ((id->xid.id >= idmap_domains[i]->low_id) && 580 (id->xid.id <= idmap_domains[i]->high_id)) { 581 dom = idmap_domains[i]; 582 break; 583 } 584 } 585 494 586 if (dom == NULL) { 495 587 return NT_STATUS_NONE_MAPPED; … … 498 590 return dom->methods->unixids_to_sids(dom, maps); 499 591 } 500 501 NTSTATUS idmap_backends_sid_to_unixid(const char *domain, struct id_map *id)502 {503 struct idmap_domain *dom;504 struct id_map *maps[2];505 506 DEBUG(10, ("idmap_backends_sid_to_unixid: domain = '%s', sid = [%s]\n",507 domain?domain:"NULL", sid_string_dbg(id->sid)));508 509 maps[0] = id;510 maps[1] = NULL;511 512 if (sid_check_is_in_builtin(id->sid)513 || (sid_check_is_in_our_domain(id->sid)))514 {515 NTSTATUS status;516 517 DEBUG(10, ("asking passdb...\n"));518 519 dom = idmap_init_passdb_domain(NULL);520 if (dom == NULL) {521 return NT_STATUS_NONE_MAPPED;522 }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;532 }533 534 dom = idmap_find_domain(domain);535 if (dom == NULL) {536 return NT_STATUS_NONE_MAPPED;537 }538 539 return dom->methods->sids_to_unixids(dom, maps);540 } -
vendor/current/source3/winbindd/idmap_ad.c
r860 r988 32 32 #include "libads/ldap_schema.h" 33 33 #include "nss_info.h" 34 #include "secrets.h"35 34 #include "idmap.h" 36 35 #include "../libcli/ldap/ldap_ndr.h" … … 40 39 #define DBGC_CLASS DBGC_IDMAP 41 40 42 #define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache"43 44 #define IDMAP_AD_MAX_IDS 3045 41 #define CHECK_ALLOC_DONE(mem) do { \ 46 42 if (!mem) { \ … … 57 53 }; 58 54 59 NTSTATUS init_module(void);60 61 55 /************************************************************************ 62 56 ***********************************************************************/ 63 57 64 static ADS_STATUS ad_idmap_cached_connection_internal(struct idmap_domain *dom) 65 { 66 ADS_STRUCT *ads; 58 static ADS_STATUS ad_idmap_cached_connection(struct idmap_domain *dom) 59 { 67 60 ADS_STATUS status; 68 bool local = False; 69 fstring dc_name; 70 struct sockaddr_storage dc_ip; 71 struct idmap_ad_context *ctx; 72 char *ldap_server = NULL; 73 char *realm = NULL; 74 struct winbindd_domain *wb_dom; 61 struct idmap_ad_context * ctx; 75 62 76 63 DEBUG(10, ("ad_idmap_cached_connection: called for domain '%s'\n", … … 79 66 ctx = talloc_get_type(dom->private_data, struct idmap_ad_context); 80 67 81 if (ctx->ads != NULL) { 82 83 time_t expire; 84 time_t now = time(NULL); 85 86 ads = ctx->ads; 87 88 expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire); 89 90 /* check for a valid structure */ 91 DEBUG(7, ("Current tickets expire in %d seconds (at %d, time is now %d)\n", 92 (uint32)expire-(uint32)now, (uint32) expire, (uint32) now)); 93 94 if ( ads->config.realm && (expire > time(NULL))) { 95 return ADS_SUCCESS; 96 } else { 97 /* we own this ADS_STRUCT so make sure it goes away */ 98 DEBUG(7,("Deleting expired krb5 credential cache\n")); 99 ads->is_mine = True; 100 ads_destroy( &ads ); 101 ads_kdestroy(WINBIND_CCACHE_NAME); 102 ctx->ads = NULL; 103 } 104 } 105 106 if (!local) { 107 /* we don't want this to affect the users ccache */ 108 setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1); 109 } 110 111 /* 112 * At this point we only have the NetBIOS domain name. 113 * Check if we can get server nam and realm from SAF cache 114 * and the domain list. 115 */ 116 ldap_server = saf_fetch(dom->name); 117 DEBUG(10, ("ldap_server from saf cache: '%s'\n", ldap_server?ldap_server:"")); 118 119 wb_dom = find_domain_from_name_noinit(dom->name); 120 if (wb_dom == NULL) { 121 DEBUG(10, ("find_domain_from_name_noinit did not find domain '%s'\n", 122 dom->name)); 123 realm = NULL; 124 } else { 125 DEBUG(10, ("find_domain_from_name_noinit found realm '%s' for " 126 " domain '%s'\n", wb_dom->alt_name, dom->name)); 127 realm = wb_dom->alt_name; 128 } 129 130 if ( (ads = ads_init(realm, dom->name, ldap_server)) == NULL ) { 131 DEBUG(1,("ads_init failed\n")); 132 return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); 133 } 134 135 /* the machine acct password might have change - fetch it every time */ 136 SAFE_FREE(ads->auth.password); 137 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); 138 139 SAFE_FREE(ads->auth.realm); 140 ads->auth.realm = SMB_STRDUP(lp_realm()); 141 142 /* setup server affinity */ 143 144 get_dc_name(dom->name, realm, dc_name, &dc_ip ); 145 146 status = ads_connect(ads); 147 if (!ADS_ERR_OK(status)) { 148 DEBUG(1, ("ad_idmap_cached_connection_internal: failed to " 149 "connect to AD\n")); 150 ads_destroy(&ads); 151 return status; 152 } 153 154 ads->is_mine = False; 155 156 ctx->ads = ads; 157 158 return ADS_SUCCESS; 159 } 160 161 /************************************************************************ 162 ***********************************************************************/ 163 164 static ADS_STATUS ad_idmap_cached_connection(struct idmap_domain *dom) 165 { 166 ADS_STATUS status; 167 struct idmap_ad_context * ctx; 168 169 status = ad_idmap_cached_connection_internal(dom); 68 status = ads_idmap_cached_connection(&ctx->ads, dom->name); 170 69 if (!ADS_ERR_OK(status)) { 171 70 return status; … … 217 116 const char *schema_mode = NULL; 218 117 219 ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context);118 ctx = talloc_zero(dom, struct idmap_ad_context); 220 119 if (ctx == NULL) { 221 120 DEBUG(0, ("Out of memory!\n")); … … 253 152 254 153 return NT_STATUS_OK; 255 }256 257 /************************************************************************258 Search up to IDMAP_AD_MAX_IDS entries in maps for a match.259 ***********************************************************************/260 261 static struct id_map *find_map_by_id(struct id_map **maps, enum id_type type, uint32_t id)262 {263 int i;264 265 for (i = 0; maps[i] && i<IDMAP_AD_MAX_IDS; i++) {266 if ((maps[i]->xid.type == type) && (maps[i]->xid.id == id)) {267 return maps[i];268 }269 }270 271 return NULL;272 }273 274 /************************************************************************275 Search up to IDMAP_AD_MAX_IDS entries in maps for a match276 ***********************************************************************/277 278 static struct id_map *find_map_by_sid(struct id_map **maps, struct dom_sid *sid)279 {280 int i;281 282 for (i = 0; maps[i] && i<IDMAP_AD_MAX_IDS; i++) {283 if (dom_sid_equal(maps[i]->sid, sid)) {284 return maps[i];285 }286 }287 288 return NULL;289 154 } 290 155 … … 343 208 again: 344 209 bidx = idx; 345 for (i = 0; (i < IDMAP_ AD_MAX_IDS) && ids[idx]; i++, idx++) {210 for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) { 346 211 switch (ids[idx]->xid.type) { 347 212 case ID_TYPE_UID: … … 468 333 } 469 334 470 map = find_map_by_id(&ids[bidx], type, id);335 map = idmap_find_map_by_id(&ids[bidx], type, id); 471 336 if (!map) { 472 337 DEBUG(2, ("WARNING: couldn't match result with requested ID\n")); … … 573 438 574 439 bidx = idx; 575 for (i = 0; (i < IDMAP_ AD_MAX_IDS) && ids[idx]; i++, idx++) {440 for (i = 0; (i < IDMAP_LDAP_MAX_IDS) && ids[idx]; i++, idx++) { 576 441 577 442 ids[idx]->status = ID_UNKNOWN; … … 623 488 } 624 489 625 map = find_map_by_sid(&ids[bidx], &sid);490 map = idmap_find_map_by_sid(&ids[bidx], &sid); 626 491 if (!map) { 627 492 DEBUG(2, ("WARNING: couldn't match result with requested SID\n")); … … 738 603 dom = talloc_get_type(e->state, struct idmap_domain); 739 604 } else { 740 dom = TALLOC_ZERO_P(e, struct idmap_domain);605 dom = talloc_zero(e, struct idmap_domain); 741 606 if (dom == NULL) { 742 607 DEBUG(0, ("Out of memory!\n")); … … 758 623 struct idmap_ad_context); 759 624 } else { 760 ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context);625 ctx = talloc_zero(dom, struct idmap_ad_context); 761 626 if (ctx == NULL) { 762 627 DEBUG(0, ("Out of memory!\n")); … … 808 673 const char **shell, 809 674 const char **gecos, 810 uint32 *gid )675 uint32_t *gid ) 811 676 { 812 677 const char *attrs[] = {NULL, /* attr_homedir */ … … 879 744 if (gid) { 880 745 if (!ads_pull_uint32(ctx->ads, msg_internal, ctx->ad_schema->posix_gidnumber_attr, gid)) 881 *gid = (uint32 )-1;746 *gid = (uint32_t)-1; 882 747 } 883 748 … … 1098 963 ***********************************************************************/ 1099 964 965 static_decl_idmap; 1100 966 NTSTATUS idmap_ad_init(void) 1101 967 { -
vendor/current/source3/winbindd/idmap_autorid.c
r746 r988 6 6 * for the domains by automatically allocating a range for each domain 7 7 * 8 * Copyright (C) Christian Ambach, 2010-201 18 * Copyright (C) Christian Ambach, 2010-2012 9 9 * 10 10 * This program is free software; you can redistribute it and/or modify … … 23 23 */ 24 24 25 #include "includes.h" 26 #include "system/filesys.h" 25 /* 26 * This module allocates ranges for domains to be used in a 27 * algorithmic mode like idmap_rid. Multiple ranges are supported 28 * for a single domain: If a rid exceeds the range size, a matching 29 * range is allocated to hold the rid's id. 30 * 31 * Here are the formulas applied: 32 * 33 * 34 * For a sid of the form domain_sid-rid, we have 35 * 36 * rid = reduced_rid + domain_range_index * range_size 37 * 38 * with 39 * reduced_rid := rid % range_size 40 * domain_range_index := rid / range_size 41 * 42 * And reduced_rid fits into a range. 43 * 44 * In the database, we associate a range_number to 45 * the pair domain_sid,domain_range_index. 46 * 47 * Now the unix id for the given sid calculates as: 48 * 49 * id = reduced_rid + range_low_id 50 * 51 * with 52 * 53 * range_low_id = low_id + range_number * range_size 54 * 55 * 56 * The inverse calculation goes like this: 57 * 58 * Given a unix id, let 59 * 60 * normalized_id := id - low_id 61 * reduced_rid := normalized_id % range_size 62 * range_number = normalized_id / range_size 63 * 64 * Then we have 65 * 66 * id = reduced_rid + low_id + range_number * range_size 67 * 68 * From the database, get the domain_sid,domain_range_index pair 69 * belonging to the range_number (if there is already one). 70 * 71 * Then the rid for the unix id calculates as: 72 * 73 * rid = reduced_rid + domain_range_index * range_size 74 */ 75 76 #include "idmap_autorid_tdb.h" 27 77 #include "winbindd.h" 28 #include "dbwrap.h"29 78 #include "idmap.h" 79 #include "idmap_rw.h" 30 80 #include "../libcli/security/dom_sid.h" 31 #include "util_tdb.h"32 81 33 82 #undef DBGC_CLASS 34 83 #define DBGC_CLASS DBGC_IDMAP 35 84 36 #define HWM "NEXT RANGE" 37 #define ALLOC_HWM_UID "NEXT ALLOC UID" 38 #define ALLOC_HWM_GID "NEXT ALLOC GID" 39 #define ALLOC_RANGE "ALLOC" 40 #define CONFIGKEY "CONFIG" 41 42 struct autorid_global_config { 43 uint32_t minvalue; 44 uint32_t rangesize; 45 uint32_t maxranges; 46 }; 47 48 struct autorid_domain_config { 49 fstring sid; 50 uint32_t domainnum; 51 struct autorid_global_config *globalcfg; 52 }; 85 #define IDMAP_AUTORID_ALLOC_RESERVED 500 53 86 54 87 /* handle to the tdb storing domain <-> range assignments */ 55 88 static struct db_context *autorid_db; 56 89 57 static NTSTATUS idmap_autorid_get_domainrange(struct db_context *db, 58 void *private_data) 59 { 90 static bool ignore_builtin = false; 91 92 static NTSTATUS idmap_autorid_get_alloc_range(struct idmap_domain *dom, 93 struct autorid_range_config *range) 94 { 95 NTSTATUS status; 96 97 ZERO_STRUCT(*range); 98 99 fstrcpy(range->domsid, ALLOC_RANGE); 100 101 status = idmap_autorid_get_domainrange(autorid_db, 102 range, 103 dom->read_only); 104 105 return status; 106 } 107 108 static NTSTATUS idmap_autorid_allocate_id(struct idmap_domain *dom, 109 struct unixid *xid) { 110 60 111 NTSTATUS ret; 61 uint32_t domainnum, hwm; 62 char *numstr; 63 struct autorid_domain_config *cfg; 64 65 cfg = (struct autorid_domain_config *)private_data; 66 67 if (!dbwrap_fetch_uint32(db, cfg->sid, &domainnum)) { 68 DEBUG(10, ("Acquiring new range for domain %s\n", cfg->sid)); 69 70 /* fetch the current HWM */ 71 if (!dbwrap_fetch_uint32(db, HWM, &hwm)) { 72 DEBUG(1, ("Fatal error while fetching current " 73 "HWM value!\n")); 74 ret = NT_STATUS_INTERNAL_ERROR; 75 goto error; 76 } 77 78 /* do we have a range left? */ 79 if (hwm >= cfg->globalcfg->maxranges) { 80 DEBUG(1, ("No more domain ranges available!\n")); 81 ret = NT_STATUS_NO_MEMORY; 82 goto error; 83 } 84 85 /* increase the HWM */ 86 ret = dbwrap_change_uint32_atomic(db, HWM, &domainnum, 1); 87 if (!NT_STATUS_IS_OK(ret)) { 88 DEBUG(1, ("Fatal error while fetching a new " 89 "domain range value!\n")); 90 goto error; 91 } 92 93 /* store away the new mapping in both directions */ 94 ret = dbwrap_trans_store_uint32(db, cfg->sid, domainnum); 95 if (!NT_STATUS_IS_OK(ret)) { 96 DEBUG(1, ("Fatal error while storing new " 97 "domain->range assignment!\n")); 98 goto error; 99 } 100 101 numstr = talloc_asprintf(db, "%u", domainnum); 102 if (!numstr) { 103 ret = NT_STATUS_NO_MEMORY; 104 goto error; 105 } 106 107 ret = dbwrap_trans_store_bystring(db, numstr, 108 string_term_tdb_data(cfg->sid), TDB_INSERT); 109 110 talloc_free(numstr); 111 if (!NT_STATUS_IS_OK(ret)) { 112 DEBUG(1, ("Fatal error while storing " 113 "new domain->range assignment!\n")); 114 goto error; 115 } 116 DEBUG(5, ("Acquired new range #%d for domain %s\n", 117 domainnum, cfg->sid)); 118 } 119 120 DEBUG(10, ("Using range #%d for domain %s\n", domainnum, cfg->sid)); 121 cfg->domainnum = domainnum; 122 123 return NT_STATUS_OK; 124 125 error: 112 struct autorid_range_config range; 113 114 if (dom->read_only) { 115 DEBUG(3, ("Backend is read-only, refusing " 116 "new allocation request\n")); 117 return NT_STATUS_UNSUCCESSFUL; 118 } 119 120 /* fetch the range for the allocation pool */ 121 122 ret = idmap_autorid_get_alloc_range(dom, &range); 123 if (!NT_STATUS_IS_OK(ret)) { 124 DEBUG(3, ("Could not determine range for allocation pool, " 125 "check previous messages for reason\n")); 126 return ret; 127 } 128 129 ret = idmap_tdb_common_get_new_id(dom, xid); 130 131 if (!NT_STATUS_IS_OK(ret)) { 132 DEBUG(1, ("Fatal error while allocating new ID!\n")); 133 return ret; 134 } 135 136 xid->id = xid->id + range.low_id; 137 138 DEBUG(10, ("Returned new %s %d from allocation range\n", 139 (xid->type==ID_TYPE_UID)?"uid":"gid", xid->id)); 140 126 141 return ret; 127 142 } 143 144 /* 145 * map a SID to xid using the idmap_tdb like pool 146 */ 147 static NTSTATUS idmap_autorid_id_to_sid_alloc(struct idmap_domain *dom, 148 struct id_map *map) 149 { 150 NTSTATUS ret; 151 152 /* look out for the mapping */ 153 ret = idmap_tdb_common_unixid_to_sid(dom, map); 154 155 if (NT_STATUS_IS_OK(ret)) { 156 map->status = ID_MAPPED; 157 return ret; 158 } 159 160 map->status = ID_UNKNOWN; 161 162 DEBUG(10, ("no ID->SID mapping for %d could be found\n", map->xid.id)); 163 164 return ret; 128 165 } 129 166 130 167 static NTSTATUS idmap_autorid_id_to_sid(struct autorid_global_config *cfg, 168 struct idmap_domain *dom, 131 169 struct id_map *map) 132 170 { 133 uint32_t range; 134 TDB_DATA data; 171 uint32_t range_number; 172 uint32_t domain_range_index = 0; 173 uint32_t normalized_id; 174 uint32_t reduced_rid; 175 uint32_t rid; 176 TDB_DATA data = tdb_null; 135 177 char *keystr; 136 struct dom_sid sid; 178 struct dom_sid domsid; 179 NTSTATUS status; 180 bool ok; 181 const char *q = NULL; 137 182 138 183 /* can this be one of our ids? */ … … 152 197 153 198 /* determine the range of this uid */ 154 range = ((map->xid.id - cfg->minvalue) / cfg->rangesize); 155 156 keystr = talloc_asprintf(talloc_tos(), "%u", range); 199 200 normalized_id = map->xid.id - cfg->minvalue; 201 range_number = normalized_id / cfg->rangesize; 202 203 keystr = talloc_asprintf(talloc_tos(), "%u", range_number); 157 204 if (!keystr) { 158 205 return NT_STATUS_NO_MEMORY; 159 206 } 160 207 161 data = dbwrap_fetch_bystring(autorid_db, talloc_tos(), keystr);208 status = dbwrap_fetch_bystring(autorid_db, talloc_tos(), keystr, &data); 162 209 TALLOC_FREE(keystr); 163 210 164 if (! data.dptr) {211 if (!NT_STATUS_IS_OK(status)) { 165 212 DEBUG(4, ("id %d belongs to range %d which does not have " 166 213 "domain mapping, ignoring mapping request\n", 167 map->xid.id, range ));214 map->xid.id, range_number)); 168 215 TALLOC_FREE(data.dptr); 169 216 map->status = ID_UNKNOWN; … … 174 221 ALLOC_RANGE, 175 222 strlen(ALLOC_RANGE)) == 0) { 176 /* this is from the alloc range, there is no mapping back */ 177 DEBUG(5, ("id %d belongs to alloc range, cannot map back\n", 223 /* 224 * this is from the alloc range, check if there is a mapping 225 */ 226 DEBUG(5, ("id %d belongs to allocation range, " 227 "checking for mapping\n", 178 228 map->xid.id)); 179 229 TALLOC_FREE(data.dptr); 230 return idmap_autorid_id_to_sid_alloc(dom, map); 231 } 232 233 ok = dom_sid_parse_endp((const char *)data.dptr, &domsid, &q); 234 TALLOC_FREE(data.dptr); 235 if (!ok) { 180 236 map->status = ID_UNKNOWN; 181 237 return NT_STATUS_OK; 182 238 } 183 184 string_to_sid(&sid, (const char *)data.dptr); 185 TALLOC_FREE(data.dptr); 186 187 sid_compose(map->sid, &sid, 188 (map->xid.id - cfg->minvalue - 189 range * cfg->rangesize)); 239 if ((q != NULL) && (*q != '\0')) 240 if (sscanf(q+1, "%"SCNu32, &domain_range_index) != 1) { 241 DEBUG(10, ("Domain range index not found, " 242 "ignoring mapping request\n")); 243 map->status = ID_UNKNOWN; 244 return NT_STATUS_OK; 245 } 246 247 reduced_rid = normalized_id % cfg->rangesize; 248 rid = reduced_rid + domain_range_index * cfg->rangesize; 249 250 sid_compose(map->sid, &domsid, rid); 190 251 191 252 /* We **really** should have some way of validating … … 194 255 195 256 map->status = ID_MAPPED; 257 map->xid.type = ID_TYPE_BOTH; 258 196 259 return NT_STATUS_OK; 197 260 } … … 201 264 **********************************/ 202 265 203 static NTSTATUS idmap_autorid_sid_to_id(struct autorid_global_config *global, 204 struct autorid_domain_config *domain, 266 static NTSTATUS idmap_autorid_sid_to_id_rid( 267 struct autorid_global_config *global, 268 struct autorid_range_config *range, 205 269 struct id_map *map) 206 270 { 207 271 uint32_t rid; 272 uint32_t reduced_rid; 208 273 209 274 sid_peek_rid(map->sid, &rid); 210 275 211 /* if the rid is higher than the size of the range, we cannot map it */ 212 if (rid >= global->rangesize) { 213 map->status = ID_UNKNOWN; 214 DEBUG(2, ("RID %d is larger then size of range (%d), " 215 "user cannot be mapped\n", rid, global->rangesize)); 216 return NT_STATUS_UNSUCCESSFUL; 217 } 218 map->xid.id = global->minvalue + 219 (global->rangesize * domain->domainnum)+rid; 220 221 /* We **really** should have some way of validating 222 the SID exists and is the correct type here. But 223 that is a deficiency in the idmap_rid design. */ 224 276 reduced_rid = rid % global->rangesize; 277 278 map->xid.id = reduced_rid + range->low_id; 279 map->xid.type = ID_TYPE_BOTH; 225 280 map->status = ID_MAPPED; 226 281 … … 235 290 struct id_map **ids) 236 291 { 292 struct idmap_tdb_common_context *commoncfg; 237 293 struct autorid_global_config *globalcfg; 238 294 NTSTATUS ret; 239 295 int i; 296 int num_tomap = 0; 297 int num_mapped = 0; 240 298 241 299 /* initialize the status to avoid surprise */ 242 300 for (i = 0; ids[i]; i++) { 243 301 ids[i]->status = ID_UNKNOWN; 244 } 245 246 globalcfg = talloc_get_type(dom->private_data, 302 num_tomap++; 303 } 304 305 commoncfg = 306 talloc_get_type_abort(dom->private_data, 307 struct idmap_tdb_common_context); 308 309 globalcfg = talloc_get_type(commoncfg->private_data, 247 310 struct autorid_global_config); 248 311 249 312 for (i = 0; ids[i]; i++) { 250 313 251 ret = idmap_autorid_id_to_sid(globalcfg, ids[i]);314 ret = idmap_autorid_id_to_sid(globalcfg, dom, ids[i]); 252 315 253 316 if ((!NT_STATUS_IS_OK(ret)) && … … 258 321 goto failure; 259 322 } 260 } 261 return NT_STATUS_OK; 323 324 if (NT_STATUS_IS_OK(ret) && ids[i]->status == ID_MAPPED) { 325 num_mapped++; 326 } 327 328 } 329 330 if (num_tomap == num_mapped) { 331 return NT_STATUS_OK; 332 } else if (num_mapped == 0) { 333 return NT_STATUS_NONE_MAPPED; 334 } 335 336 return STATUS_SOME_UNMAPPED; 337 262 338 263 339 failure: 264 340 return ret; 341 } 342 343 static bool idmap_autorid_sid_is_special(struct dom_sid *sid) 344 { 345 bool match; 346 347 match = sid_check_is_in_wellknown_domain(sid); 348 if (match) { 349 return true; 350 } 351 352 return false; 353 } 354 355 static NTSTATUS idmap_autorid_sid_to_id_special(struct idmap_domain *dom, 356 struct id_map *map) 357 { 358 struct idmap_tdb_common_context *common = 359 talloc_get_type_abort(dom->private_data, 360 struct idmap_tdb_common_context); 361 uint32_t count; 362 struct autorid_range_config range; 363 NTSTATUS status; 364 uint32_t free_id; 365 366 status = idmap_autorid_get_alloc_range(dom, &range); 367 if (!NT_STATUS_IS_OK(status)) { 368 return status; 369 } 370 371 /* Take the next free ID, counting from the top */ 372 free_id = 0; 373 for (count = 0; count < IDMAP_AUTORID_ALLOC_RESERVED; count++) { 374 struct id_map test_map; 375 struct dom_sid sid; 376 377 test_map.sid = &sid; 378 test_map.xid.type = map->xid.type; 379 test_map.xid.id = range.high_id - count; 380 test_map.status = ID_UNKNOWN; 381 382 status = idmap_tdb_common_unixid_to_sid(dom, &test_map); 383 if (NT_STATUS_EQUAL(NT_STATUS_NONE_MAPPED, status)) { 384 free_id = test_map.xid.id; 385 break; 386 } 387 388 if (!NT_STATUS_IS_OK(status)) { 389 /* error - get out */ 390 return status; 391 } 392 393 /* mapping exists - try next ID */ 394 } 395 396 if (free_id == 0) { 397 return NT_STATUS_NONE_MAPPED; 398 } 399 400 map->status = ID_MAPPED; 401 map->xid.id = free_id; 402 403 status = common->rw_ops->set_mapping(dom, map); 404 if (!NT_STATUS_IS_OK(status)) { 405 DEBUG(2, ("Error storing new mapping: %s\n", 406 nt_errstr(status))); 407 return status; 408 } 409 410 return NT_STATUS_OK; 411 } 412 413 struct idmap_autorid_sid_to_id_alloc_ctx { 414 struct idmap_domain *dom; 415 struct id_map *map; 416 }; 417 418 static NTSTATUS idmap_autorid_sid_to_id_alloc_action( 419 struct db_context *db, 420 void *private_data) 421 { 422 struct idmap_autorid_sid_to_id_alloc_ctx *ctx; 423 424 ctx = (struct idmap_autorid_sid_to_id_alloc_ctx *)private_data; 425 426 if (idmap_autorid_sid_is_special(ctx->map->sid)) { 427 NTSTATUS ret; 428 429 ret = idmap_autorid_sid_to_id_special(ctx->dom, ctx->map); 430 if (NT_STATUS_IS_OK(ret)) { 431 return NT_STATUS_OK; 432 } 433 if (!NT_STATUS_EQUAL(NT_STATUS_NONE_MAPPED, ret)) { 434 return ret; 435 } 436 437 DEBUG(10, ("Sepecial sid %s not mapped. falling back to " 438 "regular allocation\n", 439 sid_string_dbg(ctx->map->sid))); 440 } 441 442 return idmap_tdb_common_new_mapping(ctx->dom, ctx->map); 443 } 444 445 /* 446 * map a SID to xid using the idmap_tdb like pool 447 */ 448 static NTSTATUS idmap_autorid_sid_to_id_alloc( 449 struct idmap_tdb_common_context *ctx, 450 struct idmap_domain *dom, 451 struct id_map *map) 452 { 453 NTSTATUS ret; 454 struct idmap_autorid_sid_to_id_alloc_ctx alloc_ctx; 455 456 map->status = ID_UNKNOWN; 457 458 /* see if we already have a mapping */ 459 ret = idmap_tdb_common_sid_to_unixid(dom, map); 460 461 if (NT_STATUS_IS_OK(ret)) { 462 map->status = ID_MAPPED; 463 return ret; 464 } 465 466 /* bad things happened */ 467 if (!NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) { 468 DEBUG(1, ("Looking up SID->ID mapping for %s failed: %s\n", 469 sid_string_dbg(map->sid), nt_errstr(ret))); 470 return ret; 471 } 472 473 if (dom->read_only) { 474 DEBUG(3, ("Not allocating new mapping for %s, because backend " 475 "is read-only\n", sid_string_dbg(map->sid))); 476 map->status = ID_UNMAPPED; 477 return NT_STATUS_NONE_MAPPED; 478 } 479 480 DEBUG(10, ("Creating new mapping in pool for %s\n", 481 sid_string_dbg(map->sid))); 482 483 alloc_ctx.dom = dom; 484 alloc_ctx.map = map; 485 486 ret = dbwrap_trans_do(ctx->db, idmap_autorid_sid_to_id_alloc_action, 487 &alloc_ctx); 488 if (!NT_STATUS_IS_OK(ret)) { 489 DEBUG(1, ("Failed to create a new mapping in alloc range: %s\n", 490 nt_errstr(ret))); 491 return NT_STATUS_INTERNAL_DB_CORRUPTION; 492 } 493 494 map->status = ID_MAPPED; 495 return NT_STATUS_OK; 496 } 497 498 static bool idmap_autorid_domsid_is_for_alloc(struct dom_sid *sid) 499 { 500 bool match; 501 502 match = sid_check_is_wellknown_domain(sid, NULL); 503 if (match) { 504 return true; 505 } 506 507 return false; 508 } 509 510 static NTSTATUS idmap_autorid_sid_to_id(struct idmap_tdb_common_context *common, 511 struct idmap_domain *dom, 512 struct id_map *map) 513 { 514 struct autorid_global_config *global = 515 talloc_get_type_abort(common->private_data, 516 struct autorid_global_config); 517 struct winbindd_tdc_domain *domain; 518 struct autorid_range_config range; 519 uint32_t rid; 520 struct dom_sid domainsid; 521 NTSTATUS ret; 522 523 ZERO_STRUCT(range); 524 map->status = ID_UNKNOWN; 525 526 DEBUG(10, ("Trying to map %s\n", sid_string_dbg(map->sid))); 527 528 sid_copy(&domainsid, map->sid); 529 if (!sid_split_rid(&domainsid, &rid)) { 530 DEBUG(4, ("Could not determine domain SID from %s, " 531 "ignoring mapping request\n", 532 sid_string_dbg(map->sid))); 533 map->status = ID_UNMAPPED; 534 return NT_STATUS_NONE_MAPPED; 535 } 536 537 if (idmap_autorid_domsid_is_for_alloc(&domainsid)) { 538 DEBUG(10, ("SID %s is for ALLOC range.\n", 539 sid_string_dbg(map->sid))); 540 541 return idmap_autorid_sid_to_id_alloc(common, dom, map); 542 } 543 544 if (dom_sid_equal(&domainsid, &global_sid_Builtin) && ignore_builtin) { 545 DEBUG(10, ("Ignoring request for BUILTIN domain\n")); 546 map->status = ID_UNMAPPED; 547 return NT_STATUS_NONE_MAPPED; 548 } 549 550 /* 551 * Check if the domain is around 552 */ 553 domain = wcache_tdc_fetch_domainbysid(talloc_tos(), 554 &domainsid); 555 if (domain == NULL) { 556 DEBUG(10, ("Ignoring unknown domain sid %s\n", 557 sid_string_dbg(&domainsid))); 558 map->status = ID_UNMAPPED; 559 return NT_STATUS_NONE_MAPPED; 560 } 561 TALLOC_FREE(domain); 562 563 sid_to_fstring(range.domsid, &domainsid); 564 565 range.domain_range_index = rid / (global->rangesize); 566 567 ret = idmap_autorid_get_domainrange(autorid_db, &range, dom->read_only); 568 if (NT_STATUS_EQUAL(ret, NT_STATUS_NOT_FOUND) && dom->read_only) { 569 DEBUG(10, ("read-only is enabled, did not allocate " 570 "new range for domain %s\n", 571 sid_string_dbg(&domainsid))); 572 map->status = ID_UNMAPPED; 573 return NT_STATUS_NONE_MAPPED; 574 } 575 if (!NT_STATUS_IS_OK(ret)) { 576 DEBUG(3, ("Could not determine range for domain, " 577 "check previous messages for reason\n")); 578 return ret; 579 } 580 581 return idmap_autorid_sid_to_id_rid(global, &range, map); 265 582 } 266 583 … … 272 589 struct id_map **ids) 273 590 { 274 struct autorid_global_config *global;591 struct idmap_tdb_common_context *commoncfg; 275 592 NTSTATUS ret; 276 593 int i; 594 int num_tomap = 0; 595 int num_mapped = 0; 277 596 278 597 /* initialize the status to avoid surprise */ 279 598 for (i = 0; ids[i]; i++) { 280 599 ids[i]->status = ID_UNKNOWN; 281 } 282 283 global = talloc_get_type(dom->private_data, 284 struct autorid_global_config); 600 num_tomap++; 601 } 602 603 commoncfg = 604 talloc_get_type_abort(dom->private_data, 605 struct idmap_tdb_common_context); 285 606 286 607 for (i = 0; ids[i]; i++) { 287 struct winbindd_tdc_domain *domain; 288 struct autorid_domain_config domaincfg; 289 uint32_t rid; 290 struct dom_sid domainsid; 291 292 ZERO_STRUCT(domaincfg); 293 294 sid_copy(&domainsid, ids[i]->sid); 295 if (!sid_split_rid(&domainsid, &rid)) { 296 DEBUG(4, ("Could not determine domain SID from %s, " 297 "ignoring mapping request\n", 298 sid_string_dbg(ids[i]->sid))); 299 continue; 300 } 301 302 /* 303 * Check if the domain is around 304 */ 305 domain = wcache_tdc_fetch_domainbysid(talloc_tos(), 306 &domainsid); 307 if (domain == NULL) { 308 DEBUG(10, ("Ignoring unknown domain sid %s\n", 309 sid_string_dbg(&domainsid))); 310 continue; 311 } 312 TALLOC_FREE(domain); 313 314 domaincfg.globalcfg = global; 315 sid_to_fstring(domaincfg.sid, &domainsid); 316 317 ret = dbwrap_trans_do(autorid_db, 318 idmap_autorid_get_domainrange, 319 &domaincfg); 320 321 if (!NT_STATUS_IS_OK(ret)) { 322 DEBUG(3, ("Could not determine range for domain, " 323 "check previous messages for reason\n")); 324 goto failure; 325 } 326 327 ret = idmap_autorid_sid_to_id(global, &domaincfg, ids[i]); 328 608 ret = idmap_autorid_sid_to_id(commoncfg, dom, ids[i]); 329 609 if ((!NT_STATUS_IS_OK(ret)) && 330 610 (!NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED))) { … … 332 612 DEBUG(3, ("Unexpected error resolving a SID (%s)\n", 333 613 sid_string_dbg(ids[i]->sid))); 334 goto failure; 335 } 336 } 614 return ret; 615 } 616 617 if (NT_STATUS_IS_OK(ret) && ids[i]->status == ID_MAPPED) { 618 num_mapped++; 619 } 620 } 621 622 if (num_tomap == num_mapped) { 623 return NT_STATUS_OK; 624 } else if (num_mapped == 0) { 625 return NT_STATUS_NONE_MAPPED; 626 } 627 628 return STATUS_SOME_UNMAPPED; 629 } 630 631 static NTSTATUS idmap_autorid_preallocate_wellknown(struct idmap_domain *dom) 632 { 633 const char *groups[] = { "S-1-1-0", "S-1-2-0", "S-1-2-1", 634 "S-1-3-0", "S-1-3-1", "S-1-3-2", "S-1-3-3", "S-1-3-4", 635 "S-1-5-1", "S-1-5-2", "S-1-5-3", "S-1-5-4", "S-1-5-6", 636 "S-1-5-7", "S-1-5-8", "S-1-5-9", "S-1-5-10", "S-1-5-11", 637 "S-1-5-12", "S-1-5-13", "S-1-5-14", "S-1-5-15", 638 "S-1-5-17", "S-1-5-18", "S-1-5-19", "S-1-5-20" 639 }; 640 641 struct id_map **maps; 642 int i, num; 643 NTSTATUS status; 644 645 if (dom->read_only) { 646 return NT_STATUS_OK; 647 } 648 649 num = ARRAY_SIZE(groups); 650 651 maps = talloc_array(talloc_tos(), struct id_map*, num+1); 652 if (!maps) { 653 return NT_STATUS_NO_MEMORY; 654 } 655 656 for (i = 0; i < num; i++) { 657 maps[i] = talloc(maps, struct id_map); 658 if (maps[i] == NULL) { 659 talloc_free(maps); 660 return NT_STATUS_NO_MEMORY; 661 } 662 maps[i]->xid.type = ID_TYPE_GID; 663 maps[i]->sid = dom_sid_parse_talloc(maps, groups[i]); 664 } 665 666 maps[num] = NULL; 667 668 status = idmap_autorid_sids_to_unixids(dom, maps); 669 670 DEBUG(10,("Preallocation run finished with status %s\n", 671 nt_errstr(status))); 672 673 talloc_free(maps); 674 675 return NT_STATUS_IS_OK(status)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL; 676 } 677 678 static NTSTATUS idmap_autorid_initialize_action(struct db_context *db, 679 void *private_data) 680 { 681 struct idmap_domain *dom; 682 struct idmap_tdb_common_context *common; 683 struct autorid_global_config *config; 684 NTSTATUS status; 685 686 dom = (struct idmap_domain *)private_data; 687 common = (struct idmap_tdb_common_context *)dom->private_data; 688 config = (struct autorid_global_config *)common->private_data; 689 690 status = idmap_autorid_init_hwms(db); 691 if (!NT_STATUS_IS_OK(status)) { 692 return status; 693 } 694 695 status = idmap_autorid_saveconfig(db, config); 696 if (!NT_STATUS_IS_OK(status)) { 697 DEBUG(1, ("Failed to store configuration data!\n")); 698 return status; 699 } 700 701 status = idmap_autorid_preallocate_wellknown(dom); 702 if (!NT_STATUS_IS_OK(status)) { 703 DEBUG(1, ("Failed to preallocate wellknown sids: %s\n", 704 nt_errstr(status))); 705 return status; 706 } 707 337 708 return NT_STATUS_OK; 338 339 failure: 340 return ret; 341 342 } 343 344 /* initialize the given HWM to 0 if it does not exist yet */ 345 static NTSTATUS idmap_autorid_init_hwm(const char *hwm) { 346 709 } 710 711 static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom) 712 { 713 struct idmap_tdb_common_context *commonconfig; 714 struct autorid_global_config *config; 347 715 NTSTATUS status; 348 int32_t hwmval; 349 350 hwmval = dbwrap_fetch_int32(autorid_db, hwm); 351 if ((hwmval < 0)) { 352 status = dbwrap_trans_store_int32(autorid_db, hwm, 0); 353 if (!NT_STATUS_IS_OK(status)) { 354 DEBUG(0, 355 ("Unable to initialise HWM (%s) in autorid " 356 "database: %s\n", hwm, nt_errstr(status))); 357 return NT_STATUS_INTERNAL_DB_ERROR; 358 } 359 } 360 361 return NT_STATUS_OK; 362 } 363 364 /* 365 * open and initialize the database which stores the ranges for the domains 366 */ 367 static NTSTATUS idmap_autorid_db_init(void) 368 { 369 NTSTATUS status; 370 371 if (autorid_db) { 372 /* its already open */ 373 return NT_STATUS_OK; 374 } 375 376 /* Open idmap repository */ 377 autorid_db = db_open(NULL, state_path("autorid.tdb"), 0, 378 TDB_DEFAULT, O_RDWR | O_CREAT, 0644); 379 380 if (!autorid_db) { 381 DEBUG(0, ("Unable to open idmap_autorid database '%s'\n", 382 state_path("autorid.tdb"))); 383 return NT_STATUS_UNSUCCESSFUL; 384 } 385 386 /* Initialize high water mark for the currently used range to 0 */ 387 388 status = idmap_autorid_init_hwm(HWM); 389 NT_STATUS_NOT_OK_RETURN(status); 390 391 status = idmap_autorid_init_hwm(ALLOC_HWM_UID); 392 NT_STATUS_NOT_OK_RETURN(status); 393 394 status = idmap_autorid_init_hwm(ALLOC_HWM_GID); 395 396 return status; 397 } 398 399 static struct autorid_global_config *idmap_autorid_loadconfig(TALLOC_CTX * ctx) 400 { 401 402 TDB_DATA data; 403 struct autorid_global_config *cfg; 404 unsigned long minvalue, rangesize, maxranges; 405 406 data = dbwrap_fetch_bystring(autorid_db, ctx, CONFIGKEY); 407 408 if (!data.dptr) { 409 DEBUG(10, ("No saved config found\n")); 410 return NULL; 411 } 412 413 cfg = TALLOC_ZERO_P(ctx, struct autorid_global_config); 414 if (!cfg) { 415 return NULL; 416 } 417 418 if (sscanf((char *)data.dptr, 419 "minvalue:%lu rangesize:%lu maxranges:%lu", 420 &minvalue, &rangesize, &maxranges) != 3) { 421 DEBUG(1, 422 ("Found invalid configuration data" 423 "creating new config\n")); 424 return NULL; 425 } 426 427 cfg->minvalue = minvalue; 428 cfg->rangesize = rangesize; 429 cfg->maxranges = maxranges; 430 431 DEBUG(10, ("Loaded previously stored configuration " 432 "minvalue:%d rangesize:%d\n", 433 cfg->minvalue, cfg->rangesize)); 434 435 return cfg; 436 437 } 438 439 static NTSTATUS idmap_autorid_saveconfig(struct autorid_global_config *cfg) 440 { 441 442 NTSTATUS status; 443 TDB_DATA data; 444 char *cfgstr; 445 446 cfgstr = 447 talloc_asprintf(talloc_tos(), 448 "minvalue:%u rangesize:%u maxranges:%u", 449 cfg->minvalue, cfg->rangesize, cfg->maxranges); 450 451 if (!cfgstr) { 452 return NT_STATUS_NO_MEMORY; 453 } 454 455 data = string_tdb_data(cfgstr); 456 457 status = dbwrap_trans_store_bystring(autorid_db, CONFIGKEY, 458 data, TDB_REPLACE); 459 460 talloc_free(cfgstr); 461 462 return status; 463 } 464 465 static NTSTATUS idmap_autorid_initialize(struct idmap_domain *dom) 466 { 467 struct autorid_global_config *config; 468 struct autorid_global_config *storedconfig = NULL; 469 NTSTATUS status; 470 uint32_t hwm; 716 char *db_path; 471 717 472 718 if (!strequal(dom->name, "*")) { … … 477 723 } 478 724 479 config = TALLOC_ZERO_P(dom, struct autorid_global_config); 725 commonconfig = talloc_zero(dom, struct idmap_tdb_common_context); 726 if (!commonconfig) { 727 DEBUG(0, ("Out of memory!\n")); 728 return NT_STATUS_NO_MEMORY; 729 } 730 dom->private_data = commonconfig; 731 732 commonconfig->rw_ops = talloc_zero(commonconfig, struct idmap_rw_ops); 733 if (commonconfig->rw_ops == NULL) { 734 DEBUG(0, ("Out of memory!\n")); 735 return NT_STATUS_NO_MEMORY; 736 } 737 738 config = talloc_zero(commonconfig, struct autorid_global_config); 480 739 if (!config) { 481 740 DEBUG(0, ("Out of memory!\n")); 482 741 return NT_STATUS_NO_MEMORY; 483 742 } 484 485 status = idmap_autorid_db_init(); 486 if (!NT_STATUS_IS_OK(status)) { 487 goto error; 488 } 743 commonconfig->private_data = config; 489 744 490 745 config->minvalue = dom->low_id; 491 config->rangesize = lp_parm_int(-1, "idmap config *", "rangesize", 100000); 492 493 if (config->rangesize < 2000) { 494 DEBUG(1, ("autorid rangesize must be at least 2000\n")); 495 status = NT_STATUS_INVALID_PARAMETER; 496 goto error; 497 } 746 config->rangesize = lp_parm_int(-1, "idmap config *", 747 "rangesize", 100000); 498 748 499 749 config->maxranges = (dom->high_id - dom->low_id + 1) / … … 501 751 502 752 if (config->maxranges == 0) { 503 DEBUG(1, (" allowed uid range is smaller then rangesize,"504 " increase uid range or decrease rangesize\n"));753 DEBUG(1, ("Allowed uid range is smaller than rangesize. " 754 "Increase uid range or decrease rangesize.\n")); 505 755 status = NT_STATUS_INVALID_PARAMETER; 506 756 goto error; … … 516 766 } 517 767 518 DEBUG(10, ("Current configuration in config is "519 "minvalue:%d rangesize:%d maxranges:%d\n",520 config->minvalue, config->rangesize, config->maxranges));521 522 /* read previously stored config and current HWM */523 storedconfig = idmap_autorid_loadconfig(talloc_tos());524 525 if (!dbwrap_fetch_uint32(autorid_db, HWM, &hwm)) {526 DEBUG(1, ("Fatal error while fetching current "527 "HWM value!\n"));528 status = NT_STATUS_INTERNAL_ERROR;529 goto error;530 }531 532 /* did the minimum value or rangesize change? */533 if (storedconfig &&534 ((storedconfig->minvalue != config->minvalue) ||535 (storedconfig->rangesize != config->rangesize))) {536 DEBUG(1, ("New configuration values for rangesize or "537 "minimum uid value conflict with previously "538 "used values! Aborting initialization\n"));539 status = NT_STATUS_INVALID_PARAMETER;540 goto error;541 }542 543 /*544 * has the highest uid value been reduced to setting that is not545 * sufficient any more for already existing ranges?546 */547 if (hwm > config->maxranges) {548 DEBUG(1, ("New upper uid limit is too low to cover "549 "existing mappings! Aborting initialization\n"));550 status = NT_STATUS_INVALID_PARAMETER;551 goto error;552 }553 554 status = idmap_autorid_saveconfig(config);555 556 if (!NT_STATUS_IS_OK(status)) {557 DEBUG(1, ("Failed to store configuration data!\n"));558 goto error;559 }560 561 768 DEBUG(5, ("%d domain ranges with a size of %d are available\n", 562 769 config->maxranges, config->rangesize)); 563 770 564 dom->private_data = config; 771 ignore_builtin = lp_parm_bool(-1, "idmap config *", 772 "ignore builtin", false); 773 774 /* fill the TDB common configuration */ 775 776 commonconfig->max_id = config->rangesize - 1 777 - IDMAP_AUTORID_ALLOC_RESERVED; 778 commonconfig->hwmkey_uid = ALLOC_HWM_UID; 779 commonconfig->hwmkey_gid = ALLOC_HWM_GID; 780 commonconfig->rw_ops->get_new_id = idmap_autorid_allocate_id; 781 commonconfig->rw_ops->set_mapping = idmap_tdb_common_set_mapping; 782 783 db_path = state_path("autorid.tdb"); 784 if (db_path == NULL) { 785 status = NT_STATUS_NO_MEMORY; 786 goto error; 787 } 788 789 status = idmap_autorid_db_open(db_path, 790 NULL, /* TALLOC_CTX */ 791 &autorid_db); 792 TALLOC_FREE(db_path); 793 if (!NT_STATUS_IS_OK(status)) { 794 goto error; 795 } 796 797 commonconfig->db = autorid_db; 798 799 status = dbwrap_trans_do(autorid_db, 800 idmap_autorid_initialize_action, 801 dom); 802 if (!NT_STATUS_IS_OK(status)) { 803 DEBUG(1, ("Failed to init the idmap database: %s\n", 804 nt_errstr(status))); 805 goto error; 806 } 565 807 566 808 goto done; … … 570 812 571 813 done: 572 talloc_free(storedconfig);573 574 814 return status; 575 }576 577 static NTSTATUS idmap_autorid_allocate_id(struct idmap_domain *dom,578 struct unixid *xid) {579 580 NTSTATUS ret;581 struct autorid_global_config *globalcfg;582 struct autorid_domain_config domaincfg;583 uint32_t hwm;584 const char *hwmkey;585 586 if (!strequal(dom->name, "*")) {587 DEBUG(3, ("idmap_autorid_allocate_id: "588 "Refusing creation of mapping for domain'%s'. "589 "Currently only supported for the default "590 "domain \"*\".\n",591 dom->name));592 return NT_STATUS_NOT_IMPLEMENTED;593 }594 595 if ((xid->type != ID_TYPE_UID) && (xid->type != ID_TYPE_GID)) {596 return NT_STATUS_INVALID_PARAMETER;597 }598 599 600 globalcfg = talloc_get_type(dom->private_data,601 struct autorid_global_config);602 603 /* fetch the range for the allocation pool */604 605 ZERO_STRUCT(domaincfg);606 607 domaincfg.globalcfg = globalcfg;608 fstrcpy(domaincfg.sid, ALLOC_RANGE);609 610 ret = dbwrap_trans_do(autorid_db,611 idmap_autorid_get_domainrange,612 &domaincfg);613 if (!NT_STATUS_IS_OK(ret)) {614 DEBUG(3, ("Could not determine range for allocation pool, "615 "check previous messages for reason\n"));616 return ret;617 }618 619 /* fetch the current HWM */620 hwmkey = (xid->type==ID_TYPE_UID)?ALLOC_HWM_UID:ALLOC_HWM_GID;621 622 if (!dbwrap_fetch_uint32(autorid_db, hwmkey, &hwm)) {623 DEBUG(1, ("Failed to fetch current allocation HWM value: %s\n",624 nt_errstr(ret)));625 return NT_STATUS_INTERNAL_ERROR;626 }627 628 if (hwm >= globalcfg->rangesize) {629 DEBUG(1, ("allocation range is depleted!\n"));630 return NT_STATUS_NO_MEMORY;631 }632 633 ret = dbwrap_change_uint32_atomic(autorid_db, hwmkey, &(xid->id), 1);634 if (!NT_STATUS_IS_OK(ret)) {635 DEBUG(1, ("Fatal error while allocating new ID!\n"));636 return ret;637 }638 639 xid->id = globalcfg->minvalue +640 globalcfg->rangesize * domaincfg.domainnum +641 xid->id;642 643 DEBUG(10, ("Returned new %s %d from allocation range\n",644 (xid->type==ID_TYPE_UID)?"uid":"gid", xid->id));645 646 return ret;647 815 } 648 816 … … 657 825 }; 658 826 827 static_decl_idmap; 659 828 NTSTATUS idmap_autorid_init(void) 660 829 { -
vendor/current/source3/winbindd/idmap_hash/idmap_hash.c
r746 r988 105 105 ********************************************************************/ 106 106 107 static NTSTATUS be_init(struct idmap_domain *dom)107 static NTSTATUS idmap_hash_initialize(struct idmap_domain *dom) 108 108 { 109 109 struct sid_hash_table *hashed_domains; … … 113 113 int i; 114 114 115 if (!strequal(dom->name, "*")) { 116 DBG_ERR("Error: idmap_hash configured for domain '%s'. " 117 "But the hash module can only be used for the default " 118 "idmap configuration.\n", dom->name); 119 return NT_STATUS_INVALID_PARAMETER; 120 } 121 115 122 /* If the domain SID hash table has been initialized, assume 116 123 that we completed this function previously */ … … 128 135 /* Create the hash table of domain SIDs */ 129 136 130 hashed_domains = TALLOC_ZERO_ARRAY(dom, struct sid_hash_table, 4096);137 hashed_domains = talloc_zero_array(dom, struct sid_hash_table, 4096); 131 138 BAIL_ON_PTR_NT_ERROR(hashed_domains, nt_status); 132 139 … … 138 145 if (is_null_sid(&dom_list[i].sid)) 139 146 continue; 147 148 /* 149 * Check if the domain from the list is not already configured 150 * to use another idmap backend. Not checking this makes the 151 * idmap_hash module map IDs for *all* domains implicitly. This 152 * is quite dangerous in setups that use multiple idmap 153 * configurations. 154 */ 155 156 if (domain_has_idmap_config(dom_list[i].domain_name)) { 157 continue; 158 } 159 140 160 if ((hash = hash_domain_sid(&dom_list[i].sid)) == 0) 141 161 continue; 142 162 143 D EBUG(5,("hash:be_init()Adding %s (%s) -> %d\n",163 DBG_INFO("Adding %s (%s) -> %d\n", 144 164 dom_list[i].domain_name, 145 165 sid_string_dbg(&dom_list[i].sid), 146 hash) );166 hash); 147 167 148 168 hashed_domains[hash].sid = talloc(hashed_domains, struct dom_sid); … … 167 187 int i; 168 188 189 if (!ids) { 190 nt_status = NT_STATUS_INVALID_PARAMETER; 191 BAIL_ON_NTSTATUS_ERROR(nt_status); 192 } 193 169 194 /* initialize the status to avoid suprise */ 170 195 for (i = 0; ids[i]; i++) { … … 172 197 } 173 198 174 nt_status = be_init(dom);199 nt_status = idmap_hash_initialize(dom); 175 200 BAIL_ON_NTSTATUS_ERROR(nt_status); 176 177 if (!ids) {178 nt_status = NT_STATUS_INVALID_PARAMETER;179 BAIL_ON_NTSTATUS_ERROR(nt_status);180 }181 201 182 202 for (i=0; ids[i]; i++) { … … 217 237 int i; 218 238 239 if (!ids) { 240 nt_status = NT_STATUS_INVALID_PARAMETER; 241 BAIL_ON_NTSTATUS_ERROR(nt_status); 242 } 243 219 244 /* initialize the status to avoid suprise */ 220 245 for (i = 0; ids[i]; i++) { … … 222 247 } 223 248 224 nt_status = be_init(dom);249 nt_status = idmap_hash_initialize(dom); 225 250 BAIL_ON_NTSTATUS_ERROR(nt_status); 226 227 if (!ids) {228 nt_status = NT_STATUS_INVALID_PARAMETER;229 BAIL_ON_NTSTATUS_ERROR(nt_status);230 }231 251 232 252 for (i=0; ids[i]; i++) { … … 348 368 349 369 static struct idmap_methods hash_idmap_methods = { 350 .init = be_init,370 .init = idmap_hash_initialize, 351 371 .unixids_to_sids = unixids_to_sids, 352 372 .sids_to_unixids = sids_to_unixids, … … 367 387 **********************************************************************/ 368 388 389 static_decl_idmap; 369 390 NTSTATUS idmap_hash_init(void) 370 391 { -
vendor/current/source3/winbindd/idmap_hash/mapfile.c
r740 r988 68 68 return false; 69 69 70 if ((p = x_fgets(buffer, sizeof(buffer)-1, lw_map_file)) == NULL) { 70 p = x_fgets(buffer, sizeof(buffer)-1, lw_map_file); 71 if (p == NULL) { 71 72 return false; 72 73 } … … 74 75 /* Strip newlines and carriage returns */ 75 76 76 len = strlen_m(buffer) - 1; 77 len = strlen_m(buffer); 78 if (len == 0) { 79 return false; 80 } 81 len -= 1; 82 77 83 while ((buffer[len] == '\n') || (buffer[len] == '\r')) { 78 84 buffer[len--] = '\0'; … … 88 94 p++; 89 95 90 fstrcpy(key, buffer);91 fstrcpy(value, p);96 strlcpy(key, buffer, sizeof(fstring)); 97 strlcpy(value, p, sizeof(fstring)); 92 98 93 99 /* Eat whitespace */ -
vendor/current/source3/winbindd/idmap_ldap.c
r740 r988 38 38 39 39 #include "smbldap.h" 40 41 static char *idmap_fetch_secret(const char *backend, 42 const char *domain, const char *identity) 43 { 44 char *tmp, *ret; 45 int r; 46 47 r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain); 48 49 if (r < 0) 50 return NULL; 51 52 strupper_m(tmp); /* make sure the key is case insensitive */ 53 ret = secrets_fetch_generic(tmp, identity); 54 55 SAFE_FREE(tmp); 56 57 return ret; 58 } 40 #include "passdb/pdb_ldap_schema.h" 59 41 60 42 struct idmap_ldap_context { … … 300 282 } 301 283 302 talloc_autofree_ldapmsg(mem_ctx, result);284 smbldap_talloc_autofree_ldapmsg(mem_ctx, result); 303 285 304 286 count = ldap_count_entries(ctx->smbldap_state->ldap_struct, result); … … 444 426 } 445 427 446 ctx = TALLOC_ZERO_P(dom, struct idmap_ldap_context);428 ctx = talloc_zero(dom, struct idmap_ldap_context); 447 429 if ( ! ctx) { 448 430 DEBUG(0, ("Out of memory!\n")); … … 471 453 tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL); 472 454 if ( ! tmp || ! *tmp) { 473 tmp = lp_ldap_idmap_suffix( );455 tmp = lp_ldap_idmap_suffix(talloc_tos()); 474 456 if ( ! tmp) { 475 457 DEBUG(1, ("ERROR: missing idmap ldap suffix\n")); … … 488 470 ctx->rw_ops->set_mapping = idmap_ldap_set_mapping; 489 471 472 /* get_credentials deals with setting up creds */ 473 490 474 ret = smbldap_init(ctx, winbind_event_context(), ctx->url, 491 &ctx->smbldap_state);475 false, NULL, NULL, &ctx->smbldap_state); 492 476 if (!NT_STATUS_IS_OK(ret)) { 493 477 DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", ctx->url)); … … 656 640 } 657 641 658 659 /* max number of ids requested per batch query */660 #define IDMAP_LDAP_MAX_IDS 30661 662 642 /********************************** 663 643 lookup a set of unix ids. 664 644 **********************************/ 665 666 /* this function searches up to IDMAP_LDAP_MAX_IDS entries667 * in maps for a match */668 static struct id_map *find_map_by_id(struct id_map **maps,669 enum id_type type,670 uint32_t id)671 {672 int i;673 674 for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) {675 if (maps[i] == NULL) { /* end of the run */676 return NULL;677 }678 if ((maps[i]->xid.type == type) && (maps[i]->xid.id == id)) {679 return maps[i];680 }681 }682 683 return NULL;684 }685 645 686 646 static NTSTATUS idmap_ldap_unixids_to_sids(struct idmap_domain *dom, … … 839 799 TALLOC_FREE(tmp); 840 800 841 map = find_map_by_id(&ids[bidx], type, id);801 map = idmap_find_map_by_id(&ids[bidx], type, id); 842 802 if (!map) { 843 803 DEBUG(2, ("WARNING: couldn't match sid (%s) " … … 895 855 lookup a set of sids. 896 856 **********************************/ 897 898 /* this function searches up to IDMAP_LDAP_MAX_IDS entries899 * in maps for a match */900 static struct id_map *find_map_by_sid(struct id_map **maps, struct dom_sid *sid)901 {902 int i;903 904 for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) {905 if (maps[i] == NULL) { /* end of the run */906 return NULL;907 }908 if (dom_sid_equal(maps[i]->sid, sid)) {909 return maps[i];910 }911 }912 913 return NULL;914 }915 857 916 858 static NTSTATUS idmap_ldap_sids_to_unixids(struct idmap_domain *dom, … … 1046 988 } 1047 989 1048 map = find_map_by_sid(&ids[bidx], &sid);990 map = idmap_find_map_by_sid(&ids[bidx], &sid); 1049 991 if (!map) { 1050 992 DEBUG(2, ("WARNING: couldn't find entry sid (%s) " -
vendor/current/source3/winbindd/idmap_nss.c
r740 r988 31 31 32 32 /***************************** 33 Initialise idmap database. 33 Initialise idmap database. 34 34 *****************************/ 35 35 36 36 static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom) 37 { 37 { 38 38 return NT_STATUS_OK; 39 39 } 40 40 41 41 /********************************** 42 lookup a set of unix ids. 42 lookup a set of unix ids. 43 43 **********************************/ 44 44 … … 121 121 122 122 /********************************** 123 lookup a set of sids. 123 lookup a set of sids. 124 124 **********************************/ 125 125 … … 136 136 struct group *gr; 137 137 enum lsa_SidType type; 138 const char *p = NULL; 138 139 char *name = NULL; 139 140 bool ret; … … 143 144 (void)winbind_on(); 144 145 ret = winbind_lookup_sid(talloc_tos(), ids[i]->sid, NULL, 145 (const char **)&name, &type);146 &p, &type); 146 147 (void)winbind_off(); 148 name = discard_const_p(char, p); 147 149 148 150 if (!ret) { -
vendor/current/source3/winbindd/idmap_passdb.c
r740 r988 45 45 46 46 for (i = 0; ids[i]; i++) { 47 48 47 /* unmapped by default */ 49 48 ids[i]->status = ID_UNMAPPED; 50 49 51 switch (ids[i]->xid.type) { 52 case ID_TYPE_UID: 53 if (pdb_uid_to_sid((uid_t)ids[i]->xid.id, ids[i]->sid)) { 54 ids[i]->status = ID_MAPPED; 55 } 56 break; 57 case ID_TYPE_GID: 58 if (pdb_gid_to_sid((gid_t)ids[i]->xid.id, ids[i]->sid)) { 59 ids[i]->status = ID_MAPPED; 60 } 61 break; 62 default: /* ?? */ 63 ids[i]->status = ID_UNKNOWN; 50 if (pdb_id_to_sid(&ids[i]->xid, ids[i]->sid)) { 51 ids[i]->status = ID_MAPPED; 64 52 } 65 53 } … … 77 65 78 66 for (i = 0; ids[i]; i++) { 79 enum lsa_SidType type; 80 union unid_t id; 81 82 if (pdb_sid_to_id(ids[i]->sid, &id, &type)) { 83 switch (type) { 84 case SID_NAME_USER: 85 ids[i]->xid.id = id.uid; 86 ids[i]->xid.type = ID_TYPE_UID; 87 ids[i]->status = ID_MAPPED; 88 break; 89 90 case SID_NAME_DOM_GRP: 91 case SID_NAME_ALIAS: 92 case SID_NAME_WKN_GRP: 93 ids[i]->xid.id = id.gid; 94 ids[i]->xid.type = ID_TYPE_GID; 95 ids[i]->status = ID_MAPPED; 96 break; 97 98 default: /* ?? */ 99 /* make sure it is marked as unmapped */ 100 ids[i]->status = ID_UNKNOWN; 101 break; 102 } 67 if (pdb_sid_to_id(ids[i]->sid, &ids[i]->xid)) { 68 ids[i]->status = ID_MAPPED; 103 69 } else { 104 70 /* Query Failed */ -
vendor/current/source3/winbindd/idmap_proto.h
r740 r988 35 35 NTSTATUS idmap_allocate_uid(struct unixid *id); 36 36 NTSTATUS idmap_allocate_gid(struct unixid *id); 37 NTSTATUS idmap_backends_unixid_to_sid(const char *domname, 38 struct id_map *id); 39 NTSTATUS idmap_backends_sid_to_unixid(const char *domname, 40 struct id_map *id); 37 NTSTATUS idmap_backends_unixid_to_sid(struct id_map *id); 41 38 42 39 /* The following definitions come from winbindd/idmap_nss.c */ … … 54 51 /* The following definitions come from winbindd/idmap_util.c */ 55 52 56 NTSTATUS idmap_uid_to_sid(const char *domname, struct dom_sid *sid, uid_t uid); 57 NTSTATUS idmap_gid_to_sid(const char *domname, struct dom_sid *sid, gid_t gid); 58 NTSTATUS idmap_sid_to_uid(const char *dom_name, struct dom_sid *sid, uid_t *uid); 59 NTSTATUS idmap_sid_to_gid(const char *domname, struct dom_sid *sid, gid_t *gid); 53 NTSTATUS idmap_uid_to_sid(struct dom_sid *sid, uid_t uid); 54 NTSTATUS idmap_gid_to_sid(struct dom_sid *sid, gid_t gid); 60 55 bool idmap_unix_id_is_in_range(uint32_t id, struct idmap_domain *dom); 56 struct id_map *idmap_find_map_by_id(struct id_map **maps, enum id_type type, 57 uint32_t id); 58 struct id_map *idmap_find_map_by_sid(struct id_map **maps, struct dom_sid *sid); 59 char *idmap_fetch_secret(const char *backend, const char *domain, 60 const char *identity); 61 62 /* max number of ids requested per LDAP batch query */ 63 #define IDMAP_LDAP_MAX_IDS 30 61 64 62 65 #endif /* _WINBINDD_IDMAP_PROTO_H_ */ -
vendor/current/source3/winbindd/idmap_rid.c
r740 r988 42 42 char *config_option = NULL; 43 43 44 ctx = TALLOC_ZERO_P(dom, struct idmap_rid_context);44 ctx = talloc_zero(dom, struct idmap_rid_context); 45 45 if (ctx == NULL) { 46 46 DEBUG(0, ("Out of memory!\n")); … … 88 88 sid_compose(map->sid, &domain->sid, map->xid.id - dom->low_id + ctx->base_rid); 89 89 90 /* We **really** should have some way of validating91 the SID exists and is the correct type here. But92 that is a deficiency in the idmap_rid design. */93 94 90 map->status = ID_MAPPED; 91 map->xid.type = ID_TYPE_BOTH; 95 92 96 93 return NT_STATUS_OK; … … 98 95 99 96 /********************************** 100 Single sid to id lookup function. 97 Single sid to id lookup function. 101 98 **********************************/ 102 99 … … 110 107 sid_peek_rid(map->sid, &rid); 111 108 map->xid.id = rid - ctx->base_rid + dom->low_id; 109 map->xid.type = ID_TYPE_BOTH; 112 110 113 111 /* apply filters before returning result */ … … 126 124 127 125 /********************************** 128 lookup a set of unix ids. 126 lookup a set of unix ids. 129 127 **********************************/ 130 128 … … 154 152 155 153 /********************************** 156 lookup a set of sids. 154 lookup a set of sids. 157 155 **********************************/ 158 156 … … 188 186 }; 189 187 188 static_decl_idmap; 190 189 NTSTATUS idmap_rid_init(void) 191 190 { -
vendor/current/source3/winbindd/idmap_tdb.c
r740 r988 29 29 #include "idmap.h" 30 30 #include "idmap_rw.h" 31 #include "dbwrap.h" 31 #include "idmap_tdb_common.h" 32 #include "dbwrap/dbwrap.h" 33 #include "dbwrap/dbwrap_open.h" 32 34 #include "../libcli/security/security.h" 33 35 #include "util_tdb.h" … … 40 42 41 43 #define IDMAP_VERSION 2 42 43 struct idmap_tdb_context {44 struct db_context *db;45 struct idmap_rw_ops *rw_ops;46 };47 44 48 45 /* High water mark keys */ … … 66 63 NTSTATUS status; 67 64 struct dom_sid sid; 68 uint32 rid;65 uint32_t rid; 69 66 fstring keystr; 70 67 fstring dom_name; 68 TDB_DATA key; 71 69 TDB_DATA key2; 70 TDB_DATA value; 72 71 struct convert_fn_state *s = (struct convert_fn_state *)private_data; 73 72 74 DEBUG(10,("Converting %s\n", (const char *)rec->key.dptr)); 75 76 p = strchr((const char *)rec->key.dptr, '/'); 73 key = dbwrap_record_get_key(rec); 74 75 DEBUG(10,("Converting %s\n", (const char *)key.dptr)); 76 77 p = strchr((const char *)key.dptr, '/'); 77 78 if (!p) 78 79 return 0; 79 80 80 81 *p = 0; 81 fstrcpy(dom_name, (const char *) rec->key.dptr);82 fstrcpy(dom_name, (const char *)key.dptr); 82 83 *p++ = '/'; 83 84 … … 86 87 /* We must delete the old record. */ 87 88 DEBUG(0,("Unable to find domain %s\n", dom_name )); 88 DEBUG(0,("deleting record %s\n", (const char *) rec->key.dptr ));89 90 status = rec->delete_rec(rec);89 DEBUG(0,("deleting record %s\n", (const char *)key.dptr )); 90 91 status = dbwrap_record_delete(rec); 91 92 if (!NT_STATUS_IS_OK(status)) { 92 93 DEBUG(0, ("Unable to delete record %s:%s\n", 93 (const char *) rec->key.dptr,94 (const char *)key.dptr, 94 95 nt_errstr(status))); 95 96 s->failed = true; … … 107 108 key2 = string_term_tdb_data(keystr); 108 109 109 status = dbwrap_store(s->db, key2, rec->value, TDB_INSERT); 110 value = dbwrap_record_get_value(rec); 111 112 status = dbwrap_store(s->db, key2, value, TDB_INSERT); 110 113 if (!NT_STATUS_IS_OK(status)) { 111 114 DEBUG(0,("Unable to add record %s:%s\n", … … 116 119 } 117 120 118 status = dbwrap_store(s->db, rec->value, key2, TDB_REPLACE);121 status = dbwrap_store(s->db, value, key2, TDB_REPLACE); 119 122 if (!NT_STATUS_IS_OK(status)) { 120 123 DEBUG(0,("Unable to update record %s:%s\n", 121 (const char *) rec->value.dptr,124 (const char *)value.dptr, 122 125 nt_errstr(status))); 123 126 s->failed = true; … … 125 128 } 126 129 127 status = rec->delete_rec(rec);130 status = dbwrap_record_delete(rec); 128 131 if (!NT_STATUS_IS_OK(status)) { 129 132 DEBUG(0,("Unable to delete record %s:%s\n", 130 (const char *) rec->key.dptr,133 (const char *)key.dptr, 131 134 nt_errstr(status))); 132 135 s->failed = true; … … 143 146 static bool idmap_tdb_upgrade(struct idmap_domain *dom, struct db_context *db) 144 147 { 145 int32 vers; 146 bool bigendianheader; 148 int32_t vers; 147 149 struct convert_fn_state s; 148 149 DEBUG(0, ("Upgrading winbindd_idmap.tdb from an old version\n")); 150 151 bigendianheader = (db->get_flags(db) & TDB_BIGENDIAN) ? True : False;152 153 vers = dbwrap_fetch_int32(db, "IDMAP_VERSION");154 155 if ( ((vers == -1) && bigendianheader) || (IREV(vers) == IDMAP_VERSION)) {156 /* Arrggghh ! Bytereversed or old big-endian- make order independent ! */150 NTSTATUS status; 151 152 status = dbwrap_fetch_int32_bystring(db, "IDMAP_VERSION", &vers); 153 if (!NT_STATUS_IS_OK(status)) { 154 vers = -1; 155 } 156 157 if (IREV(vers) == IDMAP_VERSION) { 158 /* Arrggghh ! Bytereversed - make order independent ! */ 157 159 /* 158 160 * high and low records were created on a … … 160 162 */ 161 163 162 int32 wm; 163 164 wm = dbwrap_fetch_int32(db, HWM_USER); 164 int32_t wm; 165 166 status = dbwrap_fetch_int32_bystring(db, HWM_USER, &wm); 167 if (!NT_STATUS_IS_OK(status)) { 168 wm = -1; 169 } 165 170 166 171 if (wm != -1) { … … 170 175 } 171 176 172 if (dbwrap_store_int32(db, HWM_USER, wm) == -1) { 173 DEBUG(0, ("Unable to byteswap user hwm in idmap database\n")); 177 status = dbwrap_store_int32_bystring(db, HWM_USER, wm); 178 if (!NT_STATUS_IS_OK(status)) { 179 DEBUG(0, ("Unable to byteswap user hwm in idmap " 180 "database: %s\n", nt_errstr(status))); 174 181 return False; 175 182 } 176 183 177 wm = dbwrap_fetch_int32(db, HWM_GROUP); 184 status = dbwrap_fetch_int32_bystring(db, HWM_GROUP, &wm); 185 if (!NT_STATUS_IS_OK(status)) { 186 wm = -1; 187 } 188 178 189 if (wm != -1) { 179 190 wm = IREV(wm); … … 182 193 } 183 194 184 if (dbwrap_store_int32(db, HWM_GROUP, wm) == -1) { 185 DEBUG(0, ("Unable to byteswap group hwm in idmap database\n")); 195 status = dbwrap_store_int32_bystring(db, HWM_GROUP, wm); 196 if (!NT_STATUS_IS_OK(status)) { 197 DEBUG(0, ("Unable to byteswap group hwm in idmap " 198 "database: %s\n", nt_errstr(status))); 186 199 return False; 187 200 } … … 192 205 193 206 /* the old format stored as DOMAIN/rid - now we store the SID direct */ 194 db->traverse(db, convert_fn, &s); 207 status = dbwrap_traverse(db, convert_fn, &s, NULL); 208 209 if (!NT_STATUS_IS_OK(status)) { 210 DEBUG(0, ("Database traverse failed during conversion\n")); 211 return false; 212 } 195 213 196 214 if (s.failed) { … … 199 217 } 200 218 201 if (dbwrap_store_int32(db, "IDMAP_VERSION", IDMAP_VERSION) == -1) { 202 DEBUG(0, ("Unable to store idmap version in database\n")); 219 status = dbwrap_store_int32_bystring(db, "IDMAP_VERSION", 220 IDMAP_VERSION); 221 if (!NT_STATUS_IS_OK(status)) { 222 DEBUG(0, ("Unable to store idmap version in database: %s\n", 223 nt_errstr(status))); 203 224 return False; 204 225 } … … 209 230 static NTSTATUS idmap_tdb_init_hwm(struct idmap_domain *dom) 210 231 { 211 int ret;212 232 uint32_t low_uid; 213 233 uint32_t low_gid; 214 234 bool update_uid = false; 215 235 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) { 236 struct idmap_tdb_common_context *ctx; 237 NTSTATUS status; 238 239 ctx = talloc_get_type(dom->private_data, 240 struct idmap_tdb_common_context); 241 242 status = dbwrap_fetch_uint32_bystring(ctx->db, HWM_USER, &low_uid); 243 if (!NT_STATUS_IS_OK(status) || low_uid < dom->low_id) { 222 244 update_uid = true; 223 245 } 224 246 225 low_gid = dbwrap_fetch_int32(ctx->db, HWM_GROUP);226 if ( low_gid == -1|| low_gid < dom->low_id) {247 status = dbwrap_fetch_uint32_bystring(ctx->db, HWM_GROUP, &low_gid); 248 if (!NT_STATUS_IS_OK(status) || low_gid < dom->low_id) { 227 249 update_gid = true; 228 250 } … … 232 254 } 233 255 234 if ( ctx->db->transaction_start(ctx->db) != 0) {256 if (dbwrap_transaction_start(ctx->db) != 0) { 235 257 DEBUG(0, ("Unable to start upgrade transaction!\n")); 236 258 return NT_STATUS_INTERNAL_DB_ERROR; … … 238 260 239 261 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); 262 status = dbwrap_store_uint32_bystring(ctx->db, HWM_USER, 263 dom->low_id); 264 if (!NT_STATUS_IS_OK(status)) { 265 dbwrap_transaction_cancel(ctx->db); 243 266 DEBUG(0, ("Unable to initialise user hwm in idmap " 244 "database \n"));267 "database: %s\n", nt_errstr(status))); 245 268 return NT_STATUS_INTERNAL_DB_ERROR; 246 269 } … … 248 271 249 272 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); 273 status = dbwrap_store_uint32_bystring(ctx->db, HWM_GROUP, 274 dom->low_id); 275 if (!NT_STATUS_IS_OK(status)) { 276 dbwrap_transaction_cancel(ctx->db); 253 277 DEBUG(0, ("Unable to initialise group hwm in idmap " 254 "database \n"));278 "database: %s\n", nt_errstr(status))); 255 279 return NT_STATUS_INTERNAL_DB_ERROR; 256 280 } 257 281 } 258 282 259 if ( ctx->db->transaction_commit(ctx->db) != 0) {283 if (dbwrap_transaction_commit(ctx->db) != 0) { 260 284 DEBUG(0, ("Unable to commit upgrade transaction!\n")); 261 285 return NT_STATUS_INTERNAL_DB_ERROR; … … 273 297 int32_t version; 274 298 bool config_error = false; 275 struct idmap_tdb_context *ctx; 276 277 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context); 299 struct idmap_tdb_common_context *ctx; 300 301 ctx = talloc_get_type(dom->private_data, 302 struct idmap_tdb_common_context); 278 303 279 304 if (ctx->db) { … … 296 321 297 322 /* Open idmap repository */ 298 db = db_open(mem_ctx, tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644); 323 db = db_open(mem_ctx, tdbfile, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644, 324 DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE); 299 325 if (!db) { 300 326 DEBUG(0, ("Unable to open idmap database\n")); … … 304 330 305 331 /* check against earlier versions */ 306 version = dbwrap_fetch_int32(db, "IDMAP_VERSION"); 332 ret = dbwrap_fetch_int32_bystring(db, "IDMAP_VERSION", &version); 333 if (!NT_STATUS_IS_OK(ret)) { 334 version = -1; 335 } 336 307 337 if (version != IDMAP_VERSION) { 308 338 if (config_error) { … … 313 343 goto done; 314 344 } 315 if (db ->transaction_start(db) != 0) {345 if (dbwrap_transaction_start(db) != 0) { 316 346 DEBUG(0, ("Unable to start upgrade transaction!\n")); 317 347 ret = NT_STATUS_INTERNAL_DB_ERROR; … … 320 350 321 351 if (!idmap_tdb_upgrade(dom, db)) { 322 db ->transaction_cancel(db);352 dbwrap_transaction_cancel(db); 323 353 DEBUG(0, ("Unable to open idmap database, it's in an old format, and upgrade failed!\n")); 324 354 ret = NT_STATUS_INTERNAL_DB_ERROR; … … 326 356 } 327 357 328 if (db ->transaction_commit(db) != 0) {358 if (dbwrap_transaction_commit(db) != 0) { 329 359 DEBUG(0, ("Unable to commit upgrade transaction!\n")); 330 360 ret = NT_STATUS_INTERNAL_DB_ERROR; … … 343 373 344 374 /********************************************************************** 345 IDMAP ALLOC TDB BACKEND346 **********************************************************************/347 348 /**********************************349 Allocate a new id.350 **********************************/351 352 struct idmap_tdb_allocate_id_context {353 const char *hwmkey;354 const char *hwmtype;355 uint32_t high_hwm;356 uint32_t hwm;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);417 418 /* Get current high water mark */419 switch (xid->type) {420 421 case ID_TYPE_UID:422 hwmkey = HWM_USER;423 hwmtype = "UID";424 break;425 426 case ID_TYPE_GID:427 hwmkey = HWM_GROUP;428 hwmtype = "GID";429 break;430 431 default:432 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));433 return NT_STATUS_INVALID_PARAMETER;434 }435 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;478 }479 480 /**********************************************************************481 375 IDMAP MAPPING TDB BACKEND 482 376 **********************************************************************/ … … 486 380 *****************************/ 487 381 488 static NTSTATUS idmap_tdb_set_mapping(struct idmap_domain *dom,489 const struct id_map *map);490 491 382 static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom) 492 383 { 493 384 NTSTATUS ret; 494 struct idmap_tdb_co ntext *ctx;385 struct idmap_tdb_common_context *ctx; 495 386 496 387 DEBUG(10, ("idmap_tdb_db_init called for domain '%s'\n", dom->name)); 497 388 498 ctx = talloc_zero(dom, struct idmap_tdb_co ntext);389 ctx = talloc_zero(dom, struct idmap_tdb_common_context); 499 390 if ( ! ctx) { 500 391 DEBUG(0, ("Out of memory!\n")); … … 516 407 } 517 408 518 ctx->rw_ops->get_new_id = idmap_tdb_get_new_id; 519 ctx->rw_ops->set_mapping = idmap_tdb_set_mapping; 409 ctx->max_id = dom->high_id; 410 ctx->hwmkey_uid = HWM_USER; 411 ctx->hwmkey_gid = HWM_GROUP; 412 413 ctx->rw_ops->get_new_id = idmap_tdb_common_get_new_id; 414 ctx->rw_ops->set_mapping = idmap_tdb_common_set_mapping; 520 415 521 416 dom->private_data = ctx; … … 533 428 } 534 429 535 536 /**537 * store a mapping in the database538 */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 659 660 /**********************************661 Single id to sid lookup function.662 **********************************/663 664 static NTSTATUS idmap_tdb_id_to_sid(struct idmap_domain *dom, struct id_map *map)665 {666 NTSTATUS ret;667 TDB_DATA data;668 char *keystr;669 struct idmap_tdb_context *ctx;670 671 if (!dom || !map) {672 return NT_STATUS_INVALID_PARAMETER;673 }674 675 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);676 677 /* apply filters before checking */678 if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {679 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",680 map->xid.id, dom->low_id, dom->high_id));681 return NT_STATUS_NONE_MAPPED;682 }683 684 switch (map->xid.type) {685 686 case ID_TYPE_UID:687 keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);688 break;689 690 case ID_TYPE_GID:691 keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);692 break;693 694 default:695 DEBUG(2, ("INVALID unix ID type: 0x02%x\n", map->xid.type));696 return NT_STATUS_INVALID_PARAMETER;697 }698 699 /* final SAFE_FREE safe */700 data.dptr = NULL;701 702 if (keystr == NULL) {703 DEBUG(0, ("Out of memory!\n"));704 ret = NT_STATUS_NO_MEMORY;705 goto done;706 }707 708 DEBUG(10,("Fetching record %s\n", keystr));709 710 /* Check if the mapping exists */711 data = dbwrap_fetch_bystring(ctx->db, NULL, keystr);712 713 if (!data.dptr) {714 DEBUG(10,("Record %s not found\n", keystr));715 ret = NT_STATUS_NONE_MAPPED;716 goto done;717 }718 719 if (!string_to_sid(map->sid, (const char *)data.dptr)) {720 DEBUG(10,("INVALID SID (%s) in record %s\n",721 (const char *)data.dptr, keystr));722 ret = NT_STATUS_INTERNAL_DB_ERROR;723 goto done;724 }725 726 DEBUG(10,("Found record %s -> %s\n", keystr, (const char *)data.dptr));727 ret = NT_STATUS_OK;728 729 done:730 talloc_free(data.dptr);731 talloc_free(keystr);732 return ret;733 }734 735 /**********************************736 Single sid to id lookup function.737 **********************************/738 739 static NTSTATUS idmap_tdb_sid_to_id(struct idmap_domain *dom, struct id_map *map)740 {741 NTSTATUS ret;742 TDB_DATA data;743 char *keystr;744 unsigned long rec_id = 0;745 struct idmap_tdb_context *ctx;746 TALLOC_CTX *tmp_ctx = talloc_stackframe();747 748 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);749 750 keystr = sid_string_talloc(tmp_ctx, map->sid);751 if (keystr == NULL) {752 DEBUG(0, ("Out of memory!\n"));753 ret = NT_STATUS_NO_MEMORY;754 goto done;755 }756 757 DEBUG(10,("Fetching record %s\n", keystr));758 759 /* Check if sid is present in database */760 data = dbwrap_fetch_bystring(ctx->db, tmp_ctx, keystr);761 if (!data.dptr) {762 DEBUG(10,("Record %s not found\n", keystr));763 ret = NT_STATUS_NONE_MAPPED;764 goto done;765 }766 767 /* What type of record is this ? */768 if (sscanf((const char *)data.dptr, "UID %lu", &rec_id) == 1) { /* Try a UID record. */769 map->xid.id = rec_id;770 map->xid.type = ID_TYPE_UID;771 DEBUG(10,("Found uid record %s -> %s \n", keystr, (const char *)data.dptr ));772 ret = NT_STATUS_OK;773 774 } else if (sscanf((const char *)data.dptr, "GID %lu", &rec_id) == 1) { /* Try a GID record. */775 map->xid.id = rec_id;776 map->xid.type = ID_TYPE_GID;777 DEBUG(10,("Found gid record %s -> %s \n", keystr, (const char *)data.dptr ));778 ret = NT_STATUS_OK;779 780 } else { /* Unknown record type ! */781 DEBUG(2, ("Found INVALID record %s -> %s\n", keystr, (const char *)data.dptr));782 ret = NT_STATUS_INTERNAL_DB_ERROR;783 goto done;784 }785 786 /* apply filters before returning result */787 if (!idmap_unix_id_is_in_range(map->xid.id, dom)) {788 DEBUG(5, ("Requested id (%u) out of range (%u - %u). Filtered!\n",789 map->xid.id, dom->low_id, dom->high_id));790 ret = NT_STATUS_NONE_MAPPED;791 }792 793 done:794 talloc_free(tmp_ctx);795 return ret;796 }797 798 /**********************************799 lookup a set of unix ids.800 **********************************/801 802 static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)803 {804 NTSTATUS ret;805 int i;806 807 /* initialize the status to avoid suprise */808 for (i = 0; ids[i]; i++) {809 ids[i]->status = ID_UNKNOWN;810 }811 812 for (i = 0; ids[i]; i++) {813 ret = idmap_tdb_id_to_sid(dom, ids[i]);814 if ( ! NT_STATUS_IS_OK(ret)) {815 816 /* if it is just a failed mapping continue */817 if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {818 819 /* make sure it is marked as unmapped */820 ids[i]->status = ID_UNMAPPED;821 continue;822 }823 824 /* some fatal error occurred, return immediately */825 goto done;826 }827 828 /* all ok, id is mapped */829 ids[i]->status = ID_MAPPED;830 }831 832 ret = NT_STATUS_OK;833 834 done:835 return ret;836 }837 838 /**********************************839 lookup a set of sids.840 **********************************/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 903 static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)904 {905 struct idmap_tdb_context *ctx;906 NTSTATUS ret;907 int i;908 struct idmap_tdb_sids_to_unixids_context state;909 910 /* initialize the status to avoid suprise */911 for (i = 0; ids[i]; i++) {912 ids[i]->status = ID_UNKNOWN;913 }914 915 ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);916 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 933 934 /**********************************935 Close the idmap tdb instance936 **********************************/937 938 430 static struct idmap_methods db_methods = { 939 431 .init = idmap_tdb_db_init, 940 .unixids_to_sids = idmap_tdb_ unixids_to_sids,941 .sids_to_unixids = idmap_tdb_ sids_to_unixids,942 .allocate_id = idmap_tdb_ get_new_id,432 .unixids_to_sids = idmap_tdb_common_unixids_to_sids, 433 .sids_to_unixids = idmap_tdb_common_sids_to_unixids, 434 .allocate_id = idmap_tdb_common_get_new_id, 943 435 }; 944 436 -
vendor/current/source3/winbindd/idmap_tdb2.c
r746 r988 37 37 #include "idmap.h" 38 38 #include "idmap_rw.h" 39 #include "dbwrap.h" 39 #include "dbwrap/dbwrap.h" 40 #include "dbwrap/dbwrap_open.h" 40 41 #include "../libcli/security/dom_sid.h" 41 42 #include "util_tdb.h" 43 #include "idmap_tdb_common.h" 42 44 43 45 #undef DBGC_CLASS … … 45 47 46 48 struct idmap_tdb2_context { 47 struct db_context *db;48 49 const char *script; /* script to provide idmaps */ 49 struct idmap_rw_ops *rw_ops;50 50 }; 51 51 … … 53 53 #define HWM_GROUP "GROUP HWM" 54 54 #define HWM_USER "USER HWM" 55 56 55 57 56 /* … … 61 60 { 62 61 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); 62 uint32_t low_id; 63 struct idmap_tdb_common_context *ctx; 64 65 ctx = talloc_get_type(dom->private_data, 66 struct idmap_tdb_common_context); 67 67 68 68 /* Create high water marks for group and user id */ 69 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);70 status = dbwrap_fetch_uint32_bystring(ctx->db, HWM_USER, &low_id); 71 if (!NT_STATUS_IS_OK(status) || (low_id < dom->low_id)) { 72 status = dbwrap_trans_store_uint32_bystring(ctx->db, HWM_USER, 73 dom->low_id); 74 74 if (!NT_STATUS_IS_OK(status)) { 75 75 DEBUG(0, ("Unable to initialise user hwm in idmap " … … 79 79 } 80 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);81 status = dbwrap_fetch_uint32_bystring(ctx->db, HWM_GROUP, &low_id); 82 if (!NT_STATUS_IS_OK(status) || (low_id < dom->low_id)) { 83 status = dbwrap_trans_store_uint32_bystring(ctx->db, HWM_GROUP, 84 dom->low_id); 85 85 if (!NT_STATUS_IS_OK(status)) { 86 86 DEBUG(0, ("Unable to initialise group hwm in idmap " … … 100 100 { 101 101 char *db_path; 102 struct idmap_tdb2_context *ctx; 103 104 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 102 struct idmap_tdb_common_context *ctx; 103 104 ctx = talloc_get_type(dom->private_data, 105 struct idmap_tdb_common_context); 105 106 106 107 if (ctx->db) { … … 113 114 114 115 /* Open idmap repository */ 115 ctx->db = db_open(ctx, db_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644); 116 ctx->db = db_open(ctx, db_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644, 117 DBWRAP_LOCK_ORDER_1, DBWRAP_FLAG_NONE); 116 118 TALLOC_FREE(db_path); 117 119 … … 125 127 } 126 128 127 128 /*129 Allocate a new id.130 */131 132 struct idmap_tdb2_allocate_id_context {133 const char *hwmkey;134 const char *hwmtype;135 uint32_t high_hwm;136 uint32_t hwm;137 };138 139 static NTSTATUS idmap_tdb2_allocate_id_action(struct db_context *db,140 void *private_data)141 {142 NTSTATUS ret;143 struct idmap_tdb2_allocate_id_context *state;144 uint32_t hwm;145 146 state = (struct idmap_tdb2_allocate_id_context *)private_data;147 148 hwm = dbwrap_fetch_int32(db, state->hwmkey);149 if (hwm == -1) {150 ret = NT_STATUS_INTERNAL_DB_ERROR;151 goto done;152 }153 154 /* check it is in the range */155 if (hwm > state->high_hwm) {156 DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",157 state->hwmtype, (unsigned long)state->high_hwm));158 ret = NT_STATUS_UNSUCCESSFUL;159 goto done;160 }161 162 /* fetch a new id and increment it */163 ret = dbwrap_trans_change_uint32_atomic(db, state->hwmkey, &hwm, 1);164 if (!NT_STATUS_IS_OK(ret)) {165 DEBUG(1, ("Fatal error while fetching a new %s value\n!",166 state->hwmtype));167 goto done;168 }169 170 /* recheck it is in the range */171 if (hwm > state->high_hwm) {172 DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",173 state->hwmtype, (unsigned long)state->high_hwm));174 ret = NT_STATUS_UNSUCCESSFUL;175 goto done;176 }177 178 ret = NT_STATUS_OK;179 state->hwm = hwm;180 181 done:182 return ret;183 }184 185 static NTSTATUS idmap_tdb2_allocate_id(struct idmap_domain *dom,186 struct unixid *xid)187 {188 const char *hwmkey;189 const char *hwmtype;190 uint32_t high_hwm;191 uint32_t hwm = 0;192 NTSTATUS status;193 struct idmap_tdb2_allocate_id_context state;194 struct idmap_tdb2_context *ctx;195 196 status = idmap_tdb2_open_db(dom);197 NT_STATUS_NOT_OK_RETURN(status);198 199 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);200 201 /* Get current high water mark */202 switch (xid->type) {203 204 case ID_TYPE_UID:205 hwmkey = HWM_USER;206 hwmtype = "UID";207 break;208 209 case ID_TYPE_GID:210 hwmkey = HWM_GROUP;211 hwmtype = "GID";212 break;213 214 default:215 DEBUG(2, ("Invalid ID type (0x%x)\n", xid->type));216 return NT_STATUS_INVALID_PARAMETER;217 }218 219 high_hwm = dom->high_id;220 221 state.hwm = hwm;222 state.high_hwm = high_hwm;223 state.hwmtype = hwmtype;224 state.hwmkey = hwmkey;225 226 status = dbwrap_trans_do(ctx->db, idmap_tdb2_allocate_id_action,227 &state);228 229 if (NT_STATUS_IS_OK(status)) {230 xid->id = state.hwm;231 DEBUG(10,("New %s = %d\n", hwmtype, state.hwm));232 } else {233 DEBUG(1, ("Error allocating a new %s\n", hwmtype));234 }235 236 return status;237 }238 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;261 }262 263 /*264 IDMAP MAPPING TDB BACKEND265 */266 267 static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom,268 const struct id_map *map);269 270 /*271 Initialise idmap database.272 */273 static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom)274 {275 NTSTATUS ret;276 struct idmap_tdb2_context *ctx;277 char *config_option = NULL;278 const char * idmap_script = NULL;279 280 ctx = talloc_zero(dom, struct idmap_tdb2_context);281 if ( ! ctx) {282 DEBUG(0, ("Out of memory!\n"));283 return NT_STATUS_NO_MEMORY;284 }285 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;319 320 dom->private_data = ctx;321 322 ret = idmap_tdb2_open_db(dom);323 if (!NT_STATUS_IS_OK(ret)) {324 goto failed;325 }326 327 return NT_STATUS_OK;328 329 failed:330 talloc_free(ctx);331 return ret;332 }333 334 335 129 /** 336 130 * store a mapping in the database. … … 355 149 356 150 /* check wheter sid mapping is already present in db */ 357 data = dbwrap_fetch_bystring(db, tmp_ctx, state->ksidstr);358 if ( data.dptr) {151 ret = dbwrap_fetch_bystring(db, tmp_ctx, state->ksidstr, &data); 152 if (NT_STATUS_IS_OK(ret)) { 359 153 ret = NT_STATUS_OBJECT_NAME_COLLISION; 360 154 goto done; … … 391 185 NTSTATUS ret; 392 186 char *ksidstr, *kidstr; 187 struct idmap_tdb_common_context *commonctx; 393 188 struct idmap_tdb2_set_mapping_context state; 394 189 … … 401 196 /* TODO: should we filter a set_mapping using low/high filters ? */ 402 197 403 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 198 commonctx = talloc_get_type(dom->private_data, 199 struct idmap_tdb_common_context); 200 201 ctx = talloc_get_type(commonctx->private_data, 202 struct idmap_tdb2_context); 404 203 405 204 switch (map->xid.type) { … … 434 233 state.kidstr = kidstr; 435 234 436 ret = dbwrap_trans_do(c tx->db, idmap_tdb2_set_mapping_action,235 ret = dbwrap_trans_do(commonctx->db, idmap_tdb2_set_mapping_action, 437 236 &state); 438 237 … … 442 241 return ret; 443 242 } 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 462 return ret;463 }464 465 243 466 244 /* … … 542 320 char *keystr; 543 321 NTSTATUS status; 322 struct idmap_tdb_common_context *commonctx; 544 323 struct idmap_tdb2_context *ctx; 545 324 … … 552 331 NT_STATUS_NOT_OK_RETURN(status); 553 332 554 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 333 commonctx = talloc_get_type(dom->private_data, 334 struct idmap_tdb_common_context); 335 336 ctx = talloc_get_type(commonctx->private_data, 337 struct idmap_tdb2_context); 555 338 556 339 /* apply filters before checking */ … … 585 368 586 369 /* Check if the mapping exists */ 587 data = dbwrap_fetch_bystring(ctx->db, keystr, keystr);588 589 if (! data.dptr) {370 status = dbwrap_fetch_bystring(commonctx->db, keystr, keystr, &data); 371 372 if (!NT_STATUS_IS_OK(status)) { 590 373 char *sidstr; 591 374 struct idmap_tdb2_set_mapping_context store_state; … … 611 394 store_state.kidstr = keystr; 612 395 613 ret = dbwrap_trans_do(ctx->db, idmap_tdb2_set_mapping_action, 396 ret = dbwrap_trans_do(commonctx->db, 397 idmap_tdb2_set_mapping_action, 614 398 &store_state); 615 399 goto done; … … 641 425 char *keystr; 642 426 unsigned long rec_id = 0; 427 struct idmap_tdb_common_context *commonctx; 643 428 struct idmap_tdb2_context *ctx; 644 429 TALLOC_CTX *tmp_ctx = talloc_stackframe(); … … 647 432 NT_STATUS_NOT_OK_RETURN(ret); 648 433 649 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 434 commonctx = talloc_get_type(dom->private_data, 435 struct idmap_tdb_common_context); 436 437 ctx = talloc_get_type(commonctx->private_data, 438 struct idmap_tdb2_context); 650 439 651 440 keystr = sid_string_talloc(tmp_ctx, map->sid); … … 659 448 660 449 /* Check if sid is present in database */ 661 data = dbwrap_fetch_bystring(ctx->db, tmp_ctx, keystr);662 if (! data.dptr) {450 ret = dbwrap_fetch_bystring(commonctx->db, tmp_ctx, keystr, &data); 451 if (!NT_STATUS_IS_OK(ret)) { 663 452 char *idstr; 664 453 struct idmap_tdb2_set_mapping_context store_state; … … 696 485 store_state.kidstr = idstr; 697 486 698 ret = dbwrap_trans_do(ctx->db, idmap_tdb2_set_mapping_action, 487 ret = dbwrap_trans_do(commonctx->db, 488 idmap_tdb2_set_mapping_action, 699 489 &store_state); 700 490 goto done; … … 733 523 734 524 /* 735 lookup a set of unix ids.525 Initialise idmap database. 736 526 */ 737 static NTSTATUS idmap_tdb2_ unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)527 static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom) 738 528 { 739 529 NTSTATUS ret; 740 int i; 741 742 /* initialize the status to avoid suprise */ 743 for (i = 0; ids[i]; i++) { 744 ids[i]->status = ID_UNKNOWN; 745 } 746 747 for (i = 0; ids[i]; i++) { 748 ret = idmap_tdb2_id_to_sid(dom, ids[i]); 749 if ( ! NT_STATUS_IS_OK(ret)) { 750 751 /* if it is just a failed mapping continue */ 752 if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) { 753 754 /* make sure it is marked as unmapped */ 755 ids[i]->status = ID_UNMAPPED; 756 continue; 757 } 758 759 /* some fatal error occurred, return immediately */ 760 goto done; 761 } 762 763 /* all ok, id is mapped */ 764 ids[i]->status = ID_MAPPED; 765 } 766 767 ret = NT_STATUS_OK; 768 769 done: 770 return ret; 771 } 772 773 /* 774 lookup a set of sids. 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 838 static NTSTATUS idmap_tdb2_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids) 839 { 840 NTSTATUS ret; 841 int i; 842 struct idmap_tdb2_sids_to_unixids_context state; 530 struct idmap_tdb_common_context *commonctx; 843 531 struct idmap_tdb2_context *ctx; 844 845 ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context); 846 847 /* initialize the status to avoid suprise */ 848 for (i = 0; ids[i]; i++) { 849 ids[i]->status = ID_UNKNOWN; 850 } 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 532 char *config_option = NULL; 533 const char * idmap_script = NULL; 534 535 commonctx = talloc_zero(dom, struct idmap_tdb_common_context); 536 if(!commonctx) { 537 DEBUG(0, ("Out of memory!\n")); 538 return NT_STATUS_NO_MEMORY; 539 } 540 541 commonctx->rw_ops = talloc_zero(commonctx, struct idmap_rw_ops); 542 if (commonctx->rw_ops == NULL) { 543 DEBUG(0, ("Out of memory!\n")); 544 ret = NT_STATUS_NO_MEMORY; 545 goto failed; 546 } 547 548 ctx = talloc_zero(commonctx, struct idmap_tdb2_context); 549 if (!ctx) { 550 DEBUG(0, ("Out of memory!\n")); 551 ret = NT_STATUS_NO_MEMORY; 552 goto failed; 553 } 554 555 config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); 556 if (config_option == NULL) { 557 DEBUG(0, ("Out of memory!\n")); 558 ret = NT_STATUS_NO_MEMORY; 559 goto failed; 560 } 561 ctx->script = lp_parm_const_string(-1, config_option, "script", NULL); 562 talloc_free(config_option); 563 564 idmap_script = lp_parm_const_string(-1, "idmap", "script", NULL); 565 if (idmap_script != NULL) { 566 DEBUG(0, ("Warning: 'idmap:script' is deprecated. " 567 " Please use 'idmap config * : script' instead!\n")); 568 } 569 570 if (strequal(dom->name, "*") && ctx->script == NULL) { 571 /* fall back to idmap:script for backwards compatibility */ 572 ctx->script = idmap_script; 573 } 574 575 if (ctx->script) { 576 DEBUG(1, ("using idmap script '%s'\n", ctx->script)); 577 } 578 579 commonctx->max_id = dom->high_id; 580 commonctx->hwmkey_uid = HWM_USER; 581 commonctx->hwmkey_gid = HWM_GROUP; 582 583 commonctx->sid_to_unixid_fn = idmap_tdb2_sid_to_id; 584 commonctx->unixid_to_sid_fn = idmap_tdb2_id_to_sid; 585 586 commonctx->rw_ops->get_new_id = idmap_tdb_common_get_new_id; 587 commonctx->rw_ops->set_mapping = idmap_tdb2_set_mapping; 588 589 commonctx->private_data = ctx; 590 dom->private_data = commonctx; 591 592 ret = idmap_tdb2_open_db(dom); 593 if (!NT_STATUS_IS_OK(ret)) { 594 goto failed; 595 } 596 597 return NT_STATUS_OK; 598 599 failed: 600 talloc_free(commonctx); 865 601 return ret; 866 602 } … … 869 605 static struct idmap_methods db_methods = { 870 606 .init = idmap_tdb2_db_init, 871 .unixids_to_sids = idmap_tdb 2_unixids_to_sids,872 .sids_to_unixids = idmap_tdb 2_sids_to_unixids,873 .allocate_id = idmap_tdb 2_get_new_id607 .unixids_to_sids = idmap_tdb_common_unixids_to_sids, 608 .sids_to_unixids = idmap_tdb_common_sids_to_unixids, 609 .allocate_id = idmap_tdb_common_get_new_id 874 610 }; 875 611 612 static_decl_idmap; 876 613 NTSTATUS idmap_tdb2_init(void) 877 614 { -
vendor/current/source3/winbindd/idmap_util.c
r740 r988 25 25 #include "idmap_cache.h" 26 26 #include "../libcli/security/security.h" 27 #include "secrets.h" 27 28 28 29 #undef DBGC_CLASS … … 32 33 Returns the SID mapped to the given UID. 33 34 If mapping is not possible returns an error. 34 *****************************************************************/ 35 36 NTSTATUS idmap_uid_to_sid( const char *domname,struct dom_sid *sid, uid_t uid)35 *****************************************************************/ 36 37 NTSTATUS idmap_uid_to_sid(struct dom_sid *sid, uid_t uid) 37 38 { 38 39 NTSTATUS ret; … … 40 41 bool expired; 41 42 42 DEBUG(10,("idmap_uid_to_sid: uid = [%lu], domain = '%s'\n", 43 (unsigned long)uid, domname?domname:"NULL")); 43 DEBUG(10, ("idmap_uid_to_sid: uid = [%lu]\n", (unsigned long)uid)); 44 44 45 45 if (winbindd_use_idmap_cache() … … 61 61 62 62 backend: 63 ZERO_STRUCT(map); 63 64 map.sid = sid; 64 65 map.xid.type = ID_TYPE_UID; 65 66 map.xid.id = uid; 66 67 67 ret = idmap_backends_unixid_to_sid( domname,&map);68 ret = idmap_backends_unixid_to_sid(&map); 68 69 if ( ! NT_STATUS_IS_OK(ret)) { 69 DEBUG(10, ("error mapping uid [%lu]\n", (unsigned long)uid)); 70 return ret; 70 DEBUG(10, ("error mapping uid [%lu]: %s\n", (unsigned long)uid, 71 nt_errstr(ret))); 72 map.status = ID_UNMAPPED; 71 73 } 72 74 … … 74 76 if (winbindd_use_idmap_cache()) { 75 77 struct dom_sid null_sid; 78 struct unixid id; 79 id.type = ID_TYPE_UID; 80 id.id = uid; 76 81 ZERO_STRUCT(null_sid); 77 idmap_cache_set_sid2u id(&null_sid, uid);82 idmap_cache_set_sid2unixid(&null_sid, &id); 78 83 } 79 84 DEBUG(10, ("uid [%lu] not mapped\n", (unsigned long)uid)); … … 82 87 83 88 if (winbindd_use_idmap_cache()) { 84 idmap_cache_set_sid2u id(sid, uid);89 idmap_cache_set_sid2unixid(sid, &map.xid); 85 90 } 86 91 … … 91 96 Returns SID mapped to the given GID. 92 97 If mapping is not possible returns an error. 93 *****************************************************************/ 94 95 NTSTATUS idmap_gid_to_sid( const char *domname,struct dom_sid *sid, gid_t gid)98 *****************************************************************/ 99 100 NTSTATUS idmap_gid_to_sid(struct dom_sid *sid, gid_t gid) 96 101 { 97 102 NTSTATUS ret; … … 99 104 bool expired; 100 105 101 DEBUG(10,("idmap_gid_to_sid: gid = [%lu], domain = '%s'\n", 102 (unsigned long)gid, domname?domname:"NULL")); 106 DEBUG(10, ("idmap_gid_to_sid: gid = [%lu]\n", (unsigned long)gid)); 103 107 104 108 if (winbindd_use_idmap_cache() … … 120 124 121 125 backend: 126 ZERO_STRUCT(map); 122 127 map.sid = sid; 123 128 map.xid.type = ID_TYPE_GID; 124 129 map.xid.id = gid; 125 130 126 ret = idmap_backends_unixid_to_sid( domname,&map);131 ret = idmap_backends_unixid_to_sid(&map); 127 132 if ( ! NT_STATUS_IS_OK(ret)) { 128 DEBUG(10, ("error mapping gid [%lu]\n", (unsigned long)gid)); 129 return ret; 133 DEBUG(10, ("error mapping gid [%lu]: %s\n", (unsigned long)gid, 134 nt_errstr(ret))); 135 map.status = ID_UNMAPPED; 130 136 } 131 137 … … 133 139 if (winbindd_use_idmap_cache()) { 134 140 struct dom_sid null_sid; 141 struct unixid id; 142 id.type = ID_TYPE_GID; 143 id.id = gid; 135 144 ZERO_STRUCT(null_sid); 136 idmap_cache_set_sid2 gid(&null_sid, gid);145 idmap_cache_set_sid2unixid(&null_sid, &id); 137 146 } 138 147 DEBUG(10, ("gid [%lu] not mapped\n", (unsigned long)gid)); … … 141 150 142 151 if (winbindd_use_idmap_cache()) { 143 idmap_cache_set_sid2gid(sid, gid); 144 } 145 146 return NT_STATUS_OK; 147 } 148 149 /***************************************************************** 150 Returns the UID mapped to the given SID. 151 If mapping is not possible or SID maps to a GID returns an error. 152 *****************************************************************/ 153 154 NTSTATUS idmap_sid_to_uid(const char *dom_name, struct dom_sid *sid, uid_t *uid) 155 { 156 NTSTATUS ret; 157 struct id_map map; 158 bool expired; 159 160 DEBUG(10,("idmap_sid_to_uid: sid = [%s], domain = '%s'\n", 161 sid_string_dbg(sid), dom_name)); 162 163 if (winbindd_use_idmap_cache() 164 && idmap_cache_find_sid2uid(sid, uid, &expired)) { 165 DEBUG(10, ("idmap_cache_find_sid2uid found %d%s\n", 166 (int)(*uid), expired ? " (expired)": "")); 167 if (expired && idmap_is_online()) { 168 DEBUG(10, ("revalidating expired entry\n")); 169 goto backend; 170 } 171 if ((*uid) == -1) { 172 DEBUG(10, ("Returning negative cache entry\n")); 173 return NT_STATUS_NONE_MAPPED; 174 } 175 DEBUG(10, ("Returning positive cache entry\n")); 176 return NT_STATUS_OK; 177 } 178 179 backend: 180 map.sid = sid; 181 map.xid.type = ID_TYPE_UID; 182 183 ret = idmap_backends_sid_to_unixid(dom_name, &map); 184 185 if (!NT_STATUS_IS_OK(ret)) { 186 DEBUG(10, ("idmap_backends_sid_to_unixid failed: %s\n", 187 nt_errstr(ret))); 188 if (winbindd_use_idmap_cache()) { 189 idmap_cache_set_sid2uid(sid, -1); 190 } 191 return ret; 192 } 193 194 if (map.status != ID_MAPPED) { 195 DEBUG(10, ("sid [%s] is not mapped\n", sid_string_dbg(sid))); 196 if (winbindd_use_idmap_cache()) { 197 idmap_cache_set_sid2uid(sid, -1); 198 } 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 215 *uid = (uid_t)map.xid.id; 216 if (winbindd_use_idmap_cache()) { 217 idmap_cache_set_sid2uid(sid, *uid); 218 } 219 return NT_STATUS_OK; 220 } 221 222 /***************************************************************** 223 Returns the GID mapped to the given SID. 224 If mapping is not possible or SID maps to a UID returns an error. 225 *****************************************************************/ 226 227 NTSTATUS idmap_sid_to_gid(const char *domname, struct dom_sid *sid, gid_t *gid) 228 { 229 NTSTATUS ret; 230 struct id_map map; 231 bool expired; 232 233 DEBUG(10,("idmap_sid_to_gid: sid = [%s], domain = '%s'\n", 234 sid_string_dbg(sid), domname)); 235 236 if (winbindd_use_idmap_cache() 237 && idmap_cache_find_sid2gid(sid, gid, &expired)) { 238 DEBUG(10, ("idmap_cache_find_sid2gid found %d%s\n", 239 (int)(*gid), expired ? " (expired)": "")); 240 if (expired && idmap_is_online()) { 241 DEBUG(10, ("revalidating expired entry\n")); 242 goto backend; 243 } 244 if ((*gid) == -1) { 245 DEBUG(10, ("Returning negative cache entry\n")); 246 return NT_STATUS_NONE_MAPPED; 247 } 248 DEBUG(10, ("Returning positive cache entry\n")); 249 return NT_STATUS_OK; 250 } 251 252 backend: 253 map.sid = sid; 254 map.xid.type = ID_TYPE_GID; 255 256 ret = idmap_backends_sid_to_unixid(domname, &map); 257 258 if (!NT_STATUS_IS_OK(ret)) { 259 DEBUG(10, ("idmap_backends_sid_to_unixid failed: %s\n", 260 nt_errstr(ret))); 261 if (winbindd_use_idmap_cache()) { 262 idmap_cache_set_sid2gid(sid, -1); 263 } 264 return ret; 265 } 266 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 288 *gid = map.xid.id; 289 if (winbindd_use_idmap_cache()) { 290 idmap_cache_set_sid2gid(sid, *gid); 291 } 152 idmap_cache_set_sid2unixid(sid, &map.xid); 153 } 154 292 155 return NT_STATUS_OK; 293 156 } … … 311 174 return true; 312 175 } 176 177 /** 178 * Helper for unixids_to_sids: find entry by id in mapping array, 179 * search up to IDMAP_AD_MAX_IDS entries 180 */ 181 struct id_map *idmap_find_map_by_id(struct id_map **maps, enum id_type type, 182 uint32_t id) 183 { 184 int i; 185 186 for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) { 187 if (maps[i] == NULL) { /* end of the run */ 188 return NULL; 189 } 190 if ((maps[i]->xid.type == type) && (maps[i]->xid.id == id)) { 191 return maps[i]; 192 } 193 } 194 195 return NULL; 196 } 197 198 /** 199 * Helper for sids_to_unix_ids: find entry by SID in mapping array, 200 * search up to IDMAP_AD_MAX_IDS entries 201 */ 202 struct id_map *idmap_find_map_by_sid(struct id_map **maps, struct dom_sid *sid) 203 { 204 int i; 205 206 for (i = 0; i < IDMAP_LDAP_MAX_IDS; i++) { 207 if (maps[i] == NULL) { /* end of the run */ 208 return NULL; 209 } 210 if (dom_sid_equal(maps[i]->sid, sid)) { 211 return maps[i]; 212 } 213 } 214 215 return NULL; 216 } 217 218 char *idmap_fetch_secret(const char *backend, const char *domain, 219 const char *identity) 220 { 221 char *tmp, *ret; 222 int r; 223 224 r = asprintf(&tmp, "IDMAP_%s_%s", backend, domain); 225 226 if (r < 0) 227 return NULL; 228 229 /* make sure the key is case insensitive */ 230 if (!strupper_m(tmp)) { 231 SAFE_FREE(tmp); 232 return NULL; 233 } 234 235 ret = secrets_fetch_generic(tmp, identity); 236 237 SAFE_FREE(tmp); 238 239 return ret; 240 } -
vendor/current/source3/winbindd/nss_info.c
r740 r988 67 67 68 68 if ( nss_get_backend(name) ) { 69 DEBUG( 0,("smb_register_idmap_nss: idmap module %s "69 DEBUG(5,("smb_register_idmap_nss: idmap module %s " 70 70 "already registered!\n", name)); 71 71 return NT_STATUS_OBJECT_NAME_COLLISION; … … 119 119 struct nss_domain_entry *nss_domain; 120 120 121 nss_domain = TALLOC_ZERO_P(nss_domain_list, struct nss_domain_entry);121 nss_domain = talloc_zero(nss_domain_list, struct nss_domain_entry); 122 122 if (!nss_domain) { 123 123 DEBUG(0, ("nss_domain_list_add_domain: talloc() failure!\n")); -
vendor/current/source3/winbindd/nss_info_template.c
r740 r988 49 49 *homedir = talloc_strdup( ctx, lp_template_homedir() ); 50 50 *shell = talloc_strdup( ctx, lp_template_shell() ); 51 *gecos = NULL;52 51 53 52 if ( !*homedir || !*shell ) { -
vendor/current/source3/winbindd/wb_dsgetdcname.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 24 24 struct wb_dsgetdcname_state { … … 46 46 } 47 47 48 if (strequal(domain_name, "BUILTIN") 49 || strequal(domain_name, get_global_sam_name())) { 48 if (strequal(domain_name, "BUILTIN")) { 50 49 /* 51 * Two options here: Give back our own address, or say there's 52 * nobody around. Right now opting for the latter, one measure 53 * to prevent the loopback connects. This might change if 54 * needed. 50 * This makes no sense 55 51 */ 56 52 tevent_req_nterror(req, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND); 57 53 return tevent_req_post(req, ev); 54 } 55 56 if (strequal(domain_name, get_global_sam_name())) { 57 int role = lp_server_role(); 58 if ( role != ROLE_ACTIVE_DIRECTORY_DC ) { 59 /* 60 * Two options here: Give back our own address, or say there's 61 * nobody around. Right now opting for the latter, one measure 62 * to prevent the loopback connects. This might change if 63 * needed. 64 */ 65 tevent_req_nterror(req, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND); 66 return tevent_req_post(req, ev); 67 } 58 68 } 59 69 -
vendor/current/source3/winbindd/wb_fill_pwent.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 24 24 struct wb_fill_pwent_state { … … 30 30 static bool fillup_pw_field(const char *lp_template, 31 31 const char *username, 32 const char *grpname, 32 33 const char *domname, 33 34 uid_t uid, … … 37 38 38 39 static void wb_fill_pwent_sid2uid_done(struct tevent_req *subreq); 39 static void wb_fill_pwent_ sid2gid_done(struct tevent_req *subreq);40 static void wb_fill_pwent_getgrsid_done(struct tevent_req *subreq); 40 41 41 42 struct tevent_req *wb_fill_pwent_send(TALLOC_CTX *mem_ctx, … … 55 56 state->pw = pw; 56 57 57 subreq = wb_sid 2uid_send(state, state->ev, &state->info->user_sid);58 subreq = wb_sids2xids_send(state, state->ev, &state->info->user_sid, 1); 58 59 if (tevent_req_nomem(subreq, req)) { 59 60 return tevent_req_post(req, ev); … … 70 71 req, struct wb_fill_pwent_state); 71 72 NTSTATUS status; 72 73 status = wb_sid2uid_recv(subreq, &state->pw->pw_uid); 73 struct unixid xids[1]; 74 75 status = wb_sids2xids_recv(subreq, xids, ARRAY_SIZE(xids)); 74 76 TALLOC_FREE(subreq); 75 77 if (tevent_req_nterror(req, status)) { … … 77 79 } 78 80 79 subreq = wb_sid2gid_send(state, state->ev, &state->info->group_sid); 81 /* 82 * We are filtering further down in sids2xids, but that filtering 83 * depends on the actual type of the sid handed in (as determined 84 * by lookupsids). Here we need to filter for the type of object 85 * actually requested, in this case uid. 86 */ 87 if (!(xids[0].type == ID_TYPE_UID || xids[0].type == ID_TYPE_BOTH)) { 88 tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); 89 return; 90 } 91 92 state->pw->pw_uid = (uid_t)xids[0].id; 93 94 subreq = wb_getgrsid_send(state, state->ev, &state->info->group_sid, 0); 80 95 if (tevent_req_nomem(subreq, req)) { 81 96 return; 82 97 } 83 tevent_req_set_callback(subreq, wb_fill_pwent_ sid2gid_done, req);84 } 85 86 static void wb_fill_pwent_ sid2gid_done(struct tevent_req *subreq)98 tevent_req_set_callback(subreq, wb_fill_pwent_getgrsid_done, req); 99 } 100 101 static void wb_fill_pwent_getgrsid_done(struct tevent_req *subreq) 87 102 { 88 103 struct tevent_req *req = tevent_req_callback_data( … … 91 106 req, struct wb_fill_pwent_state); 92 107 struct winbindd_domain *domain; 93 char *dom_name; 108 const char *dom_name; 109 const char *grp_name; 94 110 fstring user_name, output_username; 95 111 char *mapped_name = NULL; 112 struct talloc_dict *members; 113 TALLOC_CTX *tmp_ctx = talloc_stackframe(); 96 114 NTSTATUS status; 97 98 status = wb_sid2gid_recv(subreq, &state->pw->pw_gid); 115 bool ok; 116 117 /* xid handling is done in getgrsid() */ 118 status = wb_getgrsid_recv(subreq, 119 tmp_ctx, 120 &dom_name, 121 &grp_name, 122 &state->pw->pw_gid, 123 &members); 99 124 TALLOC_FREE(subreq); 100 125 if (tevent_req_nterror(req, status)) { 126 talloc_free(tmp_ctx); 101 127 return; 102 128 } … … 104 130 domain = find_domain_from_sid_noinit(&state->info->user_sid); 105 131 if (domain == NULL) { 132 talloc_free(tmp_ctx); 106 133 tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); 107 134 return; … … 112 139 113 140 fstrcpy(user_name, state->info->acct_name); 114 strlower_m(user_name); 141 if (!strlower_m(user_name)) { 142 tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); 143 return; 144 } 115 145 status = normalize_name_map(state, domain, user_name, &mapped_name); 116 146 … … 130 160 } 131 161 132 fstrcpy(state->pw->pw_name, output_username); 133 fstrcpy(state->pw->pw_gecos, state->info->full_name); 162 strlcpy(state->pw->pw_name, 163 output_username, 164 sizeof(state->pw->pw_name)); 165 /* FIXME The full_name can be longer than 255 chars */ 166 strlcpy(state->pw->pw_gecos, 167 state->info->full_name != NULL ? state->info->full_name : "", 168 sizeof(state->pw->pw_gecos)); 134 169 135 170 /* Home directory and shell */ 136 137 if (!fillup_pw_field(lp_template_homedir(), user_name, dom_name, 138 state->pw->pw_uid, state->pw->pw_gid, 139 state->info->homedir, state->pw->pw_dir)) { 171 ok = fillup_pw_field(lp_template_homedir(), 172 user_name, 173 grp_name, 174 dom_name, 175 state->pw->pw_uid, 176 state->pw->pw_gid, 177 state->info->homedir, 178 state->pw->pw_dir); 179 if (!ok) { 180 talloc_free(tmp_ctx); 140 181 tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); 141 182 return; 142 183 } 143 184 144 if (!fillup_pw_field(lp_template_shell(), user_name, dom_name, 145 state->pw->pw_uid, state->pw->pw_gid, 146 state->info->shell, state->pw->pw_shell)) { 185 ok = fillup_pw_field(lp_template_shell(), 186 user_name, 187 grp_name, 188 dom_name, 189 state->pw->pw_uid, 190 state->pw->pw_gid, 191 state->info->shell, 192 state->pw->pw_shell); 193 talloc_free(tmp_ctx); 194 if (!ok) { 147 195 tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); 148 196 return; … … 163 211 static bool fillup_pw_field(const char *lp_template, 164 212 const char *username, 213 const char *grpname, 165 214 const char *domname, 166 215 uid_t uid, … … 169 218 fstring out) 170 219 { 171 char *templ; 220 const char *templ; 221 char *result; 172 222 173 223 if (out == NULL) 174 224 return False; 175 225 176 /* The substitution of %U and %D in the 'template 177 homedir' is done by talloc_sub_specified() below. 178 If we have an in string (which means the value has already 179 been set in the nss_info backend), then use that. 180 Otherwise use the template value passed in. */ 226 templ = lp_template; 181 227 182 228 if ((in != NULL) && (in[0] != '\0') && (lp_security() == SEC_ADS)) { 183 templ = talloc_sub_specified(talloc_tos(), in, 184 username, domname, 185 uid, gid); 186 } else { 187 templ = talloc_sub_specified(talloc_tos(), lp_template, 188 username, domname, 189 uid, gid); 190 } 191 192 if (!templ) 229 /* 230 * The backend has already filled in the required value. Use 231 * that instead of the template. 232 */ 233 templ = in; 234 } 235 236 result = talloc_sub_specified(talloc_tos(), templ, 237 username, grpname, domname, 238 uid, gid); 239 if (result == NULL) { 193 240 return False; 194 195 safe_strcpy(out, templ, sizeof(fstring) - 1); 196 TALLOC_FREE(templ); 241 } 242 243 fstrcpy(out, result); 244 TALLOC_FREE(result); 197 245 198 246 return True; -
vendor/current/source3/winbindd/wb_getgrsid.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 #include "../libcli/security/security.h" 24 24 … … 92 92 case SID_NAME_ALIAS: 93 93 case SID_NAME_WKN_GRP: 94 /* 95 * also treat user-type SIDS (they might map to ID_TYPE_BOTH) 96 */ 97 case SID_NAME_USER: 98 case SID_NAME_COMPUTER: 94 99 break; 95 100 default: … … 98 103 } 99 104 100 subreq = wb_sid 2gid_send(state, state->ev, &state->sid);105 subreq = wb_sids2xids_send(state, state->ev, &state->sid, 1); 101 106 if (tevent_req_nomem(subreq, req)) { 102 107 return; … … 112 117 req, struct wb_getgrsid_state); 113 118 NTSTATUS status; 114 115 status = wb_sid2gid_recv(subreq, &state->gid); 119 struct unixid xids[1]; 120 121 status = wb_sids2xids_recv(subreq, xids, ARRAY_SIZE(xids)); 116 122 TALLOC_FREE(subreq); 117 123 if (tevent_req_nterror(req, status)) { 118 124 return; 119 125 } 126 127 /* 128 * We are filtering further down in sids2xids, but that filtering 129 * depends on the actual type of the sid handed in (as determined 130 * by lookupsids). Here we need to filter for the type of object 131 * actually requested, in this case uid. 132 */ 133 if (!(xids[0].type == ID_TYPE_GID || xids[0].type == ID_TYPE_BOTH)) { 134 tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); 135 return; 136 } 137 138 state->gid = (gid_t)xids[0].id; 139 140 if (state->type == SID_NAME_USER || state->type == SID_NAME_COMPUTER) { 141 /* 142 * special treatment for a user sid that is 143 * mapped to ID_TYPE_BOTH: 144 * create a group with the sid/xid as only member 145 */ 146 const char *name; 147 148 if (xids[0].type != ID_TYPE_BOTH) { 149 tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP); 150 return; 151 } 152 153 state->members = talloc_dict_init(state); 154 if (tevent_req_nomem(state->members, req)) { 155 return; 156 } 157 158 name = fill_domain_username_talloc(talloc_tos(), 159 state->domname, 160 state->name, 161 true /* can_assume */); 162 if (tevent_req_nomem(name, req)) { 163 return; 164 } 165 166 status = add_wbint_Principal_to_dict(talloc_tos(), 167 &state->sid, 168 &name, 169 state->type, 170 state->members); 171 if (!NT_STATUS_IS_OK(status)) { 172 tevent_req_nterror(req, status); 173 return; 174 } 175 176 tevent_req_done(req); 177 return; 178 } 179 180 /* 181 * the "regular" case of a group type sid. 182 */ 183 120 184 subreq = wb_group_members_send(state, state->ev, &state->sid, 121 185 state->type, state->max_nesting); -
vendor/current/source3/winbindd/wb_getpwsid.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 #include "../libcli/security/security.h" 24 24 25 25 struct wb_getpwsid_state { 26 struct winbindd_domain *user_domain;27 26 struct tevent_context *ev; 28 27 struct dom_sid sid; … … 51 50 state->pw = pw; 52 51 53 state->user_domain = find_domain_from_sid_noinit(user_sid);54 if (state->user_domain == NULL) {55 tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER);56 return tevent_req_post(req, ev);57 }58 59 52 subreq = wb_queryuser_send(state, ev, &state->sid); 60 53 if (tevent_req_nomem(subreq, req)) { … … 75 68 status = wb_queryuser_recv(subreq, state, &state->userinfo); 76 69 TALLOC_FREE(subreq); 77 if (tevent_req_nterror(req, status)) { 78 return; 79 } 80 81 if ((state->userinfo->acct_name != NULL) 82 && (state->userinfo->acct_name[0] != '\0')) { 70 if (NT_STATUS_IS_OK(status) 71 && (state->userinfo->acct_name != NULL) 72 && (state->userinfo->acct_name[0] != '\0')) 73 { 83 74 /* 84 * QueryUser got us a name, let's go tdirectly to the75 * QueryUser got us a name, let's go directly to the 85 76 * fill_pwent step 86 77 */ … … 95 86 96 87 /* 97 * QueryUser didn't get us a name, do it via LSA. 88 * Either query_user did not succeed, or it 89 * succeeded but did not return an acct_name. 90 * (TODO: Can this happen at all???) 91 * ==> Try lsa_lookupsids. 98 92 */ 99 subreq = wb_lookupsid_send(state, state->ev, 100 &state->userinfo->user_sid); 93 if (state->userinfo == NULL) { 94 state->userinfo = talloc_zero(state, struct wbint_userinfo); 95 if (tevent_req_nomem(state->userinfo, req)) { 96 return; 97 } 98 99 /* a successful query_user call would have filled these */ 100 sid_copy(&state->userinfo->user_sid, &state->sid); 101 state->userinfo->homedir = NULL; 102 state->userinfo->shell = NULL; 103 state->userinfo->primary_gid = (gid_t)-1; 104 } 105 106 subreq = wb_lookupsid_send(state, state->ev, &state->sid); 101 107 if (tevent_req_nomem(subreq, req)) { 102 108 return; … … 121 127 return; 122 128 } 129 130 switch (type) { 131 case SID_NAME_USER: 132 case SID_NAME_COMPUTER: 133 /* 134 * user case: we only need the account name from lookup_sids 135 */ 136 break; 137 case SID_NAME_DOM_GRP: 138 case SID_NAME_ALIAS: 139 case SID_NAME_WKN_GRP: 140 /* 141 * also treat group-type SIDs (they might map to ID_TYPE_BOTH) 142 */ 143 sid_copy(&state->userinfo->group_sid, &state->sid); 144 break; 145 default: 146 tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); 147 return; 148 } 149 123 150 subreq = wb_fill_pwent_send(state, state->ev, state->userinfo, 124 151 state->pw); … … 144 171 NTSTATUS wb_getpwsid_recv(struct tevent_req *req) 145 172 { 146 NTSTATUS status; 147 148 if (tevent_req_is_nterror(req, &status)) { 149 return status; 150 } 151 return NT_STATUS_OK; 173 return tevent_req_simple_recv_ntstatus(req); 152 174 } -
vendor/current/source3/winbindd/wb_gettoken.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 #include "../libcli/security/security.h" 24 24 #include "passdb/machine_sid.h" -
vendor/current/source3/winbindd/wb_gid2sid.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 #include "idmap_cache.h" 24 24 #include "idmap.h" … … 27 27 struct wb_gid2sid_state { 28 28 struct tevent_context *ev; 29 char *dom_name;30 29 struct dom_sid sid; 31 30 }; … … 39 38 struct tevent_req *req, *subreq; 40 39 struct wb_gid2sid_state *state; 41 struct winbindd_domain *domain;42 40 struct winbindd_child *child; 43 41 bool expired; … … 65 63 } 66 64 67 state->dom_name = NULL;68 69 for (domain = domain_list(); domain != NULL; domain = domain->next) {70 if (domain->have_idmap_config71 && (gid >= domain->id_range_low)72 && (gid <= domain->id_range_high)) {73 state->dom_name = domain->name;74 break;75 }76 }77 78 65 child = idmap_child(); 79 66 80 67 subreq = dcerpc_wbint_Gid2Sid_send( 81 state, ev, child->binding_handle, state->dom_name,68 state, ev, child->binding_handle, 82 69 gid, &state->sid); 83 70 if (tevent_req_nomem(subreq, req)) { -
vendor/current/source3/winbindd/wb_group_members.c
r746 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 #include "../librpc/gen_ndr/ndr_security.h" 24 24 #include "../libcli/security/security.h" … … 140 140 struct wbint_Principal *groups) 141 141 { 142 struct tevent_req *req, *subreq ;142 struct tevent_req *req, *subreq = NULL; 143 143 struct wb_groups_members_state *state; 144 144 NTSTATUS status; … … 291 291 int max_depth) 292 292 { 293 struct tevent_req *req, *subreq ;293 struct tevent_req *req, *subreq = NULL; 294 294 struct wb_group_members_state *state; 295 295 NTSTATUS status; … … 350 350 } 351 351 352 353 /** 354 * compose a wbint_Principal and add it to talloc_dict 355 * 356 * NOTE: this has a side effect: *name needs to be talloc'd 357 * and it is talloc_move'd to mem_ctx. 358 */ 359 NTSTATUS add_wbint_Principal_to_dict(TALLOC_CTX *mem_ctx, 360 struct dom_sid *sid, 361 const char **name, 362 enum lsa_SidType type, 363 struct talloc_dict *dict) 364 { 365 struct wbint_Principal *m; 366 DATA_BLOB key; 367 bool ok; 368 369 m = talloc(mem_ctx, struct wbint_Principal); 370 if (m == NULL) { 371 return NT_STATUS_NO_MEMORY; 372 } 373 374 sid_copy(&m->sid, sid); 375 m->name = talloc_move(m, name); 376 m->type = type; 377 378 key = data_blob_const(&m->sid, sizeof(m->sid)); 379 380 ok = talloc_dict_set(dict, key, &m); 381 if (!ok) { 382 return NT_STATUS_NO_MEMORY; 383 } 384 385 return NT_STATUS_OK; 386 } 387 352 388 static void wb_group_members_done(struct tevent_req *subreq) 353 389 { … … 356 392 struct wb_group_members_state *state = tevent_req_data( 357 393 req, struct wb_group_members_state); 358 int i, num_groups, new_ users, new_groups;394 int i, num_groups, new_groups; 359 395 int num_members = 0; 360 396 struct wbint_Principal *members = NULL; … … 367 403 } 368 404 369 new_ users = new_groups = 0;405 new_groups = 0; 370 406 for (i=0; i<num_members; i++) { 371 407 switch (members[i].type) { … … 398 434 * Add a copy of members[i] to state->users 399 435 */ 400 st ruct wbint_Principal *m;401 struct dom_sid *sid;402 DATA_BLOB key;403 404 m = talloc(talloc_tos(), struct wbint_Principal);405 if (tevent_req_n omem(m, req)) {436 status = add_wbint_Principal_to_dict(talloc_tos(), 437 &members[i].sid, 438 &members[i].name, 439 members[i].type, 440 state->users); 441 if (tevent_req_nterror(req, status)) { 406 442 return; 407 443 } 408 sid_copy(&m->sid, &members[i].sid); 409 m->name = talloc_move(m, &members[i].name); 410 m->type = members[i].type; 411 412 sid = &members[i].sid; 413 key = data_blob_const( 414 sid, ndr_size_dom_sid(sid, 0)); 415 416 if (!talloc_dict_set(state->users, key, &m)) { 417 tevent_req_nterror(req, NT_STATUS_NO_MEMORY); 418 return; 419 } 444 420 445 break; 421 446 } -
vendor/current/source3/winbindd/wb_lookupname.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 #include "../libcli/security/security.h" 24 24 -
vendor/current/source3/winbindd/wb_lookupsid.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 #include "../libcli/security/security.h" 24 24 -
vendor/current/source3/winbindd/wb_lookupsids.c
r860 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 #include "../libcli/security/security.h" 24 24 #include "passdb/machine_sid.h" … … 124 124 state->num_sids = num_sids; 125 125 126 state->single_sids = TALLOC_ARRAY(state, uint32_t, num_sids);126 state->single_sids = talloc_array(state, uint32_t, num_sids); 127 127 if (tevent_req_nomem(state->single_sids, req)) { 128 128 return tevent_req_post(req, ev); 129 129 } 130 130 131 state->res_domains = TALLOC_ZERO_P(state, struct lsa_RefDomainList);131 state->res_domains = talloc_zero(state, struct lsa_RefDomainList); 132 132 if (tevent_req_nomem(state->res_domains, req)) { 133 133 return tevent_req_post(req, ev); 134 134 } 135 state->res_domains->domains = TALLOC_ARRAY(135 state->res_domains->domains = talloc_array( 136 136 state->res_domains, struct lsa_DomainInfo, num_sids); 137 137 if (tevent_req_nomem(state->res_domains->domains, req)) { … … 139 139 } 140 140 141 state->res_names = TALLOC_ZERO_P(state, struct lsa_TransNameArray);141 state->res_names = talloc_zero(state, struct lsa_TransNameArray); 142 142 if (tevent_req_nomem(state->res_names, req)) { 143 143 return tevent_req_post(req, ev); 144 144 } 145 state->res_names->names = TALLOC_ARRAY(145 state->res_names->names = talloc_array( 146 146 state->res_names, struct lsa_TranslatedName, num_sids); 147 147 if (tevent_req_nomem(state->res_names->names, req)) { … … 186 186 d = &state->domains[state->domains_done]; 187 187 188 if (sid_check_is_ domain(&d->sid)) {188 if (sid_check_is_our_sam(&d->sid)) { 189 189 state->rids.num_rids = d->sids.num_sids; 190 state->rids.rids = TALLOC_ARRAY(state, uint32_t,190 state->rids.rids = talloc_array(state, uint32_t, 191 191 state->rids.num_rids); 192 192 if (tevent_req_nomem(state->rids.rids, req)) { … … 256 256 } 257 257 258 if (sid_check_is_in_our_ domain(sid)) {258 if (sid_check_is_in_our_sam(sid)) { 259 259 /* 260 260 * Passdb lookup via lookuprids … … 321 321 } 322 322 323 wb_domain = find_ domain_from_sid_noinit(sid);323 wb_domain = find_lookup_domain_from_sid(sid); 324 324 if (wb_domain == NULL) { 325 325 return NULL; 326 326 } 327 327 328 domains = TALLOC_REALLOC_ARRAY(328 domains = talloc_realloc( 329 329 mem_ctx, domains, struct wb_lookupsids_domain, num_domains+1); 330 330 if (domains == NULL) { … … 338 338 domain->domain = wb_domain; 339 339 340 domain->sids.sids = TALLOC_ARRAY(domains, struct lsa_SidPtr, num_sids);340 domain->sids.sids = talloc_array(domains, struct lsa_SidPtr, num_sids); 341 341 if (domains->sids.sids == NULL) { 342 342 goto fail; … … 344 344 domain->sids.num_sids = 0; 345 345 346 domain->sid_indexes = TALLOC_ARRAY(domains, uint32_t, num_sids);346 domain->sid_indexes = talloc_array(domains, uint32_t, num_sids); 347 347 if (domain->sid_indexes == NULL) { 348 348 TALLOC_FREE(domain->sids.sids); … … 355 355 * Realloc to the state it was in before 356 356 */ 357 *pdomains = TALLOC_REALLOC_ARRAY(357 *pdomains = talloc_realloc( 358 358 mem_ctx, domains, struct wb_lookupsids_domain, num_domains); 359 359 return NULL; … … 368 368 369 369 for (i=0; i<list->count; i++) { 370 if ( sid_equal(domain->sid, list->domains[i].sid)) {370 if (dom_sid_equal(domain->sid, list->domains[i].sid)) { 371 371 *idx = i; 372 372 return true; … … 485 485 state->res_domains, state->res_names, 486 486 res_sid_index)) { 487 tevent_req_ nomem(NULL,req);487 tevent_req_oom(req); 488 488 return; 489 489 } … … 548 548 state->res_domains, state->res_names, 549 549 res_sid_index)) { 550 tevent_req_ nomem(NULL,req);550 tevent_req_oom(req); 551 551 return; 552 552 } … … 623 623 state->res_domains, state->res_names, 624 624 res_sid_index)) { 625 tevent_req_ nomem(NULL,req);625 tevent_req_oom(req); 626 626 return; 627 627 } … … 649 649 * 650 650 */ 651 SMB_ASSERT(state->res_names->count == state->num_sids); 651 if (state->res_names->count != state->num_sids) { 652 DEBUG(0, ("res_names->count = %d, expected %d\n", 653 state->res_names->count, state->num_sids)); 654 return NT_STATUS_INTERNAL_ERROR; 655 } 652 656 653 657 /* -
vendor/current/source3/winbindd/wb_lookupuseraliases.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 24 24 struct wb_lookupuseraliases_state { … … 45 45 } 46 46 state->sids.num_sids = num_sids; 47 state->sids.sids = CONST_DISCARD(struct dom_sid *, sids);47 state->sids.sids = discard_const_p(struct dom_sid, sids); 48 48 49 49 subreq = dcerpc_wbint_LookupUserAliases_send( -
vendor/current/source3/winbindd/wb_lookupusergroups.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 #include "../libcli/security/security.h" 24 24 … … 38 38 struct tevent_req *req, *subreq; 39 39 struct wb_lookupusergroups_state *state; 40 NTSTATUS status; 40 41 41 42 req = tevent_req_create(mem_ctx, &state, … … 45 46 } 46 47 sid_copy(&state->sid, sid); 48 49 status = lookup_usergroups_cached(NULL, 50 state, 51 &state->sid, 52 &state->sids.num_sids, 53 &state->sids.sids); 54 if (NT_STATUS_IS_OK(status)) { 55 tevent_req_done(req); 56 return tevent_req_post(req, ev); 57 } 47 58 48 59 subreq = dcerpc_wbint_LookupUserGroups_send( -
vendor/current/source3/winbindd/wb_next_grent.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 #include "passdb/machine_sid.h" 24 24 … … 27 27 int max_nesting; 28 28 struct getgrent_state *gstate; 29 struct wbint_Principals next_groups;30 29 struct winbindd_gr *gr; 31 30 struct talloc_dict *members; … … 35 34 static void wb_next_grent_getgrsid_done(struct tevent_req *subreq); 36 35 36 static void wb_next_grent_send_do(struct tevent_req *req, 37 struct wb_next_grent_state *state) 38 { 39 struct tevent_req *subreq; 40 41 if (state->gstate->next_group >= state->gstate->num_groups) { 42 TALLOC_FREE(state->gstate->groups); 43 44 state->gstate->domain = wb_next_domain(state->gstate->domain); 45 if (state->gstate->domain == NULL) { 46 tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES); 47 return; 48 } 49 50 subreq = wb_query_group_list_send(state, state->ev, 51 state->gstate->domain); 52 if (tevent_req_nomem(subreq, req)) { 53 return; 54 } 55 tevent_req_set_callback(subreq, wb_next_grent_fetch_done, req); 56 return; 57 } 58 59 subreq = wb_getgrsid_send( 60 state, state->ev, 61 &state->gstate->groups[state->gstate->next_group].sid, 62 state->max_nesting); 63 if (tevent_req_nomem(subreq, req)) { 64 return; 65 } 66 tevent_req_set_callback(subreq, wb_next_grent_getgrsid_done, req); 67 } 68 37 69 struct tevent_req *wb_next_grent_send(TALLOC_CTX *mem_ctx, 38 70 struct tevent_context *ev, … … 41 73 struct winbindd_gr *gr) 42 74 { 43 struct tevent_req *req , *subreq;75 struct tevent_req *req; 44 76 struct wb_next_grent_state *state; 45 77 … … 53 85 state->max_nesting = max_nesting; 54 86 55 if (state->gstate->next_group >= state->gstate->num_groups) { 56 TALLOC_FREE(state->gstate->groups); 57 58 if (state->gstate->domain == NULL) { 59 state->gstate->domain = domain_list(); 60 } else { 61 state->gstate->domain = state->gstate->domain->next; 62 } 63 64 if ((state->gstate->domain != NULL) 65 && sid_check_is_domain(&state->gstate->domain->sid)) { 66 state->gstate->domain = state->gstate->domain->next; 67 } 68 69 if (state->gstate->domain == NULL) { 70 tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES); 71 return tevent_req_post(req, ev); 72 } 73 subreq = dcerpc_wbint_QueryGroupList_send( 74 state, state->ev, dom_child_handle(state->gstate->domain), 75 &state->next_groups); 76 if (tevent_req_nomem(subreq, req)) { 77 return tevent_req_post(req, ev); 78 } 79 tevent_req_set_callback(subreq, wb_next_grent_fetch_done, req); 80 return req; 87 wb_next_grent_send_do(req, state); 88 if (!tevent_req_is_in_progress(req)) { 89 return tevent_req_post(req, ev); 81 90 } 82 91 83 subreq = wb_getgrsid_send(84 state, state->ev,85 &state->gstate->groups[state->gstate->next_group].sid,86 state->max_nesting);87 if (tevent_req_nomem(subreq, req)) {88 return tevent_req_post(req, ev);89 }90 tevent_req_set_callback(subreq, wb_next_grent_getgrsid_done, req);91 92 return req; 92 93 } … … 98 99 struct wb_next_grent_state *state = tevent_req_data( 99 100 req, struct wb_next_grent_state); 100 NTSTATUS status , result;101 NTSTATUS status; 101 102 102 status = dcerpc_wbint_QueryGroupList_recv(subreq, state, &result); 103 status = wb_query_group_list_recv(subreq, state->gstate, 104 &state->gstate->num_groups, 105 &state->gstate->groups); 103 106 TALLOC_FREE(subreq); 104 if ( tevent_req_nterror(req,status)) {107 if (!NT_STATUS_IS_OK(status)) { 105 108 /* 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)) { 112 /* Ignore errors here, just log it */ 113 DEBUG(10, ("query_user_list for domain %s returned %s/%s\n", 114 state->gstate->domain->name, 115 nt_errstr(status), nt_errstr(result))); 116 tevent_req_nterror(req, result); 117 return; 118 } 119 120 state->gstate->num_groups = state->next_groups.num_principals; 121 state->gstate->groups = talloc_move( 122 state->gstate, &state->next_groups.principals); 123 124 if (state->gstate->num_groups == 0) { 125 state->gstate->domain = state->gstate->domain->next; 126 127 if ((state->gstate->domain != NULL) 128 && sid_check_is_domain(&state->gstate->domain->sid)) { 129 state->gstate->domain = state->gstate->domain->next; 130 } 131 132 if (state->gstate->domain == NULL) { 133 tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES); 134 return; 135 } 136 subreq = dcerpc_wbint_QueryGroupList_send( 137 state, state->ev, dom_child_handle(state->gstate->domain), 138 &state->next_groups); 139 if (tevent_req_nomem(subreq, req)) { 140 return; 141 } 142 tevent_req_set_callback(subreq, wb_next_grent_fetch_done, req); 143 return; 109 DEBUG(10, ("query_group_list for domain %s returned %s\n", 110 state->gstate->domain->name, nt_errstr(status))); 111 state->gstate->num_groups = 0; 144 112 } 145 113 146 114 state->gstate->next_group = 0; 147 115 148 subreq = wb_getgrsid_send( 149 state, state->ev, 150 &state->gstate->groups[state->gstate->next_group].sid, 151 state->max_nesting); 152 if (tevent_req_nomem(subreq, req)) { 153 return; 154 } 155 tevent_req_set_callback(subreq, wb_next_grent_getgrsid_done, req); 156 return; 116 wb_next_grent_send_do(req, state); 157 117 } 158 118 … … 169 129 &state->gr->gr_gid, &state->members); 170 130 TALLOC_FREE(subreq); 171 if (tevent_req_nterror(req, status)) { 131 132 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) { 133 state->gstate->next_group += 1; 134 135 wb_next_grent_send_do(req, state); 136 137 return; 138 } else if (tevent_req_nterror(req, status)) { 172 139 return; 173 140 } 141 174 142 if (!fill_grent(talloc_tos(), state->gr, domname, name, 175 143 state->gr->gr_gid)) { -
vendor/current/source3/winbindd/wb_next_pwent.c
r746 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 #include "passdb/machine_sid.h" 24 24 … … 32 32 static void wb_next_pwent_fill_done(struct tevent_req *subreq); 33 33 34 static struct winbindd_domain *wb_next_find_domain(struct winbindd_domain *domain) 34 static void wb_next_pwent_send_do(struct tevent_req *req, 35 struct wb_next_pwent_state *state) 35 36 { 36 if (domain == NULL) { 37 domain = domain_list(); 38 } else { 39 domain = domain->next; 37 struct tevent_req *subreq; 38 39 if (state->gstate->next_user >= state->gstate->num_users) { 40 TALLOC_FREE(state->gstate->users); 41 42 state->gstate->domain = wb_next_domain(state->gstate->domain); 43 if (state->gstate->domain == NULL) { 44 tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES); 45 return; 46 } 47 48 subreq = wb_query_user_list_send(state, state->ev, 49 state->gstate->domain); 50 if (tevent_req_nomem(subreq, req)) { 51 return; 52 } 53 54 tevent_req_set_callback(subreq, wb_next_pwent_fetch_done, req); 55 return; 40 56 } 41 57 42 if ((domain != NULL) 43 && sid_check_is_domain(&domain->sid)) { 44 domain = domain->next; 58 subreq = wb_fill_pwent_send(state, state->ev, 59 &state->gstate->users[state->gstate->next_user], 60 state->pw); 61 if (tevent_req_nomem(subreq, req)) { 62 return; 45 63 } 46 64 47 if (domain == NULL) { 48 return NULL; 49 } 50 51 return domain; 65 tevent_req_set_callback(subreq, wb_next_pwent_fill_done, req); 52 66 } 53 67 … … 57 71 struct winbindd_pw *pw) 58 72 { 59 struct tevent_req *req , *subreq;73 struct tevent_req *req; 60 74 struct wb_next_pwent_state *state; 61 75 … … 68 82 state->pw = pw; 69 83 70 if (state->gstate->next_user >= state->gstate->num_users) { 71 TALLOC_FREE(state->gstate->users); 72 73 state->gstate->domain = wb_next_find_domain(state->gstate->domain); 74 if (state->gstate->domain == NULL) { 75 tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES); 76 return tevent_req_post(req, ev); 77 } 78 subreq = wb_query_user_list_send(state, state->ev, 79 state->gstate->domain); 80 if (tevent_req_nomem(subreq, req)) { 81 return tevent_req_post(req, ev); 82 } 83 tevent_req_set_callback(subreq, wb_next_pwent_fetch_done, req); 84 return req; 84 wb_next_pwent_send_do(req, state); 85 if (!tevent_req_is_in_progress(req)) { 86 return tevent_req_post(req, ev); 85 87 } 86 88 87 subreq = wb_fill_pwent_send(88 state, state->ev,89 &state->gstate->users[state->gstate->next_user],90 state->pw);91 if (tevent_req_nomem(subreq, req)) {92 return tevent_req_post(req, ev);93 }94 tevent_req_set_callback(subreq, wb_next_pwent_fill_done, req);95 89 return req; 96 90 } … … 116 110 } 117 111 118 if (state->gstate->num_users == 0) {119 state->gstate->domain = state->gstate->domain->next;120 121 if ((state->gstate->domain != NULL)122 && sid_check_is_domain(&state->gstate->domain->sid)) {123 state->gstate->domain = state->gstate->domain->next;124 }125 126 if (state->gstate->domain == NULL) {127 tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);128 return;129 }130 subreq = wb_query_user_list_send(state, state->ev,131 state->gstate->domain);132 if (tevent_req_nomem(subreq, req)) {133 return;134 }135 tevent_req_set_callback(subreq, wb_next_pwent_fetch_done, req);136 return;137 }138 139 112 state->gstate->next_user = 0; 140 113 141 subreq = wb_fill_pwent_send( 142 state, state->ev, 143 &state->gstate->users[state->gstate->next_user], 144 state->pw); 145 if (tevent_req_nomem(subreq, req)) { 146 return; 147 } 148 tevent_req_set_callback(subreq, wb_next_pwent_fill_done, req); 114 wb_next_pwent_send_do(req, state); 149 115 } 150 116 … … 166 132 state->gstate->next_user += 1; 167 133 168 if (state->gstate->next_user >= state->gstate->num_users) { 169 TALLOC_FREE(state->gstate->users); 170 171 state->gstate->domain = wb_next_find_domain(state->gstate->domain); 172 if (state->gstate->domain == NULL) { 173 tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES); 174 return; 175 } 176 177 subreq = wb_query_user_list_send(state, state->ev, 178 state->gstate->domain); 179 if (tevent_req_nomem(subreq, req)) { 180 return; 181 } 182 tevent_req_set_callback(subreq, wb_next_pwent_fetch_done, req); 183 return; 184 } 185 186 subreq = wb_fill_pwent_send(state, 187 state->ev, 188 &state->gstate->users[state->gstate->next_user], 189 state->pw); 190 if (tevent_req_nomem(subreq, req)) { 191 return; 192 } 193 tevent_req_set_callback(subreq, wb_next_pwent_fill_done, req); 134 wb_next_pwent_send_do(req, state); 194 135 195 136 return; -
vendor/current/source3/winbindd/wb_query_user_list.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 24 24 struct wb_query_user_list_state { -
vendor/current/source3/winbindd/wb_queryuser.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 #include "../libcli/security/security.h" 24 24 -
vendor/current/source3/winbindd/wb_seqnum.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 24 24 struct wb_seqnum_state { -
vendor/current/source3/winbindd/wb_seqnums.c
r740 r988 22 22 #include "includes.h" 23 23 #include "winbindd.h" 24 #include "librpc/gen_ndr/ndr_w bint_c.h"24 #include "librpc/gen_ndr/ndr_winbind_c.h" 25 25 26 26 struct wb_seqnums_state { -
vendor/current/source3/winbindd/wb_uid2sid.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 #include "idmap_cache.h" 24 24 #include "idmap.h" … … 27 27 struct wb_uid2sid_state { 28 28 struct tevent_context *ev; 29 char *dom_name;30 29 struct dom_sid sid; 31 30 }; … … 39 38 struct tevent_req *req, *subreq; 40 39 struct wb_uid2sid_state *state; 41 struct winbindd_domain *domain;42 40 struct winbindd_child *child; 43 41 bool expired; … … 65 63 } 66 64 67 state->dom_name = NULL;68 69 for (domain = domain_list(); domain != NULL; domain = domain->next) {70 if (domain->have_idmap_config71 && (uid >= domain->id_range_low)72 && (uid <= domain->id_range_high)) {73 state->dom_name = domain->name;74 break;75 }76 }77 78 65 child = idmap_child(); 79 66 80 67 subreq = dcerpc_wbint_Uid2Sid_send( 81 state, ev, child->binding_handle, state->dom_name,68 state, ev, child->binding_handle, 82 69 uid, &state->sid); 83 70 if (tevent_req_nomem(subreq, req)) { -
vendor/current/source3/winbindd/winbindd.c
r860 r988 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 … … 32 32 #include "../librpc/gen_ndr/srv_samr.h" 33 33 #include "secrets.h" 34 #include "rpc_client/cli_netlogon.h" 34 35 #include "idmap.h" 35 36 #include "lib/addrchange.h" … … 37 38 #include "auth.h" 38 39 #include "messages.h" 40 #include "../lib/util/pidfile.h" 41 #include "util_cluster.h" 42 #include "source4/lib/messaging/irpc.h" 43 #include "source4/lib/messaging/messaging.h" 44 #include "lib/param/param.h" 45 #include "lib/async_req/async_sock.h" 39 46 40 47 #undef DBGC_CLASS 41 48 #define DBGC_CLASS DBGC_WINBIND 42 49 50 #define SCRUB_CLIENTS_INTERVAL 5 51 43 52 static bool client_is_idle(struct winbindd_cli_state *state); 44 53 static void remove_client(struct winbindd_cli_state *state); 54 static void winbindd_setup_max_fds(void); 45 55 46 56 static bool opt_nocache = False; … … 49 59 extern bool override_logfile; 50 60 61 struct tevent_context *winbind_event_context(void) 62 { 63 static struct tevent_context *ev = NULL; 64 65 if (ev != NULL) { 66 return ev; 67 } 68 69 /* 70 * Note we MUST use the NULL context here, not the autofree context, 71 * to avoid side effects in forked children exiting. 72 */ 73 ev = samba_tevent_context_init(NULL); 74 if (ev == NULL) { 75 smb_panic("Could not init winbindd's messaging context.\n"); 76 } 77 return ev; 78 } 79 51 80 struct messaging_context *winbind_messaging_context(void) 52 81 { 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; 82 static struct messaging_context *msg = NULL; 83 84 if (msg != NULL) { 85 return msg; 86 } 87 88 /* 89 * Note we MUST use the NULL context here, not the autofree context, 90 * to avoid side effects in forked children exiting. 91 */ 92 msg = messaging_init(NULL, winbind_event_context()); 93 if (msg == NULL) { 94 smb_panic("Could not init winbindd's messaging context.\n"); 95 } 96 return msg; 97 } 98 99 struct imessaging_context *winbind_imessaging_context(void) 100 { 101 static struct imessaging_context *msg = NULL; 102 struct messaging_context *msg_ctx; 103 struct server_id myself; 104 struct loadparm_context *lp_ctx; 105 106 if (msg != NULL) { 107 return msg; 108 } 109 110 msg_ctx = server_messaging_context(); 111 if (msg_ctx == NULL) { 112 smb_panic("server_messaging_context failed\n"); 113 } 114 myself = messaging_server_id(msg_ctx); 115 116 lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers()); 117 if (lp_ctx == NULL) { 118 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n"); 119 } 120 121 /* 122 * Note we MUST use the NULL context here, not the autofree context, 123 * to avoid side effects in forked children exiting. 124 */ 125 msg = imessaging_init(NULL, lp_ctx, myself, winbind_event_context(), 126 false); 127 talloc_unlink(NULL, lp_ctx); 128 129 if (msg == NULL) { 130 smb_panic("Could not init winbindd's messaging context.\n"); 131 } 132 return msg; 59 133 } 60 134 … … 66 140 67 141 if (lp_loaded()) { 68 char *fname = lp_ configfile();142 char *fname = lp_next_configfile(talloc_tos()); 69 143 70 144 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) { … … 81 155 82 156 reopen_logs(); 83 ret = lp_load (get_dyn_CONFIGFILE(),False,False,True,True);157 ret = lp_load_global(get_dyn_CONFIGFILE()); 84 158 85 159 reopen_logs(); 86 160 load_interfaces(); 161 winbindd_setup_max_fds(); 87 162 88 163 return(ret); 89 164 } 90 165 91 92 /**************************************************************************** **93 Handle a fault..94 **************************************************************************** */95 96 static void fault_quit(void)97 {98 dump_core();99 }100 166 101 167 static void winbindd_status(void) … … 170 236 171 237 if (asprintf(&path, "%s/%s", 172 get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME) > 0) {238 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) { 173 239 unlink(path); 174 240 SAFE_FREE(path); … … 193 259 194 260 if (is_parent) { 195 serverid_deregister(procid_self()); 196 pidfile_unlink(); 261 struct messaging_context *msg = winbind_messaging_context(); 262 struct server_id self = messaging_server_id(msg); 263 serverid_deregister(self); 264 pidfile_unlink(lp_pid_directory(), "winbindd"); 197 265 } 198 266 … … 212 280 signum, (int)*is_parent)); 213 281 terminate(*is_parent); 282 } 283 284 /* 285 handle stdin becoming readable when we are in --foreground mode 286 */ 287 static void winbindd_stdin_handler(struct tevent_context *ev, 288 struct tevent_fd *fde, 289 uint16_t flags, 290 void *private_data) 291 { 292 char c; 293 if (read(0, &c, 1) != 1) { 294 bool *is_parent = talloc_get_type_abort(private_data, bool); 295 296 /* we have reached EOF on stdin, which means the 297 parent has exited. Shutdown the server */ 298 DEBUG(0,("EOF on stdin (is_parent=%d)\n", 299 (int)*is_parent)); 300 terminate(*is_parent); 301 } 214 302 } 215 303 … … 262 350 } 263 351 352 bool winbindd_setup_stdin_handler(bool parent, bool foreground) 353 { 354 bool *is_parent; 355 356 if (foreground) { 357 struct stat st; 358 359 is_parent = talloc(winbind_event_context(), bool); 360 if (!is_parent) { 361 return false; 362 } 363 364 *is_parent = parent; 365 366 /* if we are running in the foreground then look for 367 EOF on stdin, and exit if it happens. This allows 368 us to die if the parent process dies 369 Only do this on a pipe or socket, no other device. 370 */ 371 if (fstat(0, &st) != 0) { 372 return false; 373 } 374 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) { 375 tevent_add_fd(winbind_event_context(), 376 is_parent, 377 0, 378 TEVENT_FD_READ, 379 winbindd_stdin_handler, 380 is_parent); 381 } 382 } 383 384 return true; 385 } 386 264 387 static void winbindd_sig_hup_handler(struct tevent_context *ev, 265 388 struct tevent_signal *se, … … 388 511 DATA_BLOB *data) 389 512 { 390 uint8 ret;513 uint8_t ret; 391 514 pid_t child_pid; 392 515 NTSTATUS status; … … 400 523 * code can safely use fork/waitpid... 401 524 */ 402 child_pid = sys_fork();525 child_pid = fork(); 403 526 404 527 if (child_pid == -1) { … … 427 550 CatchSignal(SIGCHLD, SIG_DFL); 428 551 429 ret = (uint8 )winbindd_validate_cache_nobackup();552 ret = (uint8_t)winbindd_validate_cache_nobackup(); 430 553 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret)); 431 554 messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret, … … 460 583 { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" }, 461 584 { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" }, 462 463 /* WINS functions */464 465 { WINBINDD_WINS_BYNAME, winbindd_wins_byname, "WINS_BYNAME" },466 { WINBINDD_WINS_BYIP, winbindd_wins_byip, "WINS_BYIP" },467 585 468 586 /* End of list */ … … 556 674 winbindd_pam_chng_pswd_auth_crap_send, 557 675 winbindd_pam_chng_pswd_auth_crap_recv }, 676 { WINBINDD_WINS_BYIP, "WINS_BYIP", 677 winbindd_wins_byip_send, winbindd_wins_byip_recv }, 678 { WINBINDD_WINS_BYNAME, "WINS_BYNAME", 679 winbindd_wins_byname_send, winbindd_wins_byname_recv }, 558 680 559 681 { 0, NULL, NULL, NULL } … … 589 711 state->cmd_name = "unknown request"; 590 712 state->recv_fn = NULL; 591 state->last_access = time(NULL); 713 /* client is newest */ 714 winbindd_promote_client(state); 592 715 593 716 /* Process command */ … … 700 823 static void winbind_client_request_read(struct tevent_req *req); 701 824 static void winbind_client_response_written(struct tevent_req *req); 825 static void winbind_client_activity(struct tevent_req *req); 702 826 703 827 static void request_finished(struct winbindd_cli_state *state) 704 828 { 705 829 struct tevent_req *req; 830 831 /* free client socket monitoring request */ 832 TALLOC_FREE(state->io_req); 706 833 707 834 TALLOC_FREE(state->request); … … 717 844 } 718 845 tevent_req_set_callback(req, winbind_client_response_written, state); 846 state->io_req = req; 719 847 } 720 848 … … 725 853 ssize_t ret; 726 854 int err; 855 856 state->io_req = NULL; 727 857 728 858 ret = wb_resp_write_recv(req, &err); … … 752 882 } 753 883 tevent_req_set_callback(req, winbind_client_request_read, state); 884 state->io_req = req; 754 885 } 755 886 … … 786 917 if (sock == -1) { 787 918 if (errno != EINTR) { 788 DEBUG(0, ("Fail d to accept socket - %s\n",919 DEBUG(0, ("Failed to accept socket - %s\n", 789 920 strerror(errno))); 790 921 } … … 796 927 /* Create new connection structure */ 797 928 798 if ((state = TALLOC_ZERO_P(NULL, struct winbindd_cli_state)) == NULL) {929 if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) { 799 930 close(sock); 800 931 return; … … 809 940 return; 810 941 } 811 812 state->last_access = time(NULL);813 942 814 943 state->privileged = privileged; … … 822 951 } 823 952 tevent_req_set_callback(req, winbind_client_request_read, state); 953 state->io_req = req; 824 954 825 955 /* Add to connection list */ … … 834 964 ssize_t ret; 835 965 int err; 966 967 state->io_req = NULL; 836 968 837 969 ret = wb_req_read_recv(req, state, &state->request, &err); … … 850 982 return; 851 983 } 984 985 req = wait_for_read_send(state, winbind_event_context(), state->sock, 986 true); 987 if (req == NULL) { 988 DEBUG(0, ("winbind_client_request_read[%d:%s]:" 989 " wait_for_read_send failed - removing client\n", 990 (int)state->pid, state->cmd_name)); 991 remove_client(state); 992 return; 993 } 994 tevent_req_set_callback(req, winbind_client_activity, state); 995 state->io_req = req; 996 852 997 process_request(state); 998 } 999 1000 static void winbind_client_activity(struct tevent_req *req) 1001 { 1002 struct winbindd_cli_state *state = 1003 tevent_req_callback_data(req, struct winbindd_cli_state); 1004 int err; 1005 bool has_data; 1006 1007 has_data = wait_for_read_recv(req, &err); 1008 1009 if (has_data) { 1010 DEBUG(0, ("winbind_client_activity[%d:%s]:" 1011 "unexpected data from client - removing client\n", 1012 (int)state->pid, state->cmd_name)); 1013 } else { 1014 if (err == EPIPE) { 1015 DEBUG(6, ("winbind_client_activity[%d:%s]: " 1016 "client has closed connection - removing " 1017 "client\n", 1018 (int)state->pid, state->cmd_name)); 1019 } else { 1020 DEBUG(2, ("winbind_client_activity[%d:%s]: " 1021 "client socket error (%s) - removing " 1022 "client\n", 1023 (int)state->pid, state->cmd_name, 1024 strerror(err))); 1025 } 1026 } 1027 1028 remove_client(state); 853 1029 } 854 1030 … … 865 1041 return; 866 1042 } 1043 1044 /* 1045 * We need to remove a pending wb_req_read_* 1046 * or wb_resp_write_* request before closing the 1047 * socket. 1048 * 1049 * This is important as they might have used tevent_add_fd() and we 1050 * use the epoll * backend on linux. So we must remove the tevent_fd 1051 * before closing the fd. 1052 * 1053 * Otherwise we might hit a race with close_conns_after_fork() (via 1054 * winbindd_reinit_after_fork()) where a file description 1055 * is still open in a child, which means it's still active in 1056 * the parents epoll queue, but the related tevent_fd is already 1057 * already gone in the parent. 1058 * 1059 * See bug #11141. 1060 */ 1061 TALLOC_FREE(state->io_req); 867 1062 868 1063 if (state->sock != -1) { … … 901 1096 { 902 1097 struct winbindd_cli_state *state, *remove_state = NULL; 903 time_t last_access = 0;904 1098 int nidle = 0; 905 1099 … … 907 1101 if (client_is_idle(state)) { 908 1102 nidle++; 909 if (!last_access || state->last_access < last_access) { 910 last_access = state->last_access; 911 remove_state = state; 912 } 1103 /* list is sorted by access time */ 1104 remove_state = state; 913 1105 } 914 1106 } … … 922 1114 923 1115 return False; 1116 } 1117 1118 /* 1119 * Terminate all clients whose requests have taken longer than 1120 * "winbind request timeout" seconds to process, or have been 1121 * idle for more than "winbind request timeout" seconds. 1122 */ 1123 1124 static void remove_timed_out_clients(void) 1125 { 1126 struct winbindd_cli_state *state, *prev = NULL; 1127 time_t curr_time = time(NULL); 1128 int timeout_val = lp_winbind_request_timeout(); 1129 1130 for (state = winbindd_client_list_tail(); state; state = prev) { 1131 time_t expiry_time; 1132 1133 prev = winbindd_client_list_prev(state); 1134 expiry_time = state->last_access + timeout_val; 1135 1136 if (curr_time > expiry_time) { 1137 if (client_is_idle(state)) { 1138 DEBUG(5,("Idle client timed out, " 1139 "shutting down sock %d, pid %u\n", 1140 state->sock, 1141 (unsigned int)state->pid)); 1142 } else { 1143 DEBUG(5,("Client request timed out, " 1144 "shutting down sock %d, pid %u\n", 1145 state->sock, 1146 (unsigned int)state->pid)); 1147 } 1148 remove_client(state); 1149 } else { 1150 /* list is sorted, previous clients in 1151 list are newer */ 1152 break; 1153 } 1154 } 1155 } 1156 1157 static void winbindd_scrub_clients_handler(struct tevent_context *ev, 1158 struct tevent_timer *te, 1159 struct timeval current_time, 1160 void *private_data) 1161 { 1162 remove_timed_out_clients(); 1163 if (tevent_add_timer(ev, ev, 1164 timeval_current_ofs(SCRUB_CLIENTS_INTERVAL, 0), 1165 winbindd_scrub_clients_handler, NULL) == NULL) { 1166 DEBUG(0, ("winbindd: failed to reschedule client scrubber\n")); 1167 exit(1); 1168 } 924 1169 } 925 1170 … … 949 1194 } 950 1195 } 1196 remove_timed_out_clients(); 951 1197 new_connection(s->fd, s->privileged); 952 1198 } … … 956 1202 */ 957 1203 958 const char *get_winbind_pipe_dir(void)959 {960 return lp_parm_const_string(-1, "winbindd", "socket dir", WINBINDD_SOCKET_DIR);961 }962 963 1204 char *get_winbind_priv_pipe_dir(void) 964 1205 { 965 return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR); 1206 return state_path(WINBINDD_PRIV_SOCKET_SUBDIR); 1207 } 1208 1209 static void winbindd_setup_max_fds(void) 1210 { 1211 int num_fds = MAX_OPEN_FUDGEFACTOR; 1212 int actual_fds; 1213 1214 num_fds += lp_winbind_max_clients(); 1215 /* Add some more to account for 2 sockets open 1216 when the client transitions from unprivileged 1217 to privileged socket 1218 */ 1219 num_fds += lp_winbind_max_clients() / 10; 1220 1221 /* Add one socket per child process 1222 (yeah there are child processes other than the 1223 domain children but only domain children can vary 1224 with configuration 1225 */ 1226 num_fds += lp_winbind_max_domain_connections() * 1227 (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1); 1228 1229 actual_fds = set_maxfiles(num_fds); 1230 1231 if (actual_fds < num_fds) { 1232 DEBUG(1, ("winbindd_setup_max_fds: Information only: " 1233 "requested %d open files, %d are available.\n", 1234 num_fds, actual_fds)); 1235 } 966 1236 } 967 1237 … … 971 1241 struct winbindd_listen_state *priv_state = NULL; 972 1242 struct tevent_fd *fde; 1243 int rc; 1244 char *socket_path; 973 1245 974 1246 pub_state = talloc(winbind_event_context(), … … 980 1252 pub_state->privileged = false; 981 1253 pub_state->fd = create_pipe_sock( 982 get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME, 0755);1254 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755); 983 1255 if (pub_state->fd == -1) { 1256 goto failed; 1257 } 1258 rc = listen(pub_state->fd, 5); 1259 if (rc < 0) { 984 1260 goto failed; 985 1261 } … … 1000 1276 } 1001 1277 1278 socket_path = get_winbind_priv_pipe_dir(); 1279 if (socket_path == NULL) { 1280 goto failed; 1281 } 1282 1002 1283 priv_state->privileged = true; 1003 1284 priv_state->fd = create_pipe_sock( 1004 get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750); 1285 socket_path, WINBINDD_SOCKET_NAME, 0750); 1286 TALLOC_FREE(socket_path); 1005 1287 if (priv_state->fd == -1) { 1288 goto failed; 1289 } 1290 rc = listen(priv_state->fd, 5); 1291 if (rc < 0) { 1006 1292 goto failed; 1007 1293 } … … 1016 1302 tevent_fd_set_auto_close(fde); 1017 1303 1304 winbindd_scrub_clients_handler(winbind_event_context(), NULL, 1305 timeval_current(), NULL); 1018 1306 return true; 1019 1307 failed: … … 1033 1321 } 1034 1322 1035 void winbindd_register_handlers(void) 1036 { 1323 static void winbindd_register_handlers(struct messaging_context *msg_ctx, 1324 bool foreground) 1325 { 1326 NTSTATUS status; 1037 1327 /* Setup signal handlers */ 1038 1328 1039 1329 if (!winbindd_setup_sig_term_handler(true)) 1330 exit(1); 1331 if (!winbindd_setup_stdin_handler(true, foreground)) 1040 1332 exit(1); 1041 1333 if (!winbindd_setup_sig_hup_handler(NULL)) … … 1058 1350 /* get broadcast messages */ 1059 1351 1060 if (!serverid_register(procid_self(), 1061 FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP)) { 1352 if (!serverid_register(messaging_server_id(msg_ctx), 1353 FLAG_MSG_GENERAL | 1354 FLAG_MSG_WINBIND | 1355 FLAG_MSG_DBWRAP)) { 1062 1356 DEBUG(1, ("Could not register myself in serverid.tdb\n")); 1063 1357 exit(1); … … 1066 1360 /* React on 'smbcontrol winbindd reload-config' in the same way 1067 1361 as to SIGHUP signal */ 1068 messaging_register( winbind_messaging_context(), NULL,1362 messaging_register(msg_ctx, NULL, 1069 1363 MSG_SMB_CONF_UPDATED, msg_reload_services); 1070 messaging_register( winbind_messaging_context(), NULL,1364 messaging_register(msg_ctx, NULL, 1071 1365 MSG_SHUTDOWN, msg_shutdown); 1072 1366 1073 1367 /* Handle online/offline messages. */ 1074 messaging_register( winbind_messaging_context(), NULL,1368 messaging_register(msg_ctx, NULL, 1075 1369 MSG_WINBIND_OFFLINE, winbind_msg_offline); 1076 messaging_register( winbind_messaging_context(), NULL,1370 messaging_register(msg_ctx, NULL, 1077 1371 MSG_WINBIND_ONLINE, winbind_msg_online); 1078 messaging_register( winbind_messaging_context(), NULL,1372 messaging_register(msg_ctx, NULL, 1079 1373 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus); 1080 1374 … … 1085 1379 MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online); 1086 1380 1087 messaging_register( winbind_messaging_context(), NULL,1381 messaging_register(msg_ctx, NULL, 1088 1382 MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list); 1089 1383 1090 messaging_register( winbind_messaging_context(), NULL,1384 messaging_register(msg_ctx, NULL, 1091 1385 MSG_WINBIND_VALIDATE_CACHE, 1092 1386 winbind_msg_validate_cache); 1093 1387 1094 messaging_register( winbind_messaging_context(), NULL,1388 messaging_register(msg_ctx, NULL, 1095 1389 MSG_WINBIND_DUMP_DOMAIN_LIST, 1096 1390 winbind_msg_dump_domain_list); 1097 1391 1098 messaging_register( winbind_messaging_context(), NULL,1392 messaging_register(msg_ctx, NULL, 1099 1393 MSG_WINBIND_IP_DROPPED, 1100 1394 winbind_msg_ip_dropped_parent); 1101 1395 1102 1396 /* Register handler for MSG_DEBUG. */ 1103 messaging_register( winbind_messaging_context(), NULL,1397 messaging_register(msg_ctx, NULL, 1104 1398 MSG_DEBUG, 1105 1399 winbind_msg_debug); … … 1130 1424 } 1131 1425 1426 status = wb_irpc_register(); 1427 1428 if (!NT_STATUS_IS_OK(status)) { 1429 DEBUG(0, ("Could not register IRPC handlers\n")); 1430 exit(1); 1431 } 1132 1432 } 1133 1433 … … 1218 1518 /* Main function */ 1219 1519 1220 int main(int argc, c har **argv, char **envp)1520 int main(int argc, const char **argv) 1221 1521 { 1222 1522 static bool is_daemon = False; … … 1245 1545 TALLOC_CTX *frame; 1246 1546 NTSTATUS status; 1547 bool ok; 1247 1548 1248 1549 /* … … 1252 1553 frame = talloc_stackframe(); 1253 1554 1555 /* 1556 * We want total control over the permissions on created files, 1557 * so set our umask to 0. 1558 */ 1559 umask(0); 1560 1561 setup_logging("winbindd", DEBUG_DEFAULT_STDOUT); 1562 1254 1563 /* glibc (?) likes to print "User defined signal 1" and exit if a 1255 1564 SIGUSR[12] is received before a handler is installed */ … … 1258 1567 CatchSignal(SIGUSR2, SIG_IGN); 1259 1568 1260 fault_setup( (void (*)(void *))fault_quit);1261 dump_core_setup("winbindd" );1262 1263 load_case_tables();1569 fault_setup(); 1570 dump_core_setup("winbindd", lp_logfile(talloc_tos())); 1571 1572 smb_init_locale(); 1264 1573 1265 1574 /* Initialise for running in non-root mode */ … … 1279 1588 /* Initialise samba/rpc client stuff */ 1280 1589 1281 pc = poptGetContext("winbindd", argc, (const char **)argv, long_options, 0);1590 pc = poptGetContext("winbindd", argc, argv, long_options, 0); 1282 1591 1283 1592 while ((opt = poptGetNextOpt(pc)) != -1) { … … 1319 1628 * in production. 1320 1629 */ 1321 dump_core_setup("winbindd"); 1322 1630 dump_core_setup("winbindd", lp_logfile(talloc_tos())); 1323 1631 if (is_daemon && interactive) { 1324 1632 d_fprintf(stderr,"\nERROR: " … … 1345 1653 } 1346 1654 } 1655 1347 1656 if (log_stdout) { 1348 1657 setup_logging("winbindd", DEBUG_STDOUT); … … 1356 1665 1357 1666 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) { 1358 DEBUG(0, ("error opening config file \n"));1667 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE())); 1359 1668 exit(1); 1360 1669 } … … 1363 1672 * path is by default basename(lp_logfile()). 1364 1673 */ 1365 dump_core_setup("winbindd"); 1674 dump_core_setup("winbindd", lp_logfile(talloc_tos())); 1675 1676 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC 1677 && !lp_parm_bool(-1, "server role check", "inhibit", false)) { 1678 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n")); 1679 DEBUGADD(0, ("You should start 'samba' instead, and it will control starting the internal AD DC winbindd implementation, which is not the same as this one\n")); 1680 exit(1); 1681 } 1682 1683 if (!cluster_probe_ok()) { 1684 exit(1); 1685 } 1366 1686 1367 1687 /* Initialise messaging system */ … … 1376 1696 } 1377 1697 1378 if (!directory_exist(lp_lockdir())) { 1379 mkdir(lp_lockdir(), 0755); 1698 ok = directory_create_or_exist(lp_lock_directory(), 0755); 1699 if (!ok) { 1700 DEBUG(0, ("Failed to create directory %s for lock files - %s\n", 1701 lp_lock_directory(), strerror(errno))); 1702 exit(1); 1703 } 1704 1705 ok = directory_create_or_exist(lp_pid_directory(), 0755); 1706 if (!ok) { 1707 DEBUG(0, ("Failed to create directory %s for pid files - %s\n", 1708 lp_pid_directory(), strerror(errno))); 1709 exit(1); 1380 1710 } 1381 1711 … … 1391 1721 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n")); 1392 1722 return False; 1723 } 1724 1725 status = rpccli_pre_open_netlogon_creds(); 1726 if (!NT_STATUS_IS_OK(status)) { 1727 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n", 1728 nt_errstr(status))); 1729 exit(1); 1393 1730 } 1394 1731 … … 1407 1744 become_daemon(Fork, no_process_group, log_stdout); 1408 1745 1409 pidfile_create( "winbindd");1746 pidfile_create(lp_pid_directory(), "winbindd"); 1410 1747 1411 1748 #if HAVE_SETPGID … … 1427 1764 status = reinit_after_fork(winbind_messaging_context(), 1428 1765 winbind_event_context(), 1429 procid_self(), false);1766 false, NULL); 1430 1767 if (!NT_STATUS_IS_OK(status)) { 1431 DEBUG(0,("reinit_after_fork() failed\n")); 1432 exit(1); 1433 } 1434 1435 winbindd_register_handlers(); 1436 1437 status = init_system_info(); 1768 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status)); 1769 } 1770 1771 /* 1772 * Do not initialize the parent-child-pipe before becoming 1773 * a daemon: this is used to detect a died parent in the child 1774 * process. 1775 */ 1776 status = init_before_fork(); 1438 1777 if (!NT_STATUS_IS_OK(status)) { 1439 DEBUG(1, ("ERROR: failed to setup system user info: %s.\n", 1440 nt_errstr(status))); 1441 exit(1); 1778 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status)); 1779 } 1780 1781 winbindd_register_handlers(winbind_messaging_context(), !Fork); 1782 1783 if (!messaging_parent_dgm_cleanup_init(winbind_messaging_context())) { 1784 exit(1); 1785 } 1786 1787 status = init_system_session_info(); 1788 if (!NT_STATUS_IS_OK(status)) { 1789 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status)); 1442 1790 } 1443 1791 … … 1451 1799 1452 1800 if (!winbindd_setup_listeners()) { 1453 DEBUG(0,("winbindd_setup_listeners() failed\n")); 1454 exit(1); 1455 } 1801 exit_daemon("Winbindd failed to setup listeners", EPIPE); 1802 } 1803 1804 irpc_add_name(winbind_imessaging_context(), "winbind_server"); 1456 1805 1457 1806 TALLOC_FREE(frame); 1807 1808 if (!interactive) { 1809 daemon_ready("winbindd"); 1810 } 1811 1458 1812 /* Loop waiting for requests */ 1459 1813 while (1) { -
vendor/current/source3/winbindd/winbindd.h
r740 r988 26 26 #include "nsswitch/winbind_struct_protocol.h" 27 27 #include "nsswitch/libwbclient/wbclient.h" 28 #include "librpc/gen_ndr/wbint.h" 28 #include "librpc/gen_ndr/dcerpc.h" 29 #include "librpc/gen_ndr/winbind.h" 29 30 30 31 #include "talloc_dict.h" 31 #include "smb_ldap.h"32 32 33 33 #include "../lib/util/tevent_ntstatus.h" … … 68 68 struct tevent_queue *out_queue; 69 69 struct winbindd_response *response; /* Respose to client */ 70 bool getpwent_initialized; /* Has getpwent_state been 71 * initialized? */ 72 bool getgrent_initialized; /* Has getgrent_state been 73 * initialized? */ 70 struct tevent_req *io_req; /* wb_req_read_* or wb_resp_write_* */ 74 71 75 72 struct getpwent_state *pwent_state; /* State for getpwent() */ … … 107 104 struct cli_state *cli; 108 105 106 enum dcerpc_AuthLevel auth_level; 107 109 108 struct rpc_pipe_client *samr_pipe; 110 109 struct policy_handle sam_connect_handle, sam_domain_handle; … … 115 114 116 115 struct rpc_pipe_client *netlogon_pipe; 116 struct netlogon_creds_cli_context *netlogon_creds; 117 uint32_t netlogon_flags; 118 bool netlogon_force_reauth; 117 119 }; 118 120 … … 139 141 struct dcerpc_binding_handle *binding_handle; 140 142 141 struct t imed_event*lockout_policy_event;142 struct t imed_event*machine_password_change_event;143 struct tevent_timer *lockout_policy_event; 144 struct tevent_timer *machine_password_change_event; 143 145 144 146 const struct winbindd_child_dispatch_table *table; … … 148 150 149 151 struct winbindd_domain { 150 fstring name;/* Domain name (NetBIOS) */151 fstring alt_name;/* alt Domain name, if any (FQDN for ADS) */152 fstring forest_name;/* Name of the AD forest we're in */152 char *name; /* Domain name (NetBIOS) */ 153 char *alt_name; /* alt Domain name, if any (FQDN for ADS) */ 154 char *forest_name; /* Name of the AD forest we're in */ 153 155 struct dom_sid sid; /* SID for this domain */ 154 uint32 domain_flags; /* Domain flags from netlogon.h */155 uint32 domain_type; /* Domain type from netlogon.h */156 uint32 domain_trust_attribs; /* Trust attribs from netlogon.h */156 uint32_t domain_flags; /* Domain flags from netlogon.h */ 157 uint32_t domain_type; /* Domain type from netlogon.h */ 158 uint32_t domain_trust_attribs; /* Trust attribs from netlogon.h */ 157 159 bool initialized; /* Did we already ask for the domain mode? */ 158 160 bool native_mode; /* is this a win2k domain in native mode ? */ … … 160 162 bool primary; /* is this our primary domain ? */ 161 163 bool internal; /* BUILTIN and member SAM */ 164 bool rodc; /* Are we an RODC for this AD domain? (do some operations locally) */ 162 165 bool online; /* is this domain available ? */ 163 166 time_t startup_time; /* When we set "startup" true. monotonic clock */ 164 167 bool startup; /* are we in the first 30 seconds after startup_time ? */ 165 168 166 bool can_do_samlogon_ex; /* Due to the lack of finer control what type167 * of DC we have, let us try to do a168 * credential-chain less samlogon_ex call169 * with AD and schannel. If this fails with170 * DCERPC_FAULT_OP_RNG_ERROR, then set this171 * to False. This variable is around so that172 * we don't have to try _ex every time. */173 174 169 bool can_do_ncacn_ip_tcp; 175 bool can_do_validation6;176 170 177 171 /* Lookup methods for this domain (LDAP or RPC) */ … … 186 180 void *private_data; 187 181 188 /*189 * idmap config settings, used to tell the idmap child which190 * special domain config to use for a mapping191 */192 bool have_idmap_config;193 uint32_t id_range_low, id_range_high;194 195 182 /* A working DC */ 196 183 pid_t dc_probe_pid; /* Child we're using to detect the DC. */ 197 fstringdcname;184 char *dcname; 198 185 struct sockaddr_storage dcaddr; 199 186 … … 201 188 202 189 time_t last_seq_check; 203 uint32 sequence_number;190 uint32_t sequence_number; 204 191 NTSTATUS last_status; 205 192 … … 214 201 /* Callback we use to try put us back online. */ 215 202 216 uint32 check_online_timeout;217 struct t imed_event*check_online_event;203 uint32_t check_online_timeout; 204 struct tevent_timer *check_online_event; 218 205 219 206 /* Linked list info */ … … 238 225 NTSTATUS (*query_user_list)(struct winbindd_domain *domain, 239 226 TALLOC_CTX *mem_ctx, 240 uint32 *num_entries,227 uint32_t *num_entries, 241 228 struct wbint_userinfo **info); 242 229 … … 244 231 NTSTATUS (*enum_dom_groups)(struct winbindd_domain *domain, 245 232 TALLOC_CTX *mem_ctx, 246 uint32 *num_entries,233 uint32_t *num_entries, 247 234 struct wb_acct_info **info); 248 235 … … 250 237 NTSTATUS (*enum_local_groups)(struct winbindd_domain *domain, 251 238 TALLOC_CTX *mem_ctx, 252 uint32 *num_entries,239 uint32_t *num_entries, 253 240 struct wb_acct_info **info); 254 241 … … 273 260 TALLOC_CTX *mem_ctx, 274 261 const struct dom_sid *domain_sid, 275 uint32 *rids,262 uint32_t *rids, 276 263 size_t num_rids, 277 264 char **domain_name, … … 291 278 TALLOC_CTX *mem_ctx, 292 279 const struct dom_sid *user_sid, 293 uint32 *num_groups, struct dom_sid **user_gids);280 uint32_t *num_groups, struct dom_sid **user_gids); 294 281 295 282 /* Lookup all aliases that the sids delivered are member of. This is … … 297 284 NTSTATUS (*lookup_useraliases)(struct winbindd_domain *domain, 298 285 TALLOC_CTX *mem_ctx, 299 uint32 num_sids,286 uint32_t num_sids, 300 287 const struct dom_sid *sids, 301 uint32 *num_aliases,302 uint32 **alias_rids);288 uint32_t *num_aliases, 289 uint32_t **alias_rids); 303 290 304 291 /* find all members of the group with the specified group_rid */ … … 307 294 const struct dom_sid *group_sid, 308 295 enum lsa_SidType type, 309 uint32 *num_names,296 uint32_t *num_names, 310 297 struct dom_sid **sid_mem, char ***names, 311 uint32 **name_types);298 uint32_t **name_types); 312 299 313 300 /* return the current global sequence number */ 314 NTSTATUS (*sequence_number)(struct winbindd_domain *domain, uint32 *seq);301 NTSTATUS (*sequence_number)(struct winbindd_domain *domain, uint32_t *seq); 315 302 316 303 /* return the lockout policy */ … … 353 340 const char *dns_name; 354 341 struct dom_sid sid; 355 uint32 trust_flags;356 uint32 trust_attribs;357 uint32 trust_type;342 uint32_t trust_flags; 343 uint32_t trust_attribs; 344 uint32_t trust_type; 358 345 }; 359 346 … … 388 375 time_t renew_until; 389 376 time_t refresh_time; 390 struct t imed_event*event;377 struct tevent_timer *event; 391 378 }; 392 379 … … 396 383 #define WINBINDD_RESCAN_FREQ lp_winbind_cache_time() 397 384 #define WINBINDD_PAM_AUTH_KRB5_RENEW_TIME 2592000 /* one month */ 398 #define DOM_SEQUENCE_NONE ((uint32)-1) 399 400 #define winbind_event_context server_event_context 385 #define DOM_SEQUENCE_NONE ((uint32_t)-1) 401 386 402 387 #endif /* _WINBINDD_H */ -
vendor/current/source3/winbindd/winbindd_ads.c
r746 r988 28 28 #include "../libds/common/flags.h" 29 29 #include "ads.h" 30 #include "secrets.h"31 30 #include "../libcli/ldap/ldap_ndr.h" 32 31 #include "../libcli/security/security.h" … … 40 39 41 40 extern struct winbindd_methods reconnect_methods; 41 extern struct winbindd_methods msrpc_methods; 42 43 #define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache" 44 45 /** 46 * Check if cached connection can be reused. If the connection cannot 47 * be reused the ADS_STRUCT is freed and the pointer is set to NULL. 48 */ 49 static void ads_cached_connection_reuse(ADS_STRUCT **adsp) 50 { 51 52 ADS_STRUCT *ads = *adsp; 53 54 if (ads != NULL) { 55 time_t expire; 56 time_t now = time(NULL); 57 58 expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire); 59 60 DEBUG(7, ("Current tickets expire in %d seconds (at %d, time " 61 "is now %d)\n", (uint32_t)expire - (uint32_t)now, 62 (uint32_t) expire, (uint32_t) now)); 63 64 if ( ads->config.realm && (expire > now)) { 65 return; 66 } else { 67 /* we own this ADS_STRUCT so make sure it goes away */ 68 DEBUG(7,("Deleting expired krb5 credential cache\n")); 69 ads->is_mine = True; 70 ads_destroy( &ads ); 71 ads_kdestroy(WINBIND_CCACHE_NAME); 72 *adsp = NULL; 73 } 74 } 75 } 76 77 /** 78 * @brief Establish a connection to a DC 79 * 80 * @param[out] adsp ADS_STRUCT that will be created 81 * @param[in] target_realm Realm of domain to connect to 82 * @param[in] target_dom_name 'workgroup' name of domain to connect to 83 * @param[in] ldap_server DNS name of server to connect to 84 * @param[in] password Our machine acount secret 85 * @param[in] auth_realm Realm of local domain for creating krb token 86 * @param[in] renewable Renewable ticket time 87 * 88 * @return ADS_STATUS 89 */ 90 static ADS_STATUS ads_cached_connection_connect(ADS_STRUCT **adsp, 91 const char *target_realm, 92 const char *target_dom_name, 93 const char *ldap_server, 94 char *password, 95 char *auth_realm, 96 time_t renewable) 97 { 98 ADS_STRUCT *ads; 99 ADS_STATUS status; 100 struct sockaddr_storage dc_ss; 101 fstring dc_name; 102 103 if (auth_realm == NULL) { 104 return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); 105 } 106 107 /* we don't want this to affect the users ccache */ 108 setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1); 109 110 ads = ads_init(target_realm, target_dom_name, ldap_server); 111 if (!ads) { 112 DEBUG(1,("ads_init for domain %s failed\n", target_dom_name)); 113 return ADS_ERROR(LDAP_NO_MEMORY); 114 } 115 116 SAFE_FREE(ads->auth.password); 117 SAFE_FREE(ads->auth.realm); 118 119 ads->auth.renewable = renewable; 120 ads->auth.password = password; 121 122 ads->auth.realm = SMB_STRDUP(auth_realm); 123 if (!strupper_m(ads->auth.realm)) { 124 ads_destroy(&ads); 125 return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); 126 } 127 128 /* Setup the server affinity cache. We don't reaally care 129 about the name. Just setup affinity and the KRB5_CONFIG 130 file. */ 131 get_dc_name(ads->server.workgroup, ads->server.realm, dc_name, &dc_ss); 132 133 status = ads_connect(ads); 134 if (!ADS_ERR_OK(status)) { 135 DEBUG(1,("ads_connect for domain %s failed: %s\n", 136 target_dom_name, ads_errstr(status))); 137 ads_destroy(&ads); 138 return status; 139 } 140 141 /* set the flag that says we don't own the memory even 142 though we do so that ads_destroy() won't destroy the 143 structure we pass back by reference */ 144 145 ads->is_mine = False; 146 147 *adsp = ads; 148 149 return status; 150 } 151 152 ADS_STATUS ads_idmap_cached_connection(ADS_STRUCT **adsp, const char *dom_name) 153 { 154 char *ldap_server, *realm, *password; 155 struct winbindd_domain *wb_dom; 156 ADS_STATUS status; 157 158 ads_cached_connection_reuse(adsp); 159 if (*adsp != NULL) { 160 return ADS_SUCCESS; 161 } 162 163 /* 164 * At this point we only have the NetBIOS domain name. 165 * Check if we can get server nam and realm from SAF cache 166 * and the domain list. 167 */ 168 ldap_server = saf_fetch(talloc_tos(), dom_name); 169 DEBUG(10, ("ldap_server from saf cache: '%s'\n", 170 ldap_server ? ldap_server : "")); 171 172 wb_dom = find_domain_from_name(dom_name); 173 if (wb_dom == NULL) { 174 DEBUG(10, ("could not find domain '%s'\n", dom_name)); 175 return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); 176 } 177 178 DEBUG(10, ("find_domain_from_name found realm '%s' for " 179 " domain '%s'\n", wb_dom->alt_name, dom_name)); 180 181 if (!get_trust_pw_clear(dom_name, &password, NULL, NULL)) { 182 TALLOC_FREE(ldap_server); 183 return ADS_ERROR_NT(NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 184 } 185 186 if (IS_DC) { 187 SMB_ASSERT(wb_dom->alt_name != NULL); 188 realm = SMB_STRDUP(wb_dom->alt_name); 189 } else { 190 struct winbindd_domain *our_domain = wb_dom; 191 192 /* always give preference to the alt_name in our 193 primary domain if possible */ 194 195 if (!wb_dom->primary) { 196 our_domain = find_our_domain(); 197 } 198 199 if (our_domain->alt_name != NULL) { 200 realm = SMB_STRDUP(our_domain->alt_name); 201 } else { 202 realm = SMB_STRDUP(lp_realm()); 203 } 204 } 205 206 status = ads_cached_connection_connect( 207 adsp, /* Returns ads struct. */ 208 wb_dom->alt_name, /* realm to connect to. */ 209 dom_name, /* 'workgroup' name for ads_init */ 210 ldap_server, /* DNS name to connect to. */ 211 password, /* password for auth realm. */ 212 realm, /* realm used for krb5 ticket. */ 213 0); /* renewable ticket time. */ 214 215 SAFE_FREE(realm); 216 TALLOC_FREE(ldap_server); 217 218 return status; 219 } 42 220 43 221 /* … … 47 225 static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) 48 226 { 49 ADS_STRUCT *ads;50 227 ADS_STATUS status; 51 fstring dc_name; 52 struct sockaddr_storage dc_ss; 228 char *password, *realm; 53 229 54 230 DEBUG(10,("ads_cached_connection\n")); 231 ads_cached_connection_reuse((ADS_STRUCT **)&domain->private_data); 55 232 56 233 if (domain->private_data) { 57 58 time_t expire; 59 time_t now = time(NULL); 60 61 /* check for a valid structure */ 62 ads = (ADS_STRUCT *)domain->private_data; 63 64 expire = MIN(ads->auth.tgt_expire, ads->auth.tgs_expire); 65 66 DEBUG(7, ("Current tickets expire in %d seconds (at %d, time is now %d)\n", 67 (uint32)expire-(uint32)now, (uint32) expire, (uint32) now)); 68 69 if ( ads->config.realm && (expire > now)) { 70 return ads; 71 } else { 72 /* we own this ADS_STRUCT so make sure it goes away */ 73 DEBUG(7,("Deleting expired krb5 credential cache\n")); 74 ads->is_mine = True; 75 ads_destroy( &ads ); 76 ads_kdestroy("MEMORY:winbind_ccache"); 77 domain->private_data = NULL; 78 } 79 } 80 81 /* we don't want this to affect the users ccache */ 82 setenv("KRB5CCNAME", "MEMORY:winbind_ccache", 1); 83 84 ads = ads_init(domain->alt_name, domain->name, NULL); 85 if (!ads) { 86 DEBUG(1,("ads_init for domain %s failed\n", domain->name)); 234 return (ADS_STRUCT *)domain->private_data; 235 } 236 237 /* the machine acct password might have change - fetch it every time */ 238 239 if (!get_trust_pw_clear(domain->name, &password, NULL, NULL)) { 87 240 return NULL; 88 241 } 89 242 90 /* the machine acct password might have change - fetch it every time */91 92 SAFE_FREE(ads->auth.password);93 SAFE_FREE(ads->auth.realm);94 95 243 if ( IS_DC ) { 96 97 if ( !pdb_get_trusteddom_pw( domain->name, &ads->auth.password, NULL, NULL ) ) { 98 ads_destroy( &ads ); 99 return NULL; 100 } 101 ads->auth.realm = SMB_STRDUP( ads->server.realm ); 102 strupper_m( ads->auth.realm ); 244 SMB_ASSERT(domain->alt_name != NULL); 245 realm = SMB_STRDUP(domain->alt_name); 103 246 } 104 247 else { 105 248 struct winbindd_domain *our_domain = domain; 106 249 107 ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);108 250 109 251 /* always give preference to the alt_name in our … … 113 255 our_domain = find_our_domain(); 114 256 115 if ( our_domain->alt_name[0] != '\0' ) { 116 ads->auth.realm = SMB_STRDUP( our_domain->alt_name ); 117 strupper_m( ads->auth.realm ); 257 if (our_domain->alt_name != NULL) { 258 realm = SMB_STRDUP( our_domain->alt_name ); 118 259 } 119 260 else 120 ads->auth.realm = SMB_STRDUP( lp_realm() ); 121 } 122 123 ads->auth.renewable = WINBINDD_PAM_AUTH_KRB5_RENEW_TIME; 124 125 /* Setup the server affinity cache. We don't reaally care 126 about the name. Just setup affinity and the KRB5_CONFIG 127 file. */ 128 129 get_dc_name( ads->server.workgroup, ads->server.realm, dc_name, &dc_ss ); 130 131 status = ads_connect(ads); 132 if (!ADS_ERR_OK(status) || !ads->config.realm) { 133 DEBUG(1,("ads_connect for domain %s failed: %s\n", 134 domain->name, ads_errstr(status))); 135 ads_destroy(&ads); 136 261 realm = SMB_STRDUP( lp_realm() ); 262 } 263 264 status = ads_cached_connection_connect( 265 (ADS_STRUCT **)&domain->private_data, 266 domain->alt_name, 267 domain->name, NULL, 268 password, realm, 269 WINBINDD_PAM_AUTH_KRB5_RENEW_TIME); 270 SAFE_FREE(realm); 271 272 if (!ADS_ERR_OK(status)) { 137 273 /* if we get ECONNREFUSED then it might be a NT4 138 274 server, fall back to MSRPC */ … … 146 282 } 147 283 148 /* set the flag that says we don't own the memory even 149 though we do so that ads_destroy() won't destroy the 150 structure we pass back by reference */ 151 152 ads->is_mine = False; 153 154 domain->private_data = (void *)ads; 155 return ads; 156 } 157 284 return (ADS_STRUCT *)domain->private_data; 285 } 158 286 159 287 /* Query display info for a realm. This is the basic user list fn */ 160 288 static NTSTATUS query_user_list(struct winbindd_domain *domain, 161 289 TALLOC_CTX *mem_ctx, 162 uint32 *num_entries,290 uint32_t *num_entries, 163 291 struct wbint_userinfo **pinfo) 164 292 { … … 192 320 DEBUG(1,("query_user_list ads_search: %s\n", ads_errstr(rc))); 193 321 status = ads_ntstatus(rc); 322 goto done; 194 323 } else if (!res) { 195 324 DEBUG(1,("query_user_list ads_search returned NULL res\n")); 196 197 325 goto done; 198 326 } … … 204 332 } 205 333 206 (*pinfo) = TALLOC_ZERO_ARRAY(mem_ctx, struct wbint_userinfo, count);334 (*pinfo) = talloc_zero_array(mem_ctx, struct wbint_userinfo, count); 207 335 if (!*pinfo) { 208 336 status = NT_STATUS_NO_MEMORY; … … 214 342 for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { 215 343 struct wbint_userinfo *info = &((*pinfo)[count]); 216 uint32 group;217 uint32 atype;344 uint32_t group; 345 uint32_t atype; 218 346 219 347 if (!ads_pull_uint32(ads, msg, "sAMAccountType", &atype) || … … 224 352 225 353 info->acct_name = ads_pull_username(ads, mem_ctx, msg); 226 info->full_name = ads_pull_string(ads, mem_ctx, msg, "name"); 354 info->full_name = ads_pull_string(ads, mem_ctx, msg, "displayName"); 355 if (info->full_name == NULL) { 356 info->full_name = ads_pull_string(ads, mem_ctx, msg, "name"); 357 } 227 358 info->homedir = NULL; 228 359 info->shell = NULL; … … 281 412 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, 282 413 TALLOC_CTX *mem_ctx, 283 uint32 *num_entries,414 uint32_t *num_entries, 284 415 struct wb_acct_info **info) 285 416 { … … 360 491 } 361 492 362 (*info) = TALLOC_ZERO_ARRAY(mem_ctx, struct wb_acct_info, count);493 (*info) = talloc_zero_array(mem_ctx, struct wb_acct_info, count); 363 494 if (!*info) { 364 495 status = NT_STATUS_NO_MEMORY; … … 371 502 char *name, *gecos; 372 503 struct dom_sid sid; 373 uint32 rid;504 uint32_t rid; 374 505 375 506 name = ads_pull_username(ads, mem_ctx, msg); … … 407 538 static NTSTATUS enum_local_groups(struct winbindd_domain *domain, 408 539 TALLOC_CTX *mem_ctx, 409 uint32 *num_entries,540 uint32_t *num_entries, 410 541 struct wb_acct_info **info) 411 542 { … … 434 565 enum lsa_SidType *type) 435 566 { 436 return reconnect_methods.name_to_sid(domain, mem_ctx, 437 domain_name, name, flags, 438 sid, type); 567 return msrpc_methods.name_to_sid(domain, mem_ctx, domain_name, name, 568 flags, sid, type); 439 569 } 440 570 … … 447 577 enum lsa_SidType *type) 448 578 { 449 return reconnect_methods.sid_to_name(domain, mem_ctx, sid,450 579 return msrpc_methods.sid_to_name(domain, mem_ctx, sid, 580 domain_name, name, type); 451 581 } 452 582 … … 455 585 TALLOC_CTX *mem_ctx, 456 586 const struct dom_sid *sid, 457 uint32 *rids,587 uint32_t *rids, 458 588 size_t num_rids, 459 589 char **domain_name, … … 461 591 enum lsa_SidType **types) 462 592 { 463 return reconnect_methods.rids_to_names(domain, mem_ctx, sid,464 465 593 return msrpc_methods.rids_to_names(domain, mem_ctx, sid, 594 rids, num_rids, 595 domain_name, names, types); 466 596 } 467 597 … … 484 614 char *ldap_exp; 485 615 char *sidstr; 486 uint32 group_rid;616 uint32_t group_rid; 487 617 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 488 618 struct netr_SamInfo3 *user = NULL; 489 619 gid_t gid = -1; 490 620 int ret; 491 char * ads_name;621 char *full_name; 492 622 493 623 DEBUG(3,("ads: query_user\n")); … … 498 628 /* try netsamlogon cache first */ 499 629 500 if ( (user = netsamlogon_cache_get( mem_ctx, sid )) != NULL ) 630 if ( (user = netsamlogon_cache_get( mem_ctx, sid )) != NULL ) 501 631 { 502 632 DEBUG(5,("query_user: Cache lookup succeeded for %s\n", … … 515 645 516 646 TALLOC_FREE(user); 647 648 if (info->full_name == NULL) { 649 /* this might fail so we don't check the return code */ 650 wcache_query_user_fullname(domain, 651 mem_ctx, 652 sid, 653 &info->full_name); 654 } 517 655 518 656 return NT_STATUS_OK; … … 593 731 * the ads struct, potentially invalidating the ldap message. 594 732 */ 595 ads_name = ads_pull_string(ads, mem_ctx, msg, "name"); 733 full_name = ads_pull_string(ads, mem_ctx, msg, "displayName"); 734 if (full_name == NULL) { 735 full_name = ads_pull_string(ads, mem_ctx, msg, "name"); 736 } 596 737 597 738 ads_msgfree(ads, msg); … … 609 750 610 751 if (info->full_name == NULL) { 611 info->full_name = ads_name;752 info->full_name = full_name; 612 753 } else { 613 TALLOC_FREE( ads_name);754 TALLOC_FREE(full_name); 614 755 } 615 756 … … 786 927 } 787 928 788 group_sids = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_strings + 1);929 group_sids = talloc_zero_array(mem_ctx, struct dom_sid, num_strings + 1); 789 930 if (!group_sids) { 790 931 status = NT_STATUS_NO_MEMORY; … … 849 990 TALLOC_CTX *mem_ctx, 850 991 const struct dom_sid *sid, 851 uint32 *p_num_groups, struct dom_sid **user_sids)992 uint32_t *p_num_groups, struct dom_sid **user_sids) 852 993 { 853 994 ADS_STRUCT *ads = NULL; … … 860 1001 int i; 861 1002 struct dom_sid primary_group; 862 uint32 primary_group_rid;1003 uint32_t primary_group_rid; 863 1004 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 864 1005 uint32_t num_groups = 0; … … 985 1126 } 986 1127 987 *p_num_groups = (uint32 )num_groups;1128 *p_num_groups = (uint32_t)num_groups; 988 1129 status = (*user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; 989 1130 … … 999 1140 static NTSTATUS lookup_useraliases(struct winbindd_domain *domain, 1000 1141 TALLOC_CTX *mem_ctx, 1001 uint32 num_sids, const struct dom_sid *sids, 1002 uint32 *num_aliases, uint32 **alias_rids) 1003 { 1004 return reconnect_methods.lookup_useraliases(domain, mem_ctx, 1005 num_sids, sids, 1006 num_aliases, 1007 alias_rids); 1142 uint32_t num_sids, const struct dom_sid *sids, 1143 uint32_t *num_aliases, uint32_t **alias_rids) 1144 { 1145 return msrpc_methods.lookup_useraliases(domain, mem_ctx, num_sids, sids, 1146 num_aliases, alias_rids); 1147 } 1148 1149 static NTSTATUS add_primary_group_members( 1150 ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, uint32_t rid, 1151 char ***all_members, size_t *num_all_members) 1152 { 1153 char *filter; 1154 NTSTATUS status = NT_STATUS_NO_MEMORY; 1155 ADS_STATUS rc; 1156 const char *attrs[] = { "dn", NULL }; 1157 LDAPMessage *res = NULL; 1158 LDAPMessage *msg; 1159 char **members; 1160 size_t num_members; 1161 ads_control args; 1162 1163 filter = talloc_asprintf( 1164 mem_ctx, "(&(objectCategory=user)(primaryGroupID=%u))", 1165 (unsigned)rid); 1166 if (filter == NULL) { 1167 goto done; 1168 } 1169 1170 args.control = ADS_EXTENDED_DN_OID; 1171 args.val = ADS_EXTENDED_DN_HEX_STRING; 1172 args.critical = True; 1173 1174 rc = ads_do_search_all_args(ads, ads->config.bind_path, 1175 LDAP_SCOPE_SUBTREE, filter, attrs, &args, 1176 &res); 1177 1178 if (!ADS_ERR_OK(rc)) { 1179 status = ads_ntstatus(rc); 1180 DEBUG(1,("%s: ads_search: %s\n", __func__, ads_errstr(rc))); 1181 goto done; 1182 } 1183 if (res == NULL) { 1184 DEBUG(1,("%s: ads_search returned NULL res\n", __func__)); 1185 goto done; 1186 } 1187 1188 num_members = ads_count_replies(ads, res); 1189 1190 DEBUG(10, ("%s: Got %ju primary group members\n", __func__, 1191 (uintmax_t)num_members)); 1192 1193 if (num_members == 0) { 1194 status = NT_STATUS_OK; 1195 goto done; 1196 } 1197 1198 members = talloc_realloc(mem_ctx, *all_members, char *, 1199 *num_all_members + num_members); 1200 if (members == NULL) { 1201 DEBUG(1, ("%s: talloc_realloc failed\n", __func__)); 1202 goto done; 1203 } 1204 *all_members = members; 1205 1206 for (msg = ads_first_entry(ads, res); msg != NULL; 1207 msg = ads_next_entry(ads, msg)) { 1208 char *dn; 1209 1210 dn = ads_get_dn(ads, members, msg); 1211 if (dn == NULL) { 1212 DEBUG(1, ("%s: ads_get_dn failed\n", __func__)); 1213 continue; 1214 } 1215 1216 members[*num_all_members] = dn; 1217 *num_all_members += 1; 1218 } 1219 1220 status = NT_STATUS_OK; 1221 done: 1222 if (res != NULL) { 1223 ads_msgfree(ads, res); 1224 } 1225 TALLOC_FREE(filter); 1226 return status; 1008 1227 } 1009 1228 … … 1015 1234 const struct dom_sid *group_sid, 1016 1235 enum lsa_SidType type, 1017 uint32 *num_names,1236 uint32_t *num_names, 1018 1237 struct dom_sid **sid_mem, char ***names, 1019 uint32 **name_types)1238 uint32_t **name_types) 1020 1239 { 1021 1240 ADS_STATUS rc; … … 1032 1251 enum lsa_SidType *name_types_nocache = NULL; 1033 1252 char **domains_nocache = NULL; /* only needed for rpccli_lsa_lookup_sids */ 1034 uint32 num_nocache = 0;1253 uint32_t num_nocache = 0; 1035 1254 TALLOC_CTX *tmp_ctx = NULL; 1255 uint32_t rid; 1036 1256 1037 1257 DEBUG(10,("ads: lookup_groupmem %s sid=%s\n", domain->name, … … 1044 1264 DEBUG(1, ("ads: lookup_groupmem: talloc failed\n")); 1045 1265 status = NT_STATUS_NO_MEMORY; 1266 goto done; 1267 } 1268 1269 if (!sid_peek_rid(group_sid, &rid)) { 1270 DEBUG(1, ("%s: sid_peek_rid failed\n", __func__)); 1271 status = NT_STATUS_INVALID_PARAMETER; 1046 1272 goto done; 1047 1273 } … … 1088 1314 1089 1315 DEBUG(10, ("ads lookup_groupmem: got %d sids via extended dn call\n", (int)num_members)); 1316 1317 status = add_primary_group_members(ads, mem_ctx, rid, 1318 &members, &num_members); 1319 if (!NT_STATUS_IS_OK(status)) { 1320 DEBUG(10, ("%s: add_primary_group_members failed: %s\n", 1321 __func__, nt_errstr(status))); 1322 goto done; 1323 } 1324 1325 DEBUG(10, ("%s: Got %d sids after adding primary group members\n", 1326 __func__, (int)num_members)); 1090 1327 1091 1328 /* Now that we have a list of sids, we need to get the … … 1102 1339 1103 1340 if (num_members) { 1104 (*sid_mem) = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, num_members);1105 (*names) = TALLOC_ZERO_ARRAY(mem_ctx, char *, num_members);1106 (*name_types) = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_members);1107 (sid_mem_nocache) = TALLOC_ZERO_ARRAY(tmp_ctx, struct dom_sid, num_members);1341 (*sid_mem) = talloc_zero_array(mem_ctx, struct dom_sid, num_members); 1342 (*names) = talloc_zero_array(mem_ctx, char *, num_members); 1343 (*name_types) = talloc_zero_array(mem_ctx, uint32_t, num_members); 1344 (sid_mem_nocache) = talloc_zero_array(tmp_ctx, struct dom_sid, num_members); 1108 1345 1109 1346 if ((members == NULL) || (*sid_mem == NULL) || … … 1244 1481 1245 1482 /* find the sequence number for a domain */ 1246 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)1483 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32_t *seq) 1247 1484 { 1248 1485 ADS_STRUCT *ads = NULL; … … 1277 1514 ads->is_mine = True; 1278 1515 ads_destroy(&ads); 1279 ads_kdestroy( "MEMORY:winbind_ccache");1516 ads_kdestroy(WINBIND_CCACHE_NAME); 1280 1517 domain->private_data = NULL; 1281 1518 } … … 1289 1526 struct samr_DomInfo12 *policy) 1290 1527 { 1291 return reconnect_methods.lockout_policy(domain, mem_ctx, policy);1528 return msrpc_methods.lockout_policy(domain, mem_ctx, policy); 1292 1529 } 1293 1530 … … 1297 1534 struct samr_DomInfo1 *policy) 1298 1535 { 1299 return reconnect_methods.password_policy(domain, mem_ctx, policy);1536 return msrpc_methods.password_policy(domain, mem_ctx, policy); 1300 1537 } 1301 1538 … … 1308 1545 WERROR werr; 1309 1546 int i; 1310 uint32 flags;1547 uint32_t flags; 1311 1548 struct rpc_pipe_client *cli; 1312 1549 int ret_count; … … 1373 1610 1374 1611 if ((trust->trust_attributes 1375 == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) &&1612 == LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) && 1376 1613 !domain->primary ) 1377 1614 { … … 1385 1622 /* add to the trusted domain cache */ 1386 1623 1387 fstrcpy(d.name, trust->netbios_name); 1388 fstrcpy(d.alt_name, trust->dns_name); 1624 d.name = discard_const_p(char, trust->netbios_name); 1625 d.alt_name = discard_const_p(char, trust->dns_name); 1626 1389 1627 if (trust->sid) { 1390 1628 sid_copy(&d.sid, trust->sid); -
vendor/current/source3/winbindd/winbindd_allocate_gid.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 24 24 struct winbindd_allocate_gid_state { -
vendor/current/source3/winbindd/winbindd_allocate_uid.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 24 24 struct winbindd_allocate_uid_state { -
vendor/current/source3/winbindd/winbindd_cache.c
r860 r988 29 29 #include "tdb_validate.h" 30 30 #include "../libcli/auth/libcli_auth.h" 31 #include "../librpc/gen_ndr/ndr_w bint.h"31 #include "../librpc/gen_ndr/ndr_winbind.h" 32 32 #include "ads.h" 33 33 #include "nss_info.h" … … 47 47 extern struct winbindd_methods reconnect_methods; 48 48 #ifdef HAVE_ADS 49 extern struct winbindd_methods ads_methods;49 extern struct winbindd_methods reconnect_ads_methods; 50 50 #endif 51 51 extern struct winbindd_methods builtin_passdb_methods; … … 60 60 static const char *non_centry_keys[] = { 61 61 "SEQNUM/", 62 "DR/",63 "DE/",64 62 "WINBINDD_OFFLINE", 65 63 WINBINDD_CACHE_VERSION_KEYSTR, … … 102 100 struct cache_entry { 103 101 NTSTATUS status; 104 uint32 sequence_number;102 uint32_t sequence_number; 105 103 uint64_t timeout; 106 uint8 *data;107 uint32 len, ofs;104 uint8_t *data; 105 uint32_t len, ofs; 108 106 }; 109 107 … … 123 121 if (domain->internal) { 124 122 domain->backend = &builtin_passdb_methods; 125 domain->initialized = True; 123 } 124 125 if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) { 126 domain->initialized = true; 126 127 } 127 128 128 129 if (strequal(domain->name, get_global_sam_name()) && 129 sid_check_is_ domain(&domain->sid)) {130 sid_check_is_our_sam(&domain->sid)) { 130 131 domain->backend = &sam_passdb_methods; 131 domain->initialized = True;132 132 } 133 133 134 134 if ( !domain->initialized ) { 135 init_dc_connection( domain ); 135 /* We do not need a connection to an RW DC for cache operation */ 136 init_dc_connection(domain, false); 136 137 } 137 138 … … 168 169 && !lp_winbind_rpc_only()) { 169 170 DEBUG(5,("get_cache: Setting ADS methods for domain %s\n", domain->name)); 170 domain->backend = & ads_methods;171 domain->backend = &reconnect_ads_methods; 171 172 } else { 172 173 #endif /* HAVE_ADS */ … … 228 229 229 230 /* 230 pull a uint32 from a cache entry231 pull a uint32_t from a cache entry 231 232 */ 232 static uint32 centry_uint32(struct cache_entry *centry)233 { 234 uint32 ret;233 static uint32_t centry_uint32(struct cache_entry *centry) 234 { 235 uint32_t ret; 235 236 236 237 if (!centry_check_bytes(centry, 4)) { … … 243 244 244 245 /* 245 pull a uint16 from a cache entry246 pull a uint16_t from a cache entry 246 247 */ 247 static uint16 centry_uint16(struct cache_entry *centry)248 { 249 uint16 ret;248 static uint16_t centry_uint16(struct cache_entry *centry) 249 { 250 uint16_t ret; 250 251 if (!centry_check_bytes(centry, 2)) { 251 252 smb_panic_fn("centry_uint16"); … … 257 258 258 259 /* 259 pull a uint8 from a cache entry260 pull a uint8_t from a cache entry 260 261 */ 261 static uint8 centry_uint8(struct cache_entry *centry)262 { 263 uint8 ret;262 static uint8_t centry_uint8(struct cache_entry *centry) 263 { 264 uint8_t ret; 264 265 if (!centry_check_bytes(centry, 1)) { 265 266 smb_panic_fn("centry_uint8"); … … 281 282 ret = IVAL(centry->data, centry->ofs); 282 283 centry->ofs += 4; 283 ret += (uint64 )IVAL(centry->data, centry->ofs) << 32;284 ret += (uint64_t)IVAL(centry->data, centry->ofs) << 32; 284 285 centry->ofs += 4; 285 286 return ret; … … 299 300 static char *centry_string(struct cache_entry *centry, TALLOC_CTX *mem_ctx) 300 301 { 301 uint32 len;302 uint32_t len; 302 303 char *ret; 303 304 … … 313 314 } 314 315 315 ret = TALLOC_ARRAY(mem_ctx, char, len+1);316 ret = talloc_array(mem_ctx, char, len+1); 316 317 if (!ret) { 317 318 smb_panic_fn("centry_string out of memory\n"); … … 328 329 static char *centry_hash16(struct cache_entry *centry, TALLOC_CTX *mem_ctx) 329 330 { 330 uint32 len;331 uint32_t len; 331 332 char *ret; 332 333 … … 343 344 } 344 345 345 ret = TALLOC_ARRAY(mem_ctx, char, 16);346 ret = talloc_array(mem_ctx, char, 16); 346 347 if (!ret) { 347 348 smb_panic_fn("centry_hash out of memory\n"); … … 398 399 } 399 400 401 struct wcache_seqnum_state { 402 uint32_t *seqnum; 403 uint32_t *last_seq_check; 404 }; 405 406 static int wcache_seqnum_parser(TDB_DATA key, TDB_DATA data, 407 void *private_data) 408 { 409 struct wcache_seqnum_state *state = private_data; 410 411 if (data.dsize != 8) { 412 DEBUG(10, ("wcache_fetch_seqnum: invalid data size %d\n", 413 (int)data.dsize)); 414 return -1; 415 } 416 417 *state->seqnum = IVAL(data.dptr, 0); 418 *state->last_seq_check = IVAL(data.dptr, 4); 419 return 0; 420 } 421 400 422 static bool wcache_fetch_seqnum(const char *domain_name, uint32_t *seqnum, 401 423 uint32_t *last_seq_check) 402 424 { 403 char *key; 404 TDB_DATA data; 425 struct wcache_seqnum_state state = { 426 .seqnum = seqnum, .last_seq_check = last_seq_check 427 }; 428 size_t len = strlen(domain_name); 429 char keystr[len+8]; 430 TDB_DATA key = { .dptr = (uint8_t *)keystr, .dsize = sizeof(keystr) }; 431 int ret; 405 432 406 433 if (wcache->tdb == NULL) { … … 409 436 } 410 437 411 key = talloc_asprintf(talloc_tos(), "SEQNUM/%s", domain_name); 412 if (key == NULL) { 413 DEBUG(10, ("talloc failed\n")); 414 return false; 415 } 416 417 data = tdb_fetch_bystring(wcache->tdb, key); 418 TALLOC_FREE(key); 419 420 if (data.dptr == NULL) { 421 DEBUG(10, ("wcache_fetch_seqnum: %s not found\n", 422 domain_name)); 423 return false; 424 } 425 if (data.dsize != 8) { 426 DEBUG(10, ("wcache_fetch_seqnum: invalid data size %d\n", 427 (int)data.dsize)); 428 SAFE_FREE(data.dptr); 429 return false; 430 } 431 432 *seqnum = IVAL(data.dptr, 0); 433 *last_seq_check = IVAL(data.dptr, 4); 434 SAFE_FREE(data.dptr); 435 436 return true; 438 snprintf(keystr, sizeof(keystr), "SEQNUM/%s", domain_name); 439 440 ret = tdb_parse_record(wcache->tdb, key, wcache_seqnum_parser, 441 &state); 442 return (ret == 0); 437 443 } 438 444 439 445 static NTSTATUS fetch_cache_seqnum( struct winbindd_domain *domain, time_t now ) 440 446 { 441 uint32 last_check, time_diff;447 uint32_t last_check, time_diff; 442 448 443 449 if (!wcache_fetch_seqnum(domain->name, &domain->sequence_number, … … 453 459 DEBUG(10,("fetch_cache_seqnum: timeout [%s][%u @ %u]\n", 454 460 domain->name, domain->sequence_number, 455 (uint32 )domain->last_seq_check));461 (uint32_t)domain->last_seq_check)); 456 462 return NT_STATUS_UNSUCCESSFUL; 457 463 } … … 459 465 DEBUG(10,("fetch_cache_seqnum: success [%s][%u @ %u]\n", 460 466 domain->name, domain->sequence_number, 461 (uint32 )domain->last_seq_check));467 (uint32_t)domain->last_seq_check)); 462 468 463 469 return NT_STATUS_OK; … … 467 473 time_t last_seq_check) 468 474 { 469 char *key_str; 475 size_t len = strlen(domain_name); 476 char keystr[len+8]; 477 TDB_DATA key = { .dptr = (uint8_t *)keystr, .dsize = sizeof(keystr) }; 470 478 uint8_t buf[8]; 471 479 int ret; … … 476 484 } 477 485 478 key_str = talloc_asprintf(talloc_tos(), "SEQNUM/%s", domain_name); 479 if (key_str == NULL) { 480 DEBUG(10, ("talloc_asprintf failed\n")); 481 return false; 482 } 486 snprintf(keystr, sizeof(keystr), "SEQNUM/%s", domain_name); 483 487 484 488 SIVAL(buf, 0, seqnum); 485 489 SIVAL(buf, 4, last_seq_check); 486 490 487 ret = tdb_store_bystring(wcache->tdb, key_str, 488 make_tdb_data(buf, sizeof(buf)), TDB_REPLACE); 489 TALLOC_FREE(key_str); 490 if (ret == -1) { 491 ret = tdb_store(wcache->tdb, key, make_tdb_data(buf, sizeof(buf)), 492 TDB_REPLACE); 493 if (ret != 0) { 491 494 DEBUG(10, ("tdb_store_bystring failed: %s\n", 492 495 tdb_errorstr(wcache->tdb))); 493 TALLOC_FREE(key_str);494 496 return false; 495 497 } … … 671 673 { 672 674 if (strequal(domain->name, get_global_sam_name()) && 673 sid_check_is_ domain(&domain->sid)) {675 sid_check_is_our_sam(&domain->sid)) { 674 676 return true; 675 677 } … … 758 760 make sure we have at least len bytes available in a centry 759 761 */ 760 static void centry_expand(struct cache_entry *centry, uint32 len)762 static void centry_expand(struct cache_entry *centry, uint32_t len) 761 763 { 762 764 if (centry->len - centry->ofs >= len) … … 782 784 783 785 /* 784 push a uint32 into a centry786 push a uint32_t into a centry 785 787 */ 786 static void centry_put_uint32(struct cache_entry *centry, uint32 v)788 static void centry_put_uint32(struct cache_entry *centry, uint32_t v) 787 789 { 788 790 centry_expand(centry, 4); … … 792 794 793 795 /* 794 push a uint16 into a centry796 push a uint16_t into a centry 795 797 */ 796 static void centry_put_uint16(struct cache_entry *centry, uint16 v)798 static void centry_put_uint16(struct cache_entry *centry, uint16_t v) 797 799 { 798 800 centry_expand(centry, 2); … … 802 804 803 805 /* 804 push a uint8 into a centry806 push a uint8_t into a centry 805 807 */ 806 static void centry_put_uint8(struct cache_entry *centry, uint8 v)808 static void centry_put_uint8(struct cache_entry *centry, uint8_t v) 807 809 { 808 810 centry_expand(centry, 1); … … 839 841 push a 16 byte hash into a centry - treat as 16 byte string. 840 842 */ 841 static void centry_put_hash16(struct cache_entry *centry, const uint8 val[16])843 static void centry_put_hash16(struct cache_entry *centry, const uint8_t val[16]) 842 844 { 843 845 centry_put_uint8(centry, 16); … … 859 861 static void centry_put_ntstatus(struct cache_entry *centry, NTSTATUS status) 860 862 { 861 uint32 status_value = NT_STATUS_V(status);863 uint32_t status_value = NT_STATUS_V(status); 862 864 centry_put_uint32(centry, status_value); 863 865 } … … 889 891 start a centry for output. When finished, call centry_end() 890 892 */ 891 struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status) 893 static struct cache_entry *centry_start(struct winbindd_domain *domain, 894 NTSTATUS status) 892 895 { 893 896 struct cache_entry *centry; … … 899 902 900 903 centry->len = 8192; /* reasonable default */ 901 centry->data = SMB_XMALLOC_ARRAY(uint8 , centry->len);904 centry->data = SMB_XMALLOC_ARRAY(uint8_t, centry->len); 902 905 centry->ofs = 0; 903 906 centry->sequence_number = domain->sequence_number; … … 958 961 centry_put_sid(centry, sid); 959 962 fstrcpy(uname, name); 960 strupper_m(uname);963 (void)strupper_m(uname); 961 964 centry_end(centry, "NS/%s/%s", domain_name, uname); 962 965 DEBUG(10,("wcache_save_name_to_sid: %s\\%s -> %s (%s)\n", domain_name, … … 990 993 991 994 centry_end(centry, "SN/%s", sid_to_fstring(sid_string, sid)); 992 DEBUG(10,("wcache_save_sid_to_name: %s -> %s (%s)\n", sid_string,993 name, nt_errstr(status)));995 DEBUG(10,("wcache_save_sid_to_name: %s -> %s\\%s (%s)\n", sid_string, 996 domain_name, name, nt_errstr(status))); 994 997 centry_free(centry); 995 998 } … … 1084 1087 1085 1088 fstrcpy(uname, name); 1086 strupper_m(uname);1089 (void)strupper_m(uname); 1087 1090 centry_end(centry, "NSS/NA/%s", uname); 1088 1091 … … 1105 1108 1106 1109 fstrcpy(uname, alias); 1107 strupper_m(uname);1110 (void)strupper_m(uname); 1108 1111 centry_end(centry, "NSS/AN/%s", uname); 1109 1112 … … 1131 1134 goto do_query; 1132 1135 1133 if ( (upper_name = SMB_STRDUP(name)) == NULL ) 1136 upper_name = talloc_strdup(mem_ctx, name); 1137 if (upper_name == NULL) { 1134 1138 return NT_STATUS_NO_MEMORY; 1135 strupper_m(upper_name); 1139 } 1140 if (!strupper_m(upper_name)) { 1141 talloc_free(upper_name); 1142 return NT_STATUS_INVALID_PARAMETER; 1143 } 1136 1144 1137 1145 centry = wcache_fetch(cache, domain, "NSS/NA/%s", upper_name); 1138 1146 1139 SAFE_FREE( upper_name);1147 talloc_free(upper_name); 1140 1148 1141 1149 if (!centry) … … 1206 1214 goto do_query; 1207 1215 1208 if ( (upper_name = SMB_STRDUP(alias)) == NULL ) 1216 upper_name = talloc_strdup(mem_ctx, alias); 1217 if (upper_name == NULL) { 1209 1218 return NT_STATUS_NO_MEMORY; 1210 strupper_m(upper_name); 1219 } 1220 if (!strupper_m(upper_name)) { 1221 talloc_free(upper_name); 1222 return NT_STATUS_INVALID_PARAMETER; 1223 } 1211 1224 1212 1225 centry = wcache_fetch(cache, domain, "NSS/AN/%s", upper_name); 1213 1226 1214 SAFE_FREE( upper_name);1227 talloc_free(upper_name); 1215 1228 1216 1229 if (!centry) … … 1276 1289 TDB_DATA data; 1277 1290 fstring key_str, tmp; 1278 uint32 rid;1291 uint32_t rid; 1279 1292 1280 1293 if (!cache->tdb) { … … 1307 1320 TALLOC_CTX *mem_ctx, 1308 1321 const struct dom_sid *sid, 1309 const uint8 **cached_nt_pass,1310 const uint8 **cached_salt)1322 const uint8_t **cached_nt_pass, 1323 const uint8_t **cached_salt) 1311 1324 { 1312 1325 struct winbind_cache *cache = get_cache(domain); 1313 1326 struct cache_entry *centry = NULL; 1314 1327 NTSTATUS status; 1315 time_t t; 1316 uint32 rid; 1328 uint32_t rid; 1317 1329 fstring tmp; 1318 1330 … … 1340 1352 } 1341 1353 1342 t = centry_time(centry); 1354 /* 1355 * We don't use the time element at this moment, 1356 * but we have to consume it, so that we don't 1357 * neet to change the disk format of the cache. 1358 */ 1359 (void)centry_time(centry); 1343 1360 1344 1361 /* In the salted case this isn't actually the nt_hash itself, … … 1347 1364 if we are returning a salted cred. */ 1348 1365 1349 *cached_nt_pass = (const uint8 *)centry_hash16(centry, mem_ctx);1366 *cached_nt_pass = (const uint8_t *)centry_hash16(centry, mem_ctx); 1350 1367 if (*cached_nt_pass == NULL) { 1351 1368 fstring sidstr; … … 1364 1381 /* We only have 17 bytes more data in the salted cred case. */ 1365 1382 if (centry->len - centry->ofs == 17) { 1366 *cached_salt = (const uint8 *)centry_hash16(centry, mem_ctx);1383 *cached_salt = (const uint8_t *)centry_hash16(centry, mem_ctx); 1367 1384 } else { 1368 1385 *cached_salt = NULL; … … 1387 1404 NTSTATUS wcache_save_creds(struct winbindd_domain *domain, 1388 1405 const struct dom_sid *sid, 1389 const uint8 nt_pass[NT_HASH_LEN])1406 const uint8_t nt_pass[NT_HASH_LEN]) 1390 1407 { 1391 1408 struct cache_entry *centry; 1392 1409 fstring sid_string; 1393 uint32 rid;1394 uint8 cred_salt[NT_HASH_LEN];1395 uint8 salted_hash[NT_HASH_LEN];1410 uint32_t rid; 1411 uint8_t cred_salt[NT_HASH_LEN]; 1412 uint8_t salted_hash[NT_HASH_LEN]; 1396 1413 1397 1414 if (is_null_sid(sid)) { … … 1431 1448 static NTSTATUS query_user_list(struct winbindd_domain *domain, 1432 1449 TALLOC_CTX *mem_ctx, 1433 uint32 *num_entries,1450 uint32_t *num_entries, 1434 1451 struct wbint_userinfo **info) 1435 1452 { … … 1453 1470 goto do_cached; 1454 1471 1455 (*info) = TALLOC_ARRAY(mem_ctx, struct wbint_userinfo, *num_entries);1472 (*info) = talloc_array(mem_ctx, struct wbint_userinfo, *num_entries); 1456 1473 if (! (*info)) { 1457 1474 smb_panic_fn("query_user_list out of memory"); … … 1506 1523 DEBUG(3, ("query_user_list: flushing " 1507 1524 "connection cache\n")); 1508 invalidate_cm_connection( &domain->conn);1525 invalidate_cm_connection(domain); 1509 1526 } 1510 1527 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) || … … 1582 1599 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, 1583 1600 TALLOC_CTX *mem_ctx, 1584 uint32 *num_entries,1601 uint32_t *num_entries, 1585 1602 struct wb_acct_info **info) 1586 1603 { … … 1605 1622 goto do_cached; 1606 1623 1607 (*info) = TALLOC_ARRAY(mem_ctx, struct wb_acct_info, *num_entries);1624 (*info) = talloc_array(mem_ctx, struct wb_acct_info, *num_entries); 1608 1625 if (! (*info)) { 1609 1626 smb_panic_fn("enum_dom_groups out of memory"); … … 1677 1694 static NTSTATUS enum_local_groups(struct winbindd_domain *domain, 1678 1695 TALLOC_CTX *mem_ctx, 1679 uint32 *num_entries,1696 uint32_t *num_entries, 1680 1697 struct wb_acct_info **info) 1681 1698 { … … 1700 1717 goto do_cached; 1701 1718 1702 (*info) = TALLOC_ARRAY(mem_ctx, struct wb_acct_info, *num_entries);1719 (*info) = talloc_array(mem_ctx, struct wb_acct_info, *num_entries); 1703 1720 if (! (*info)) { 1704 1721 smb_panic_fn("enum_dom_groups out of memory"); … … 1882 1899 /* Only save the reverse mapping if this was not a UPN */ 1883 1900 if (!strchr(name, '@')) { 1884 strupper_m(CONST_DISCARD(char *,domain_name)); 1885 strlower_m(CONST_DISCARD(char *,name)); 1901 if (!strupper_m(discard_const_p(char, domain_name))) { 1902 return NT_STATUS_INVALID_PARAMETER; 1903 } 1904 (void)strlower_m(discard_const_p(char, name)); 1886 1905 wcache_save_sid_to_name(domain, status, sid, domain_name, name, *type); 1887 1906 } … … 1891 1910 } 1892 1911 1893 NTSTATUS wcache_sid_to_name(struct winbindd_domain *domain,1894 1895 1896 1897 1898 1912 static NTSTATUS wcache_sid_to_name(struct winbindd_domain *domain, 1913 const struct dom_sid *sid, 1914 TALLOC_CTX *mem_ctx, 1915 char **domain_name, 1916 char **name, 1917 enum lsa_SidType *type) 1899 1918 { 1900 1919 struct winbind_cache *cache = get_cache(domain); … … 2001 2020 TALLOC_CTX *mem_ctx, 2002 2021 const struct dom_sid *domain_sid, 2003 uint32 *rids,2022 uint32_t *rids, 2004 2023 size_t num_rids, 2005 2024 char **domain_name, … … 2027 2046 } 2028 2047 2029 *names = TALLOC_ARRAY(mem_ctx, char *, num_rids);2030 *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);2048 *names = talloc_array(mem_ctx, char *, num_rids); 2049 *types = talloc_array(mem_ctx, enum lsa_SidType, num_rids); 2031 2050 2032 2051 if ((*names == NULL) || (*types == NULL)) { … … 2077 2096 /* something's definitely wrong */ 2078 2097 result = centry->status; 2098 centry_free(centry); 2079 2099 goto error; 2080 2100 } … … 2110 2130 old_status) { 2111 2131 have_mapped = have_unmapped = false; 2132 2133 *names = talloc_array(mem_ctx, char *, num_rids); 2134 if (*names == NULL) { 2135 result = NT_STATUS_NO_MEMORY; 2136 goto error; 2137 } 2138 2139 *types = talloc_array(mem_ctx, enum lsa_SidType, 2140 num_rids); 2141 if (*types == NULL) { 2142 result = NT_STATUS_NO_MEMORY; 2143 goto error; 2144 } 2112 2145 2113 2146 for (i=0; i<num_rids; i++) { … … 2283 2316 } 2284 2317 2318 2319 /** 2320 * @brief Query a fullname from the username cache (for further gecos processing) 2321 * 2322 * @param domain A pointer to the winbindd_domain struct. 2323 * @param mem_ctx The talloc context. 2324 * @param user_sid The user sid. 2325 * @param full_name A pointer to the full_name string. 2326 * 2327 * @return NTSTATUS code 2328 */ 2329 NTSTATUS wcache_query_user_fullname(struct winbindd_domain *domain, 2330 TALLOC_CTX *mem_ctx, 2331 const struct dom_sid *user_sid, 2332 const char **full_name) 2333 { 2334 NTSTATUS status; 2335 struct wbint_userinfo info; 2336 2337 status = wcache_query_user(domain, mem_ctx, user_sid, &info); 2338 if (!NT_STATUS_IS_OK(status)) { 2339 return status; 2340 } 2341 2342 if (info.full_name != NULL) { 2343 *full_name = talloc_strdup(mem_ctx, info.full_name); 2344 if (*full_name == NULL) { 2345 return NT_STATUS_NO_MEMORY; 2346 } 2347 } 2348 2349 return NT_STATUS_OK; 2350 } 2351 2285 2352 /* Lookup user information from a rid */ 2286 2353 static NTSTATUS query_user(struct winbindd_domain *domain, … … 2396 2463 TALLOC_CTX *mem_ctx, 2397 2464 const struct dom_sid *user_sid, 2398 uint32 *num_groups, struct dom_sid **user_gids)2465 uint32_t *num_groups, struct dom_sid **user_gids) 2399 2466 { 2400 2467 struct cache_entry *centry = NULL; … … 2546 2613 static NTSTATUS lookup_useraliases(struct winbindd_domain *domain, 2547 2614 TALLOC_CTX *mem_ctx, 2548 uint32 num_sids, const struct dom_sid *sids,2549 uint32 *num_aliases, uint32**alias_rids)2615 uint32_t num_sids, const struct dom_sid *sids, 2616 uint32_t *num_aliases, uint32_t **alias_rids) 2550 2617 { 2551 2618 struct cache_entry *centry = NULL; … … 2652 2719 *sid_mem = talloc_array(mem_ctx, struct dom_sid, *num_names); 2653 2720 *names = talloc_array(mem_ctx, char *, *num_names); 2654 *name_types = talloc_array(mem_ctx, uint32 , *num_names);2721 *name_types = talloc_array(mem_ctx, uint32_t, *num_names); 2655 2722 2656 2723 if ((*sid_mem == NULL) || (*names == NULL) || (*name_types == NULL)) { … … 2681 2748 const struct dom_sid *group_sid, 2682 2749 enum lsa_SidType type, 2683 uint32 *num_names,2750 uint32_t *num_names, 2684 2751 struct dom_sid **sid_mem, char ***names, 2685 uint32 **name_types)2752 uint32_t **name_types) 2686 2753 { 2687 2754 struct cache_entry *centry = NULL; … … 2752 2819 2753 2820 /* find the sequence number for a domain */ 2754 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)2821 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32_t *seq) 2755 2822 { 2756 2823 refresh_sequence_number(domain, false); … … 2796 2863 2797 2864 do_fetch_cache: 2798 trusts->array = TALLOC_ZERO_ARRAY(mem_ctx, struct netr_DomainTrust, num_domains);2865 trusts->array = talloc_zero_array(mem_ctx, struct netr_DomainTrust, num_domains); 2799 2866 if (!trusts->array) { 2800 2867 TALLOC_FREE(dom_list); … … 3034 3101 struct winbind_cache *cache; 3035 3102 3036 /* don t clear cached U/SID and UG/SID entries when we want to logon3103 /* don't clear cached U/SID and UG/SID entries when we want to logon 3037 3104 * offline - gd */ 3038 3105 … … 3119 3186 bool init_wcache(void) 3120 3187 { 3188 char *db_path; 3189 3121 3190 if (wcache == NULL) { 3122 3191 wcache = SMB_XMALLOC_P(struct winbind_cache); … … 3127 3196 return true; 3128 3197 3198 db_path = state_path("winbindd_cache.tdb"); 3199 if (db_path == NULL) { 3200 return false; 3201 } 3202 3129 3203 /* when working offline we must not clear the cache on restart */ 3130 wcache->tdb = tdb_open_log( cache_path("winbindd_cache.tdb"),3204 wcache->tdb = tdb_open_log(db_path, 3131 3205 WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, 3132 3206 TDB_INCOMPATIBLE_HASH | 3133 3207 (lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST)), 3134 3208 O_RDWR|O_CREAT, 0600); 3135 3209 TALLOC_FREE(db_path); 3136 3210 if (wcache->tdb == NULL) { 3137 3211 DEBUG(0,("Failed to open winbindd_cache.tdb!\n")); … … 3151 3225 { 3152 3226 bool cache_bad = true; 3153 uint32 vers;3227 uint32_t vers; 3154 3228 3155 3229 if (!init_wcache()) { … … 3165 3239 3166 3240 if (cache_bad) { 3241 char *db_path; 3242 3167 3243 DEBUG(0,("initialize_winbindd_cache: clearing cache " 3168 3244 "and re-creating with version number %d\n", … … 3172 3248 wcache->tdb = NULL; 3173 3249 3174 if (unlink(cache_path("winbindd_cache.tdb")) == -1) { 3250 db_path = state_path("winbindd_cache.tdb"); 3251 if (db_path == NULL) { 3252 return false; 3253 } 3254 3255 if (unlink(db_path) == -1) { 3175 3256 DEBUG(0,("initialize_winbindd_cache: unlink %s failed %s ", 3176 cache_path("winbindd_cache.tdb"),3257 db_path, 3177 3258 strerror(errno) )); 3259 TALLOC_FREE(db_path); 3178 3260 return false; 3179 3261 } 3262 TALLOC_FREE(db_path); 3180 3263 if (!init_wcache()) { 3181 3264 DEBUG(0,("initialize_winbindd_cache: re-initialization " … … 3290 3373 void wcache_flush_cache(void) 3291 3374 { 3375 char *db_path; 3376 3292 3377 if (!wcache) 3293 3378 return; … … 3300 3385 } 3301 3386 3387 db_path = state_path("winbindd_cache.tdb"); 3388 if (db_path == NULL) { 3389 return; 3390 } 3391 3302 3392 /* when working offline we must not clear the cache on restart */ 3303 wcache->tdb = tdb_open_log( cache_path("winbindd_cache.tdb"),3304 WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, 3393 wcache->tdb = tdb_open_log(db_path, 3394 WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, 3305 3395 TDB_INCOMPATIBLE_HASH | 3306 3396 (lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST)), 3307 3397 O_RDWR|O_CREAT, 0600); 3308 3398 TALLOC_FREE(db_path); 3309 3399 if (!wcache->tdb) { 3310 3400 DEBUG(0,("Failed to open winbindd_cache.tdb!\n")); … … 3405 3495 if (ret == 0) { 3406 3496 return NT_STATUS_OK; 3407 } else if ((ret == -1) || (wcache_cred_list == NULL)) {3497 } else if ((ret < 0) || (wcache_cred_list == NULL)) { 3408 3498 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 3409 3499 } … … 3534 3624 3535 3625 centry = SMB_XMALLOC_P(struct cache_entry); 3536 centry->data = (unsigned char *) memdup(data.dptr, data.dsize);3626 centry->data = (unsigned char *)smb_memdup(data.dptr, data.dsize); 3537 3627 if (!centry->data) { 3538 3628 SAFE_FREE(centry); … … 3719 3809 { 3720 3810 struct cache_entry *centry = create_centry_validate(keystr, dbuf, state); 3721 int32 num_entries, i;3811 int32_t num_entries, i; 3722 3812 3723 3813 if (!centry) { … … 3725 3815 } 3726 3816 3727 num_entries = (int32 )centry_uint32(centry);3817 num_entries = (int32_t)centry_uint32(centry); 3728 3818 3729 3819 for (i=0; i< num_entries; i++) { … … 3750 3840 { 3751 3841 struct cache_entry *centry = create_centry_validate(keystr, dbuf, state); 3752 int32 num_entries, i;3842 int32_t num_entries, i; 3753 3843 3754 3844 if (!centry) { … … 3777 3867 { 3778 3868 struct cache_entry *centry = create_centry_validate(keystr, dbuf, state); 3779 int32 num_groups, i;3869 int32_t num_groups, i; 3780 3870 3781 3871 if (!centry) { … … 3803 3893 { 3804 3894 struct cache_entry *centry = create_centry_validate(keystr, dbuf, state); 3805 int32 num_aliases, i;3895 int32_t num_aliases, i; 3806 3896 3807 3897 if (!centry) { … … 3828 3918 { 3829 3919 struct cache_entry *centry = create_centry_validate(keystr, dbuf, state); 3830 int32 num_names, i;3920 int32_t num_names, i; 3831 3921 3832 3922 if (!centry) { … … 4051 4141 4052 4142 /* Paranoia check. */ 4053 if (strncmp("UA/", (const char *)kbuf.dptr, 3) == 0) { 4143 if (strncmp("UA/", (const char *)kbuf.dptr, 3) == 0 || 4144 strncmp("NDR/", (const char *)kbuf.dptr, 4) == 0) { 4054 4145 max_key_len = 1024 * 1024; 4055 4146 } … … 4092 4183 4093 4184 DEBUG(0,("cache_traverse_validate_fn: unknown cache entry\nkey :\n")); 4094 dump_data(0, (uint8 *)kbuf.dptr, kbuf.dsize);4185 dump_data(0, (uint8_t *)kbuf.dptr, kbuf.dsize); 4095 4186 DEBUG(0,("data :\n")); 4096 dump_data(0, (uint8 *)dbuf.dptr, dbuf.dsize);4187 dump_data(0, (uint8_t *)dbuf.dptr, dbuf.dsize); 4097 4188 v_state->unknown_key = true; 4098 4189 v_state->success = false; … … 4179 4270 { 4180 4271 int ret = -1; 4181 c onst char *tdb_path = cache_path("winbindd_cache.tdb");4272 char *tdb_path = NULL; 4182 4273 TDB_CONTEXT *tdb = NULL; 4183 4274 uint32_t vers_id; … … 4187 4278 smb_panic_fn = validate_panic; 4188 4279 4189 tdb = tdb_open_log(tdb_path, 4280 tdb_path = state_path("winbindd_cache.tdb"); 4281 if (tdb_path == NULL) { 4282 goto done; 4283 } 4284 4285 tdb = tdb_open_log(tdb_path, 4190 4286 WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, 4191 4287 TDB_INCOMPATIBLE_HASH | 4192 ( lp_winbind_offline_logon() 4193 ? TDB_DEFAULT 4288 ( lp_winbind_offline_logon() 4289 ? TDB_DEFAULT 4194 4290 : TDB_DEFAULT | TDB_CLEAR_IF_FIRST ), 4195 O_RDWR|O_CREAT, 4291 O_RDWR|O_CREAT, 4196 4292 0600); 4197 4293 if (!tdb) { … … 4235 4331 4236 4332 done: 4333 TALLOC_FREE(tdb_path); 4237 4334 DEBUG(10, ("winbindd_validate_cache: restoring panic function\n")); 4238 4335 smb_panic_fn = smb_panic; … … 4247 4344 { 4248 4345 int ret = -1; 4249 c onst char *tdb_path = cache_path("winbindd_cache.tdb");4346 char *tdb_path; 4250 4347 4251 4348 DEBUG(10, ("winbindd_validate_cache: replacing panic function\n")); 4252 4349 smb_panic_fn = validate_panic; 4253 4350 4351 tdb_path = state_path("winbindd_cache.tdb"); 4352 if (tdb_path == NULL) { 4353 goto err_panic_restore; 4354 } 4254 4355 4255 4356 if (wcache == NULL || wcache->tdb == NULL) { … … 4264 4365 } 4265 4366 4367 TALLOC_FREE(tdb_path); 4368 err_panic_restore: 4266 4369 DEBUG(10, ("winbindd_validate_cache_nobackup: restoring panic " 4267 4370 "function\n")); … … 4314 4417 if ( !set_only ) { 4315 4418 if ( !*domains ) { 4316 list = TALLOC_ARRAY( NULL, struct winbindd_tdc_domain, 1 );4419 list = talloc_array( NULL, struct winbindd_tdc_domain, 1 ); 4317 4420 idx = 0; 4318 4421 } else { 4319 list = TALLOC_REALLOC_ARRAY( *domains, *domains,4422 list = talloc_realloc( *domains, *domains, 4320 4423 struct winbindd_tdc_domain, 4321 4424 (*num_domains)+1); … … 4329 4432 return false; 4330 4433 4331 list[idx].domain_name = talloc_strdup( list, new_dom->name ); 4332 list[idx].dns_name = talloc_strdup( list, new_dom->alt_name ); 4434 list[idx].domain_name = talloc_strdup(list, new_dom->name); 4435 if (list[idx].domain_name == NULL) { 4436 return false; 4437 } 4438 if (new_dom->alt_name != NULL) { 4439 list[idx].dns_name = talloc_strdup(list, new_dom->alt_name); 4440 if (list[idx].dns_name == NULL) { 4441 return false; 4442 } 4443 } 4333 4444 4334 4445 if ( !is_null_sid( &new_dom->sid ) ) { … … 4413 4524 len += tdb_pack( buffer+len, buflen-len, "fffddd", 4414 4525 domains[i].domain_name, 4415 domains[i].dns_name ,4526 domains[i].dns_name ? domains[i].dns_name : "", 4416 4527 sid_to_fstring(tmp, &domains[i].sid), 4417 4528 domains[i].trust_flags, … … 4444 4555 { 4445 4556 fstring domain_name, dns_name, sid_string; 4446 uint32 type, attribs, flags;4557 uint32_t type, attribs, flags; 4447 4558 int num_domains; 4448 4559 int len = 0; … … 4457 4568 } 4458 4569 4459 list = TALLOC_ARRAY( NULL, struct winbindd_tdc_domain, num_domains );4570 list = talloc_array( NULL, struct winbindd_tdc_domain, num_domains ); 4460 4571 if ( !list ) { 4461 4572 DEBUG(0,("unpack_tdc_domains: Failed to talloc() domain list!\n")); … … 4464 4575 4465 4576 for ( i=0; i<num_domains; i++ ) { 4466 len += tdb_unpack( buf+len, buflen-len, "fffddd", 4577 int this_len; 4578 4579 this_len = tdb_unpack( buf+len, buflen-len, "fffddd", 4467 4580 domain_name, 4468 4581 dns_name, … … 4472 4585 &type ); 4473 4586 4474 if ( len == -1 ) {4587 if ( this_len == -1 ) { 4475 4588 DEBUG(5,("unpack_tdc_domains: Failed to unpack domain array\n")); 4476 4589 TALLOC_FREE( list ); 4477 4590 return 0; 4478 4591 } 4592 len += this_len; 4479 4593 4480 4594 DEBUG(11,("unpack_tdc_domains: Unpacking domain %s (%s) " … … 4484 4598 4485 4599 list[i].domain_name = talloc_strdup( list, domain_name ); 4486 list[i].dns_name = talloc_strdup( list, dns_name ); 4600 list[i].dns_name = NULL; 4601 if (dns_name[0] != '\0') { 4602 list[i].dns_name = talloc_strdup(list, dns_name); 4603 } 4487 4604 if ( !string_to_sid( &(list[i].sid), sid_string ) ) { 4488 4605 DEBUG(10,("unpack_tdc_domains: no SID for domain %s\n", … … 4531 4648 SAFE_FREE( key.dptr ); 4532 4649 4533 return ( ret != -1 );4650 return ( ret == 0 ); 4534 4651 } 4535 4652 … … 4611 4728 } 4612 4729 4730 static struct winbindd_tdc_domain *wcache_tdc_dup_domain( 4731 TALLOC_CTX *mem_ctx, const struct winbindd_tdc_domain *src) 4732 { 4733 struct winbindd_tdc_domain *dst; 4734 4735 dst = talloc(mem_ctx, struct winbindd_tdc_domain); 4736 if (dst == NULL) { 4737 goto fail; 4738 } 4739 dst->domain_name = talloc_strdup(dst, src->domain_name); 4740 if (dst->domain_name == NULL) { 4741 goto fail; 4742 } 4743 4744 dst->dns_name = NULL; 4745 if (src->dns_name != NULL) { 4746 dst->dns_name = talloc_strdup(dst, src->dns_name); 4747 if (dst->dns_name == NULL) { 4748 goto fail; 4749 } 4750 } 4751 4752 sid_copy(&dst->sid, &src->sid); 4753 dst->trust_flags = src->trust_flags; 4754 dst->trust_type = src->trust_type; 4755 dst->trust_attribs = src->trust_attribs; 4756 return dst; 4757 fail: 4758 TALLOC_FREE(dst); 4759 return NULL; 4760 } 4761 4613 4762 /********************************************************************* 4614 4763 ********************************************************************/ … … 4624 4773 4625 4774 if ( !init_wcache() ) { 4626 return false;4775 return NULL; 4627 4776 } 4628 4777 … … 4638 4787 name)); 4639 4788 4640 d = TALLOC_P( ctx, struct winbindd_tdc_domain ); 4641 if ( !d ) 4642 break; 4643 4644 d->domain_name = talloc_strdup( d, dom_list[i].domain_name ); 4645 d->dns_name = talloc_strdup( d, dom_list[i].dns_name ); 4646 sid_copy( &d->sid, &dom_list[i].sid ); 4647 d->trust_flags = dom_list[i].trust_flags; 4648 d->trust_type = dom_list[i].trust_type; 4649 d->trust_attribs = dom_list[i].trust_attribs; 4650 4789 d = wcache_tdc_dup_domain(ctx, &dom_list[i]); 4651 4790 break; 4652 4791 } … … 4674 4813 4675 4814 if (!init_wcache()) { 4676 return false;4815 return NULL; 4677 4816 } 4678 4817 … … 4682 4821 4683 4822 for (i = 0; i<num_domains; i++) { 4684 if ( sid_equal(sid, &(dom_list[i].sid))) {4823 if (dom_sid_equal(sid, &(dom_list[i].sid))) { 4685 4824 DEBUG(10, ("wcache_tdc_fetch_domainbysid: " 4686 4825 "Found domain %s for SID %s\n", … … 4688 4827 sid_string_dbg(sid))); 4689 4828 4690 d = TALLOC_P(ctx, struct winbindd_tdc_domain); 4691 if (!d) 4692 break; 4693 4694 d->domain_name = talloc_strdup(d, 4695 dom_list[i].domain_name); 4696 4697 d->dns_name = talloc_strdup(d, dom_list[i].dns_name); 4698 sid_copy(&d->sid, &dom_list[i].sid); 4699 d->trust_flags = dom_list[i].trust_flags; 4700 d->trust_type = dom_list[i].trust_type; 4701 d->trust_attribs = dom_list[i].trust_attribs; 4702 4829 d = wcache_tdc_dup_domain(ctx, &dom_list[i]); 4703 4830 break; 4704 4831 } … … 4734 4861 const char *shell, 4735 4862 const char *gecos, 4736 uint32 gid)4863 uint32_t gid) 4737 4864 { 4738 4865 struct cache_entry *centry; … … 4835 4962 }; 4836 4963 4837 static bool wcache_ndr_key(TALLOC_CTX *mem_ctx, c har *domain_name,4964 static bool wcache_ndr_key(TALLOC_CTX *mem_ctx, const char *domain_name, 4838 4965 uint32_t opnum, const DATA_BLOB *req, 4839 4966 TDB_DATA *pkey) -
vendor/current/source3/winbindd/winbindd_ccache_access.c
r740 r988 7 7 Copyright (C) Jeremy Allison 2006 (minor fixes to fit into Samba and 8 8 protect against integer wrap). 9 Copyright (C) Andrew Bartlett 2011 9 10 10 11 This program is free software; you can redistribute it and/or modify … … 24 25 #include "includes.h" 25 26 #include "winbindd.h" 26 #include "../libcli/auth/ntlmssp.h" 27 #include "auth/gensec/gensec.h" 28 #include "auth_generic.h" 27 29 28 30 #undef DBGC_CLASS … … 42 44 } 43 45 44 static NTSTATUS do_ntlm_auth_with_hashes(const char *username, 45 const char *domain, 46 const unsigned char lm_hash[LM_HASH_LEN], 47 const unsigned char nt_hash[NT_HASH_LEN], 48 const DATA_BLOB initial_msg, 49 const DATA_BLOB challenge_msg, 50 DATA_BLOB *auth_msg, 51 uint8_t session_key[16]) 46 static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username, 47 const char *domain, 48 const char *password, 49 const DATA_BLOB initial_msg, 50 const DATA_BLOB challenge_msg, 51 TALLOC_CTX *mem_ctx, 52 DATA_BLOB *auth_msg, 53 uint8_t session_key[16], 54 uint8_t *new_spnego) 52 55 { 53 56 NTSTATUS status; 54 struct ntlmssp_state *ntlmssp_state = NULL; 55 DATA_BLOB dummy_msg, reply; 56 57 status = ntlmssp_client_start(NULL, 58 global_myname(), 59 lp_workgroup(), 60 lp_client_ntlmv2_auth(), 61 &ntlmssp_state); 57 struct auth_generic_state *auth_generic_state = NULL; 58 DATA_BLOB reply, session_key_blob; 59 60 status = auth_generic_client_prepare(mem_ctx, &auth_generic_state); 62 61 63 62 if (!NT_STATUS_IS_OK(status)) { … … 67 66 } 68 67 69 status = ntlmssp_set_username(ntlmssp_state, username);68 status = auth_generic_set_username(auth_generic_state, username); 70 69 71 70 if (!NT_STATUS_IS_OK(status)) { … … 75 74 } 76 75 77 status = ntlmssp_set_domain(ntlmssp_state, domain);76 status = auth_generic_set_domain(auth_generic_state, domain); 78 77 79 78 if (!NT_STATUS_IS_OK(status)) { … … 83 82 } 84 83 85 status = ntlmssp_set_hashes(ntlmssp_state, lm_hash, nt_hash); 86 87 if (!NT_STATUS_IS_OK(status)) { 88 DEBUG(1, ("Could not set hashes: %s\n", 89 nt_errstr(status))); 90 goto done; 91 } 92 93 ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); 94 95 /* We need to get our protocol handler into the right state. So first 96 we ask it to generate the initial message. Actually the client has already 97 sent its own initial message, so we're going to drop this one on the floor. 98 The client might have sent a different message, for example with different 99 negotiation options, but as far as I can tell this won't hurt us. (Unless 100 the client sent a different username or domain, in which case that's their 101 problem for telling us the wrong username or domain.) 102 Since we have a copy of the initial message that the client sent, we could 103 resolve any discrepancies if we had to. 104 */ 105 dummy_msg = data_blob_null; 84 status = auth_generic_set_password(auth_generic_state, password); 85 86 if (!NT_STATUS_IS_OK(status)) { 87 DEBUG(1, ("Could not set password: %s\n", 88 nt_errstr(status))); 89 goto done; 90 } 91 92 if (initial_msg.length == 0) { 93 gensec_want_feature(auth_generic_state->gensec_security, 94 GENSEC_FEATURE_SESSION_KEY); 95 } 96 97 status = auth_generic_client_start_by_name(auth_generic_state, 98 "ntlmssp_resume_ccache"); 99 if (!NT_STATUS_IS_OK(status)) { 100 DEBUG(1, ("Could not start NTLMSSP resume mech: %s\n", 101 nt_errstr(status))); 102 goto done; 103 } 104 105 /* 106 * We inject the inital NEGOTIATE message our caller used 107 * in order to get the state machine into the correct possition. 108 */ 106 109 reply = data_blob_null; 107 status = ntlmssp_update(ntlmssp_state, dummy_msg, &reply);108 data_blob_free(&dummy_msg);110 status = gensec_update(auth_generic_state->gensec_security, 111 talloc_tos(), initial_msg, &reply); 109 112 data_blob_free(&reply); 110 113 … … 116 119 117 120 /* Now we are ready to handle the server's actual response. */ 118 status = ntlmssp_update(ntlmssp_state, challenge_msg, &reply);119 121 status = gensec_update(auth_generic_state->gensec_security, 122 mem_ctx, challenge_msg, &reply); 120 123 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) { 121 124 DEBUG(1, ("We didn't get a response to the challenge! [%s]\n", … … 125 128 } 126 129 127 if (ntlmssp_state->session_key.length != 16) { 130 status = gensec_session_key(auth_generic_state->gensec_security, 131 talloc_tos(), &session_key_blob); 132 if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) { 133 DEBUG(1, ("We didn't get the session key we requested! [%s]\n", 134 nt_errstr(status))); 135 data_blob_free(&reply); 136 goto done; 137 } 138 139 if (session_key_blob.length != 16) { 128 140 DEBUG(1, ("invalid session key length %d\n", 129 (int) ntlmssp_state->session_key.length));141 (int)session_key_blob.length)); 130 142 data_blob_free(&reply); 131 143 goto done; 132 144 } 133 134 *auth_msg = data_blob(reply.data, reply.length); 135 memcpy(session_key, ntlmssp_state->session_key.data, 16); 145 memcpy(session_key, session_key_blob.data, 16); 146 data_blob_free(&session_key_blob); 147 *auth_msg = reply; 148 *new_spnego = gensec_have_feature(auth_generic_state->gensec_security, 149 GENSEC_FEATURE_NEW_SPNEGO); 136 150 status = NT_STATUS_OK; 137 151 138 152 done: 139 TALLOC_FREE( ntlmssp_state);153 TALLOC_FREE(auth_generic_state); 140 154 return status; 141 155 } … … 145 159 int ret; 146 160 uid_t ret_uid; 161 gid_t ret_gid; 147 162 148 163 ret_uid = (uid_t)-1; 149 164 150 ret = sys_getpeereid(state->sock, &ret_uid);165 ret = getpeereid(state->sock, &ret_uid, &ret_gid); 151 166 if (ret != 0) { 152 167 DEBUG(1, ("check_client_uid: Could not get socket peer uid: %s; " … … 155 170 } 156 171 157 if (uid != ret_uid ) {172 if (uid != ret_uid && ret_uid != sec_initial_uid()) { 158 173 DEBUG(1, ("check_client_uid: Client lied about its uid: said %u, " 159 174 "actually was %u; denying access\n", … … 172 187 struct WINBINDD_MEMORY_CREDS *entry; 173 188 DATA_BLOB initial, challenge, auth; 174 uint32 initial_blob_len, challenge_blob_len, extra_len;189 uint32_t initial_blob_len, challenge_blob_len, extra_len; 175 190 176 191 /* Ensure null termination */ … … 258 273 state->request->data.ccache_ntlm_auth.challenge_blob_len); 259 274 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); 275 result = do_ntlm_auth_with_stored_pw( 276 name_user, name_domain, entry->pass, 277 initial, challenge, talloc_tos(), &auth, 278 state->response->data.ccache_ntlm_auth.session_key, 279 &state->response->data.ccache_ntlm_auth.new_spnego); 264 280 265 281 if (!NT_STATUS_IS_OK(result)) { -
vendor/current/source3/winbindd/winbindd_change_machine_acct.c
r740 r988 21 21 #include "includes.h" 22 22 #include "winbindd.h" 23 #include "librpc/gen_ndr/ndr_w bint_c.h"23 #include "librpc/gen_ndr/ndr_winbind_c.h" 24 24 25 25 struct winbindd_change_machine_acct_state { … … 53 53 * Internal domains are passdb based, we can always 54 54 * contact them. 55 * 56 * This also protects us from changing the password on 57 * the AD DC without updating all the right databases. 58 * Do not remove this until that code is fixed. 55 59 */ 56 60 tevent_req_done(req); -
vendor/current/source3/winbindd/winbindd_check_machine_acct.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 24 24 struct winbindd_check_machine_acct_state { -
vendor/current/source3/winbindd/winbindd_cm.c
r919 r988 77 77 #include "passdb.h" 78 78 #include "messages.h" 79 #include "auth/gensec/gensec.h" 80 #include "../libcli/smb/smbXcli_base.h" 81 #include "libcli/auth/netlogon_creds_cli.h" 82 #include "auth.h" 83 #include "rpc_server/rpc_ncacn_np.h" 84 #include "auth/credentials/credentials.h" 85 #include "lib/param/param.h" 79 86 80 87 #undef DBGC_CLASS … … 89 96 extern bool override_logfile; 90 97 91 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain );98 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain, bool need_rw_dc); 92 99 static void set_dc_type_and_flags( struct winbindd_domain *domain ); 100 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain ); 93 101 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, 94 102 struct dc_name_ip **dcs, int *num_dcs); … … 171 179 check so always does network calls. */ 172 180 173 init_dc_connection_network(domain );181 init_dc_connection_network(domain, true); 174 182 break; 175 183 } … … 188 196 int num_dcs = 0; 189 197 TALLOC_CTX *mem_ctx = NULL; 190 pid_t parent_pid = sys_getpid();198 pid_t parent_pid = getpid(); 191 199 char *lfile = NULL; 192 200 NTSTATUS status; … … 206 214 } 207 215 208 domain->dc_probe_pid = sys_fork();216 domain->dc_probe_pid = fork(); 209 217 210 218 if (domain->dc_probe_pid == (pid_t)-1) { … … 242 250 pid_to_procid(parent_pid), 243 251 MSG_WINBIND_FAILED_TO_GO_ONLINE, 244 ( uint8*)domain->name,252 (const uint8_t *)domain->name, 245 253 strlen(domain->name)+1); 246 254 _exit(1); … … 254 262 pid_to_procid(parent_pid), 255 263 MSG_WINBIND_FAILED_TO_GO_ONLINE, 256 ( uint8*)domain->name,264 (const uint8_t *)domain->name, 257 265 strlen(domain->name)+1); 258 266 _exit(1); … … 264 272 pid_to_procid(parent_pid), 265 273 MSG_WINBIND_FAILED_TO_GO_ONLINE, 266 ( uint8*)domain->name,274 (const uint8_t *)domain->name, 267 275 strlen(domain->name)+1); 268 276 _exit(0); … … 275 283 pid_to_procid(parent_pid), 276 284 MSG_WINBIND_TRY_TO_GO_ONLINE, 277 ( uint8*)domain->name,285 (const uint8_t *)domain->name, 278 286 strlen(domain->name)+1); 279 287 _exit(0); … … 284 292 ****************************************************************/ 285 293 286 static void check_domain_online_handler(struct event_context *ctx,287 struct t imed_event*te,294 static void check_domain_online_handler(struct tevent_context *ctx, 295 struct tevent_timer *te, 288 296 struct timeval now, 289 297 void *private_data) … … 420 428 calc_new_online_timeout_check(domain); 421 429 422 domain->check_online_event = event_add_timed(winbind_event_context(),430 domain->check_online_event = tevent_add_timer(winbind_event_context(), 423 431 NULL, 424 432 timeval_current_ofs(domain->check_online_timeout,0), … … 439 447 pid_to_procid(parent_pid), 440 448 MSG_WINBIND_DOMAIN_OFFLINE, 441 (uint8 *)domain->name,449 (uint8_t *)domain->name, 442 450 strlen(domain->name) + 1); 443 451 } … … 453 461 pid_to_procid(idmap->pid), 454 462 MSG_WINBIND_OFFLINE, 455 ( uint8 *)domain->name,463 (const uint8_t *)domain->name, 456 464 strlen(domain->name)+1); 457 465 } … … 525 533 pid_to_procid(parent_pid), 526 534 MSG_WINBIND_DOMAIN_ONLINE, 527 (uint8 *)domain->name,535 (uint8_t *)domain->name, 528 536 strlen(domain->name) + 1); 529 537 } … … 539 547 pid_to_procid(idmap->pid), 540 548 MSG_WINBIND_ONLINE, 541 ( uint8 *)domain->name,549 (const uint8_t *)domain->name, 542 550 strlen(domain->name)+1); 543 551 } … … 596 604 TALLOC_FREE(domain->check_online_event); 597 605 598 domain->check_online_event = event_add_timed(winbind_event_context(),606 domain->check_online_event = tevent_add_timer(winbind_event_context(), 599 607 NULL, 600 608 tev, … … 621 629 remove it. */ 622 630 saf_delete(domain->name); 623 if ( *domain->alt_name) {631 if (domain->alt_name != NULL) { 624 632 add_failed_connection_entry(domain->alt_name, server, result); 625 633 saf_delete(domain->alt_name); … … 659 667 *password = smb_xstrdup(""); 660 668 } 669 } 670 671 static NTSTATUS cm_get_ipc_credentials(TALLOC_CTX *mem_ctx, 672 struct cli_credentials **_creds) 673 { 674 675 TALLOC_CTX *frame = talloc_stackframe(); 676 NTSTATUS status = NT_STATUS_INTERNAL_ERROR; 677 struct loadparm_context *lp_ctx; 678 char *username = NULL; 679 char *netbios_domain = NULL; 680 char *password = NULL; 681 struct cli_credentials *creds = NULL; 682 bool ok; 683 684 cm_get_ipc_userpass(&username, &netbios_domain, &password); 685 686 lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers()); 687 if (lp_ctx == NULL) { 688 DEBUG(1, ("loadparm_init_s3 failed\n")); 689 status = NT_STATUS_INTERNAL_ERROR; 690 goto fail; 691 } 692 693 creds = cli_credentials_init(mem_ctx); 694 if (creds == NULL) { 695 status = NT_STATUS_NO_MEMORY; 696 goto fail; 697 } 698 699 cli_credentials_set_conf(creds, lp_ctx); 700 cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS); 701 702 ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED); 703 if (!ok) { 704 status = NT_STATUS_NO_MEMORY; 705 goto fail; 706 } 707 708 ok = cli_credentials_set_username(creds, username, CRED_SPECIFIED); 709 if (!ok) { 710 status = NT_STATUS_NO_MEMORY; 711 goto fail; 712 } 713 714 ok = cli_credentials_set_password(creds, password, CRED_SPECIFIED); 715 if (!ok) { 716 status = NT_STATUS_NO_MEMORY; 717 goto fail; 718 } 719 720 *_creds = creds; 721 creds = NULL; 722 status = NT_STATUS_OK; 723 fail: 724 TALLOC_FREE(creds); 725 SAFE_FREE(username); 726 SAFE_FREE(netbios_domain); 727 SAFE_FREE(password); 728 TALLOC_FREE(frame); 729 return status; 730 } 731 732 static bool cm_is_ipc_credentials(struct cli_credentials *creds) 733 { 734 TALLOC_CTX *frame = talloc_stackframe(); 735 char *ipc_account = NULL; 736 char *ipc_domain = NULL; 737 char *ipc_password = NULL; 738 const char *creds_account = NULL; 739 const char *creds_domain = NULL; 740 const char *creds_password = NULL; 741 bool ret = false; 742 743 cm_get_ipc_userpass(&ipc_account, &ipc_domain, &ipc_password); 744 745 creds_account = cli_credentials_get_username(creds); 746 creds_domain = cli_credentials_get_domain(creds); 747 creds_password = cli_credentials_get_password(creds); 748 749 if (!strequal(ipc_domain, creds_domain)) { 750 goto done; 751 } 752 753 if (!strequal(ipc_account, creds_account)) { 754 goto done; 755 } 756 757 if (!strcsequal(ipc_password, creds_password)) { 758 goto done; 759 } 760 761 ret = true; 762 done: 763 SAFE_FREE(ipc_account); 764 SAFE_FREE(ipc_domain); 765 SAFE_FREE(ipc_password); 766 TALLOC_FREE(frame); 767 return ret; 661 768 } 662 769 … … 725 832 return false; 726 833 } 727 if (strlen(domain->alt_name) == 0) { 728 fstrcpy(domain->alt_name, 729 domain_info->domain_name); 834 if (domain->alt_name == NULL) { 835 domain->alt_name = talloc_strdup(domain, 836 domain_info->domain_name); 837 if (domain->alt_name == NULL) { 838 DEBUG(0, ("talloc_strdup failed\n")); 839 talloc_destroy(mem_ctx); 840 return false; 841 } 730 842 } 731 if (strlen(domain->forest_name) == 0) { 732 fstrcpy(domain->forest_name, 733 domain_info->forest_name); 843 if (domain->forest_name == NULL) { 844 domain->forest_name = talloc_strdup(domain, 845 domain_info->forest_name); 846 if (domain->forest_name == NULL) { 847 DEBUG(0, ("talloc_strdup failed\n")); 848 talloc_destroy(mem_ctx); 849 return false; 850 } 734 851 } 735 852 } … … 778 895 * Helper function to assemble trust password and account name 779 896 */ 780 static NTSTATUS get_trust_creds(const struct winbindd_domain *domain, 781 char **machine_password, 782 char **machine_account, 783 char **machine_krb5_principal) 784 { 785 const char *account_name; 786 const char *name = NULL; 897 static NTSTATUS get_trust_credentials(struct winbindd_domain *domain, 898 TALLOC_CTX *mem_ctx, 899 bool netlogon, 900 struct cli_credentials **_creds) 901 { 902 const struct winbindd_domain *creds_domain = NULL; 903 struct cli_credentials *creds; 904 NTSTATUS status; 905 bool force_machine_account = false; 787 906 788 907 /* If we are a DC and this is not our own domain */ 789 908 790 if (IS_DC) { 791 name = domain->name; 909 if (!domain->active_directory) { 910 if (!netlogon) { 911 /* 912 * For non active directory domains 913 * we can only use NTLMSSP for SMB. 914 * 915 * But the trust account is not allowed 916 * to use SMB with NTLMSSP. 917 */ 918 force_machine_account = true; 919 } 920 } 921 922 if (IS_DC && !force_machine_account) { 923 creds_domain = domain; 792 924 } else { 793 struct winbindd_domain *our_domain = find_our_domain(); 794 795 if (!our_domain) 796 return NT_STATUS_INVALID_SERVER_STATE; 797 798 name = our_domain->name; 799 } 800 801 if (!get_trust_pw_clear(name, machine_password, 802 &account_name, NULL)) 803 { 925 creds_domain = find_our_domain(); 926 if (creds_domain == NULL) { 927 return NT_STATUS_INVALID_SERVER_STATE; 928 } 929 } 930 931 status = pdb_get_trust_credentials(creds_domain->name, 932 creds_domain->alt_name, 933 mem_ctx, 934 &creds); 935 if (!NT_STATUS_IS_OK(status)) { 936 goto ipc_fallback; 937 } 938 939 if (domain->primary && lp_security() == SEC_ADS) { 940 cli_credentials_set_kerberos_state(creds, 941 CRED_AUTO_USE_KERBEROS); 942 } else if (domain->active_directory) { 943 cli_credentials_set_kerberos_state(creds, 944 CRED_MUST_USE_KERBEROS); 945 } else { 946 cli_credentials_set_kerberos_state(creds, 947 CRED_DONT_USE_KERBEROS); 948 } 949 950 if (creds_domain != domain) { 951 /* 952 * We can only use schannel against a direct trust 953 */ 954 cli_credentials_set_secure_channel_type(creds, 955 SEC_CHAN_NULL); 956 } 957 958 *_creds = creds; 959 return NT_STATUS_OK; 960 961 ipc_fallback: 962 if (netlogon) { 804 963 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 805 964 } 806 965 807 if ((machine_account != NULL) && 808 (asprintf(machine_account, "%s$", account_name) == -1)) 809 { 810 return NT_STATUS_NO_MEMORY; 811 } 812 813 /* For now assume our machine account only exists in our domain */ 814 815 if (machine_krb5_principal != NULL) 816 { 817 struct winbindd_domain *our_domain = find_our_domain(); 818 819 if (!our_domain) { 820 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 821 } 822 823 if (asprintf(machine_krb5_principal, "%s$@%s", 824 account_name, our_domain->alt_name) == -1) 825 { 826 return NT_STATUS_NO_MEMORY; 827 } 828 829 strupper_m(*machine_krb5_principal); 830 } 831 966 status = cm_get_ipc_credentials(mem_ctx, &creds); 967 if (!NT_STATUS_IS_OK(status)) { 968 return status; 969 } 970 971 *_creds = creds; 832 972 return NT_STATUS_OK; 833 973 } … … 838 978 ************************************************************************/ 839 979 840 static NTSTATUS cm_prepare_connection( conststruct winbindd_domain *domain,980 static NTSTATUS cm_prepare_connection(struct winbindd_domain *domain, 841 981 const int sockfd, 842 982 const char *controller, … … 844 984 bool *retry) 845 985 { 846 char *machine_password = NULL; 847 char *machine_krb5_principal = NULL; 848 char *machine_account = NULL; 849 char *ipc_username = NULL; 850 char *ipc_domain = NULL; 851 char *ipc_password = NULL; 986 bool try_ipc_auth = false; 987 const char *machine_password = NULL; 988 const char *machine_krb5_principal = NULL; 989 const char *machine_account = NULL; 990 const char *machine_domain = NULL; 991 int flags = 0; 992 struct cli_credentials *creds = NULL; 993 enum credentials_use_kerberos krb5_state; 852 994 853 995 struct named_mutex *mutex; … … 855 997 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 856 998 857 struct sockaddr peeraddr; 858 socklen_t peeraddr_len; 859 860 struct sockaddr_in *peeraddr_in = 861 (struct sockaddr_in *)(void *)&peeraddr; 999 enum smb_signing_setting smb_sign_client_connections = lp_client_ipc_signing(); 1000 1001 if (smb_sign_client_connections == SMB_SIGNING_DEFAULT) { 1002 /* 1003 * If we are connecting to our own AD domain, require 1004 * smb signing to disrupt MITM attacks 1005 */ 1006 if (domain->primary && lp_security() == SEC_ADS) { 1007 smb_sign_client_connections = SMB_SIGNING_REQUIRED; 1008 /* 1009 * If we are in or are an AD domain and connecting to another 1010 * AD domain in our forest 1011 * then require smb signing to disrupt MITM attacks 1012 */ 1013 } else if ((lp_security() == SEC_ADS || 1014 lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) 1015 && domain->active_directory 1016 && (domain->domain_trust_attribs 1017 & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST)) { 1018 smb_sign_client_connections = SMB_SIGNING_REQUIRED; 1019 } 1020 } 862 1021 863 1022 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n", … … 869 1028 WINBIND_SERVER_MUTEX_WAIT_TIME); 870 1029 if (mutex == NULL) { 1030 close(sockfd); 871 1031 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n", 872 1032 controller)); … … 875 1035 } 876 1036 877 if ((*cli = cli_initialise()) == NULL) { 1037 flags |= CLI_FULL_CONNECTION_USE_KERBEROS; 1038 1039 *cli = cli_state_create(NULL, sockfd, 1040 controller, domain->alt_name, 1041 smb_sign_client_connections, flags); 1042 if (*cli == NULL) { 1043 close(sockfd); 878 1044 DEBUG(1, ("Could not cli_initialize\n")); 879 1045 result = NT_STATUS_NO_MEMORY; … … 881 1047 } 882 1048 883 (*cli)->timeout = 10000; /* 10 seconds */ 884 (*cli)->fd = sockfd; 885 (*cli)->desthost = talloc_strdup((*cli), controller); 886 if ((*cli)->desthost == NULL) { 887 result = NT_STATUS_NO_MEMORY; 888 goto done; 889 } 890 891 (*cli)->use_kerberos = True; 892 893 peeraddr_len = sizeof(peeraddr); 894 895 if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0)) { 896 DEBUG(0,("cm_prepare_connection: getpeername failed with: %s\n", 897 strerror(errno))); 898 result = NT_STATUS_UNSUCCESSFUL; 899 goto done; 900 } 901 902 if ((peeraddr_len != sizeof(struct sockaddr_in)) 903 #ifdef HAVE_IPV6 904 && (peeraddr_len != sizeof(struct sockaddr_in6)) 905 #endif 906 ) { 907 DEBUG(0,("cm_prepare_connection: got unexpected peeraddr len %d\n", 908 peeraddr_len)); 909 result = NT_STATUS_UNSUCCESSFUL; 910 goto done; 911 } 912 913 if ((peeraddr_in->sin_family != PF_INET) 914 #ifdef HAVE_IPV6 915 && (peeraddr_in->sin_family != PF_INET6) 916 #endif 917 ) { 918 DEBUG(0,("cm_prepare_connection: got unexpected family %d\n", 919 peeraddr_in->sin_family)); 920 result = NT_STATUS_UNSUCCESSFUL; 921 goto done; 922 } 923 924 result = cli_negprot(*cli); 1049 cli_set_timeout(*cli, 10000); /* 10 seconds */ 1050 1051 result = smbXcli_negprot((*cli)->conn, (*cli)->timeout, 1052 lp_client_ipc_min_protocol(), 1053 lp_client_ipc_max_protocol()); 925 1054 926 1055 if (!NT_STATUS_IS_OK(result)) { … … 929 1058 } 930 1059 931 if (!is_dc_trusted_domain_situation(domain->name) && 932 (*cli)->protocol >= PROTOCOL_NT1 && 933 (*cli)->capabilities & CAP_EXTENDED_SECURITY) 934 { 935 ADS_STATUS ads_status; 936 937 result = get_trust_creds(domain, &machine_password, 938 &machine_account, 939 &machine_krb5_principal); 1060 if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_NT1 && 1061 smb1cli_conn_capabilities((*cli)->conn) & CAP_EXTENDED_SECURITY) { 1062 try_ipc_auth = true; 1063 } else if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) { 1064 try_ipc_auth = true; 1065 } else if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) { 1066 /* 1067 * If we are forcing on SMB signing, then we must 1068 * require authentication unless this is a one-way 1069 * trust, and we have no stored user/password 1070 */ 1071 try_ipc_auth = true; 1072 } 1073 1074 if (try_ipc_auth) { 1075 result = get_trust_credentials(domain, talloc_tos(), false, &creds); 940 1076 if (!NT_STATUS_IS_OK(result)) { 941 goto anon_fallback; 942 } 943 944 if (lp_security() == SEC_ADS) { 945 946 /* Try a krb5 session */ 947 948 (*cli)->use_kerberos = True; 949 DEBUG(5, ("connecting to %s from %s with kerberos principal " 950 "[%s] and realm [%s]\n", controller, global_myname(), 951 machine_krb5_principal, domain->alt_name)); 952 953 winbindd_set_locator_kdc_envs(domain); 954 955 ads_status = cli_session_setup_spnego(*cli, 956 machine_krb5_principal, 957 machine_password, 958 lp_workgroup(), 959 domain->alt_name); 960 961 if (!ADS_ERR_OK(ads_status)) { 962 DEBUG(4,("failed kerberos session setup with %s\n", 963 ads_errstr(ads_status))); 964 } 965 966 result = ads_ntstatus(ads_status); 967 if (NT_STATUS_IS_OK(result)) { 968 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */ 969 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password); 970 if (!NT_STATUS_IS_OK(result)) { 971 goto done; 972 } 973 goto session_setup_done; 974 } 975 } 976 1077 DEBUG(1, ("get_trust_credentials(%s) failed: %s\n", 1078 domain->name, nt_errstr(result))); 1079 goto done; 1080 } 1081 } else { 1082 /* 1083 * Without SPNEGO or NTLMSSP (perhaps via SMB2) we 1084 * would try and authentication with our machine 1085 * account password and fail. This is very rare in 1086 * the modern world however 1087 */ 1088 creds = cli_credentials_init_anon(talloc_tos()); 1089 if (creds == NULL) { 1090 result = NT_STATUS_NO_MEMORY; 1091 DEBUG(1, ("cli_credentials_init_anon(%s) failed: %s\n", 1092 domain->name, nt_errstr(result))); 1093 goto done; 1094 } 1095 } 1096 1097 krb5_state = cli_credentials_get_kerberos_state(creds); 1098 1099 machine_krb5_principal = cli_credentials_get_principal(creds, 1100 talloc_tos()); 1101 if (machine_krb5_principal == NULL) { 1102 krb5_state = CRED_DONT_USE_KERBEROS; 1103 } 1104 1105 machine_account = cli_credentials_get_username(creds); 1106 machine_password = cli_credentials_get_password(creds); 1107 machine_domain = cli_credentials_get_domain(creds); 1108 1109 if (krb5_state != CRED_DONT_USE_KERBEROS) { 1110 1111 /* Try a krb5 session */ 1112 1113 (*cli)->use_kerberos = True; 1114 DEBUG(5, ("connecting to %s from %s with kerberos principal " 1115 "[%s] and realm [%s]\n", controller, lp_netbios_name(), 1116 machine_krb5_principal, domain->alt_name)); 1117 1118 winbindd_set_locator_kdc_envs(domain); 1119 1120 result = cli_session_setup(*cli, 1121 machine_krb5_principal, 1122 machine_password, 1123 strlen(machine_password)+1, 1124 machine_password, 1125 strlen(machine_password)+1, 1126 machine_domain); 1127 1128 if (NT_STATUS_IS_OK(result)) { 1129 goto session_setup_done; 1130 } 1131 1132 DEBUG(4,("failed kerberos session setup with %s\n", 1133 nt_errstr(result))); 1134 } 1135 1136 if (krb5_state != CRED_MUST_USE_KERBEROS) { 977 1137 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */ 978 1138 (*cli)->use_kerberos = False; 979 1139 980 DEBUG(5, ("connecting to %s from %s with username " 981 "[%s]\\[%s]\n", controller, global_myname(), 982 lp_workgroup(), machine_account)); 983 984 ads_status = cli_session_setup_spnego(*cli, 985 machine_account, 986 machine_password, 987 lp_workgroup(), 988 NULL); 989 if (!ADS_ERR_OK(ads_status)) { 990 DEBUG(4, ("authenticated session setup failed with %s\n", 991 ads_errstr(ads_status))); 992 } 993 994 result = ads_ntstatus(ads_status); 995 if (NT_STATUS_IS_OK(result)) { 996 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */ 997 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password); 998 if (!NT_STATUS_IS_OK(result)) { 999 goto done; 1000 } 1001 goto session_setup_done; 1002 } 1003 } 1004 1005 /* Fall back to non-kerberos session setup with auth_user */ 1006 1140 DEBUG(5, ("connecting to %s from %s using NTLMSSP with username " 1141 "[%s]\\[%s]\n", controller, lp_netbios_name(), 1142 machine_domain, machine_account)); 1143 1144 result = cli_session_setup(*cli, 1145 machine_account, 1146 machine_password, 1147 strlen(machine_password)+1, 1148 machine_password, 1149 strlen(machine_password)+1, 1150 machine_domain); 1151 } 1152 1153 if (NT_STATUS_IS_OK(result)) { 1154 goto session_setup_done; 1155 } 1156 1157 /* 1158 * If we are not going to validiate the conneciton 1159 * with SMB signing, then allow us to fall back to 1160 * anonymous 1161 */ 1162 if (NT_STATUS_EQUAL(result, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT) 1163 || NT_STATUS_EQUAL(result, NT_STATUS_TRUSTED_DOMAIN_FAILURE) 1164 || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_ACCOUNT_NAME) 1165 || NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS) 1166 || NT_STATUS_EQUAL(result, NT_STATUS_LOGON_FAILURE)) 1167 { 1168 if (cli_credentials_is_anonymous(creds)) { 1169 goto done; 1170 } 1171 1172 if (!cm_is_ipc_credentials(creds)) { 1173 goto ipc_fallback; 1174 } 1175 1176 if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) { 1177 goto done; 1178 } 1179 1180 goto anon_fallback; 1181 } 1182 1183 DEBUG(4, ("authenticated session setup failed with %s\n", 1184 nt_errstr(result))); 1185 1186 goto done; 1187 1188 ipc_fallback: 1189 result = cm_get_ipc_credentials(talloc_tos(), &creds); 1190 if (!NT_STATUS_IS_OK(result)) { 1191 goto done; 1192 } 1193 1194 if (cli_credentials_is_anonymous(creds)) { 1195 TALLOC_FREE(creds); 1196 goto anon_fallback; 1197 } 1198 1199 machine_account = cli_credentials_get_username(creds); 1200 machine_password = cli_credentials_get_password(creds); 1201 machine_domain = cli_credentials_get_domain(creds); 1202 1203 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the ipc creds. */ 1007 1204 (*cli)->use_kerberos = False; 1008 1205 1009 cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password); 1010 1011 if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) && 1012 (strlen(ipc_username) > 0)) { 1013 1014 /* Only try authenticated if we have a username */ 1015 1016 DEBUG(5, ("connecting to %s from %s with username " 1017 "[%s]\\[%s]\n", controller, global_myname(), 1018 ipc_domain, ipc_username)); 1019 1020 if (NT_STATUS_IS_OK(cli_session_setup( 1021 *cli, ipc_username, 1022 ipc_password, strlen(ipc_password)+1, 1023 ipc_password, strlen(ipc_password)+1, 1024 ipc_domain))) { 1025 /* Successful logon with given username. */ 1026 result = cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password); 1027 if (!NT_STATUS_IS_OK(result)) { 1028 goto done; 1029 } 1030 goto session_setup_done; 1031 } else { 1032 DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n", 1033 ipc_domain, ipc_username )); 1034 } 1035 } 1206 DEBUG(5, ("connecting to %s from %s using NTLMSSP with username " 1207 "[%s]\\[%s]\n", controller, lp_netbios_name(), 1208 machine_domain, machine_account)); 1209 1210 result = cli_session_setup(*cli, 1211 machine_account, 1212 machine_password, 1213 strlen(machine_password)+1, 1214 machine_password, 1215 strlen(machine_password)+1, 1216 machine_domain); 1217 1218 if (NT_STATUS_IS_OK(result)) { 1219 goto session_setup_done; 1220 } 1221 1222 /* 1223 * If we are not going to validiate the conneciton 1224 * with SMB signing, then allow us to fall back to 1225 * anonymous 1226 */ 1227 if (NT_STATUS_EQUAL(result, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT) 1228 || NT_STATUS_EQUAL(result, NT_STATUS_TRUSTED_DOMAIN_FAILURE) 1229 || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_ACCOUNT_NAME) 1230 || NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS) 1231 || NT_STATUS_EQUAL(result, NT_STATUS_LOGON_FAILURE)) 1232 { 1233 goto anon_fallback; 1234 } 1235 1236 DEBUG(4, ("authenticated session setup failed with %s\n", 1237 nt_errstr(result))); 1238 1239 goto done; 1036 1240 1037 1241 anon_fallback: 1242 1243 if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) { 1244 goto done; 1245 } 1038 1246 1039 1247 /* Fall back to anonymous connection, this might fail later */ … … 1042 1250 controller )); 1043 1251 1044 if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0, 1045 NULL, 0, ""))) { 1252 (*cli)->use_kerberos = False; 1253 1254 result = cli_session_setup(*cli, "", "", 0, "", 0, ""); 1255 if (NT_STATUS_IS_OK(result)) { 1046 1256 DEBUG(5, ("Connected anonymously\n")); 1047 result = cli_init_creds(*cli, "", "", "");1048 if (!NT_STATUS_IS_OK(result)) {1049 goto done;1050 }1051 1257 goto session_setup_done; 1052 1258 } 1053 1259 1054 result = cli_nt_error(*cli);1055 1056 if (NT_STATUS_IS_OK(result))1057 result = NT_STATUS_UNSUCCESSFUL;1058 1059 1260 /* We can't session setup */ 1060 1061 1261 goto done; 1062 1262 1063 1263 session_setup_done: 1064 1264 1065 /* cache the server name for later connections */ 1066 1067 saf_store( domain->name, (*cli)->desthost ); 1068 if (domain->alt_name && (*cli)->use_kerberos) { 1069 saf_store( domain->alt_name, (*cli)->desthost ); 1070 } 1071 1072 winbindd_set_locator_kdc_envs(domain); 1073 1074 result = cli_tcon_andx(*cli, "IPC$", "IPC", "", 0); 1265 /* 1266 * This should be a short term hack until 1267 * dynamic re-authentication is implemented. 1268 * 1269 * See Bug 9175 - winbindd doesn't recover from 1270 * NT_STATUS_NETWORK_SESSION_EXPIRED 1271 */ 1272 if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) { 1273 smbXcli_session_set_disconnect_expired((*cli)->smb2.session); 1274 } 1275 1276 result = cli_tree_connect(*cli, "IPC$", "IPC", "", 0); 1075 1277 1076 1278 if (!NT_STATUS_IS_OK(result)) { … … 1079 1281 } 1080 1282 1283 /* cache the server name for later connections */ 1284 1285 saf_store(domain->name, controller); 1286 if (domain->alt_name && (*cli)->use_kerberos) { 1287 saf_store(domain->alt_name, controller); 1288 } 1289 1290 winbindd_set_locator_kdc_envs(domain); 1291 1081 1292 TALLOC_FREE(mutex); 1082 1293 *retry = False; 1083 1294 1084 /* set the domain if empty; needed for schannel connections */1085 if ( !(*cli)->domain[0] ) {1086 result = cli_set_domain((*cli), domain->name);1087 if (!NT_STATUS_IS_OK(result)) {1088 SAFE_FREE(ipc_username);1089 SAFE_FREE(ipc_domain);1090 SAFE_FREE(ipc_password);1091 return result;1092 }1093 }1094 1095 1295 result = NT_STATUS_OK; 1096 1296 1097 1297 done: 1098 1298 TALLOC_FREE(mutex); 1099 SAFE_FREE(machine_account);1100 SAFE_FREE(machine_password);1101 SAFE_FREE(machine_krb5_principal);1102 SAFE_FREE(ipc_username);1103 SAFE_FREE(ipc_domain);1104 SAFE_FREE(ipc_password);1105 1299 1106 1300 if (!NT_STATUS_IS_OK(result)) { … … 1148 1342 return False; 1149 1343 1150 *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);1344 *dcs = talloc_realloc(mem_ctx, *dcs, struct dc_name_ip, (*num)+1); 1151 1345 1152 1346 if (*dcs == NULL) … … 1160 1354 1161 1355 static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx, 1162 struct sockaddr_storage *pss, uint16 port,1356 struct sockaddr_storage *pss, uint16_t port, 1163 1357 struct sockaddr_storage **addrs, int *num) 1164 1358 { 1165 *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);1359 *addrs = talloc_realloc(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1); 1166 1360 1167 1361 if (*addrs == NULL) { … … 1184 1378 const struct winbindd_domain *domain, 1185 1379 struct sockaddr_storage *pss, 1186 fstring name)1380 char **name) 1187 1381 { 1188 1382 struct ip_service ip_list; … … 1190 1384 NTSTATUS status; 1191 1385 const char *dc_name; 1192 1386 fstring nbtname; 1387 #ifdef HAVE_ADS 1388 bool is_ad_domain = false; 1389 #endif 1193 1390 ip_list.ss = *pss; 1194 1391 ip_list.port = 0; … … 1198 1395 None of these failures should be considered critical for now */ 1199 1396 1200 if (lp_security() == SEC_ADS) { 1397 if ((lp_security() == SEC_ADS) && (domain->alt_name != NULL)) { 1398 is_ad_domain = true; 1399 } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) { 1400 is_ad_domain = domain->active_directory; 1401 } 1402 1403 if (is_ad_domain) { 1201 1404 ADS_STRUCT *ads; 1202 1405 ADS_STATUS ads_status; … … 1211 1414 if (ADS_ERR_OK(ads_status)) { 1212 1415 /* We got a cldap packet. */ 1213 fstrcpy(name, ads->config.ldap_server_name); 1214 namecache_store(name, 0x20, 1, &ip_list); 1416 *name = talloc_strdup(mem_ctx, 1417 ads->config.ldap_server_name); 1418 if (*name == NULL) { 1419 return false; 1420 } 1421 namecache_store(*name, 0x20, 1, &ip_list); 1215 1422 1216 1423 DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags)); … … 1218 1425 if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) { 1219 1426 if (ads_closest_dc(ads)) { 1220 char *sitename = sitename_fetch( ads->config.realm);1427 char *sitename = sitename_fetch(mem_ctx, ads->config.realm); 1221 1428 1222 1429 /* We're going to use this KDC for this realm/domain. … … 1227 1434 domain->name, 1228 1435 sitename, 1229 pss, 1230 name); 1231 1232 SAFE_FREE(sitename); 1436 pss); 1437 1438 TALLOC_FREE(sitename); 1233 1439 } else { 1234 1440 /* use an off site KDC */ … … 1236 1442 domain->name, 1237 1443 NULL, 1238 pss, 1239 name); 1444 pss); 1240 1445 } 1241 1446 winbindd_set_locator_kdc_envs(domain); 1242 1447 1243 1448 /* Ensure we contact this DC also. */ 1244 saf_store( domain->name,name);1245 saf_store( domain->alt_name,name);1449 saf_store(domain->name, *name); 1450 saf_store(domain->alt_name, *name); 1246 1451 } 1247 1452 … … 1259 1464 &dc_name, NULL); 1260 1465 if (NT_STATUS_IS_OK(status)) { 1261 fstrcpy(name, dc_name); 1262 namecache_store(name, 0x20, 1, &ip_list); 1466 *name = talloc_strdup(mem_ctx, dc_name); 1467 if (*name == NULL) { 1468 return false; 1469 } 1470 namecache_store(*name, 0x20, 1, &ip_list); 1263 1471 return True; 1264 1472 } … … 1266 1474 /* try node status request */ 1267 1475 1268 if ( name_status_find(domain->name, 0x1c, 0x20, pss, name) ) { 1269 namecache_store(name, 0x20, 1, &ip_list); 1270 return True; 1476 if (name_status_find(domain->name, 0x1c, 0x20, pss, nbtname) ) { 1477 namecache_store(nbtname, 0x20, 1, &ip_list); 1478 1479 if (name != NULL) { 1480 *name = talloc_strdup(mem_ctx, nbtname); 1481 if (*name == NULL) { 1482 return false; 1483 } 1484 } 1485 1486 return true; 1271 1487 } 1272 1488 return False; … … 1311 1527 } 1312 1528 1313 if ( sec == SEC_ADS) {1529 if ((sec == SEC_ADS) && (domain->alt_name != NULL)) { 1314 1530 char *sitename = NULL; 1315 1531 … … 1325 1541 get_dc_name(domain->name, domain->alt_name, dcname, &ss); 1326 1542 1327 sitename = sitename_fetch( domain->alt_name);1543 sitename = sitename_fetch(mem_ctx, domain->alt_name); 1328 1544 if (sitename) { 1329 1545 … … 1349 1565 1350 1566 SAFE_FREE(ip_list); 1351 SAFE_FREE(sitename);1567 TALLOC_FREE(sitename); 1352 1568 iplist_size = 0; 1353 1569 } … … 1373 1589 } 1374 1590 1375 /* Try standard netbios queries if no ADS */ 1591 /* Try standard netbios queries if no ADS and fall back to DNS queries 1592 * if alt_name is available */ 1376 1593 if (*num_dcs == 0) { 1377 1594 get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size, 1378 False); 1595 false); 1596 if (iplist_size == 0) { 1597 if (domain->alt_name != NULL) { 1598 get_sorted_dc_list(domain->alt_name, NULL, &ip_list, 1599 &iplist_size, true); 1600 } 1601 } 1379 1602 1380 1603 for ( i=0; i<iplist_size; i++ ) { … … 1410 1633 static bool find_new_dc(TALLOC_CTX *mem_ctx, 1411 1634 struct winbindd_domain *domain, 1412 fstringdcname, struct sockaddr_storage *pss, int *fd)1635 char **dcname, struct sockaddr_storage *pss, int *fd) 1413 1636 { 1414 1637 struct dc_name_ip *dcs = NULL; … … 1416 1639 1417 1640 const char **dcnames = NULL; 1418 int num_dcnames = 0;1641 size_t num_dcnames = 0; 1419 1642 1420 1643 struct sockaddr_storage *addrs = NULL; … … 1438 1661 return False; 1439 1662 } 1440 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 445,1663 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, TCP_SMB_PORT, 1441 1664 &addrs, &num_addrs)) { 1442 1665 return False; … … 1469 1692 if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) { 1470 1693 /* Ok, we've got a name for the DC */ 1471 fstrcpy(dcname, dcnames[fd_index]); 1472 return True; 1694 *dcname = talloc_strdup(mem_ctx, dcnames[fd_index]); 1695 if (*dcname == NULL) { 1696 return false; 1697 } 1698 return true; 1473 1699 } 1474 1700 … … 1512 1738 char *value = NULL; 1513 1739 1514 if ( cli == NULL) {1740 if (!cli_state_is_connected(cli)) { 1515 1741 return; 1516 1742 } 1517 if (cli->fd == -1) { 1518 return; 1519 } 1520 get_peer_addr(cli->fd, addr, sizeof(addr)); 1743 1744 print_sockaddr(addr, sizeof(addr), 1745 smbXcli_conn_remote_sockaddr(cli->conn)); 1521 1746 1522 1747 key = current_dc_key(talloc_tos(), domain_name); … … 1540 1765 char **p_dc_name, char **p_dc_ip) 1541 1766 { 1542 char *key, *value, *p; 1767 char *key, *p; 1768 char *value = NULL; 1543 1769 bool ret = false; 1544 1770 char *dc_name = NULL; … … 1549 1775 goto done; 1550 1776 } 1551 if (!gencache_get(key, &value, NULL)) {1777 if (!gencache_get(key, mem_ctx, &value, NULL)) { 1552 1778 goto done; 1553 1779 } … … 1578 1804 TALLOC_FREE(dc_ip); 1579 1805 TALLOC_FREE(key); 1806 TALLOC_FREE(value); 1580 1807 return ret; 1808 } 1809 1810 NTSTATUS wb_open_internal_pipe(TALLOC_CTX *mem_ctx, 1811 const struct ndr_interface_table *table, 1812 struct rpc_pipe_client **ret_pipe) 1813 { 1814 struct rpc_pipe_client *cli = NULL; 1815 const struct auth_session_info *session_info; 1816 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 1817 1818 1819 session_info = get_session_info_system(); 1820 SMB_ASSERT(session_info != NULL); 1821 1822 /* create a connection to the specified pipe */ 1823 if (lp_parm_bool(-1, "winbindd", "use external pipes", false)) { 1824 status = rpc_pipe_open_interface(mem_ctx, 1825 table, 1826 session_info, 1827 NULL, 1828 winbind_messaging_context(), 1829 &cli); 1830 } else { 1831 status = rpc_pipe_open_internal(mem_ctx, 1832 &table->syntax_id, 1833 session_info, 1834 NULL, 1835 winbind_messaging_context(), 1836 &cli); 1837 } 1838 if (!NT_STATUS_IS_OK(status)) { 1839 DEBUG(0, ("open_internal_pipe: Could not connect to %s pipe: %s\n", 1840 table->name, nt_errstr(status))); 1841 return status; 1842 } 1843 1844 if (ret_pipe) { 1845 *ret_pipe = cli; 1846 } 1847 1848 return NT_STATUS_OK; 1581 1849 } 1582 1850 … … 1586 1854 TALLOC_CTX *mem_ctx; 1587 1855 NTSTATUS result; 1588 char *saf_servername = saf_fetch( domain->name );1856 char *saf_servername; 1589 1857 int retries; 1590 1858 1591 1859 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) { 1592 SAFE_FREE(saf_servername);1593 1860 set_domain_offline(domain); 1594 1861 return NT_STATUS_NO_MEMORY; 1595 1862 } 1863 1864 saf_servername = saf_fetch(mem_ctx, domain->name ); 1596 1865 1597 1866 /* we have to check the server affinity cache here since … … 1609 1878 /* convert an ip address to a name */ 1610 1879 if (is_ipaddress( saf_servername ) ) { 1611 fstring saf_name;1880 char *dcname = NULL; 1612 1881 struct sockaddr_storage ss; 1613 1882 1614 1883 if (!interpret_string_addr(&ss, saf_servername, 1615 1884 AI_NUMERICHOST)) { 1885 TALLOC_FREE(mem_ctx); 1616 1886 return NT_STATUS_UNSUCCESSFUL; 1617 1887 } 1618 if (dcip_to_name(mem_ctx, domain, &ss, saf_name )) { 1619 fstrcpy( domain->dcname, saf_name ); 1888 if (dcip_to_name(mem_ctx, domain, &ss, &dcname)) { 1889 domain->dcname = talloc_strdup(domain, 1890 dcname); 1891 if (domain->dcname == NULL) { 1892 TALLOC_FREE(mem_ctx); 1893 return NT_STATUS_NO_MEMORY; 1894 } 1620 1895 } else { 1621 1896 winbind_add_failed_connection_entry( … … 1624 1899 } 1625 1900 } else { 1626 fstrcpy( domain->dcname, saf_servername ); 1627 } 1628 1629 SAFE_FREE( saf_servername ); 1901 domain->dcname = talloc_strdup(domain, saf_servername); 1902 if (domain->dcname == NULL) { 1903 TALLOC_FREE(mem_ctx); 1904 return NT_STATUS_NO_MEMORY; 1905 } 1906 } 1630 1907 } 1631 1908 … … 1633 1910 int fd = -1; 1634 1911 bool retry = False; 1912 char *dcname = NULL; 1635 1913 1636 1914 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; 1637 1915 1638 1916 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n", 1639 domain->dcname , domain->name ));1640 1641 if ( *domain->dcname1917 domain->dcname ? domain->dcname : "", domain->name )); 1918 1919 if (domain->dcname != NULL 1642 1920 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname)) 1643 1921 && (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true))) … … 1653 1931 } 1654 1932 1655 if ((fd == -1) 1656 && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))1933 if ((fd == -1) && 1934 !find_new_dc(mem_ctx, domain, &dcname, &domain->dcaddr, &fd)) 1657 1935 { 1658 1936 /* This is the one place where we will … … 1663 1941 break; 1664 1942 } 1943 if (dcname != NULL) { 1944 talloc_free(domain->dcname); 1945 1946 domain->dcname = talloc_move(domain, &dcname); 1947 if (domain->dcname == NULL) { 1948 result = NT_STATUS_NO_MEMORY; 1949 break; 1950 } 1951 } 1665 1952 1666 1953 new_conn->cli = NULL; … … 1678 1965 1679 1966 if (NT_STATUS_IS_OK(result)) { 1967 bool seal_pipes = true; 1680 1968 1681 1969 winbindd_set_locator_kdc_envs(domain); … … 1697 1985 store_current_dc_in_gencache(domain->name, domain->dcname, 1698 1986 new_conn->cli); 1987 1988 seal_pipes = lp_winbind_sealed_pipes(); 1989 seal_pipes = lp_parm_bool(-1, "winbind sealed pipes", 1990 domain->name, 1991 seal_pipes); 1992 1993 if (seal_pipes) { 1994 new_conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY; 1995 } else { 1996 new_conn->auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; 1997 } 1699 1998 } else { 1700 1999 /* Ensure we setup the retry handler. */ … … 1708 2007 /* Close down all open pipes on a connection. */ 1709 2008 1710 void invalidate_cm_connection(struct winbindd_ cm_conn *conn)2009 void invalidate_cm_connection(struct winbindd_domain *domain) 1711 2010 { 1712 2011 NTSTATUS result; 2012 struct winbindd_cm_conn *conn = &domain->conn; 1713 2013 1714 2014 /* We're closing down a possibly dead … … 1769 2069 } 1770 2070 2071 conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY; 2072 conn->netlogon_force_reauth = false; 2073 conn->netlogon_flags = 0; 2074 TALLOC_FREE(conn->netlogon_creds); 2075 1771 2076 if (conn->cli) { 1772 2077 cli_shutdown(conn->cli); … … 1782 2087 1783 2088 for (domain = domain_list(); domain; domain = domain->next) { 1784 struct cli_state *cli = domain->conn.cli;1785 1786 2089 /* 1787 2090 * first close the low level SMB TCP connection … … 1789 2092 * requests in invalidate_cm_connection() 1790 2093 */ 1791 if (cli && cli->fd != -1) { 1792 close(domain->conn.cli->fd); 1793 domain->conn.cli->fd = -1; 1794 } 1795 1796 invalidate_cm_connection(&domain->conn); 2094 if (cli_state_is_connected(domain->conn.cli)) { 2095 smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK); 2096 } 2097 2098 invalidate_cm_connection(domain); 1797 2099 } 1798 2100 … … 1829 2131 Bypass online status check so always does network calls. */ 1830 2132 1831 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain )2133 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain, bool need_rw_dc) 1832 2134 { 1833 2135 NTSTATUS result; 2136 bool skip_connection = domain->internal; 2137 if (need_rw_dc && domain->rodc) { 2138 skip_connection = false; 2139 } 1834 2140 1835 2141 /* Internal connections never use the network. */ 1836 if (dom ain->internal) {1837 domain->initialized = True;1838 return NT_STATUS_OK;1839 } 1840 1841 if ( connection_ok(domain)) {2142 if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) { 2143 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 2144 } 2145 2146 /* Still ask the internal LSA and SAMR server about the local domain */ 2147 if (skip_connection || connection_ok(domain)) { 1842 2148 if (!domain->initialized) { 1843 2149 set_dc_type_and_flags(domain); … … 1846 2152 } 1847 2153 1848 invalidate_cm_connection(&domain->conn); 2154 invalidate_cm_connection(domain); 2155 2156 if (!domain->primary && !domain->initialized) { 2157 /* 2158 * Before we connect to a trust, work out if it is an 2159 * AD domain by asking our own domain. 2160 */ 2161 set_dc_type_and_flags_trustinfo(domain); 2162 } 1849 2163 1850 2164 result = cm_open_connection(domain, &domain->conn); … … 1857 2171 } 1858 2172 1859 NTSTATUS init_dc_connection(struct winbindd_domain *domain )1860 { 1861 if (dom ain->internal) {2173 NTSTATUS init_dc_connection(struct winbindd_domain *domain, bool need_rw_dc) 2174 { 2175 if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) { 1862 2176 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 1863 2177 } … … 1868 2182 } 1869 2183 1870 return init_dc_connection_network(domain );1871 } 1872 1873 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain )2184 return init_dc_connection_network(domain, need_rw_dc); 2185 } 2186 2187 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain, bool need_rw_dc) 1874 2188 { 1875 2189 NTSTATUS status; 1876 2190 1877 status = init_dc_connection(domain );2191 status = init_dc_connection(domain, need_rw_dc); 1878 2192 if (!NT_STATUS_IS_OK(status)) { 1879 2193 return status; … … 1899 2213 struct netr_DomainTrustList trusts; 1900 2214 int i; 1901 uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |2215 uint32_t flags = (NETR_TRUST_FLAG_IN_FOREST | 1902 2216 NETR_TRUST_FLAG_OUTBOUND | 1903 2217 NETR_TRUST_FLAG_INBOUND); … … 1914 2228 } 1915 2229 2230 mem_ctx = talloc_stackframe(); 1916 2231 our_domain = find_our_domain(); 1917 1918 if ( !connection_ok(our_domain) ) { 1919 DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n")); 2232 if (our_domain->internal) { 2233 result = init_dc_connection(our_domain, false); 2234 if (!NT_STATUS_IS_OK(result)) { 2235 DEBUG(3,("set_dc_type_and_flags_trustinfo: " 2236 "Not able to make a connection to our domain: %s\n", 2237 nt_errstr(result))); 2238 TALLOC_FREE(mem_ctx); 2239 return false; 2240 } 2241 } 2242 2243 /* This won't work unless our domain is AD */ 2244 if ( !our_domain->active_directory ) { 2245 TALLOC_FREE(mem_ctx); 1920 2246 return False; 1921 2247 } 1922 2248 1923 /* This won't work unless our domain is AD */ 1924 1925 if ( !our_domain->active_directory ) { 2249 if (our_domain->internal) { 2250 result = wb_open_internal_pipe(mem_ctx, &ndr_table_netlogon, &cli); 2251 } else if (!connection_ok(our_domain)) { 2252 DEBUG(3,("set_dc_type_and_flags_trustinfo: " 2253 "No connection to our domain!\n")); 2254 TALLOC_FREE(mem_ctx); 1926 2255 return False; 1927 } 1928 1929 /* Use DsEnumerateDomainTrusts to get us the trust direction 1930 and type */ 1931 1932 result = cm_connect_netlogon(our_domain, &cli); 2256 } else { 2257 result = cm_connect_netlogon(our_domain, &cli); 2258 } 1933 2259 1934 2260 if (!NT_STATUS_IS_OK(result)) { … … 1936 2262 "a connection to %s for PIPE_NETLOGON (%s)\n", 1937 2263 domain->name, nt_errstr(result))); 2264 TALLOC_FREE(mem_ctx); 1938 2265 return False; 1939 2266 } 1940 1941 2267 b = cli->binding_handle; 1942 2268 1943 if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) { 1944 DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n")); 1945 return False; 1946 } 1947 2269 /* Use DsEnumerateDomainTrusts to get us the trust direction and type. */ 1948 2270 result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx, 1949 2271 cli->desthost, … … 1955 2277 "failed to query trusted domain list: %s\n", 1956 2278 nt_errstr(result))); 1957 talloc_destroy(mem_ctx);2279 TALLOC_FREE(mem_ctx); 1958 2280 return false; 1959 2281 } … … 1962 2284 "failed to query trusted domain list: %s\n", 1963 2285 win_errstr(werr))); 1964 talloc_destroy(mem_ctx);2286 TALLOC_FREE(mem_ctx); 1965 2287 return false; 1966 2288 } … … 1974 2296 domain->domain_trust_attribs = trusts.array[i].trust_attributes; 1975 2297 1976 if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )2298 if ( domain->domain_type == LSA_TRUST_TYPE_UPLEVEL ) 1977 2299 domain->active_directory = True; 1978 2300 … … 1992 2314 1993 2315 domain->can_do_ncacn_ip_tcp = domain->active_directory; 1994 domain->can_do_validation6 = domain->active_directory;1995 2316 1996 2317 domain->initialized = True; … … 2000 2321 } 2001 2322 2002 talloc_destroy( mem_ctx);2323 TALLOC_FREE(mem_ctx); 2003 2324 2004 2325 return domain->initialized; … … 2023 2344 union lsa_PolicyInformation *lsa_info = NULL; 2024 2345 2025 if (! connection_ok(domain)) {2346 if (!domain->internal && !connection_ok(domain)) { 2026 2347 return; 2027 2348 } … … 2036 2357 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name )); 2037 2358 2038 status = cli_rpc_pipe_open_noauth(domain->conn.cli, 2039 &ndr_table_dssetup.syntax_id, 2040 &cli); 2359 if (domain->internal) { 2360 status = wb_open_internal_pipe(mem_ctx, 2361 &ndr_table_dssetup, 2362 &cli); 2363 } else { 2364 status = cli_rpc_pipe_open_noauth(domain->conn.cli, 2365 &ndr_table_dssetup, 2366 &cli); 2367 } 2041 2368 2042 2369 if (!NT_STATUS_IS_OK(status)) { … … 2087 2414 2088 2415 no_dssetup: 2089 status = cli_rpc_pipe_open_noauth(domain->conn.cli, 2090 &ndr_table_lsarpc.syntax_id, &cli); 2091 2416 if (domain->internal) { 2417 status = wb_open_internal_pipe(mem_ctx, 2418 &ndr_table_lsarpc, 2419 &cli); 2420 } else { 2421 status = cli_rpc_pipe_open_noauth(domain->conn.cli, 2422 &ndr_table_lsarpc, &cli); 2423 } 2092 2424 if (!NT_STATUS_IS_OK(status)) { 2093 2425 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to " … … 2116 2448 2117 2449 if (lsa_info->dns.name.string) { 2118 fstrcpy(domain->name, lsa_info->dns.name.string); 2450 if (!strequal(domain->name, lsa_info->dns.name.string)) 2451 { 2452 DEBUG(1, ("set_dc_type_and_flags_connect: DC " 2453 "for domain %s claimed it was a DC " 2454 "for domain %s, refusing to " 2455 "initialize\n", 2456 domain->name, 2457 lsa_info->dns.name.string)); 2458 TALLOC_FREE(cli); 2459 TALLOC_FREE(mem_ctx); 2460 return; 2461 } 2462 talloc_free(domain->name); 2463 domain->name = talloc_strdup(domain, 2464 lsa_info->dns.name.string); 2465 if (domain->name == NULL) { 2466 goto done; 2467 } 2119 2468 } 2120 2469 2121 2470 if (lsa_info->dns.dns_domain.string) { 2122 fstrcpy(domain->alt_name, 2123 lsa_info->dns.dns_domain.string); 2471 if (domain->alt_name != NULL && 2472 !strequal(domain->alt_name, 2473 lsa_info->dns.dns_domain.string)) 2474 { 2475 DEBUG(1, ("set_dc_type_and_flags_connect: DC " 2476 "for domain %s (%s) claimed it was " 2477 "a DC for domain %s, refusing to " 2478 "initialize\n", 2479 domain->alt_name, domain->name, 2480 lsa_info->dns.dns_domain.string)); 2481 TALLOC_FREE(cli); 2482 TALLOC_FREE(mem_ctx); 2483 return; 2484 } 2485 talloc_free(domain->alt_name); 2486 domain->alt_name = 2487 talloc_strdup(domain, 2488 lsa_info->dns.dns_domain.string); 2489 if (domain->alt_name == NULL) { 2490 goto done; 2491 } 2124 2492 } 2125 2493 … … 2128 2496 2129 2497 if (lsa_info->dns.dns_forest.string) { 2130 fstrcpy(domain->forest_name, 2131 lsa_info->dns.dns_forest.string); 2498 talloc_free(domain->forest_name); 2499 domain->forest_name = 2500 talloc_strdup(domain, 2501 lsa_info->dns.dns_forest.string); 2502 if (domain->forest_name == NULL) { 2503 goto done; 2504 } 2132 2505 2133 2506 if (strequal(domain->forest_name, domain->alt_name)) { … … 2137 2510 2138 2511 if (lsa_info->dns.sid) { 2512 if (!is_null_sid(&domain->sid) && 2513 !dom_sid_equal(&domain->sid, 2514 lsa_info->dns.sid)) 2515 { 2516 DEBUG(1, ("set_dc_type_and_flags_connect: DC " 2517 "for domain %s (%s) claimed it was " 2518 "a DC for domain %s, refusing to " 2519 "initialize\n", 2520 dom_sid_string(talloc_tos(), 2521 &domain->sid), 2522 domain->name, 2523 dom_sid_string(talloc_tos(), 2524 lsa_info->dns.sid))); 2525 TALLOC_FREE(cli); 2526 TALLOC_FREE(mem_ctx); 2527 return; 2528 } 2139 2529 sid_copy(&domain->sid, lsa_info->dns.sid); 2140 2530 } … … 2158 2548 2159 2549 if (lsa_info->account_domain.name.string) { 2160 fstrcpy(domain->name, 2161 lsa_info->account_domain.name.string); 2550 if (!strequal(domain->name, 2551 lsa_info->account_domain.name.string)) 2552 { 2553 DEBUG(1, 2554 ("set_dc_type_and_flags_connect: " 2555 "DC for domain %s claimed it was" 2556 " a DC for domain %s, refusing " 2557 "to initialize\n", domain->name, 2558 lsa_info-> 2559 account_domain.name.string)); 2560 TALLOC_FREE(cli); 2561 TALLOC_FREE(mem_ctx); 2562 return; 2563 } 2564 talloc_free(domain->name); 2565 domain->name = 2566 talloc_strdup(domain, 2567 lsa_info->account_domain.name.string); 2162 2568 } 2163 2569 2164 2570 if (lsa_info->account_domain.sid) { 2571 if (!is_null_sid(&domain->sid) && 2572 !dom_sid_equal(&domain->sid, 2573 lsa_info->account_domain.sid)) 2574 { 2575 DEBUG(1, 2576 ("set_dc_type_and_flags_connect: " 2577 "DC for domain %s (%s) claimed " 2578 "it was a DC for domain %s, " 2579 "refusing to initialize\n", 2580 dom_sid_string(talloc_tos(), 2581 &domain->sid), 2582 domain->name, 2583 dom_sid_string(talloc_tos(), 2584 lsa_info->account_domain.sid))); 2585 TALLOC_FREE(cli); 2586 TALLOC_FREE(mem_ctx); 2587 return; 2588 } 2165 2589 sid_copy(&domain->sid, lsa_info->account_domain.sid); 2166 2590 } … … 2176 2600 2177 2601 domain->can_do_ncacn_ip_tcp = domain->active_directory; 2178 domain->can_do_validation6 = domain->active_directory;2179 2602 2180 2603 TALLOC_FREE(cli); … … 2193 2616 /* we always have to contact our primary domain */ 2194 2617 2195 if ( domain->primary ) {2618 if ( domain->primary || domain->internal) { 2196 2619 DEBUG(10,("set_dc_type_and_flags: setting up flags for " 2197 "primary domain\n"));2620 "primary or internal domain\n")); 2198 2621 set_dc_type_and_flags_connect( domain ); 2199 2622 return; … … 2217 2640 2218 2641 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain, 2219 struct netlogon_creds_ CredentialState**ppdc)2642 struct netlogon_creds_cli_context **ppdc) 2220 2643 { 2221 2644 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 2222 2645 struct rpc_pipe_client *netlogon_pipe; 2223 2646 2224 if (lp_client_schannel() == False) { 2225 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 2647 *ppdc = NULL; 2648 2649 if ((!IS_DC) && (!domain->primary)) { 2650 return NT_STATUS_TRUSTED_DOMAIN_FAILURE; 2651 } 2652 2653 if (domain->conn.netlogon_creds != NULL) { 2654 if (!(domain->conn.netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) { 2655 return NT_STATUS_TRUSTED_DOMAIN_FAILURE; 2656 } 2657 *ppdc = domain->conn.netlogon_creds; 2658 return NT_STATUS_OK; 2226 2659 } 2227 2660 … … 2231 2664 } 2232 2665 2233 /* Return a pointer to the struct netlogon_creds_CredentialState from the 2234 netlogon pipe. */ 2235 2236 if (!domain->conn.netlogon_pipe->dc) { 2237 return NT_STATUS_INTERNAL_ERROR; /* This shouldn't happen. */ 2238 } 2239 2240 *ppdc = domain->conn.netlogon_pipe->dc; 2666 if (domain->conn.netlogon_creds == NULL) { 2667 return NT_STATUS_TRUSTED_DOMAIN_FAILURE; 2668 } 2669 2670 if (!(domain->conn.netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) { 2671 return NT_STATUS_TRUSTED_DOMAIN_FAILURE; 2672 } 2673 2674 *ppdc = domain->conn.netlogon_creds; 2241 2675 return NT_STATUS_OK; 2242 2676 } 2243 2677 2244 2678 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, 2679 bool need_rw_dc, 2245 2680 struct rpc_pipe_client **cli, struct policy_handle *sam_handle) 2246 2681 { 2247 2682 struct winbindd_cm_conn *conn; 2248 2683 NTSTATUS status, result; 2249 struct netlogon_creds_CredentialState *p_creds; 2250 char *machine_password = NULL; 2251 char *machine_account = NULL; 2252 char *domain_name = NULL; 2253 2254 if (sid_check_is_domain(&domain->sid)) { 2255 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle); 2256 } 2257 2258 status = init_dc_connection_rpc(domain); 2684 struct netlogon_creds_cli_context *p_creds; 2685 struct cli_credentials *creds = NULL; 2686 bool retry = false; /* allow one retry attempt for expired session */ 2687 2688 if (sid_check_is_our_sam(&domain->sid)) { 2689 if (domain->rodc == false || need_rw_dc == false) { 2690 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle); 2691 } 2692 } 2693 2694 retry: 2695 status = init_dc_connection_rpc(domain, need_rw_dc); 2259 2696 if (!NT_STATUS_IS_OK(status)) { 2260 2697 return status; … … 2276 2713 */ 2277 2714 2278 if ((conn->cli->user_name[0] == '\0') || 2279 (conn->cli->domain[0] == '\0') || 2280 (conn->cli->password == NULL || conn->cli->password[0] == '\0')) 2281 { 2282 status = get_trust_creds(domain, &machine_password, 2283 &machine_account, NULL); 2284 if (!NT_STATUS_IS_OK(status)) { 2285 DEBUG(10, ("cm_connect_sam: No no user available for " 2286 "domain %s, trying schannel\n", conn->cli->domain)); 2287 goto schannel; 2288 } 2289 domain_name = domain->name; 2290 } else { 2291 machine_password = SMB_STRDUP(conn->cli->password); 2292 machine_account = SMB_STRDUP(conn->cli->user_name); 2293 domain_name = conn->cli->domain; 2294 } 2295 2296 if (!machine_password || !machine_account) { 2297 status = NT_STATUS_NO_MEMORY; 2298 goto done; 2299 } 2300 2301 /* We have an authenticated connection. Use a NTLMSSP SPNEGO 2302 authenticated SAMR pipe with sign & seal. */ 2303 status = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli, 2304 &ndr_table_samr.syntax_id, 2305 NCACN_NP, 2306 DCERPC_AUTH_LEVEL_PRIVACY, 2307 domain_name, 2308 machine_account, 2309 machine_password, 2310 &conn->samr_pipe); 2715 result = get_trust_credentials(domain, talloc_tos(), false, &creds); 2716 if (!NT_STATUS_IS_OK(result)) { 2717 DEBUG(10, ("cm_connect_sam: No user available for " 2718 "domain %s, trying schannel\n", domain->name)); 2719 goto schannel; 2720 } 2721 2722 if (cli_credentials_is_anonymous(creds)) { 2723 goto anonymous; 2724 } 2725 2726 /* 2727 * We have an authenticated connection. Use a SPNEGO 2728 * authenticated SAMR pipe with sign & seal. 2729 */ 2730 status = cli_rpc_pipe_open_with_creds(conn->cli, 2731 &ndr_table_samr, 2732 NCACN_NP, 2733 DCERPC_AUTH_TYPE_SPNEGO, 2734 conn->auth_level, 2735 smbXcli_conn_remote_name(conn->cli->conn), 2736 creds, 2737 &conn->samr_pipe); 2738 2739 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED) 2740 && !retry) { 2741 invalidate_cm_connection(domain); 2742 retry = true; 2743 goto retry; 2744 } 2311 2745 2312 2746 if (!NT_STATUS_IS_OK(status)) { 2313 2747 DEBUG(10,("cm_connect_sam: failed to connect to SAMR " 2314 2748 "pipe for domain %s using NTLMSSP " 2315 "authenticated pipe: user %s\\%s. Error was " 2316 "%s\n", domain->name, domain_name, 2317 machine_account, nt_errstr(status))); 2749 "authenticated pipe: user %s. Error was " 2750 "%s\n", domain->name, 2751 cli_credentials_get_unparsed_name(creds, talloc_tos()), 2752 nt_errstr(status))); 2318 2753 goto schannel; 2319 2754 } … … 2321 2756 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for " 2322 2757 "domain %s using NTLMSSP authenticated " 2323 "pipe: user %s\ \%s\n", domain->name,2324 domain_name, machine_account));2758 "pipe: user %s\n", domain->name, 2759 cli_credentials_get_unparsed_name(creds, talloc_tos()))); 2325 2760 2326 2761 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx, … … 2329 2764 &conn->sam_connect_handle, 2330 2765 &result); 2766 2767 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) { 2768 invalidate_cm_connection(domain); 2769 TALLOC_FREE(conn->samr_pipe); 2770 retry = true; 2771 goto retry; 2772 } 2773 2331 2774 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) { 2332 2775 goto open_domain; … … 2354 2797 goto anonymous; 2355 2798 } 2356 status = cli_rpc_pipe_open_schannel_with_key 2357 (conn->cli, &ndr_table_samr.syntax_id, NCACN_NP, 2358 DCERPC_AUTH_LEVEL_PRIVACY, 2359 domain->name, &p_creds, &conn->samr_pipe); 2799 TALLOC_FREE(creds); 2800 result = get_trust_credentials(domain, talloc_tos(), true, &creds); 2801 if (!NT_STATUS_IS_OK(result)) { 2802 DEBUG(10, ("cm_connect_sam: No user available for " 2803 "domain %s (error %s), trying anon\n", domain->name, 2804 nt_errstr(result))); 2805 goto anonymous; 2806 } 2807 status = cli_rpc_pipe_open_schannel_with_creds 2808 (conn->cli, &ndr_table_samr, NCACN_NP, 2809 creds, p_creds, &conn->samr_pipe); 2810 2811 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED) 2812 && !retry) { 2813 invalidate_cm_connection(domain); 2814 retry = true; 2815 goto retry; 2816 } 2360 2817 2361 2818 if (!NT_STATUS_IS_OK(status)) { … … 2373 2830 &conn->sam_connect_handle, 2374 2831 &result); 2832 2833 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) { 2834 invalidate_cm_connection(domain); 2835 TALLOC_FREE(conn->samr_pipe); 2836 retry = true; 2837 goto retry; 2838 } 2839 2375 2840 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) { 2376 2841 goto open_domain; … … 2385 2850 2386 2851 anonymous: 2387 if (lp_winbind_sealed_pipes() && (IS_DC || domain->primary)) { 2852 2853 /* Finally fall back to anonymous. */ 2854 if (lp_winbind_sealed_pipes() || lp_require_strong_key()) { 2388 2855 status = NT_STATUS_DOWNGRADE_DETECTED; 2389 DEBUG(1, ("Unwilling to make SAMR connection to domain %s 2856 DEBUG(1, ("Unwilling to make SAMR connection to domain %s" 2390 2857 "without connection level security, " 2391 "must set 'winbind sealed pipes = false' "2392 " to proceed: %s\n",2858 "must set 'winbind sealed pipes = false' and " 2859 "'require strong key = false' to proceed: %s\n", 2393 2860 domain->name, nt_errstr(status))); 2394 2861 goto done; 2395 2862 } 2396 2397 /* Finally fall back to anonymous. */ 2398 status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id, 2863 status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr, 2399 2864 &conn->samr_pipe); 2865 2866 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED) 2867 && !retry) { 2868 invalidate_cm_connection(domain); 2869 retry = true; 2870 goto retry; 2871 } 2400 2872 2401 2873 if (!NT_STATUS_IS_OK(status)) { … … 2408 2880 &conn->sam_connect_handle, 2409 2881 &result); 2882 2883 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) { 2884 invalidate_cm_connection(domain); 2885 TALLOC_FREE(conn->samr_pipe); 2886 retry = true; 2887 goto retry; 2888 } 2889 2410 2890 if (!NT_STATUS_IS_OK(status)) { 2411 2891 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed " … … 2449 2929 return status; 2450 2930 } else if (!NT_STATUS_IS_OK(status)) { 2451 invalidate_cm_connection( conn);2931 invalidate_cm_connection(domain); 2452 2932 return status; 2453 2933 } … … 2455 2935 *cli = conn->samr_pipe; 2456 2936 *sam_handle = conn->sam_domain_handle; 2457 SAFE_FREE(machine_password);2458 SAFE_FREE(machine_account);2459 2937 return status; 2460 2938 } … … 2464 2942 ***********************************************************************/ 2465 2943 2466 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,2467 2468 2944 static NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain, 2945 TALLOC_CTX *mem_ctx, 2946 struct rpc_pipe_client **cli) 2469 2947 { 2470 2948 struct winbindd_cm_conn *conn; 2471 struct netlogon_creds_CredentialState *creds; 2949 struct netlogon_creds_cli_context *p_creds = NULL; 2950 struct cli_credentials *creds = NULL; 2472 2951 NTSTATUS status; 2473 2952 2474 2953 DEBUG(10,("cm_connect_lsa_tcp\n")); 2475 2954 2476 status = init_dc_connection_rpc(domain );2955 status = init_dc_connection_rpc(domain, false); 2477 2956 if (!NT_STATUS_IS_OK(status)) { 2478 2957 return status; … … 2483 2962 if (conn->lsa_pipe_tcp && 2484 2963 conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP && 2485 conn->lsa_pipe_tcp->auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY &&2964 conn->lsa_pipe_tcp->auth->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY && 2486 2965 rpccli_is_connected(conn->lsa_pipe_tcp)) { 2487 2966 goto done; … … 2490 2969 TALLOC_FREE(conn->lsa_pipe_tcp); 2491 2970 2492 status = cm_get_schannel_creds(domain, & creds);2971 status = cm_get_schannel_creds(domain, &p_creds); 2493 2972 if (!NT_STATUS_IS_OK(status)) { 2494 2973 goto done; 2495 2974 } 2496 2975 2497 status = cli_rpc_pipe_open_schannel_with_key(conn->cli, 2498 &ndr_table_lsarpc.syntax_id, 2499 NCACN_IP_TCP, 2500 DCERPC_AUTH_LEVEL_PRIVACY, 2501 domain->name, 2502 &creds, 2503 &conn->lsa_pipe_tcp); 2976 status = get_trust_credentials(domain, talloc_tos(), true, &creds); 2977 if (!NT_STATUS_IS_OK(status)) { 2978 goto done; 2979 } 2980 2981 status = cli_rpc_pipe_open_schannel_with_creds(conn->cli, 2982 &ndr_table_lsarpc, 2983 NCACN_IP_TCP, 2984 creds, 2985 p_creds, 2986 &conn->lsa_pipe_tcp); 2504 2987 if (!NT_STATUS_IS_OK(status)) { 2505 2988 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n", … … 2524 3007 struct winbindd_cm_conn *conn; 2525 3008 NTSTATUS result = NT_STATUS_UNSUCCESSFUL; 2526 struct netlogon_creds_CredentialState *p_creds; 2527 2528 result = init_dc_connection_rpc(domain); 3009 struct netlogon_creds_cli_context *p_creds; 3010 struct cli_credentials *creds = NULL; 3011 bool retry = false; /* allow one retry attempt for expired session */ 3012 3013 retry: 3014 result = init_dc_connection_rpc(domain, false); 2529 3015 if (!NT_STATUS_IS_OK(result)) 2530 3016 return result; … … 2538 3024 TALLOC_FREE(conn->lsa_pipe); 2539 3025 2540 if ((conn->cli->user_name[0] == '\0') || 2541 (conn->cli->domain[0] == '\0') || 2542 (conn->cli->password == NULL || conn->cli->password[0] == '\0')) { 2543 DEBUG(10, ("cm_connect_lsa: No no user available for " 2544 "domain %s, trying schannel\n", conn->cli->domain)); 3026 result = get_trust_credentials(domain, talloc_tos(), false, &creds); 3027 if (!NT_STATUS_IS_OK(result)) { 3028 DEBUG(10, ("cm_connect_lsa: No user available for " 3029 "domain %s, trying schannel\n", domain->name)); 2545 3030 goto schannel; 2546 3031 } 2547 3032 2548 /* We have an authenticated connection. Use a NTLMSSP SPNEGO 2549 * authenticated LSA pipe with sign & seal. */ 2550 result = cli_rpc_pipe_open_spnego_ntlmssp 2551 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP, 2552 DCERPC_AUTH_LEVEL_PRIVACY, 2553 conn->cli->domain, conn->cli->user_name, conn->cli->password, 3033 if (cli_credentials_is_anonymous(creds)) { 3034 goto anonymous; 3035 } 3036 3037 /* 3038 * We have an authenticated connection. Use a SPNEGO 3039 * authenticated LSA pipe with sign & seal. 3040 */ 3041 result = cli_rpc_pipe_open_with_creds 3042 (conn->cli, &ndr_table_lsarpc, NCACN_NP, 3043 DCERPC_AUTH_TYPE_SPNEGO, 3044 conn->auth_level, 3045 smbXcli_conn_remote_name(conn->cli->conn), 3046 creds, 2554 3047 &conn->lsa_pipe); 3048 3049 if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED) 3050 && !retry) { 3051 invalidate_cm_connection(domain); 3052 retry = true; 3053 goto retry; 3054 } 2555 3055 2556 3056 if (!NT_STATUS_IS_OK(result)) { 2557 3057 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for " 2558 3058 "domain %s using NTLMSSP authenticated pipe: user " 2559 "%s\\%s. Error was %s. Trying schannel.\n", 2560 domain->name, conn->cli->domain, 2561 conn->cli->user_name, nt_errstr(result))); 3059 "%s. Error was %s. Trying schannel.\n", 3060 domain->name, 3061 cli_credentials_get_unparsed_name(creds, talloc_tos()), 3062 nt_errstr(result))); 2562 3063 goto schannel; 2563 3064 } 2564 3065 2565 3066 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using " 2566 "NTLMSSP authenticated pipe: user %s\ \%s\n",2567 domain->name, c onn->cli->domain, conn->cli->user_name));3067 "NTLMSSP authenticated pipe: user %s\n", 3068 domain->name, cli_credentials_get_unparsed_name(creds, talloc_tos()))); 2568 3069 2569 3070 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True, 2570 3071 SEC_FLAG_MAXIMUM_ALLOWED, 2571 3072 &conn->lsa_policy); 3073 if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) { 3074 invalidate_cm_connection(domain); 3075 TALLOC_FREE(conn->lsa_pipe); 3076 retry = true; 3077 goto retry; 3078 } 3079 2572 3080 if (NT_STATUS_IS_OK(result)) { 2573 3081 goto done; … … 2592 3100 goto anonymous; 2593 3101 } 2594 result = cli_rpc_pipe_open_schannel_with_key 2595 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP, 2596 DCERPC_AUTH_LEVEL_PRIVACY, 2597 domain->name, &p_creds, &conn->lsa_pipe); 3102 3103 TALLOC_FREE(creds); 3104 result = get_trust_credentials(domain, talloc_tos(), true, &creds); 3105 if (!NT_STATUS_IS_OK(result)) { 3106 DEBUG(10, ("cm_connect_lsa: No user available for " 3107 "domain %s (error %s), trying anon\n", domain->name, 3108 nt_errstr(result))); 3109 goto anonymous; 3110 } 3111 result = cli_rpc_pipe_open_schannel_with_creds 3112 (conn->cli, &ndr_table_lsarpc, NCACN_NP, 3113 creds, p_creds, &conn->lsa_pipe); 3114 3115 if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED) 3116 && !retry) { 3117 invalidate_cm_connection(domain); 3118 retry = true; 3119 goto retry; 3120 } 2598 3121 2599 3122 if (!NT_STATUS_IS_OK(result)) { … … 2609 3132 SEC_FLAG_MAXIMUM_ALLOWED, 2610 3133 &conn->lsa_policy); 3134 3135 if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) { 3136 invalidate_cm_connection(domain); 3137 TALLOC_FREE(conn->lsa_pipe); 3138 retry = true; 3139 goto retry; 3140 } 3141 2611 3142 if (NT_STATUS_IS_OK(result)) { 2612 3143 goto done; … … 2620 3151 anonymous: 2621 3152 2622 if (lp_winbind_sealed_pipes() && (IS_DC || domain->primary)) {3153 if (lp_winbind_sealed_pipes() || lp_require_strong_key()) { 2623 3154 result = NT_STATUS_DOWNGRADE_DETECTED; 2624 3155 DEBUG(1, ("Unwilling to make LSA connection to domain %s " 2625 3156 "without connection level security, " 2626 "must set 'winbind sealed pipes = false' "2627 " to proceed: %s\n",3157 "must set 'winbind sealed pipes = false' and " 3158 "'require strong key = false' to proceed: %s\n", 2628 3159 domain->name, nt_errstr(result))); 2629 3160 goto done; … … 2631 3162 2632 3163 result = cli_rpc_pipe_open_noauth(conn->cli, 2633 &ndr_table_lsarpc .syntax_id,3164 &ndr_table_lsarpc, 2634 3165 &conn->lsa_pipe); 3166 3167 if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED) 3168 && !retry) { 3169 invalidate_cm_connection(domain); 3170 retry = true; 3171 goto retry; 3172 } 3173 2635 3174 if (!NT_STATUS_IS_OK(result)) { 2636 result = NT_STATUS_PIPE_NOT_AVAILABLE;2637 3175 goto done; 2638 3176 } … … 2641 3179 SEC_FLAG_MAXIMUM_ALLOWED, 2642 3180 &conn->lsa_policy); 3181 3182 if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) { 3183 invalidate_cm_connection(domain); 3184 TALLOC_FREE(conn->lsa_pipe); 3185 retry = true; 3186 goto retry; 3187 } 3188 2643 3189 done: 2644 3190 if (!NT_STATUS_IS_OK(result)) { 2645 invalidate_cm_connection( conn);3191 invalidate_cm_connection(domain); 2646 3192 return result; 2647 3193 } … … 2668 3214 NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) || 2669 3215 NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) { 2670 invalidate_cm_connection( &domain->conn);3216 invalidate_cm_connection(domain); 2671 3217 status = cm_connect_lsa_tcp(domain, mem_ctx, cli); 2672 3218 } … … 2679 3225 * failed - maybe it is a trusted domain we can't connect to ? 2680 3226 * do not try tcp next time - gd 3227 * 3228 * This also prevents NETLOGON over TCP 2681 3229 */ 2682 3230 domain->can_do_ncacn_ip_tcp = false; … … 2693 3241 ****************************************************************************/ 2694 3242 2695 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, 2696 struct rpc_pipe_client **cli) 2697 { 3243 static NTSTATUS cm_connect_netlogon_transport(struct winbindd_domain *domain, 3244 enum dcerpc_transport_t transport, 3245 struct rpc_pipe_client **cli) 3246 { 3247 struct messaging_context *msg_ctx = winbind_messaging_context(); 2698 3248 struct winbindd_cm_conn *conn; 2699 3249 NTSTATUS result; 2700 2701 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;2702 uint8 mach_pwd[16];2703 3250 enum netr_SchannelType sec_chan_type; 2704 const char *account_name;2705 struct rpc_pipe_client *netlogon_pipe= NULL;3251 struct netlogon_creds_CredentialState *netlogon_creds = NULL; 3252 struct cli_credentials *creds = NULL; 2706 3253 2707 3254 *cli = NULL; 2708 3255 2709 result = init_dc_connection_rpc(domain );3256 result = init_dc_connection_rpc(domain, domain->rodc); 2710 3257 if (!NT_STATUS_IS_OK(result)) { 2711 3258 return result; … … 2720 3267 2721 3268 TALLOC_FREE(conn->netlogon_pipe); 2722 2723 result = cli_rpc_pipe_open_noauth(conn->cli,2724 &ndr_table_netlogon.syntax_id, 2725 &netlogon_pipe);3269 conn->netlogon_flags = 0; 3270 TALLOC_FREE(conn->netlogon_creds); 3271 3272 result = get_trust_credentials(domain, talloc_tos(), true, &creds); 2726 3273 if (!NT_STATUS_IS_OK(result)) { 3274 DEBUG(10, ("cm_connect_sam: No user available for " 3275 "domain %s when trying schannel\n", domain->name)); 3276 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 3277 } 3278 3279 if (cli_credentials_is_anonymous(creds)) { 3280 DEBUG(1, ("get_trust_credential only gave anonymous for %s, unable to make get NETLOGON credentials\n", 3281 domain->name)); 3282 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 3283 } 3284 3285 sec_chan_type = cli_credentials_get_secure_channel_type(creds); 3286 if (sec_chan_type == SEC_CHAN_NULL) { 3287 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 3288 } 3289 3290 result = rpccli_create_netlogon_creds_with_creds(creds, 3291 domain->dcname, 3292 msg_ctx, 3293 domain, 3294 &conn->netlogon_creds); 3295 if (!NT_STATUS_IS_OK(result)) { 3296 DEBUG(1, ("rpccli_create_netlogon_creds failed for %s, " 3297 "unable to create NETLOGON credentials: %s\n", 3298 domain->name, nt_errstr(result))); 2727 3299 return result; 2728 3300 } 2729 3301 2730 if ((!IS_DC) && (!domain->primary)) { 2731 /* Clear the schannel request bit and drop down */ 2732 neg_flags &= ~NETLOGON_NEG_SCHANNEL; 2733 goto no_schannel; 2734 } 2735 2736 if (lp_client_schannel() != False) { 2737 neg_flags |= NETLOGON_NEG_SCHANNEL; 2738 } 2739 2740 if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name, 2741 &sec_chan_type)) 2742 { 2743 TALLOC_FREE(netlogon_pipe); 2744 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 2745 } 2746 2747 result = rpccli_netlogon_setup_creds( 2748 netlogon_pipe, 2749 domain->dcname, /* server name. */ 2750 domain->name, /* domain name */ 2751 global_myname(), /* client name */ 2752 account_name, /* machine account */ 2753 mach_pwd, /* machine password */ 2754 sec_chan_type, /* from get_trust_pw */ 2755 &neg_flags); 2756 3302 result = rpccli_setup_netlogon_creds_with_creds(conn->cli, transport, 3303 conn->netlogon_creds, 3304 conn->netlogon_force_reauth, 3305 creds); 3306 conn->netlogon_force_reauth = false; 2757 3307 if (!NT_STATUS_IS_OK(result)) { 2758 TALLOC_FREE(netlogon_pipe); 3308 DEBUG(1, ("rpccli_setup_netlogon_creds failed for %s, " 3309 "unable to setup NETLOGON credentials: %s\n", 3310 domain->name, nt_errstr(result))); 2759 3311 return result; 2760 3312 } 2761 3313 2762 if ((lp_client_schannel() == True) && 2763 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) { 2764 DEBUG(3, ("Server did not offer schannel\n")); 2765 TALLOC_FREE(netlogon_pipe); 2766 return NT_STATUS_ACCESS_DENIED; 2767 } 2768 2769 no_schannel: 2770 if ((lp_client_schannel() == False) || 2771 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) { 2772 if (lp_winbind_sealed_pipes() && (IS_DC || domain->primary)) { 3314 result = netlogon_creds_cli_get(conn->netlogon_creds, 3315 talloc_tos(), 3316 &netlogon_creds); 3317 if (!NT_STATUS_IS_OK(result)) { 3318 DEBUG(1, ("netlogon_creds_cli_get failed for %s, " 3319 "unable to get NETLOGON credentials: %s\n", 3320 domain->name, nt_errstr(result))); 3321 return result; 3322 } 3323 conn->netlogon_flags = netlogon_creds->negotiate_flags; 3324 TALLOC_FREE(netlogon_creds); 3325 3326 if (!(conn->netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) { 3327 if (lp_winbind_sealed_pipes() || lp_require_strong_key()) { 2773 3328 result = NT_STATUS_DOWNGRADE_DETECTED; 2774 DEBUG(1, ("Unwilling to make connection to domain %s 3329 DEBUG(1, ("Unwilling to make connection to domain %s" 2775 3330 "without connection level security, " 2776 "must set 'winbind sealed pipes = false' "2777 " to proceed: %s\n",3331 "must set 'winbind sealed pipes = false' and " 3332 "'require strong key = false' to proceed: %s\n", 2778 3333 domain->name, nt_errstr(result))); 2779 TALLOC_FREE(netlogon_pipe); 2780 invalidate_cm_connection(conn); 3334 invalidate_cm_connection(domain); 2781 3335 return result; 2782 3336 } 2783 /* 2784 * NetSamLogonEx only works for schannel 2785 */ 2786 domain->can_do_samlogon_ex = False; 2787 2788 /* We're done - just keep the existing connection to NETLOGON 2789 * open */ 2790 conn->netlogon_pipe = netlogon_pipe; 3337 result = cli_rpc_pipe_open_noauth_transport(conn->cli, 3338 transport, 3339 &ndr_table_netlogon, 3340 &conn->netlogon_pipe); 3341 if (!NT_STATUS_IS_OK(result)) { 3342 invalidate_cm_connection(domain); 3343 return result; 3344 } 3345 2791 3346 *cli = conn->netlogon_pipe; 2792 3347 return NT_STATUS_OK; … … 2798 3353 */ 2799 3354 2800 result = cli_rpc_pipe_open_schannel_with_key( 2801 conn->cli, &ndr_table_netlogon.syntax_id, NCACN_NP, 2802 DCERPC_AUTH_LEVEL_PRIVACY, domain->name, &netlogon_pipe->dc, 3355 result = cli_rpc_pipe_open_schannel_with_creds( 3356 conn->cli, &ndr_table_netlogon, transport, 3357 creds, 3358 conn->netlogon_creds, 2803 3359 &conn->netlogon_pipe); 2804 2805 /* We can now close the initial netlogon pipe. */2806 TALLOC_FREE(netlogon_pipe);2807 2808 3360 if (!NT_STATUS_IS_OK(result)) { 2809 3361 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error " 2810 3362 "was %s\n", nt_errstr(result))); 2811 3363 2812 invalidate_cm_connection( conn);3364 invalidate_cm_connection(domain); 2813 3365 return result; 2814 3366 } 2815 2816 /*2817 * Always try netr_LogonSamLogonEx. We will fall back for NT42818 * which gives DCERPC_FAULT_OP_RNG_ERROR (function not2819 * supported). We used to only try SamLogonEx for AD, but2820 * Samba DCs can also do it. And because we don't distinguish2821 * between Samba and NT4, always try it once.2822 */2823 domain->can_do_samlogon_ex = true;2824 3367 2825 3368 *cli = conn->netlogon_pipe; 2826 3369 return NT_STATUS_OK; 3370 } 3371 3372 /**************************************************************************** 3373 Open a LSA connection to a DC, suiteable for LSA lookup calls. 3374 ****************************************************************************/ 3375 3376 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, 3377 struct rpc_pipe_client **cli) 3378 { 3379 NTSTATUS status; 3380 3381 status = init_dc_connection_rpc(domain, domain->rodc); 3382 if (!NT_STATUS_IS_OK(status)) { 3383 return status; 3384 } 3385 3386 if (domain->active_directory && domain->can_do_ncacn_ip_tcp) { 3387 status = cm_connect_netlogon_transport(domain, NCACN_IP_TCP, cli); 3388 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) || 3389 NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) || 3390 NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) { 3391 invalidate_cm_connection(domain); 3392 status = cm_connect_netlogon_transport(domain, NCACN_IP_TCP, cli); 3393 } 3394 if (NT_STATUS_IS_OK(status)) { 3395 return status; 3396 } 3397 3398 /* 3399 * we tried twice to connect via ncan_ip_tcp and schannel and 3400 * failed - maybe it is a trusted domain we can't connect to ? 3401 * do not try tcp next time - gd 3402 * 3403 * This also prevents LSA over TCP 3404 */ 3405 domain->can_do_ncacn_ip_tcp = false; 3406 } 3407 3408 status = cm_connect_netlogon_transport(domain, NCACN_NP, cli); 3409 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) { 3410 /* 3411 * SMB2 session expired, needs reauthentication. Drop 3412 * connection and retry. 3413 */ 3414 invalidate_cm_connection(domain); 3415 status = cm_connect_netlogon_transport(domain, NCACN_NP, cli); 3416 } 3417 3418 return status; 2827 3419 } 2828 3420 … … 2872 3464 for (domain = domain_list(); domain != NULL; domain = domain->next) { 2873 3465 char sockaddr[INET6_ADDRSTRLEN]; 2874 if (domain->conn.cli == NULL) { 3466 3467 if (!cli_state_is_connected(domain->conn.cli)) { 2875 3468 continue; 2876 3469 } 2877 if (domain->conn.cli->fd == -1) { 2878 continue; 2879 } 2880 client_socket_addr(domain->conn.cli->fd, sockaddr, 2881 sizeof(sockaddr)); 3470 3471 print_sockaddr(sockaddr, sizeof(sockaddr), 3472 smbXcli_conn_local_sockaddr(domain->conn.cli->conn)); 3473 2882 3474 if (strequal(sockaddr, addr)) { 2883 close(domain->conn.cli->fd); 2884 domain->conn.cli->fd = -1; 3475 smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK); 2885 3476 } 2886 3477 } -
vendor/current/source3/winbindd/winbindd_cred_cache.c
r746 r988 39 39 40 40 static struct WINBINDD_CCACHE_ENTRY *ccache_list; 41 static void krb5_ticket_gain_handler(struct event_context *,42 struct t imed_event*,41 static void krb5_ticket_gain_handler(struct tevent_context *, 42 struct tevent_timer *, 43 43 struct timeval, 44 44 void *); … … 105 105 ****************************************************************/ 106 106 107 static void krb5_ticket_refresh_handler(struct event_context *event_ctx,108 struct t imed_event*te,107 static void krb5_ticket_refresh_handler(struct tevent_context *event_ctx, 108 struct tevent_timer *te, 109 109 struct timeval now, 110 110 void *private_data) … … 286 286 entry->refresh_time = new_start; 287 287 } 288 entry->event = event_add_timed(winbind_event_context(), entry,288 entry->event = tevent_add_timer(winbind_event_context(), entry, 289 289 timeval_set(new_start, 0), 290 290 krb5_ticket_refresh_handler, … … 298 298 ****************************************************************/ 299 299 300 static void krb5_ticket_gain_handler(struct event_context *event_ctx,301 struct t imed_event*te,300 static void krb5_ticket_gain_handler(struct tevent_context *event_ctx, 301 struct tevent_timer *te, 302 302 struct timeval now, 303 303 void *private_data) … … 386 386 entry->refresh_time = t.tv_sec; 387 387 } 388 entry->event = event_add_timed(winbind_event_context(),388 entry->event = tevent_add_timer(winbind_event_context(), 389 389 entry, 390 390 t, … … 405 405 { 406 406 entry->refresh_time = 0; 407 entry->event = event_add_timed(winbind_event_context(),407 entry->event = tevent_add_timer(winbind_event_context(), 408 408 entry, 409 409 t, … … 418 418 419 419 for (cur = ccache_list; cur; cur = cur->next) { 420 struct t imed_event*new_event;420 struct tevent_timer *new_event; 421 421 422 422 /* … … 425 425 */ 426 426 if (cur->refresh_time == 0) { 427 new_event = event_add_timed(winbind_event_context(),427 new_event = tevent_add_timer(winbind_event_context(), 428 428 cur, 429 429 t, … … 431 431 cur); 432 432 } else { 433 new_event = event_add_timed(winbind_event_context(),433 new_event = tevent_add_timer(winbind_event_context(), 434 434 cur, 435 435 t, … … 502 502 struct timeval t; 503 503 NTSTATUS ntret; 504 #ifdef HAVE_KRB5505 int ret;506 #endif507 504 508 505 if ((username == NULL && princ_name == NULL) || … … 516 513 return NT_STATUS_NO_MORE_ENTRIES; 517 514 } 518 519 /* If it is cached login, destroy krb5 ticket520 * to avoid surprise. */521 #ifdef HAVE_KRB5522 if (postponed_request) {523 /* ignore KRB5_FCC_NOFILE error here */524 ret = ads_kdestroy(ccname);525 if (ret == KRB5_FCC_NOFILE) {526 ret = 0;527 }528 if (ret) {529 DEBUG(0, ("add_ccache_to_list: failed to destroy "530 "user krb5 ccache %s with %s\n", ccname,531 error_message(ret)));532 return krb5_to_nt_status(ret);533 }534 DEBUG(10, ("add_ccache_to_list: successfully destroyed "535 "krb5 ccache %s for user %s\n", ccname,536 username));537 }538 #endif539 515 540 516 /* Reference count old entries */ … … 572 548 entry->refresh_time = t.tv_sec; 573 549 } 574 entry->event = event_add_timed(winbind_event_context(),550 entry->event = tevent_add_timer(winbind_event_context(), 575 551 entry, 576 552 t, … … 612 588 } 613 589 614 entry = TALLOC_P(NULL, struct WINBINDD_CCACHE_ENTRY);590 entry = talloc(NULL, struct WINBINDD_CCACHE_ENTRY); 615 591 if (!entry) { 616 592 return NT_STATUS_NO_MEMORY; … … 670 646 entry->refresh_time = t.tv_sec; 671 647 } 672 entry->event = event_add_timed(winbind_event_context(),648 entry->event = tevent_add_timer(winbind_event_context(), 673 649 entry, 674 650 t, … … 847 823 #endif 848 824 849 /* Create and store the password hashes. */850 E_md4hash(pass, memcredp->nt_hash);851 E_deshash(pass, memcredp->lm_hash);852 853 825 if (pass) { 826 /* Create and store the password hashes. */ 827 E_md4hash(pass, memcredp->nt_hash); 828 E_deshash(pass, memcredp->lm_hash); 829 854 830 memcredp->pass = (char *)memcredp->lm_hash + LM_HASH_LEN; 855 831 memcpy(memcredp->pass, pass, … … 938 914 } 939 915 940 memcredp = TALLOC_ZERO_P(NULL, struct WINBINDD_MEMORY_CREDS);916 memcredp = talloc_zero(NULL, struct WINBINDD_MEMORY_CREDS); 941 917 if (!memcredp) { 942 918 return NT_STATUS_NO_MEMORY; -
vendor/current/source3/winbindd/winbindd_creds.c
r740 r988 33 33 const struct dom_sid *sid, 34 34 struct netr_SamInfo3 **info3, 35 const uint8 *cached_nt_pass[NT_HASH_LEN],36 const uint8 *cred_salt[NT_HASH_LEN])35 const uint8_t *cached_nt_pass[NT_HASH_LEN], 36 const uint8_t *cred_salt[NT_HASH_LEN]) 37 37 { 38 38 struct netr_SamInfo3 *info; -
vendor/current/source3/winbindd/winbindd_dsgetdcname.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 24 24 struct winbindd_dsgetdcname_state { … … 58 58 request->data.dsgetdcname.domain_name)); 59 59 60 ds_flags = get_dsgetdc_flags(request-> flags);60 ds_flags = get_dsgetdc_flags(request->data.dsgetdcname.flags); 61 61 62 62 status = GUID_from_string(request->data.dsgetdcname.domain_guid, … … 102 102 struct winbindd_dsgetdcname_state *state = tevent_req_data( 103 103 req, struct winbindd_dsgetdcname_state); 104 struct GUID_txt_buf guid_str_buf; 104 105 char *guid_str; 105 106 NTSTATUS status; … … 110 111 } 111 112 112 guid_str = GUID_string(talloc_tos(), &state->dc_info->domain_guid);113 if (guid_str == NULL) {114 return NT_STATUS_NO_MEMORY;115 }116 113 117 114 fstrcpy(response->data.dsgetdcname.dc_unc, … … 121 118 response->data.dsgetdcname.dc_address_type = 122 119 state->dc_info->dc_address_type; 120 121 guid_str = GUID_buf_string(&state->dc_info->domain_guid, 122 &guid_str_buf); 123 123 fstrcpy(response->data.dsgetdcname.domain_guid, guid_str); 124 TALLOC_FREE(guid_str); 124 125 125 fstrcpy(response->data.dsgetdcname.domain_name, 126 126 state->dc_info->domain_name); -
vendor/current/source3/winbindd/winbindd_dual.c
r860 r988 30 30 #include "includes.h" 31 31 #include "winbindd.h" 32 #include "rpc_client/rpc_client.h" 32 33 #include "nsswitch/wb_reqtrans.h" 33 34 #include "secrets.h" … … 37 38 #include "messages.h" 38 39 #include "../lib/util/tevent_unix.h" 40 #include "lib/param/loadparm.h" 41 #include "lib/util/sys_rw.h" 42 #include "lib/util/sys_rw_data.h" 39 43 40 44 #undef DBGC_CLASS … … 42 46 43 47 extern bool override_logfile; 44 extern struct winbindd_methods cache_methods;45 48 46 49 static struct winbindd_child *winbindd_children = NULL; … … 48 51 /* Read some data from a client connection */ 49 52 50 static NTSTATUS child_read_request( struct winbindd_cli_state *state)53 static NTSTATUS child_read_request(int sock, struct winbindd_request *wreq) 51 54 { 52 55 NTSTATUS status; 53 56 54 /* Read data */ 55 56 status = read_data(state->sock, (char *)state->request, 57 sizeof(*state->request)); 58 57 status = read_data_ntstatus(sock, (char *)wreq, sizeof(*wreq)); 59 58 if (!NT_STATUS_IS_OK(status)) { 60 59 DEBUG(3, ("child_read_request: read_data failed: %s\n", … … 63 62 } 64 63 65 if ( state->request->extra_len == 0) {66 state->request->extra_data.data = NULL;64 if (wreq->extra_len == 0) { 65 wreq->extra_data.data = NULL; 67 66 return NT_STATUS_OK; 68 67 } 69 68 70 DEBUG(10, ("Need to read %d extra bytes\n", (int)state->request->extra_len)); 71 72 state->request->extra_data.data = 73 SMB_MALLOC_ARRAY(char, state->request->extra_len + 1); 74 75 if (state->request->extra_data.data == NULL) { 69 DEBUG(10, ("Need to read %d extra bytes\n", (int)wreq->extra_len)); 70 71 wreq->extra_data.data = SMB_MALLOC_ARRAY(char, wreq->extra_len + 1); 72 if (wreq->extra_data.data == NULL) { 76 73 DEBUG(0, ("malloc failed\n")); 77 74 return NT_STATUS_NO_MEMORY; … … 79 76 80 77 /* Ensure null termination */ 81 state->request->extra_data.data[state->request->extra_len] = '\0'; 82 83 status= read_data(state->sock, state->request->extra_data.data, 84 state->request->extra_len); 85 78 wreq->extra_data.data[wreq->extra_len] = '\0'; 79 80 status = read_data_ntstatus(sock, wreq->extra_data.data, 81 wreq->extra_len); 86 82 if (!NT_STATUS_IS_OK(status)) { 87 83 DEBUG(0, ("Could not read extra data: %s\n", … … 89 85 } 90 86 return status; 87 } 88 89 static NTSTATUS child_write_response(int sock, struct winbindd_response *wrsp) 90 { 91 struct iovec iov[2]; 92 int iov_count; 93 94 iov[0].iov_base = (void *)wrsp; 95 iov[0].iov_len = sizeof(struct winbindd_response); 96 iov_count = 1; 97 98 if (wrsp->length > sizeof(struct winbindd_response)) { 99 iov[1].iov_base = (void *)wrsp->extra_data.data; 100 iov[1].iov_len = wrsp->length-iov[0].iov_len; 101 iov_count = 2; 102 } 103 104 DEBUG(10, ("Writing %d bytes to parent\n", (int)wrsp->length)); 105 106 if (write_data_iov(sock, iov, iov_count) != wrsp->length) { 107 DEBUG(0, ("Could not write result\n")); 108 return NT_STATUS_INVALID_HANDLE; 109 } 110 111 return NT_STATUS_OK; 91 112 } 92 113 … … 99 120 struct wb_child_request_state { 100 121 struct tevent_context *ev; 122 struct tevent_req *subreq; 101 123 struct winbindd_child *child; 102 124 struct winbindd_request *request; … … 110 132 static void wb_child_request_done(struct tevent_req *subreq); 111 133 134 static void wb_child_request_cleanup(struct tevent_req *req, 135 enum tevent_req_state req_state); 136 112 137 struct tevent_req *wb_child_request_send(TALLOC_CTX *mem_ctx, 113 138 struct tevent_context *ev, … … 130 155 if (!tevent_queue_add(child->queue, ev, req, 131 156 wb_child_request_trigger, NULL)) { 132 tevent_req_ nomem(NULL,req);157 tevent_req_oom(req); 133 158 return tevent_req_post(req, ev); 134 159 } 160 161 tevent_req_set_cleanup_fn(req, wb_child_request_cleanup); 162 135 163 return req; 136 164 } … … 153 181 return; 154 182 } 183 184 state->subreq = subreq; 155 185 tevent_req_set_callback(subreq, wb_child_request_done, req); 156 186 tevent_req_set_endtime(req, state->ev, timeval_current_ofs(300, 0)); … … 166 196 167 197 ret = wb_simple_trans_recv(subreq, state, &state->response, &err); 168 TALLOC_FREE(subreq); 198 /* Freeing the subrequest is deferred until the cleanup function, 199 * which has to know whether a subrequest exists, and consequently 200 * decide whether to shut down the pipe to the child process. 201 */ 169 202 if (ret == -1) { 170 /*171 * The basic parent/child communication broke, close172 * our socket173 */174 close(state->child->sock);175 state->child->sock = -1;176 DLIST_REMOVE(winbindd_children, state->child);177 203 tevent_req_error(req, err); 178 204 return; … … 192 218 *presponse = talloc_move(mem_ctx, &state->response); 193 219 return 0; 220 } 221 222 static void wb_child_request_cleanup(struct tevent_req *req, 223 enum tevent_req_state req_state) 224 { 225 struct wb_child_request_state *state = 226 tevent_req_data(req, struct wb_child_request_state); 227 228 if (state->subreq == NULL) { 229 /* nothing to cleanup */ 230 return; 231 } 232 233 TALLOC_FREE(state->subreq); 234 235 if (req_state == TEVENT_REQ_DONE) { 236 /* transmitted request and got response */ 237 return; 238 } 239 240 /* 241 * Failed to transmit and receive response, or request 242 * cancelled while being serviced. 243 * The basic parent/child communication broke, close 244 * our socket 245 */ 246 close(state->child->sock); 247 state->child->sock = -1; 248 DLIST_REMOVE(winbindd_children, state->child); 194 249 } 195 250 … … 369 424 return; 370 425 } 371 fstrcpy(state->domain->name, response->data.domain_info.name); 372 fstrcpy(state->domain->alt_name, response->data.domain_info.alt_name); 426 427 talloc_free(state->domain->name); 428 state->domain->name = talloc_strdup(state->domain, 429 response->data.domain_info.name); 430 if (state->domain->name == NULL) { 431 tevent_req_error(req, ENOMEM); 432 return; 433 } 434 435 if (response->data.domain_info.alt_name[0] != '\0') { 436 talloc_free(state->domain->alt_name); 437 438 state->domain->alt_name = talloc_strdup(state->domain, 439 response->data.domain_info.alt_name); 440 if (state->domain->alt_name == NULL) { 441 tevent_req_error(req, ENOMEM); 442 return; 443 } 444 } 445 373 446 state->domain->native_mode = response->data.domain_info.native_mode; 374 447 state->domain->active_directory = … … 456 529 char *logbase = NULL; 457 530 458 if (*lp_logfile( )) {531 if (*lp_logfile(talloc_tos())) { 459 532 char *end = NULL; 460 533 461 if (asprintf(&logbase, "%s", lp_logfile( )) < 0) {534 if (asprintf(&logbase, "%s", lp_logfile(talloc_tos())) < 0) { 462 535 smb_panic("Internal error: asprintf failed"); 463 536 } … … 524 597 { 525 598 flush_negative_conn_cache_for_domain(domain->name); 526 if ( *domain->alt_name) {599 if (domain->alt_name != NULL) { 527 600 flush_negative_conn_cache_for_domain(domain->alt_name); 528 601 } … … 608 681 609 682 DEBUG(10,("winbind_msg_offline: sending message to pid %u for domain %s.\n", 610 (unsigned int)child->pid, domain->name ));683 (unsigned int)child->pid, child->domain->name )); 611 684 612 685 messaging_send_buf(msg_ctx, pid_to_procid(child->pid), 613 686 MSG_WINBIND_OFFLINE, 614 ( uint8*)child->domain->name,687 (const uint8_t *)child->domain->name, 615 688 strlen(child->domain->name)+1); 616 689 } … … 661 734 pid_to_procid(idmap->pid), 662 735 MSG_WINBIND_ONLINE, 663 ( uint8*)domain->name,736 (const uint8_t *)domain->name, 664 737 strlen(domain->name)+1); 665 738 } … … 686 759 messaging_send_buf(msg_ctx, pid_to_procid(child->pid), 687 760 MSG_WINBIND_ONLINE, 688 ( uint8*)child->domain->name,761 (const uint8_t *)child->domain->name, 689 762 strlen(child->domain->name)+1); 690 763 } … … 748 821 749 822 messaging_send_buf(msg_ctx, *sender, MSG_WINBIND_ONLINESTATUS, 750 ( uint8*)message, strlen(message) + 1);823 (const uint8_t *)message, strlen(message) + 1); 751 824 752 825 talloc_destroy(mem_ctx); … … 825 898 messaging_send_buf(msg_ctx, *sender, 826 899 MSG_WINBIND_DUMP_DOMAIN_LIST, 827 ( uint8_t *)message, strlen(message) + 1);900 (const uint8_t *)message, strlen(message) + 1); 828 901 829 902 talloc_destroy(mem_ctx); … … 859 932 } 860 933 861 static void account_lockout_policy_handler(struct event_context *ctx,862 struct t imed_event*te,934 static void account_lockout_policy_handler(struct tevent_context *ctx, 935 struct tevent_timer *te, 863 936 struct timeval now, 864 937 void *private_data) … … 898 971 } 899 972 900 child->lockout_policy_event = event_add_timed(winbind_event_context(), NULL,973 child->lockout_policy_event = tevent_add_timer(winbind_event_context(), NULL, 901 974 timeval_current_ofs(3600, 0), 902 975 account_lockout_policy_handler, … … 976 1049 } 977 1050 978 static void machine_password_change_handler(struct event_context *ctx,979 struct t imed_event*te,1051 static void machine_password_change_handler(struct tevent_context *ctx, 1052 struct tevent_timer *te, 980 1053 struct timeval now, 981 1054 void *private_data) 982 1055 { 1056 struct messaging_context *msg_ctx = winbind_messaging_context(); 983 1057 struct winbindd_child *child = 984 1058 (struct winbindd_child *)private_data; 985 1059 struct rpc_pipe_client *netlogon_pipe = NULL; 986 TALLOC_CTX *frame;987 1060 NTSTATUS result; 988 1061 struct timeval next_change; … … 1021 1094 } 1022 1095 1023 frame = talloc_stackframe(); 1024 1025 result = trust_pw_find_change_and_store_it(netlogon_pipe, 1026 frame, 1027 child->domain->name); 1028 TALLOC_FREE(frame); 1096 result = trust_pw_change(child->domain->conn.netlogon_creds, 1097 msg_ctx, 1098 netlogon_pipe->binding_handle, 1099 child->domain->name, 1100 false); /* force */ 1029 1101 1030 1102 DEBUG(10, ("machine_password_change_handler: " 1031 "trust_pw_ find_change_and_store_itreturned %s\n",1103 "trust_pw_change returned %s\n", 1032 1104 nt_errstr(result))); 1033 1105 … … 1038 1110 "Killing connections to domain %s\n", 1039 1111 child->domain->name)); 1040 TALLOC_FREE(child->domain->conn.netlogon_pipe);1112 invalidate_cm_connection(child->domain); 1041 1113 } 1042 1114 … … 1060 1132 1061 1133 done: 1062 child->machine_password_change_event = event_add_timed(winbind_event_context(), NULL,1134 child->machine_password_change_event = tevent_add_timer(winbind_event_context(), NULL, 1063 1135 next_change, 1064 1136 machine_password_change_handler, … … 1183 1255 winbind_messaging_context(), 1184 1256 winbind_event_context(), 1185 procid_self(), 1186 true); 1257 true, NULL); 1187 1258 if (!NT_STATUS_IS_OK(status)) { 1188 1259 DEBUG(0,("reinit_after_fork() failed\n")); … … 1295 1366 } 1296 1367 1368 struct child_handler_state { 1369 struct winbindd_child *child; 1370 struct winbindd_cli_state cli; 1371 }; 1372 1373 static void child_handler(struct tevent_context *ev, struct tevent_fd *fde, 1374 uint16_t flags, void *private_data) 1375 { 1376 struct child_handler_state *state = 1377 (struct child_handler_state *)private_data; 1378 NTSTATUS status; 1379 1380 /* fetch a request from the main daemon */ 1381 status = child_read_request(state->cli.sock, state->cli.request); 1382 1383 if (!NT_STATUS_IS_OK(status)) { 1384 /* we lost contact with our parent */ 1385 _exit(0); 1386 } 1387 1388 DEBUG(4,("child daemon request %d\n", 1389 (int)state->cli.request->cmd)); 1390 1391 ZERO_STRUCTP(state->cli.response); 1392 state->cli.request->null_term = '\0'; 1393 state->cli.mem_ctx = talloc_tos(); 1394 child_process_request(state->child, &state->cli); 1395 1396 DEBUG(4, ("Finished processing child request %d\n", 1397 (int)state->cli.request->cmd)); 1398 1399 SAFE_FREE(state->cli.request->extra_data.data); 1400 1401 status = child_write_response(state->cli.sock, state->cli.response); 1402 if (!NT_STATUS_IS_OK(status)) { 1403 exit(1); 1404 } 1405 } 1406 1297 1407 static bool fork_domain_child(struct winbindd_child *child) 1298 1408 { 1299 1409 int fdpair[2]; 1300 struct winbindd_cli_state state;1410 struct child_handler_state state; 1301 1411 struct winbindd_request request; 1302 1412 struct winbindd_response response; … … 1304 1414 NTSTATUS status; 1305 1415 ssize_t nwritten; 1416 struct tevent_fd *fde; 1306 1417 1307 1418 if (child->domain) { … … 1319 1430 1320 1431 ZERO_STRUCT(state); 1321 state.pid = sys_getpid(); 1322 state.request = &request; 1323 state.response = &response; 1324 1325 child->pid = sys_fork(); 1432 state.child = child; 1433 state.cli.pid = getpid(); 1434 state.cli.request = &request; 1435 state.cli.response = &response; 1436 1437 child->pid = fork(); 1326 1438 1327 1439 if (child->pid == -1) { 1328 1440 DEBUG(0, ("Could not fork: %s\n", strerror(errno))); 1441 close(fdpair[0]); 1442 close(fdpair[1]); 1329 1443 return False; 1330 1444 } … … 1360 1474 child_domain = child->domain; 1361 1475 1362 DEBUG(10, ("Child process %d\n", (int) sys_getpid()));1363 1364 state. sock = fdpair[0];1476 DEBUG(10, ("Child process %d\n", (int)getpid())); 1477 1478 state.cli.sock = fdpair[0]; 1365 1479 close(fdpair[1]); 1366 1480 1367 1481 status = winbindd_reinit_after_fork(child, child->logfilename); 1368 1482 1369 nwritten = sys_write(state. sock, &status, sizeof(status));1483 nwritten = sys_write(state.cli.sock, &status, sizeof(status)); 1370 1484 if (nwritten != sizeof(status)) { 1371 1485 DEBUG(1, ("fork_domain_child: Could not write status: " … … 1444 1558 } 1445 1559 1446 child->lockout_policy_event = event_add_timed(1560 child->lockout_policy_event = tevent_add_timer( 1447 1561 winbind_event_context(), NULL, timeval_zero(), 1448 1562 account_lockout_policy_handler, … … 1458 1572 if (calculate_next_machine_pwd_change(child->domain->name, 1459 1573 &next_change)) { 1460 child->machine_password_change_event = event_add_timed(1574 child->machine_password_change_event = tevent_add_timer( 1461 1575 winbind_event_context(), NULL, next_change, 1462 1576 machine_password_change_handler, … … 1465 1579 } 1466 1580 1581 fde = tevent_add_fd(winbind_event_context(), NULL, state.cli.sock, 1582 TEVENT_FD_READ, child_handler, &state); 1583 if (fde == NULL) { 1584 DEBUG(1, ("tevent_add_fd failed\n")); 1585 _exit(1); 1586 } 1587 1467 1588 while (1) { 1468 1589 1469 1590 int ret; 1470 struct pollfd *pfds;1471 int num_pfds;1472 int timeout;1473 struct timeval t;1474 struct timeval *tp;1475 1591 TALLOC_CTX *frame = talloc_stackframe(); 1476 struct iovec iov[2]; 1477 int iov_count;1478 1479 if (run_events_poll(winbind_event_context(), 0, NULL, 0)) {1480 TALLOC_FREE(frame);1481 continue;1592 1593 ret = tevent_loop_once(winbind_event_context()); 1594 if (ret != 0) { 1595 DEBUG(1, ("tevent_loop_once failed: %s\n", 1596 strerror(errno))); 1597 _exit(1); 1482 1598 } 1483 1599 … … 1490 1606 } 1491 1607 1492 pfds = TALLOC_ZERO_P(talloc_tos(), struct pollfd);1493 if (pfds == NULL) {1494 DEBUG(1, ("talloc failed\n"));1495 _exit(1);1496 }1497 1498 pfds->fd = state.sock;1499 pfds->events = POLLIN|POLLHUP;1500 num_pfds = 1;1501 1502 timeout = INT_MAX;1503 1504 if (!event_add_to_poll_args(1505 winbind_event_context(), talloc_tos(),1506 &pfds, &num_pfds, &timeout)) {1507 DEBUG(1, ("event_add_to_poll_args failed\n"));1508 _exit(1);1509 }1510 tp = get_timed_events_timeout(winbind_event_context(), &t);1511 if (tp) {1512 DEBUG(11,("select will use timeout of %u.%u seconds\n",1513 (unsigned int)tp->tv_sec, (unsigned int)tp->tv_usec ));1514 }1515 1516 ret = sys_poll(pfds, num_pfds, timeout);1517 1518 if (run_events_poll(winbind_event_context(), ret,1519 pfds, num_pfds)) {1520 /* We got a signal - continue. */1521 TALLOC_FREE(frame);1522 continue;1523 }1524 1525 TALLOC_FREE(pfds);1526 1527 if (ret == 0) {1528 DEBUG(11,("nothing is ready yet, continue\n"));1529 TALLOC_FREE(frame);1530 continue;1531 }1532 1533 if (ret == -1 && errno == EINTR) {1534 /* We got a signal - continue. */1535 TALLOC_FREE(frame);1536 continue;1537 }1538 1539 if (ret == -1 && errno != EINTR) {1540 DEBUG(0,("poll error occured\n"));1541 TALLOC_FREE(frame);1542 perror("poll");1543 _exit(1);1544 }1545 1546 /* fetch a request from the main daemon */1547 status = child_read_request(&state);1548 1549 if (!NT_STATUS_IS_OK(status)) {1550 /* we lost contact with our parent */1551 _exit(0);1552 }1553 1554 DEBUG(4,("child daemon request %d\n", (int)state.request->cmd));1555 1556 ZERO_STRUCTP(state.response);1557 state.request->null_term = '\0';1558 state.mem_ctx = frame;1559 child_process_request(child, &state);1560 1561 DEBUG(4, ("Finished processing child request %d\n",1562 (int)state.request->cmd));1563 1564 SAFE_FREE(state.request->extra_data.data);1565 1566 iov[0].iov_base = (void *)state.response;1567 iov[0].iov_len = sizeof(struct winbindd_response);1568 iov_count = 1;1569 1570 if (state.response->length > sizeof(struct winbindd_response)) {1571 iov[1].iov_base =1572 (void *)state.response->extra_data.data;1573 iov[1].iov_len = state.response->length-iov[0].iov_len;1574 iov_count = 2;1575 }1576 1577 DEBUG(10, ("Writing %d bytes to parent\n",1578 (int)state.response->length));1579 1580 if (write_data_iov(state.sock, iov, iov_count) !=1581 state.response->length) {1582 DEBUG(0, ("Could not write result\n"));1583 exit(1);1584 }1585 1608 TALLOC_FREE(frame); 1586 1609 } -
vendor/current/source3/winbindd/winbindd_dual_ndr.c
r740 r988 31 31 #include "winbindd/winbindd_proto.h" 32 32 #include "ntdomain.h" 33 #include "librpc/gen_ndr/srv_w bint.h"33 #include "librpc/gen_ndr/srv_winbind.h" 34 34 35 35 struct wbint_bh_state { … … 97 97 ok = wbint_bh_is_connected(h); 98 98 if (!ok) { 99 tevent_req_nterror(req, NT_STATUS_ INVALID_CONNECTION);99 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED); 100 100 return tevent_req_post(req, ev); 101 101 } … … 145 145 state->response->length - sizeof(struct winbindd_response)); 146 146 if (state->response->extra_data.data && !state->out_data.data) { 147 tevent_req_ nomem(NULL,req);147 tevent_req_oom(req); 148 148 return; 149 149 } … … 202 202 ok = wbint_bh_is_connected(h); 203 203 if (!ok) { 204 tevent_req_nterror(req, NT_STATUS_ INVALID_CONNECTION);204 tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED); 205 205 return tevent_req_post(req, ev); 206 206 } … … 284 284 &wbint_bh_ops, 285 285 NULL, 286 &ndr_table_w bint,286 &ndr_table_winbind, 287 287 &hs, 288 288 struct wbint_bh_state, … … 305 305 bool ret; 306 306 307 w bint_get_pipe_fns(&fns, &num_fns);307 winbind_get_pipe_fns(&fns, &num_fns); 308 308 309 309 if (state->request->data.ndrcmd >= num_fns) { -
vendor/current/source3/winbindd/winbindd_dual_srv.c
r740 r988 26 26 #include "rpc_client/cli_pipe.h" 27 27 #include "ntdomain.h" 28 #include "librpc/gen_ndr/srv_w bint.h"28 #include "librpc/gen_ndr/srv_winbind.h" 29 29 #include "../librpc/gen_ndr/ndr_netlogon_c.h" 30 #include "../librpc/gen_ndr/ndr_lsa_c.h" 30 31 #include "idmap.h" 31 32 #include "../libcli/security/security.h" 33 #include "../libcli/auth/netlogon_creds_cli.h" 34 #include "passdb.h" 35 #include "../source4/dsdb/samdb/samdb.h" 32 36 33 37 void _wbint_Ping(struct pipes_struct *p, struct wbint_Ping *r) … … 40 44 { 41 45 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { 42 invalidate_cm_connection( &domain->conn);46 invalidate_cm_connection(domain); 43 47 /* We invalidated the connection. */ 44 48 return true; … … 75 79 { 76 80 struct winbindd_domain *domain = wb_child_domain(); 81 struct lsa_RefDomainList *domains = r->out.domains; 77 82 NTSTATUS status; 78 83 … … 88 93 */ 89 94 status = rpc_lookup_sids(p->mem_ctx, domain, r->in.sids, 90 &r->out.domains, &r->out.names); 95 &domains, &r->out.names); 96 97 if (domains != NULL) { 98 r->out.domains = domains; 99 } 100 91 101 reset_cm_connection_on_error(domain, status); 92 102 return status; … … 107 117 reset_cm_connection_on_error(domain, status); 108 118 return status; 109 }110 111 NTSTATUS _wbint_Sid2Uid(struct pipes_struct *p, struct wbint_Sid2Uid *r)112 {113 uid_t uid;114 NTSTATUS status;115 116 status = idmap_sid_to_uid(r->in.dom_name ? r->in.dom_name : "",117 r->in.sid, &uid);118 if (!NT_STATUS_IS_OK(status)) {119 return status;120 }121 *r->out.uid = uid;122 return NT_STATUS_OK;123 }124 125 NTSTATUS _wbint_Sid2Gid(struct pipes_struct *p, struct wbint_Sid2Gid *r)126 {127 gid_t gid;128 NTSTATUS status;129 130 status = idmap_sid_to_gid(r->in.dom_name ? r->in.dom_name : "",131 r->in.sid, &gid);132 if (!NT_STATUS_IS_OK(status)) {133 return status;134 }135 *r->out.gid = gid;136 return NT_STATUS_OK;137 119 } 138 120 … … 152 134 uint32_t num_ids; 153 135 154 dom = idmap_find_domain (d->name.string);136 dom = idmap_find_domain_with_sid(d->name.string, d->sid); 155 137 if (dom == NULL) { 156 DEBUG(10, ("idmap domain %s not found\n",157 d->name.string ));138 DEBUG(10, ("idmap domain %s:%s not found\n", 139 d->name.string, sid_string_dbg(d->sid))); 158 140 continue; 159 141 } … … 167 149 } 168 150 169 ids = TALLOC_REALLOC_ARRAY(talloc_tos(), ids,151 ids = talloc_realloc(talloc_tos(), ids, 170 152 struct id_map, num_ids); 171 153 if (ids == NULL) { 172 154 goto nomem; 173 155 } 174 id_ptrs = TALLOC_REALLOC_ARRAY(talloc_tos(), id_ptrs,156 id_ptrs = talloc_realloc(talloc_tos(), id_ptrs, 175 157 struct id_map *, num_ids+1); 176 158 if (id_ptrs == NULL) { 177 159 goto nomem; 178 160 } 179 id_idx = TALLOC_REALLOC_ARRAY(talloc_tos(), id_idx,161 id_idx = talloc_realloc(talloc_tos(), id_idx, 180 162 uint32_t, num_ids); 181 163 if (id_idx == NULL) { 182 164 goto nomem; 183 165 } 184 sids = TALLOC_REALLOC_ARRAY(talloc_tos(), sids,166 sids = talloc_realloc(talloc_tos(), sids, 185 167 struct dom_sid, num_ids); 186 168 if (sids == NULL) { … … 190 172 num_ids = 0; 191 173 174 /* 175 * Convert the input data into a list of 176 * id_map structs suitable for handing in 177 * to the idmap sids_to_unixids method. 178 */ 192 179 for (j=0; j<r->in.ids->num_ids; j++) { 193 180 struct wbint_TransID *id = &r->in.ids->ids[j]; … … 211 198 nt_errstr(status))); 212 199 200 /* 201 * Extract the results for handing them back to the caller. 202 */ 213 203 for (j=0; j<num_ids; j++) { 214 204 struct wbint_TransID *id = &r->in.ids->ids[id_idx[j]]; 215 205 216 206 if (ids[j].status != ID_MAPPED) { 207 id->xid.id = UINT32_MAX; 208 id->xid.type = ID_TYPE_NOT_SPECIFIED; 217 209 continue; 218 210 } 219 id->unix_id = ids[j].xid.id; 211 212 id->xid = ids[j].xid; 220 213 } 221 214 } … … 231 224 NTSTATUS _wbint_Uid2Sid(struct pipes_struct *p, struct wbint_Uid2Sid *r) 232 225 { 233 return idmap_uid_to_sid(r->in.dom_name ? r->in.dom_name : "", 234 r->out.sid, r->in.uid); 226 return idmap_uid_to_sid(r->out.sid, r->in.uid); 235 227 } 236 228 237 229 NTSTATUS _wbint_Gid2Sid(struct pipes_struct *p, struct wbint_Gid2Sid *r) 238 230 { 239 return idmap_gid_to_sid(r->in.dom_name ? r->in.dom_name : "", 240 r->out.sid, r->in.gid); 231 return idmap_gid_to_sid(r->out.sid, r->in.gid); 241 232 } 242 233 … … 391 382 { 392 383 struct winbindd_domain *domain = wb_child_domain(); 393 uint32_t i, num_groups; 394 struct wb_acct_info *groups; 384 uint32_t i; 385 uint32_t num_local_groups = 0; 386 struct wb_acct_info *local_groups = NULL; 387 uint32_t num_dom_groups = 0; 388 struct wb_acct_info *dom_groups = NULL; 389 uint32_t ti = 0; 390 uint64_t num_total = 0; 395 391 struct wbint_Principal *result; 396 392 NTSTATUS status; 393 bool include_local_groups = false; 397 394 398 395 if (domain == NULL) { … … 400 397 } 401 398 399 switch (lp_server_role()) { 400 case ROLE_ACTIVE_DIRECTORY_DC: 401 if (domain->internal) { 402 /* 403 * we want to include local groups 404 * for BUILTIN and WORKGROUP 405 */ 406 include_local_groups = true; 407 } 408 break; 409 default: 410 /* 411 * We might include local groups in more 412 * setups later, but that requires more work 413 * elsewhere. 414 */ 415 break; 416 } 417 418 if (include_local_groups) { 419 status = domain->methods->enum_local_groups(domain, talloc_tos(), 420 &num_local_groups, 421 &local_groups); 422 reset_cm_connection_on_error(domain, status); 423 if (!NT_STATUS_IS_OK(status)) { 424 return status; 425 } 426 } 427 402 428 status = domain->methods->enum_dom_groups(domain, talloc_tos(), 403 &num_groups, &groups); 429 &num_dom_groups, 430 &dom_groups); 404 431 reset_cm_connection_on_error(domain, status); 405 432 if (!NT_STATUS_IS_OK(status)) { … … 407 434 } 408 435 436 num_total = num_local_groups + num_dom_groups; 437 if (num_total > UINT32_MAX) { 438 return NT_STATUS_INTERNAL_ERROR; 439 } 440 409 441 result = talloc_array(r->out.groups, struct wbint_Principal, 410 num_ groups);442 num_total); 411 443 if (result == NULL) { 412 444 return NT_STATUS_NO_MEMORY; 413 445 } 414 446 415 for (i=0; i<num_groups; i++) { 416 sid_compose(&result[i].sid, &domain->sid, groups[i].rid); 417 result[i].type = SID_NAME_DOM_GRP; 418 result[i].name = talloc_strdup(result, groups[i].acct_name); 419 if (result[i].name == NULL) { 447 for (i = 0; i < num_local_groups; i++) { 448 struct wb_acct_info *lg = &local_groups[i]; 449 struct wbint_Principal *rg = &result[ti++]; 450 451 sid_compose(&rg->sid, &domain->sid, lg->rid); 452 rg->type = SID_NAME_ALIAS; 453 rg->name = talloc_strdup(result, lg->acct_name); 454 if (rg->name == NULL) { 420 455 TALLOC_FREE(result); 421 TALLOC_FREE(groups); 456 TALLOC_FREE(dom_groups); 457 TALLOC_FREE(local_groups); 422 458 return NT_STATUS_NO_MEMORY; 423 459 } 424 460 } 425 426 r->out.groups->num_principals = num_groups; 461 num_local_groups = 0; 462 TALLOC_FREE(local_groups); 463 464 for (i = 0; i < num_dom_groups; i++) { 465 struct wb_acct_info *dg = &dom_groups[i]; 466 struct wbint_Principal *rg = &result[ti++]; 467 468 sid_compose(&rg->sid, &domain->sid, dg->rid); 469 rg->type = SID_NAME_DOM_GRP; 470 rg->name = talloc_strdup(result, dg->acct_name); 471 if (rg->name == NULL) { 472 TALLOC_FREE(result); 473 TALLOC_FREE(dom_groups); 474 TALLOC_FREE(local_groups); 475 return NT_STATUS_NO_MEMORY; 476 } 477 } 478 num_dom_groups = 0; 479 TALLOC_FREE(dom_groups); 480 481 r->out.groups->num_principals = ti; 427 482 r->out.groups->principals = result; 428 483 429 TALLOC_FREE(groups);430 484 return NT_STATUS_OK; 431 485 } … … 591 645 592 646 again: 593 invalidate_cm_connection(&domain->conn); 647 invalidate_cm_connection(domain); 648 domain->conn.netlogon_force_reauth = true; 594 649 595 650 { … … 633 688 struct wbint_ChangeMachineAccount *r) 634 689 { 690 struct messaging_context *msg_ctx = winbind_messaging_context(); 635 691 struct winbindd_domain *domain; 636 int num_retries = 0;637 692 NTSTATUS status; 638 693 struct rpc_pipe_client *netlogon_pipe; 639 TALLOC_CTX *tmp_ctx; 640 641 again: 694 642 695 domain = wb_child_domain(); 643 696 if (domain == NULL) { … … 645 698 } 646 699 647 invalidate_cm_connection(&domain->conn); 648 649 { 650 status = cm_connect_netlogon(domain, &netlogon_pipe); 651 } 652 653 /* There is a race condition between fetching the trust account 654 password and the periodic machine password change. So it's 655 possible that the trust account password has been changed on us. 656 We are returned NT_STATUS_ACCESS_DENIED if this happens. */ 657 658 #define MAX_RETRIES 3 659 660 if ((num_retries < MAX_RETRIES) 661 && NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { 662 num_retries++; 663 goto again; 664 } 665 700 status = cm_connect_netlogon(domain, &netlogon_pipe); 666 701 if (!NT_STATUS_IS_OK(status)) { 667 702 DEBUG(3, ("could not open handle to NETLOGON pipe\n")); … … 669 704 } 670 705 671 tmp_ctx = talloc_new(p->mem_ctx); 672 673 status = trust_pw_find_change_and_store_it(netlogon_pipe, 674 tmp_ctx, 675 domain->name); 676 talloc_destroy(tmp_ctx); 706 status = trust_pw_change(domain->conn.netlogon_creds, 707 msg_ctx, 708 netlogon_pipe->binding_handle, 709 domain->name, 710 true); /* force */ 677 711 678 712 /* Pass back result code - zero for success, other values for … … 699 733 fstring logon_server; 700 734 struct dcerpc_binding_handle *b; 735 bool retry = false; 701 736 702 737 domain = wb_child_domain(); … … 705 740 } 706 741 742 reconnect: 707 743 status = cm_connect_netlogon(domain, &netlogon_pipe); 708 744 reset_cm_connection_on_error(domain, status); 709 745 if (!NT_STATUS_IS_OK(status)) { 710 DEBUG(3, ("could not open handle to NETLOGON pipe\n")); 746 DEBUG(3, ("could not open handle to NETLOGON pipe: %s\n", 747 nt_errstr(status))); 711 748 return status; 712 749 } … … 715 752 716 753 fstr_sprintf(logon_server, "\\\\%s", domain->dcname); 754 *r->out.dcname = talloc_strdup(p->mem_ctx, domain->dcname); 755 if (*r->out.dcname == NULL) { 756 DEBUG(2, ("Could not allocate memory\n")); 757 return NT_STATUS_NO_MEMORY; 758 } 717 759 718 760 /* … … 726 768 2, &info, &werr); 727 769 770 if (!dcerpc_binding_handle_is_connected(b) && !retry) { 771 DEBUG(10, ("Session might have expired. " 772 "Reconnect and retry once.\n")); 773 invalidate_cm_connection(domain); 774 retry = true; 775 goto reconnect; 776 } 777 728 778 reset_cm_connection_on_error(domain, status); 729 779 if (!NT_STATUS_IS_OK(status)) { … … 743 793 return NT_STATUS_OK; 744 794 } 795 796 NTSTATUS _winbind_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p, 797 struct winbind_DsrUpdateReadOnlyServerDnsRecords *r) 798 { 799 struct winbindd_domain *domain; 800 NTSTATUS status; 801 struct rpc_pipe_client *netlogon_pipe; 802 803 domain = wb_child_domain(); 804 if (domain == NULL) { 805 return NT_STATUS_REQUEST_NOT_ACCEPTED; 806 } 807 808 status = cm_connect_netlogon(domain, &netlogon_pipe); 809 if (!NT_STATUS_IS_OK(status)) { 810 DEBUG(3, ("could not open handle to NETLOGON pipe\n")); 811 goto done; 812 } 813 814 status = netlogon_creds_cli_DsrUpdateReadOnlyServerDnsRecords(domain->conn.netlogon_creds, 815 netlogon_pipe->binding_handle, 816 r->in.site_name, 817 r->in.dns_ttl, 818 r->in.dns_names); 819 820 /* Pass back result code - zero for success, other values for 821 specific failures. */ 822 823 DEBUG(3,("DNS records for domain %s %s\n", domain->name, 824 NT_STATUS_IS_OK(status) ? "changed" : "unchanged")); 825 826 done: 827 DEBUG(NT_STATUS_IS_OK(status) ? 5 : 2, 828 ("Update of DNS records via RW DC %s returned %s\n", 829 domain->name, nt_errstr(status))); 830 831 return status; 832 } 833 834 NTSTATUS _winbind_SamLogon(struct pipes_struct *p, 835 struct winbind_SamLogon *r) 836 { 837 struct winbindd_domain *domain; 838 NTSTATUS status; 839 DATA_BLOB lm_response, nt_response; 840 domain = wb_child_domain(); 841 if (domain == NULL) { 842 return NT_STATUS_REQUEST_NOT_ACCEPTED; 843 } 844 845 /* TODO: Handle interactive logons here */ 846 if (r->in.validation_level != 3 || 847 r->in.logon.network == NULL || 848 (r->in.logon_level != NetlogonNetworkInformation 849 && r->in.logon_level != NetlogonNetworkTransitiveInformation)) { 850 return NT_STATUS_REQUEST_NOT_ACCEPTED; 851 } 852 853 854 lm_response = data_blob_talloc(p->mem_ctx, r->in.logon.network->lm.data, r->in.logon.network->lm.length); 855 nt_response = data_blob_talloc(p->mem_ctx, r->in.logon.network->nt.data, r->in.logon.network->nt.length); 856 857 status = winbind_dual_SamLogon(domain, p->mem_ctx, 858 r->in.logon.network->identity_info.parameter_control, 859 r->in.logon.network->identity_info.account_name.string, 860 r->in.logon.network->identity_info.domain_name.string, 861 r->in.logon.network->identity_info.workstation.string, 862 r->in.logon.network->challenge, 863 lm_response, nt_response, &r->out.validation.sam3); 864 return status; 865 } 866 867 static WERROR _winbind_LogonControl_REDISCOVER(struct pipes_struct *p, 868 struct winbindd_domain *domain, 869 struct winbind_LogonControl *r) 870 { 871 NTSTATUS status; 872 struct rpc_pipe_client *netlogon_pipe = NULL; 873 struct netr_NETLOGON_INFO_2 *info2 = NULL; 874 WERROR check_result = WERR_INTERNAL_ERROR; 875 876 info2 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_2); 877 if (info2 == NULL) { 878 return WERR_NOMEM; 879 } 880 881 if (domain->internal) { 882 check_result = WERR_OK; 883 goto check_return; 884 } 885 886 /* 887 * For now we just force a reconnect 888 * 889 * TODO: take care of the optional '\dcname' 890 */ 891 invalidate_cm_connection(domain); 892 domain->conn.netlogon_force_reauth = true; 893 status = cm_connect_netlogon(domain, &netlogon_pipe); 894 reset_cm_connection_on_error(domain, status); 895 if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { 896 status = NT_STATUS_NO_LOGON_SERVERS; 897 } 898 if (!NT_STATUS_IS_OK(status)) { 899 DEBUG(2, ("%s: domain[%s/%s] cm_connect_netlogon() returned %s\n", 900 __func__, domain->name, domain->alt_name, 901 nt_errstr(status))); 902 /* 903 * Here we return a top level error! 904 * This is different than TC_QUERY or TC_VERIFY. 905 */ 906 return ntstatus_to_werror(status); 907 } 908 check_result = WERR_OK; 909 910 check_return: 911 info2->pdc_connection_status = WERR_OK; 912 if (domain->dcname != NULL) { 913 info2->flags |= NETLOGON_HAS_IP; 914 info2->flags |= NETLOGON_HAS_TIMESERV; 915 info2->trusted_dc_name = talloc_asprintf(info2, "\\\\%s", 916 domain->dcname); 917 if (info2->trusted_dc_name == NULL) { 918 return WERR_NOMEM; 919 } 920 } else { 921 info2->trusted_dc_name = talloc_strdup(info2, ""); 922 if (info2->trusted_dc_name == NULL) { 923 return WERR_NOMEM; 924 } 925 } 926 info2->tc_connection_status = check_result; 927 928 if (!W_ERROR_IS_OK(info2->pdc_connection_status)) { 929 DEBUG(2, ("%s: domain[%s/%s] dcname[%s] " 930 "pdc_connection[%s] tc_connection[%s]\n", 931 __func__, domain->name, domain->alt_name, 932 domain->dcname, 933 win_errstr(info2->pdc_connection_status), 934 win_errstr(info2->tc_connection_status))); 935 } 936 937 r->out.query->info2 = info2; 938 939 DEBUG(5, ("%s: succeeded.\n", __func__)); 940 return WERR_OK; 941 } 942 943 static WERROR _winbind_LogonControl_TC_QUERY(struct pipes_struct *p, 944 struct winbindd_domain *domain, 945 struct winbind_LogonControl *r) 946 { 947 NTSTATUS status; 948 struct rpc_pipe_client *netlogon_pipe = NULL; 949 struct netr_NETLOGON_INFO_2 *info2 = NULL; 950 WERROR check_result = WERR_INTERNAL_ERROR; 951 952 info2 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_2); 953 if (info2 == NULL) { 954 return WERR_NOMEM; 955 } 956 957 if (domain->internal) { 958 check_result = WERR_OK; 959 goto check_return; 960 } 961 962 status = cm_connect_netlogon(domain, &netlogon_pipe); 963 reset_cm_connection_on_error(domain, status); 964 if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { 965 status = NT_STATUS_NO_LOGON_SERVERS; 966 } 967 if (!NT_STATUS_IS_OK(status)) { 968 DEBUG(3, ("could not open handle to NETLOGON pipe: %s\n", 969 nt_errstr(status))); 970 check_result = ntstatus_to_werror(status); 971 goto check_return; 972 } 973 check_result = WERR_OK; 974 975 check_return: 976 info2->pdc_connection_status = WERR_OK; 977 if (domain->dcname != NULL) { 978 info2->flags |= NETLOGON_HAS_IP; 979 info2->flags |= NETLOGON_HAS_TIMESERV; 980 info2->trusted_dc_name = talloc_asprintf(info2, "\\\\%s", 981 domain->dcname); 982 if (info2->trusted_dc_name == NULL) { 983 return WERR_NOMEM; 984 } 985 } else { 986 info2->trusted_dc_name = talloc_strdup(info2, ""); 987 if (info2->trusted_dc_name == NULL) { 988 return WERR_NOMEM; 989 } 990 } 991 info2->tc_connection_status = check_result; 992 993 if (!W_ERROR_IS_OK(info2->pdc_connection_status)) { 994 DEBUG(2, ("%s: domain[%s/%s] dcname[%s] " 995 "pdc_connection[%s] tc_connection[%s]\n", 996 __func__, domain->name, domain->alt_name, 997 domain->dcname, 998 win_errstr(info2->pdc_connection_status), 999 win_errstr(info2->tc_connection_status))); 1000 } 1001 1002 r->out.query->info2 = info2; 1003 1004 DEBUG(5, ("%s: succeeded.\n", __func__)); 1005 return WERR_OK; 1006 } 1007 1008 static WERROR _winbind_LogonControl_TC_VERIFY(struct pipes_struct *p, 1009 struct winbindd_domain *domain, 1010 struct winbind_LogonControl *r) 1011 { 1012 TALLOC_CTX *frame = talloc_stackframe(); 1013 NTSTATUS status; 1014 NTSTATUS result; 1015 struct lsa_String trusted_domain_name = {}; 1016 struct lsa_StringLarge trusted_domain_name_l = {}; 1017 struct rpc_pipe_client *local_lsa_pipe = NULL; 1018 struct policy_handle local_lsa_policy = {}; 1019 struct dcerpc_binding_handle *local_lsa = NULL; 1020 struct rpc_pipe_client *netlogon_pipe = NULL; 1021 struct cli_credentials *creds = NULL; 1022 struct samr_Password *cur_nt_hash = NULL; 1023 uint32_t trust_attributes = 0; 1024 struct samr_Password new_owf_password = {}; 1025 int cmp_new = -1; 1026 struct samr_Password old_owf_password = {}; 1027 int cmp_old = -1; 1028 const struct lsa_TrustDomainInfoInfoEx *local_tdo = NULL; 1029 bool fetch_fti = false; 1030 struct lsa_ForestTrustInformation *new_fti = NULL; 1031 struct netr_TrustInfo *trust_info = NULL; 1032 struct netr_NETLOGON_INFO_2 *info2 = NULL; 1033 struct dcerpc_binding_handle *b = NULL; 1034 WERROR check_result = WERR_INTERNAL_ERROR; 1035 WERROR verify_result = WERR_INTERNAL_ERROR; 1036 bool retry = false; 1037 1038 trusted_domain_name.string = domain->name; 1039 trusted_domain_name_l.string = domain->name; 1040 1041 info2 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_2); 1042 if (info2 == NULL) { 1043 TALLOC_FREE(frame); 1044 return WERR_NOMEM; 1045 } 1046 1047 if (domain->internal) { 1048 check_result = WERR_OK; 1049 goto check_return; 1050 } 1051 1052 status = pdb_get_trust_credentials(domain->name, 1053 domain->alt_name, 1054 frame, 1055 &creds); 1056 if (NT_STATUS_IS_OK(status)) { 1057 cur_nt_hash = cli_credentials_get_nt_hash(creds, frame); 1058 TALLOC_FREE(creds); 1059 } 1060 1061 if (!domain->primary) { 1062 union lsa_TrustedDomainInfo *tdi = NULL; 1063 1064 status = open_internal_lsa_conn(frame, &local_lsa_pipe, 1065 &local_lsa_policy); 1066 if (!NT_STATUS_IS_OK(status)) { 1067 DEBUG(0,("%s:%s: open_internal_lsa_conn() failed - %s\n", 1068 __location__, __func__, nt_errstr(status))); 1069 TALLOC_FREE(frame); 1070 return WERR_INTERNAL_ERROR; 1071 } 1072 local_lsa = local_lsa_pipe->binding_handle; 1073 1074 status = dcerpc_lsa_QueryTrustedDomainInfoByName(local_lsa, frame, 1075 &local_lsa_policy, 1076 &trusted_domain_name, 1077 LSA_TRUSTED_DOMAIN_INFO_INFO_EX, 1078 &tdi, &result); 1079 if (!NT_STATUS_IS_OK(status)) { 1080 DEBUG(0,("%s:%s: local_lsa.QueryTrustedDomainInfoByName(%s) failed - %s\n", 1081 __location__, __func__, domain->name, nt_errstr(status))); 1082 TALLOC_FREE(frame); 1083 return WERR_INTERNAL_ERROR; 1084 } 1085 if (NT_STATUS_EQUAL(result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 1086 DEBUG(1,("%s:%s: domain[%s] not found via LSA, might be removed already.\n", 1087 __location__, __func__, domain->name)); 1088 TALLOC_FREE(frame); 1089 return WERR_NO_SUCH_DOMAIN; 1090 } 1091 if (!NT_STATUS_IS_OK(result)) { 1092 DEBUG(0,("%s:%s: local_lsa.QueryTrustedDomainInfoByName(%s) returned %s\n", 1093 __location__, __func__, domain->name, nt_errstr(result))); 1094 TALLOC_FREE(frame); 1095 return WERR_INTERNAL_ERROR; 1096 } 1097 if (tdi == NULL) { 1098 DEBUG(0,("%s:%s: local_lsa.QueryTrustedDomainInfoByName() " 1099 "returned no trusted domain information\n", 1100 __location__, __func__)); 1101 TALLOC_FREE(frame); 1102 return WERR_INTERNAL_ERROR; 1103 } 1104 1105 local_tdo = &tdi->info_ex; 1106 trust_attributes = local_tdo->trust_attributes; 1107 } 1108 1109 if (trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) { 1110 struct lsa_ForestTrustInformation *old_fti = NULL; 1111 1112 status = dcerpc_lsa_lsaRQueryForestTrustInformation(local_lsa, frame, 1113 &local_lsa_policy, 1114 &trusted_domain_name, 1115 LSA_FOREST_TRUST_DOMAIN_INFO, 1116 &old_fti, &result); 1117 if (!NT_STATUS_IS_OK(status)) { 1118 DEBUG(0,("%s:%s: local_lsa.lsaRQueryForestTrustInformation(%s) failed %s\n", 1119 __location__, __func__, domain->name, nt_errstr(status))); 1120 TALLOC_FREE(frame); 1121 return WERR_INTERNAL_ERROR; 1122 } 1123 if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_FOUND)) { 1124 DEBUG(2,("%s: no forest trust information available for domain[%s] yet.\n", 1125 __func__, domain->name)); 1126 old_fti = NULL; 1127 fetch_fti = true; 1128 result = NT_STATUS_OK; 1129 } 1130 if (!NT_STATUS_IS_OK(result)) { 1131 DEBUG(0,("%s:%s: local_lsa.lsaRQueryForestTrustInformation(%s) returned %s\n", 1132 __location__, __func__, domain->name, nt_errstr(result))); 1133 TALLOC_FREE(frame); 1134 return WERR_INTERNAL_ERROR; 1135 } 1136 1137 TALLOC_FREE(old_fti); 1138 } 1139 1140 reconnect: 1141 status = cm_connect_netlogon(domain, &netlogon_pipe); 1142 reset_cm_connection_on_error(domain, status); 1143 if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { 1144 status = NT_STATUS_NO_LOGON_SERVERS; 1145 } 1146 if (!NT_STATUS_IS_OK(status)) { 1147 DEBUG(3, ("could not open handle to NETLOGON pipe: %s\n", 1148 nt_errstr(status))); 1149 check_result = ntstatus_to_werror(status); 1150 goto check_return; 1151 } 1152 check_result = WERR_OK; 1153 b = netlogon_pipe->binding_handle; 1154 1155 if (cur_nt_hash == NULL) { 1156 verify_result = WERR_NO_TRUST_LSA_SECRET; 1157 goto verify_return; 1158 } 1159 1160 if (fetch_fti) { 1161 status = netlogon_creds_cli_GetForestTrustInformation(domain->conn.netlogon_creds, 1162 b, frame, 1163 &new_fti); 1164 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) { 1165 status = NT_STATUS_NOT_SUPPORTED; 1166 } 1167 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { 1168 new_fti = NULL; 1169 status = NT_STATUS_OK; 1170 } 1171 if (!NT_STATUS_IS_OK(status)) { 1172 if (!retry && dcerpc_binding_handle_is_connected(b)) { 1173 invalidate_cm_connection(domain); 1174 retry = true; 1175 goto reconnect; 1176 } 1177 DEBUG(2, ("netlogon_creds_cli_GetForestTrustInformation(%s)" 1178 "failed: %s\n", 1179 domain->name, nt_errstr(status))); 1180 check_result = ntstatus_to_werror(status); 1181 goto check_return; 1182 } 1183 } 1184 1185 if (new_fti != NULL) { 1186 struct lsa_ForestTrustInformation old_fti = {}; 1187 struct lsa_ForestTrustInformation *merged_fti = NULL; 1188 struct lsa_ForestTrustCollisionInfo *collision_info = NULL; 1189 1190 status = dsdb_trust_merge_forest_info(frame, local_tdo, 1191 &old_fti, new_fti, 1192 &merged_fti); 1193 if (!NT_STATUS_IS_OK(status)) { 1194 DEBUG(0,("%s:%s: dsdb_trust_merge_forest_info(%s) failed %s\n", 1195 __location__, __func__, 1196 domain->name, nt_errstr(status))); 1197 TALLOC_FREE(frame); 1198 return ntstatus_to_werror(status); 1199 } 1200 1201 status = dcerpc_lsa_lsaRSetForestTrustInformation(local_lsa, frame, 1202 &local_lsa_policy, 1203 &trusted_domain_name_l, 1204 LSA_FOREST_TRUST_DOMAIN_INFO, 1205 merged_fti, 1206 0, /* check_only=0 => store it! */ 1207 &collision_info, 1208 &result); 1209 if (!NT_STATUS_IS_OK(status)) { 1210 DEBUG(0,("%s:%s: local_lsa.lsaRSetForestTrustInformation(%s) failed %s\n", 1211 __location__, __func__, domain->name, nt_errstr(status))); 1212 TALLOC_FREE(frame); 1213 return WERR_INTERNAL_ERROR; 1214 } 1215 if (!NT_STATUS_IS_OK(result)) { 1216 DEBUG(0,("%s:%s: local_lsa.lsaRSetForestTrustInformation(%s) returned %s\n", 1217 __location__, __func__, domain->name, nt_errstr(result))); 1218 TALLOC_FREE(frame); 1219 return ntstatus_to_werror(result); 1220 } 1221 } 1222 1223 status = netlogon_creds_cli_ServerGetTrustInfo(domain->conn.netlogon_creds, 1224 b, frame, 1225 &new_owf_password, 1226 &old_owf_password, 1227 &trust_info); 1228 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) { 1229 status = NT_STATUS_NOT_SUPPORTED; 1230 } 1231 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { 1232 DEBUG(5, ("netlogon_creds_cli_ServerGetTrustInfo failed: %s\n", 1233 nt_errstr(status))); 1234 verify_result = WERR_OK; 1235 goto verify_return; 1236 } 1237 if (!NT_STATUS_IS_OK(status)) { 1238 if (!retry && dcerpc_binding_handle_is_connected(b)) { 1239 invalidate_cm_connection(domain); 1240 retry = true; 1241 goto reconnect; 1242 } 1243 DEBUG(2, ("netlogon_creds_cli_ServerGetTrustInfo failed: %s\n", 1244 nt_errstr(status))); 1245 1246 if (!dcerpc_binding_handle_is_connected(b)) { 1247 check_result = ntstatus_to_werror(status); 1248 goto check_return; 1249 } else { 1250 verify_result = ntstatus_to_werror(status); 1251 goto verify_return; 1252 } 1253 } 1254 1255 if (trust_info != NULL && trust_info->count >= 1) { 1256 uint32_t diff = trust_info->data[0] ^ trust_attributes; 1257 1258 if (diff & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) { 1259 verify_result = WERR_DOMAIN_TRUST_INCONSISTENT; 1260 goto verify_return; 1261 } 1262 } 1263 1264 cmp_new = memcmp(new_owf_password.hash, 1265 cur_nt_hash->hash, 1266 sizeof(cur_nt_hash->hash)); 1267 cmp_old = memcmp(old_owf_password.hash, 1268 cur_nt_hash->hash, 1269 sizeof(cur_nt_hash->hash)); 1270 if (cmp_new != 0 && cmp_old != 0) { 1271 DEBUG(1,("%s:Error: credentials for domain[%s/%s] doesn't match " 1272 "any password known to dcname[%s]\n", 1273 __func__, domain->name, domain->alt_name, 1274 domain->dcname)); 1275 verify_result = WERR_WRONG_PASSWORD; 1276 goto verify_return; 1277 } 1278 1279 if (cmp_new != 0) { 1280 DEBUG(2,("%s:Warning: credentials for domain[%s/%s] only match " 1281 "against the old password known to dcname[%s]\n", 1282 __func__, domain->name, domain->alt_name, 1283 domain->dcname)); 1284 } 1285 1286 verify_result = WERR_OK; 1287 goto verify_return; 1288 1289 check_return: 1290 verify_result = check_result; 1291 verify_return: 1292 info2->flags |= NETLOGON_VERIFY_STATUS_RETURNED; 1293 info2->pdc_connection_status = verify_result; 1294 if (domain->dcname != NULL) { 1295 info2->flags |= NETLOGON_HAS_IP; 1296 info2->flags |= NETLOGON_HAS_TIMESERV; 1297 info2->trusted_dc_name = talloc_asprintf(info2, "\\\\%s", 1298 domain->dcname); 1299 if (info2->trusted_dc_name == NULL) { 1300 TALLOC_FREE(frame); 1301 return WERR_NOMEM; 1302 } 1303 } else { 1304 info2->trusted_dc_name = talloc_strdup(info2, ""); 1305 if (info2->trusted_dc_name == NULL) { 1306 TALLOC_FREE(frame); 1307 return WERR_NOMEM; 1308 } 1309 } 1310 info2->tc_connection_status = check_result; 1311 1312 if (!W_ERROR_IS_OK(info2->pdc_connection_status)) { 1313 DEBUG(2, ("%s: domain[%s/%s] dcname[%s] " 1314 "pdc_connection[%s] tc_connection[%s]\n", 1315 __func__, domain->name, domain->alt_name, 1316 domain->dcname, 1317 win_errstr(info2->pdc_connection_status), 1318 win_errstr(info2->tc_connection_status))); 1319 } 1320 1321 r->out.query->info2 = info2; 1322 1323 DEBUG(5, ("%s: succeeded.\n", __func__)); 1324 TALLOC_FREE(frame); 1325 return WERR_OK; 1326 } 1327 1328 static WERROR _winbind_LogonControl_CHANGE_PASSWORD(struct pipes_struct *p, 1329 struct winbindd_domain *domain, 1330 struct winbind_LogonControl *r) 1331 { 1332 struct messaging_context *msg_ctx = winbind_messaging_context(); 1333 NTSTATUS status; 1334 struct rpc_pipe_client *netlogon_pipe; 1335 struct cli_credentials *creds = NULL; 1336 struct samr_Password *cur_nt_hash = NULL; 1337 struct netr_NETLOGON_INFO_1 *info1 = NULL; 1338 struct dcerpc_binding_handle *b; 1339 WERROR change_result = WERR_OK; 1340 bool retry = false; 1341 1342 info1 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_1); 1343 if (info1 == NULL) { 1344 return WERR_NOMEM; 1345 } 1346 1347 if (domain->internal) { 1348 return WERR_NOT_SUPPORTED; 1349 } 1350 1351 status = pdb_get_trust_credentials(domain->name, 1352 domain->alt_name, 1353 p->mem_ctx, 1354 &creds); 1355 if (NT_STATUS_IS_OK(status)) { 1356 cur_nt_hash = cli_credentials_get_nt_hash(creds, p->mem_ctx); 1357 TALLOC_FREE(creds); 1358 } 1359 1360 reconnect: 1361 status = cm_connect_netlogon(domain, &netlogon_pipe); 1362 reset_cm_connection_on_error(domain, status); 1363 if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { 1364 status = NT_STATUS_NO_LOGON_SERVERS; 1365 } 1366 if (!NT_STATUS_IS_OK(status)) { 1367 DEBUG(2, ("%s: domain[%s/%s] cm_connect_netlogon() returned %s\n", 1368 __func__, domain->name, domain->alt_name, 1369 nt_errstr(status))); 1370 /* 1371 * Here we return a top level error! 1372 * This is different than TC_QUERY or TC_VERIFY. 1373 */ 1374 return ntstatus_to_werror(status); 1375 } 1376 b = netlogon_pipe->binding_handle; 1377 1378 if (cur_nt_hash == NULL) { 1379 change_result = WERR_NO_TRUST_LSA_SECRET; 1380 goto change_return; 1381 } 1382 TALLOC_FREE(cur_nt_hash); 1383 1384 status = trust_pw_change(domain->conn.netlogon_creds, 1385 msg_ctx, b, domain->name, 1386 true); /* force */ 1387 if (!NT_STATUS_IS_OK(status)) { 1388 if (!retry && dcerpc_binding_handle_is_connected(b)) { 1389 invalidate_cm_connection(domain); 1390 retry = true; 1391 goto reconnect; 1392 } 1393 1394 DEBUG(1, ("trust_pw_change(%s): %s\n", 1395 domain->name, nt_errstr(status))); 1396 1397 change_result = ntstatus_to_werror(status); 1398 goto change_return; 1399 } 1400 1401 change_result = WERR_OK; 1402 1403 change_return: 1404 info1->pdc_connection_status = change_result; 1405 1406 if (!W_ERROR_IS_OK(info1->pdc_connection_status)) { 1407 DEBUG(2, ("%s: domain[%s/%s] dcname[%s] " 1408 "pdc_connection[%s]\n", 1409 __func__, domain->name, domain->alt_name, 1410 domain->dcname, 1411 win_errstr(info1->pdc_connection_status))); 1412 } 1413 1414 r->out.query->info1 = info1; 1415 1416 DEBUG(5, ("%s: succeeded.\n", __func__)); 1417 return WERR_OK; 1418 } 1419 1420 WERROR _winbind_LogonControl(struct pipes_struct *p, 1421 struct winbind_LogonControl *r) 1422 { 1423 struct winbindd_domain *domain; 1424 1425 domain = wb_child_domain(); 1426 if (domain == NULL) { 1427 return WERR_NO_SUCH_DOMAIN; 1428 } 1429 1430 switch (r->in.function_code) { 1431 case NETLOGON_CONTROL_REDISCOVER: 1432 if (r->in.level != 2) { 1433 return WERR_INVALID_PARAMETER; 1434 } 1435 return _winbind_LogonControl_REDISCOVER(p, domain, r); 1436 case NETLOGON_CONTROL_TC_QUERY: 1437 if (r->in.level != 2) { 1438 return WERR_INVALID_PARAMETER; 1439 } 1440 return _winbind_LogonControl_TC_QUERY(p, domain, r); 1441 case NETLOGON_CONTROL_TC_VERIFY: 1442 if (r->in.level != 2) { 1443 return WERR_INVALID_PARAMETER; 1444 } 1445 return _winbind_LogonControl_TC_VERIFY(p, domain, r); 1446 case NETLOGON_CONTROL_CHANGE_PASSWORD: 1447 if (r->in.level != 1) { 1448 return WERR_INVALID_PARAMETER; 1449 } 1450 return _winbind_LogonControl_CHANGE_PASSWORD(p, domain, r); 1451 default: 1452 break; 1453 } 1454 1455 DEBUG(4, ("%s: function_code[0x%x] not supported\n", 1456 __func__, r->in.function_code)); 1457 return WERR_NOT_SUPPORTED; 1458 } 1459 1460 WERROR _winbind_GetForestTrustInformation(struct pipes_struct *p, 1461 struct winbind_GetForestTrustInformation *r) 1462 { 1463 TALLOC_CTX *frame = talloc_stackframe(); 1464 NTSTATUS status, result; 1465 struct winbindd_domain *domain; 1466 struct rpc_pipe_client *netlogon_pipe; 1467 struct dcerpc_binding_handle *b; 1468 bool retry = false; 1469 struct lsa_String trusted_domain_name = {}; 1470 struct lsa_StringLarge trusted_domain_name_l = {}; 1471 union lsa_TrustedDomainInfo *tdi = NULL; 1472 const struct lsa_TrustDomainInfoInfoEx *tdo = NULL; 1473 struct lsa_ForestTrustInformation _old_fti = {}; 1474 struct lsa_ForestTrustInformation *old_fti = NULL; 1475 struct lsa_ForestTrustInformation *new_fti = NULL; 1476 struct lsa_ForestTrustInformation *merged_fti = NULL; 1477 struct lsa_ForestTrustCollisionInfo *collision_info = NULL; 1478 bool update_fti = false; 1479 struct rpc_pipe_client *local_lsa_pipe; 1480 struct policy_handle local_lsa_policy; 1481 struct dcerpc_binding_handle *local_lsa = NULL; 1482 1483 domain = wb_child_domain(); 1484 if (domain == NULL) { 1485 TALLOC_FREE(frame); 1486 return WERR_NO_SUCH_DOMAIN; 1487 } 1488 1489 /* 1490 * checking for domain->internal and domain->primary 1491 * makes sure we only do some work when running as DC. 1492 */ 1493 1494 if (domain->internal) { 1495 TALLOC_FREE(frame); 1496 return WERR_NO_SUCH_DOMAIN; 1497 } 1498 1499 if (domain->primary) { 1500 TALLOC_FREE(frame); 1501 return WERR_NO_SUCH_DOMAIN; 1502 } 1503 1504 trusted_domain_name.string = domain->name; 1505 trusted_domain_name_l.string = domain->name; 1506 1507 status = open_internal_lsa_conn(frame, &local_lsa_pipe, 1508 &local_lsa_policy); 1509 if (!NT_STATUS_IS_OK(status)) { 1510 DEBUG(0,("%s:%s: open_internal_lsa_conn() failed - %s\n", 1511 __location__, __func__, nt_errstr(status))); 1512 TALLOC_FREE(frame); 1513 return WERR_INTERNAL_ERROR; 1514 } 1515 local_lsa = local_lsa_pipe->binding_handle; 1516 1517 status = dcerpc_lsa_QueryTrustedDomainInfoByName(local_lsa, frame, 1518 &local_lsa_policy, 1519 &trusted_domain_name, 1520 LSA_TRUSTED_DOMAIN_INFO_INFO_EX, 1521 &tdi, &result); 1522 if (!NT_STATUS_IS_OK(status)) { 1523 DEBUG(0,("%s:%s: local_lsa.QueryTrustedDomainInfoByName(%s) failed - %s\n", 1524 __location__, __func__, domain->name, nt_errstr(status))); 1525 TALLOC_FREE(frame); 1526 return WERR_INTERNAL_ERROR; 1527 } 1528 if (NT_STATUS_EQUAL(result, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 1529 DEBUG(1,("%s:%s: domain[%s] not found via LSA, might be removed already.\n", 1530 __location__, __func__, domain->name)); 1531 TALLOC_FREE(frame); 1532 return WERR_NO_SUCH_DOMAIN; 1533 } 1534 if (!NT_STATUS_IS_OK(result)) { 1535 DEBUG(0,("%s:%s: local_lsa.QueryTrustedDomainInfoByName(%s) returned %s\n", 1536 __location__, __func__, domain->name, nt_errstr(result))); 1537 TALLOC_FREE(frame); 1538 return WERR_INTERNAL_ERROR; 1539 } 1540 if (tdi == NULL) { 1541 DEBUG(0,("%s:%s: local_lsa.QueryTrustedDomainInfoByName() " 1542 "returned no trusted domain information\n", 1543 __location__, __func__)); 1544 TALLOC_FREE(frame); 1545 return WERR_INTERNAL_ERROR; 1546 } 1547 1548 tdo = &tdi->info_ex; 1549 1550 if (!(tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) { 1551 DEBUG(2,("%s: tdo[%s/%s] is no forest trust attributes[0x%08X]\n", 1552 __func__, tdo->netbios_name.string, 1553 tdo->domain_name.string, 1554 (unsigned)tdo->trust_attributes)); 1555 TALLOC_FREE(frame); 1556 return WERR_NO_SUCH_DOMAIN; 1557 } 1558 1559 if (r->in.flags & ~DS_GFTI_UPDATE_TDO) { 1560 TALLOC_FREE(frame); 1561 return WERR_INVALID_FLAGS; 1562 } 1563 1564 reconnect: 1565 status = cm_connect_netlogon(domain, &netlogon_pipe); 1566 reset_cm_connection_on_error(domain, status); 1567 if (NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) { 1568 status = NT_STATUS_NO_LOGON_SERVERS; 1569 } 1570 if (!NT_STATUS_IS_OK(status)) { 1571 DEBUG(3, ("could not open handle to NETLOGON pipe: %s\n", 1572 nt_errstr(status))); 1573 TALLOC_FREE(frame); 1574 return ntstatus_to_werror(status); 1575 } 1576 b = netlogon_pipe->binding_handle; 1577 1578 status = netlogon_creds_cli_GetForestTrustInformation(domain->conn.netlogon_creds, 1579 b, p->mem_ctx, 1580 &new_fti); 1581 if (!NT_STATUS_IS_OK(status)) { 1582 if (!retry && dcerpc_binding_handle_is_connected(b)) { 1583 invalidate_cm_connection(domain); 1584 retry = true; 1585 goto reconnect; 1586 } 1587 DEBUG(2, ("netlogon_creds_cli_GetForestTrustInformation(%s) failed: %s\n", 1588 domain->name, nt_errstr(status))); 1589 TALLOC_FREE(frame); 1590 return ntstatus_to_werror(status); 1591 } 1592 1593 *r->out.forest_trust_info = new_fti; 1594 1595 if (r->in.flags & DS_GFTI_UPDATE_TDO) { 1596 update_fti = true; 1597 } 1598 1599 status = dcerpc_lsa_lsaRQueryForestTrustInformation(local_lsa, frame, 1600 &local_lsa_policy, 1601 &trusted_domain_name, 1602 LSA_FOREST_TRUST_DOMAIN_INFO, 1603 &old_fti, &result); 1604 if (!NT_STATUS_IS_OK(status)) { 1605 DEBUG(0,("%s:%s: local_lsa.lsaRQueryForestTrustInformation(%s) failed %s\n", 1606 __location__, __func__, domain->name, nt_errstr(status))); 1607 TALLOC_FREE(frame); 1608 return WERR_INTERNAL_ERROR; 1609 } 1610 if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_FOUND)) { 1611 DEBUG(2,("%s: no forest trust information available for domain[%s] yet.\n", 1612 __func__, domain->name)); 1613 update_fti = true; 1614 old_fti = &_old_fti; 1615 result = NT_STATUS_OK; 1616 } 1617 if (!NT_STATUS_IS_OK(result)) { 1618 DEBUG(0,("%s:%s: local_lsa.lsaRQueryForestTrustInformation(%s) returned %s\n", 1619 __location__, __func__, domain->name, nt_errstr(result))); 1620 TALLOC_FREE(frame); 1621 return WERR_INTERNAL_ERROR; 1622 } 1623 1624 if (old_fti == NULL) { 1625 DEBUG(0,("%s:%s: local_lsa.lsaRQueryForestTrustInformation() " 1626 "returned success without returning forest trust information\n", 1627 __location__, __func__)); 1628 TALLOC_FREE(frame); 1629 return WERR_INTERNAL_ERROR; 1630 } 1631 1632 if (!update_fti) { 1633 goto done; 1634 } 1635 1636 status = dsdb_trust_merge_forest_info(frame, tdo, old_fti, new_fti, 1637 &merged_fti); 1638 if (!NT_STATUS_IS_OK(status)) { 1639 DEBUG(0,("%s:%s: dsdb_trust_merge_forest_info(%s) failed %s\n", 1640 __location__, __func__, domain->name, nt_errstr(status))); 1641 TALLOC_FREE(frame); 1642 return ntstatus_to_werror(status); 1643 } 1644 1645 status = dcerpc_lsa_lsaRSetForestTrustInformation(local_lsa, frame, 1646 &local_lsa_policy, 1647 &trusted_domain_name_l, 1648 LSA_FOREST_TRUST_DOMAIN_INFO, 1649 merged_fti, 1650 0, /* check_only=0 => store it! */ 1651 &collision_info, 1652 &result); 1653 if (!NT_STATUS_IS_OK(status)) { 1654 DEBUG(0,("%s:%s: local_lsa.lsaRSetForestTrustInformation(%s) failed %s\n", 1655 __location__, __func__, domain->name, nt_errstr(status))); 1656 TALLOC_FREE(frame); 1657 return WERR_INTERNAL_ERROR; 1658 } 1659 if (!NT_STATUS_IS_OK(result)) { 1660 DEBUG(0,("%s:%s: local_lsa.lsaRSetForestTrustInformation(%s) returned %s\n", 1661 __location__, __func__, domain->name, nt_errstr(result))); 1662 TALLOC_FREE(frame); 1663 return ntstatus_to_werror(result); 1664 } 1665 1666 done: 1667 DEBUG(5, ("_winbind_GetForestTrustInformation succeeded\n")); 1668 TALLOC_FREE(frame); 1669 return WERR_OK; 1670 } -
vendor/current/source3/winbindd/winbindd_getdcname.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 24 24 struct winbindd_getdcname_state { -
vendor/current/source3/winbindd/winbindd_getgrgid.c
r740 r988 125 125 } 126 126 127 response->data.gr.num_gr_mem = (uint32 )num_members;127 response->data.gr.num_gr_mem = (uint32_t)num_members; 128 128 129 129 /* Group membership lives at start of extra data */ -
vendor/current/source3/winbindd/winbindd_getgrnam.c
r740 r988 31 31 }; 32 32 33 static void winbindd_getgrnam_lookup sid_done(struct tevent_req *subreq);33 static void winbindd_getgrnam_lookupname_done(struct tevent_req *subreq); 34 34 static void winbindd_getgrnam_done(struct tevent_req *subreq); 35 35 … … 82 82 return tevent_req_post(req, ev); 83 83 } 84 tevent_req_set_callback(subreq, winbindd_getgrnam_lookup sid_done,84 tevent_req_set_callback(subreq, winbindd_getgrnam_lookupname_done, 85 85 req); 86 86 return req; 87 87 } 88 88 89 static void winbindd_getgrnam_lookup sid_done(struct tevent_req *subreq)89 static void winbindd_getgrnam_lookupname_done(struct tevent_req *subreq) 90 90 { 91 91 struct tevent_req *req = tevent_req_callback_data( … … 102 102 } 103 103 104 if ( (type != SID_NAME_DOM_GRP) && (type != SID_NAME_ALIAS) ) { 105 DEBUG(5,("getgrnam_recv: not a group!\n")); 104 switch (type) { 105 case SID_NAME_DOM_GRP: 106 case SID_NAME_ALIAS: 107 case SID_NAME_WKN_GRP: 108 /* 109 * Also give user types a chance: 110 * These might be user sids mapped to the ID_TYPE_BOTH, 111 * and in that case we should construct a group struct. 112 */ 113 case SID_NAME_USER: 114 case SID_NAME_COMPUTER: 115 break; 116 default: 106 117 tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP); 107 118 return; … … 160 171 } 161 172 162 response->data.gr.num_gr_mem = (uint32 )num_members;173 response->data.gr.num_gr_mem = (uint32_t)num_members; 163 174 164 175 /* Group membership lives at start of extra data */ -
vendor/current/source3/winbindd/winbindd_getgroups.c
r740 r988 30 30 int num_sids; 31 31 struct dom_sid *sids; 32 int next_sid;33 32 int num_gids; 34 33 gid_t *gids; … … 125 124 /* 126 125 * Convert the group SIDs to gids. state->sids[0] contains the user 127 * sid, so start at index 1. 126 * sid. If the idmap backend uses ID_TYPE_BOTH, we might need the 127 * the id of the user sid in the list of group sids, so map the 128 * complete token. 128 129 */ 129 130 130 state->gids = talloc_array(state, gid_t, state->num_sids-1); 131 if (tevent_req_nomem(state->gids, req)) { 132 return; 133 } 134 state->num_gids = 0; 135 state->next_sid = 1; 136 137 subreq = wb_sid2gid_send(state, state->ev, 138 &state->sids[state->next_sid]); 131 subreq = wb_sids2xids_send(state, state->ev, 132 state->sids, state->num_sids); 139 133 if (tevent_req_nomem(subreq, req)) { 140 134 return; … … 150 144 req, struct winbindd_getgroups_state); 151 145 NTSTATUS status; 152 153 status = wb_sid2gid_recv(subreq, &state->gids[state->num_gids]); 146 struct unixid *xids; 147 int i; 148 149 xids = talloc_array(state, struct unixid, state->num_sids); 150 if (tevent_req_nomem(xids, req)) { 151 return; 152 } 153 for (i=0; i < state->num_sids; i++) { 154 xids[i].type = ID_TYPE_NOT_SPECIFIED; 155 xids[i].id = UINT32_MAX; 156 } 157 158 status = wb_sids2xids_recv(subreq, xids, state->num_sids); 154 159 TALLOC_FREE(subreq); 160 if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED) || 161 NT_STATUS_EQUAL(status, STATUS_SOME_UNMAPPED)) 162 { 163 status = NT_STATUS_OK; 164 } 165 if (tevent_req_nterror(req, status)) { 166 return; 167 } 168 169 state->gids = talloc_array(state, gid_t, state->num_sids); 170 if (tevent_req_nomem(state->gids, req)) { 171 return; 172 } 173 state->num_gids = 0; 174 175 for (i=0; i < state->num_sids; i++) { 176 bool include_gid = false; 177 const char *debug_missing = NULL; 178 179 switch (xids[i].type) { 180 case ID_TYPE_NOT_SPECIFIED: 181 debug_missing = "not specified"; 182 break; 183 case ID_TYPE_UID: 184 if (i != 0) { 185 debug_missing = "uid"; 186 } 187 break; 188 case ID_TYPE_GID: 189 case ID_TYPE_BOTH: 190 include_gid = true; 191 break; 192 } 193 194 if (!include_gid) { 195 if (debug_missing == NULL) { 196 continue; 197 } 198 199 DEBUG(10, ("WARNING: skipping unix id (%u) for sid %s " 200 "from group list because the idmap type " 201 "is %s. " 202 "This might be a security problem when ACLs " 203 "contain DENY ACEs!\n", 204 (unsigned)xids[i].id, 205 sid_string_tos(&state->sids[i]), 206 debug_missing)); 207 continue; 208 } 209 210 state->gids[state->num_gids] = (gid_t)xids[i].id; 211 state->num_gids += 1; 212 } 155 213 156 214 /* 157 * In case of failure, just continue with the next gid 215 * This should not fail, as it does not do any reallocation, 216 * just updating the talloc size. 158 217 */ 159 if (NT_STATUS_IS_OK(status)) { 160 state->num_gids += 1; 161 } 162 state->next_sid += 1; 163 164 if (state->next_sid >= state->num_sids) { 165 tevent_req_done(req); 166 return; 167 } 168 169 subreq = wb_sid2gid_send(state, state->ev, 170 &state->sids[state->next_sid]); 171 if (tevent_req_nomem(subreq, req)) { 172 return; 173 } 174 tevent_req_set_callback(subreq, winbindd_getgroups_sid2gid_done, req); 218 state->gids = talloc_realloc(state, state->gids, gid_t, state->num_gids); 219 if (tevent_req_nomem(state->gids, req)) { 220 return; 221 } 222 223 tevent_req_done(req); 175 224 } 176 225 -
vendor/current/source3/winbindd/winbindd_group.c
r746 r988 69 69 /* Group name and password */ 70 70 71 s afe_strcpy(gr->gr_name, full_group_name, sizeof(gr->gr_name) - 1);72 s afe_strcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd) - 1);71 strlcpy(gr->gr_name, full_group_name, sizeof(gr->gr_name)); 72 strlcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd)); 73 73 74 74 return True; -
vendor/current/source3/winbindd/winbindd_list_groups.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 24 24 struct winbindd_list_groups_domstate { -
vendor/current/source3/winbindd/winbindd_list_users.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 24 24 struct winbindd_list_users_domstate { -
vendor/current/source3/winbindd/winbindd_lookuprids.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 #include "../libcli/security/security.h" 24 24 -
vendor/current/source3/winbindd/winbindd_misc.c
r740 r988 23 23 #include "includes.h" 24 24 #include "winbindd.h" 25 #include "libcli/security/dom_sid.h" 25 26 26 27 #undef DBGC_CLASS … … 43 44 static enum trust_type get_trust_type(struct winbindd_tdc_domain *domain) 44 45 { 45 if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN)46 if (domain->trust_attribs == LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) 46 47 return EXTERNAL; 47 else if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)48 else if (domain->trust_attribs == LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) 48 49 return FOREST; 49 50 else if (((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) == NETR_TRUST_FLAG_IN_FOREST) && … … 78 79 static bool trust_is_transitive(struct winbindd_tdc_domain *domain) 79 80 { 80 if ((domain->trust_attribs == NETR_TRUST_ATTRIBUTE_NON_TRANSITIVE) ||81 (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) ||82 (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL))81 if ((domain->trust_attribs == LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE) || 82 (domain->trust_attribs == LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) || 83 (domain->trust_attribs == LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL)) 83 84 return False; 84 85 return True; … … 121 122 "%s\\%s\\%s\\%s\\%s\\%s\\%s\\%s\n", 122 123 d->domain_name, 123 d->dns_name ? d->dns_name : d->domain_name,124 d->dns_name ? d->dns_name : "", 124 125 sid_string_talloc(state->mem_ctx, &d->sid), 125 126 get_trust_type_string(d), … … 172 173 173 174 for (i=0; i<trusts.count; i++) { 175 176 if (trusts.array[i].sid == NULL) { 177 continue; 178 } 179 if (dom_sid_equal(trusts.array[i].sid, &global_sid_NULL)) { 180 continue; 181 } 182 174 183 extra_data = talloc_asprintf_append_buffer( 175 extra_data, "%s\\%s\\%s\n", 176 trusts.array[i].netbios_name, 177 trusts.array[i].dns_name, 178 sid_string_talloc(state->mem_ctx, 179 trusts.array[i].sid)); 184 extra_data, "%s\\%s\\%s\\%u\\%u\\%u\n", 185 trusts.array[i].netbios_name, trusts.array[i].dns_name, 186 sid_string_talloc(state->mem_ctx, trusts.array[i].sid), 187 trusts.array[i].trust_flags, 188 (uint32_t)trusts.array[i].trust_type, 189 trusts.array[i].trust_attributes); 180 190 } 181 191 … … 192 202 extra_data = talloc_asprintf_append_buffer( 193 203 extra_data, "%s\\%s\\%s\n", domain->name, 194 domain->alt_name ? domain->alt_name : domain->name, 204 domain->alt_name != NULL ? 205 domain->alt_name : 206 domain->name, 195 207 sid_string_talloc(state->mem_ctx, &domain->sid)); 196 208 } … … 203 215 204 216 state->response->extra_data.data = extra_data; 205 state->response->length += extra_data_len +1;217 state->response->length += extra_data_len; 206 218 } 207 219 … … 381 393 void winbindd_interface_version(struct winbindd_cli_state *state) 382 394 { 383 DEBUG(3, ("[%5lu]: request interface version \n",384 (unsigned long)state->pid ));395 DEBUG(3, ("[%5lu]: request interface version (version = %d)\n", 396 (unsigned long)state->pid, WINBIND_INTERFACE_VERSION)); 385 397 386 398 state->response->data.interface_version = WINBIND_INTERFACE_VERSION; … … 405 417 (unsigned long)state->pid)); 406 418 407 fstrcpy(state->response->data.netbios_name, global_myname());419 fstrcpy(state->response->data.netbios_name, lp_netbios_name()); 408 420 request_ok(state); 409 421 } -
vendor/current/source3/winbindd/winbindd_msrpc.c
r860 r988 77 77 } 78 78 79 status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);79 status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol); 80 80 if (!NT_STATUS_IS_OK(status)) { 81 81 goto done; … … 136 136 } 137 137 138 status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);138 status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol); 139 139 if (!NT_STATUS_IS_OK(status)) { 140 140 goto done; … … 195 195 } 196 196 197 status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);197 status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol); 198 198 if (!NT_STATUS_IS_OK(status)) { 199 199 goto done; … … 235 235 enum lsa_SidType *types = NULL; 236 236 char *full_name = NULL; 237 const char *names[1]; 237 238 NTSTATUS name_map_status = NT_STATUS_UNSUCCESSFUL; 238 239 char *mapped_name = NULL; … … 255 256 &mapped_name); 256 257 257 /* Reset the full_name pointer if we mapped anyt thing */258 /* Reset the full_name pointer if we mapped anything */ 258 259 259 260 if (NT_STATUS_IS_OK(name_map_status) || … … 266 267 full_name?full_name:"", domain_name )); 267 268 269 names[0] = full_name; 270 268 271 result = winbindd_lookup_names(mem_ctx, domain, 1, 269 (const char **)&full_name, NULL,272 names, NULL, 270 273 &sids, &types); 271 274 if (!NT_STATUS_IS_OK(result)) … … 335 338 TALLOC_CTX *mem_ctx, 336 339 const struct dom_sid *sid, 337 uint32 *rids,340 uint32_t *rids, 338 341 size_t num_rids, 339 342 char **domain_name, … … 350 353 351 354 if (num_rids) { 352 sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids);355 sids = talloc_array(mem_ctx, struct dom_sid, num_rids); 353 356 if (sids == NULL) { 354 357 return NT_STATUS_NO_MEMORY; … … 440 443 user->base.full_name.string); 441 444 445 if (user_info->full_name == NULL) { 446 /* this might fail so we don't check the return code */ 447 wcache_query_user_fullname(domain, 448 mem_ctx, 449 user_sid, 450 &user_info->full_name); 451 } 452 442 453 status = NT_STATUS_OK; 443 454 goto done; … … 453 464 454 465 /* no cache; hit the wire */ 455 status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);466 status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol); 456 467 if (!NT_STATUS_IS_OK(status)) { 457 468 goto done; … … 513 524 514 525 /* no cache; hit the wire */ 515 status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);526 status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol); 516 527 if (!NT_STATUS_IS_OK(status)) { 517 528 goto done; … … 546 557 static NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain, 547 558 TALLOC_CTX *mem_ctx, 548 uint32 num_sids, const struct dom_sid *sids,549 uint32 *pnum_aliases,550 uint32 **palias_rids)559 uint32_t num_sids, const struct dom_sid *sids, 560 uint32_t *pnum_aliases, 561 uint32_t **palias_rids) 551 562 { 552 563 struct rpc_pipe_client *samr_pipe; … … 576 587 } 577 588 578 status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);589 status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol); 579 590 if (!NT_STATUS_IS_OK(status)) { 580 591 goto done; … … 617 628 { 618 629 NTSTATUS status, result; 619 uint32i, total_names = 0;630 uint32_t i, total_names = 0; 620 631 struct policy_handle dom_pol, group_pol; 621 uint32des_access = SEC_FLAG_MAXIMUM_ALLOWED;622 uint32 *rid_mem = NULL;623 uint32 group_rid;632 uint32_t des_access = SEC_FLAG_MAXIMUM_ALLOWED; 633 uint32_t *rid_mem = NULL; 634 uint32_t group_rid; 624 635 unsigned int j, r; 625 636 struct rpc_pipe_client *cli; … … 642 653 *num_names = 0; 643 654 644 result = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);655 result = cm_connect_sam(domain, mem_ctx, false, &cli, &dom_pol); 645 656 if (!NT_STATUS_IS_OK(result)) 646 657 return result; … … 707 718 #define MAX_LOOKUP_RIDS 900 708 719 709 *names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_names);710 *name_types = TALLOC_ZERO_ARRAY(mem_ctx, uint32, *num_names);711 *sid_mem = TALLOC_ZERO_ARRAY(mem_ctx, struct dom_sid, *num_names);720 *names = talloc_zero_array(mem_ctx, char *, *num_names); 721 *name_types = talloc_zero_array(mem_ctx, uint32_t, *num_names); 722 *sid_mem = talloc_zero_array(mem_ctx, struct dom_sid, *num_names); 712 723 713 724 for (j=0;j<(*num_names);j++) … … 774 785 #ifdef HAVE_LDAP 775 786 776 #include <ldap.h>777 778 static int get_ldap_seq(const char *server, int port, uint32*seq)787 #include "ads.h" 788 789 static int get_ldap_seq(const char *server, struct sockaddr_storage *ss, int port, uint32_t *seq) 779 790 { 780 791 int ret = -1; … … 792 803 */ 793 804 794 ldp = ldap_open_with_timeout(server, port, lp_ldap_timeout());805 ldp = ldap_open_with_timeout(server, ss, port, lp_ldap_timeout()); 795 806 if (ldp == NULL) 796 807 return -1; … … 801 812 802 813 if (ldap_search_st(ldp, "", LDAP_SCOPE_BASE, "(objectclass=*)", 803 CONST_DISCARD(char **, attrs), 0, &to, &res))814 discard_const_p(char *, attrs), 0, &to, &res)) 804 815 goto done; 805 816 … … 830 841 **********************************************************************/ 831 842 832 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32 *seq)843 static int get_ldap_sequence_number(struct winbindd_domain *domain, uint32_t *seq) 833 844 { 834 845 int ret = -1; … … 836 847 837 848 print_sockaddr(addr, sizeof(addr), &domain->dcaddr); 838 if ((ret = get_ldap_seq(addr, LDAP_PORT, seq)) == 0) {849 if ((ret = get_ldap_seq(addr, &domain->dcaddr, LDAP_PORT, seq)) == 0) { 839 850 DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence " 840 851 "number for Domain (%s) from DC (%s)\n", … … 852 863 struct rpc_pipe_client *samr_pipe; 853 864 struct policy_handle dom_pol; 854 uint32_t seq ;865 uint32_t seq = DOM_SEQUENCE_NONE; 855 866 TALLOC_CTX *tmp_ctx; 856 867 NTSTATUS status; … … 904 915 #endif /* HAVE_LDAP */ 905 916 906 status = cm_connect_sam(domain, tmp_ctx, &samr_pipe, &dom_pol);917 status = cm_connect_sam(domain, tmp_ctx, false, &samr_pipe, &dom_pol); 907 918 if (!NT_STATUS_IS_OK(status)) { 908 919 goto done; … … 993 1004 } 994 1005 995 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);1006 status = cm_connect_sam(domain, mem_ctx, false, &cli, &dom_pol); 996 1007 if (!NT_STATUS_IS_OK(status)) { 997 1008 goto done; … … 1043 1054 } 1044 1055 1045 status = cm_connect_sam(domain, mem_ctx, &cli, &dom_pol);1056 status = cm_connect_sam(domain, mem_ctx, false, &cli, &dom_pol); 1046 1057 if (!NT_STATUS_IS_OK(status)) { 1047 1058 goto done; … … 1131 1142 * a netlogon connection first. 1132 1143 */ 1133 invalidate_cm_connection( &domain->conn);1144 invalidate_cm_connection(domain); 1134 1145 domain->can_do_ncacn_ip_tcp = domain->active_directory; 1135 1146 if (!retried) { … … 1211 1222 * a netlogon connection first. 1212 1223 */ 1213 invalidate_cm_connection( &domain->conn);1224 invalidate_cm_connection(domain); 1214 1225 if (!retried) { 1215 1226 retried = true; -
vendor/current/source3/winbindd/winbindd_ndr.c
r740 r988 22 22 #include "../librpc/gen_ndr/ndr_netlogon.h" 23 23 #include "../librpc/gen_ndr/ndr_security.h" 24 #include "librpc/ndr/util.h" 24 #include "../librpc/gen_ndr/ndr_lsa.h" 25 #include "../librpc/ndr/libndr.h" 25 26 26 27 #undef DBGC_CLASS … … 75 76 #ifdef HAVE_ADS 76 77 extern struct winbindd_methods ads_methods; 78 extern struct winbindd_methods reconnect_ads_methods; 77 79 #endif 78 80 extern struct winbindd_methods msrpc_methods; … … 100 102 } else if (r == &ads_methods) { 101 103 ndr_print_string(ndr, name, "ads_methods"); 104 } else if (r == &reconnect_ads_methods) { 105 ndr_print_string(ndr, name, "reconnect_ads_methods"); 102 106 #endif 103 107 } else if (r == &builtin_passdb_methods) { … … 134 138 ndr_print_dom_sid(ndr, "sid", &r->sid); 135 139 ndr_print_netr_TrustFlags(ndr, "domain_flags", r->domain_flags); 136 ndr_print_ netr_TrustType(ndr, "domain_type", r->domain_type);137 ndr_print_ netr_TrustAttributes(ndr, "domain_trust_attribs", r->domain_trust_attribs);140 ndr_print_lsa_TrustType(ndr, "domain_type", r->domain_type); 141 ndr_print_lsa_TrustAttributes(ndr, "domain_trust_attribs", r->domain_trust_attribs); 138 142 ndr_print_bool(ndr, "initialized", r->initialized); 139 143 ndr_print_bool(ndr, "native_mode", r->native_mode); -
vendor/current/source3/winbindd/winbindd_pam.c
r860 r988 38 38 #include "passdb/machine_sid.h" 39 39 #include "auth.h" 40 #include "../lib/tsocket/tsocket.h" 41 #include "auth/kerberos/pac_utils.h" 42 #include "auth/gensec/gensec.h" 43 #include "librpc/crypto/gse_krb5.h" 44 #include "lib/afs/afs_funcs.h" 40 45 41 46 #undef DBGC_CLASS … … 52 57 53 58 resp->data.auth.info3.logon_time = 54 nt_time_to_unix(info3->base.l ast_logon);59 nt_time_to_unix(info3->base.logon_time); 55 60 resp->data.auth.info3.logoff_time = 56 nt_time_to_unix(info3->base.l ast_logoff);61 nt_time_to_unix(info3->base.logoff_time); 57 62 resp->data.auth.info3.kickoff_time = 58 nt_time_to_unix(info3->base. acct_expiry);63 nt_time_to_unix(info3->base.kickoff_time); 59 64 resp->data.auth.info3.pass_last_set_time = 60 65 nt_time_to_unix(info3->base.last_password_change); … … 93 98 info3->base.logon_server.string); 94 99 fstrcpy(resp->data.auth.info3.logon_dom, 95 info3->base. domain.string);100 info3->base.logon_domain.string); 96 101 97 102 ex = talloc_strdup(mem_ctx, ""); … … 156 161 const char *nt_username, *nt_domain; 157 162 158 nt_domain = talloc_strdup(mem_ctx, info3->base. domain.string);163 nt_domain = talloc_strdup(mem_ctx, info3->base.logon_domain.string); 159 164 if (!nt_domain) { 160 165 /* If the server didn't give us one, just use the one … … 217 222 } 218 223 219 strlower_m(afsname); 224 if (!strlower_m(afsname)) { 225 return NT_STATUS_INVALID_PARAMETER; 226 } 220 227 221 228 DEBUG(10, ("Generating token for user %s\n", afsname)); … … 271 278 if (!group_sid || !group_sid[0]) { 272 279 /* NO sid supplied, all users may access */ 280 TALLOC_FREE(frame); 273 281 return NT_STATUS_OK; 274 282 } … … 386 394 p->password_properties; 387 395 r->data.auth.policy.expire = 388 nt_time_to_unix_abs(( NTTIME *)&(p->max_password_age));396 nt_time_to_unix_abs((const NTTIME *)&(p->max_password_age)); 389 397 r->data.auth.policy.min_passwordage = 390 nt_time_to_unix_abs(( NTTIME *)&(p->min_password_age));398 nt_time_to_unix_abs((const NTTIME *)&(p->min_password_age)); 391 399 } 392 400 … … 422 430 static NTSTATUS get_max_bad_attempts_from_lockout_policy(struct winbindd_domain *domain, 423 431 TALLOC_CTX *mem_ctx, 424 uint16 *lockout_threshold)432 uint16_t *lockout_threshold) 425 433 { 426 434 struct winbindd_methods *methods; … … 444 452 static NTSTATUS get_pwd_properties(struct winbindd_domain *domain, 445 453 TALLOC_CTX *mem_ctx, 446 uint32 *password_properties)454 uint32_t *password_properties) 447 455 { 448 456 struct winbindd_methods *methods; … … 485 493 gen_cc = talloc_asprintf( 486 494 mem_ctx, "WRFILE:/tmp/krb5cc_%d", uid); 495 } 496 if (strequal(type, "KEYRING")) { 497 gen_cc = talloc_asprintf( 498 mem_ctx, "KEYRING:persistent:%d", uid); 499 } 500 501 if (strnequal(type, "FILE:/", 6) || 502 strnequal(type, "WRFILE:/", 8) || 503 strnequal(type, "DIR:/", 5)) { 504 505 /* we allow only one "%u" substitution */ 506 507 char *p; 508 509 p = strchr(type, '%'); 510 if (p != NULL) { 511 512 p++; 513 514 if (p != NULL && *p == 'u' && strchr(p, '%') == NULL) { 515 char uid_str[sizeof("18446744073709551615")]; 516 517 snprintf(uid_str, sizeof(uid_str), "%u", uid); 518 519 gen_cc = talloc_string_sub2(mem_ctx, 520 type, 521 "%u", 522 uid_str, 523 /* remove_unsafe_characters */ 524 false, 525 /* replace_once */ 526 true, 527 /* allow_trailing_dollar */ 528 false); 529 } 530 } 487 531 } 488 532 } … … 547 591 const char *user_ccache_file; 548 592 struct PAC_LOGON_INFO *logon_info = NULL; 593 struct PAC_DATA *pac_data = NULL; 594 struct PAC_DATA_CTR *pac_data_ctr = NULL; 595 const char *local_service; 596 int i; 597 struct netr_SamInfo3 *info3_copy = NULL; 549 598 550 599 *info3 = NULL; 600 601 if (domain->alt_name == NULL) { 602 return NT_STATUS_INVALID_PARAMETER; 603 } 551 604 552 605 /* 1st step: … … 580 633 parse_domain_user(user, name_domain, name_user); 581 634 582 realm = domain->alt_name; 583 strupper_m(realm); 635 realm = talloc_strdup(mem_ctx, domain->alt_name); 636 if (realm == NULL) { 637 return NT_STATUS_NO_MEMORY; 638 } 639 640 if (!strupper_m(realm)) { 641 return NT_STATUS_INVALID_PARAMETER; 642 } 584 643 585 644 principal_s = talloc_asprintf(mem_ctx, "%s@%s", name_user, realm); … … 592 651 return NT_STATUS_NO_MEMORY; 593 652 } 653 654 local_service = talloc_asprintf(mem_ctx, "%s$@%s", 655 lp_netbios_name(), lp_realm()); 656 if (local_service == NULL) { 657 return NT_STATUS_NO_MEMORY; 658 } 659 594 660 595 661 /* if this is a user ccache, we need to act as the user to let the krb5 … … 614 680 WINBINDD_PAM_AUTH_KRB5_RENEW_TIME, 615 681 NULL, 616 &logon_info); 682 local_service, 683 &pac_data_ctr); 617 684 if (user_ccache_file != NULL) { 618 685 gain_root_privilege(); … … 625 692 } 626 693 627 *info3 = &logon_info->info3; 694 if (pac_data_ctr == NULL) { 695 goto failed; 696 } 697 698 pac_data = pac_data_ctr->pac_data; 699 if (pac_data == NULL) { 700 goto failed; 701 } 702 703 for (i=0; i < pac_data->num_buffers; i++) { 704 705 if (pac_data->buffers[i].type != PAC_TYPE_LOGON_INFO) { 706 continue; 707 } 708 709 logon_info = pac_data->buffers[i].info->logon_info.info; 710 if (!logon_info) { 711 return NT_STATUS_INVALID_PARAMETER; 712 } 713 714 break; 715 } 716 717 if (logon_info == NULL) { 718 DEBUG(10,("Missing logon_info in ticket of %s\n", 719 principal_s)); 720 return NT_STATUS_INVALID_PARAMETER; 721 } 628 722 629 723 DEBUG(10,("winbindd_raw_kerberos_login: winbindd validated ticket of %s\n", 630 724 principal_s)); 725 726 result = create_info3_from_pac_logon_info(mem_ctx, logon_info, &info3_copy); 727 if (!NT_STATUS_IS_OK(result)) { 728 goto failed; 729 } 631 730 632 731 /* if we had a user's ccache then return that string for the pam … … 665 764 666 765 } 667 766 *info3 = info3_copy; 668 767 return NT_STATUS_OK; 669 768 … … 727 826 ****************************************************************/ 728 827 729 staticNTSTATUS append_auth_data(TALLOC_CTX *mem_ctx,730 731 732 733 734 828 NTSTATUS append_auth_data(TALLOC_CTX *mem_ctx, 829 struct winbindd_response *resp, 830 uint32_t request_flags, 831 struct netr_SamInfo3 *info3, 832 const char *name_domain, 833 const char *name_user) 735 834 { 736 835 NTSTATUS result; … … 798 897 { 799 898 NTSTATUS result = NT_STATUS_LOGON_FAILURE; 800 uint16 max_allowed_bad_attempts;899 uint16_t max_allowed_bad_attempts; 801 900 fstring name_domain, name_user; 802 901 struct dom_sid sid; 803 902 enum lsa_SidType type; 804 903 uchar new_nt_pass[NT_HASH_LEN]; 805 const uint8 *cached_nt_pass;806 const uint8 *cached_salt;904 const uint8_t *cached_nt_pass; 905 const uint8_t *cached_salt; 807 906 struct netr_SamInfo3 *my_info3; 808 907 time_t kickoff_time, must_change_time; … … 904 1003 } 905 1004 906 kickoff_time = nt_time_to_unix(my_info3->base. acct_expiry);1005 kickoff_time = nt_time_to_unix(my_info3->base.kickoff_time); 907 1006 if (kickoff_time != 0 && time(NULL) > kickoff_time) { 908 1007 return NT_STATUS_ACCOUNT_EXPIRED; … … 920 1019 if ((state->request->flags & WBFLAG_PAM_KRB5) && 921 1020 ((tdc_domain = wcache_tdc_fetch_domain(state->mem_ctx, name_domain)) != NULL) && 922 ((tdc_domain->trust_type & NETR_TRUST_TYPE_UPLEVEL) ||1021 ((tdc_domain->trust_type & LSA_TRUST_TYPE_UPLEVEL) || 923 1022 /* used to cope with the case winbindd starting without network. */ 924 1023 !strequal(tdc_domain->domain_name, tdc_domain->dns_name))) { … … 930 1029 const char *service = NULL; 931 1030 const char *user_ccache_file; 1031 1032 if (domain->alt_name == NULL) { 1033 return NT_STATUS_INVALID_PARAMETER; 1034 } 932 1035 933 1036 uid = get_uid_from_request(state->request); … … 945 1048 } 946 1049 947 realm = domain->alt_name; 948 strupper_m(realm); 1050 realm = talloc_strdup(state->mem_ctx, domain->alt_name); 1051 if (realm == NULL) { 1052 return NT_STATUS_NO_MEMORY; 1053 } 1054 1055 if (!strupper_m(realm)) { 1056 return NT_STATUS_INVALID_PARAMETER; 1057 } 949 1058 950 1059 principal_s = talloc_asprintf(state->mem_ctx, "%s@%s", name_user, realm); … … 968 1077 state->request->data.auth.user, 969 1078 state->request->data.auth.pass, 970 domain->alt_name,1079 realm, 971 1080 uid, 972 1081 time(NULL), … … 987 1096 * offline?) see auth/auth_sam.c:sam_account_ok for details */ 988 1097 989 unix_to_nt_time(&my_info3->base.l ast_logon, time(NULL));1098 unix_to_nt_time(&my_info3->base.logon_time, time(NULL)); 990 1099 my_info3->base.bad_password_count = 0; 991 1100 … … 1026 1135 if (my_info3->base.bad_password_count >= max_allowed_bad_attempts) { 1027 1136 1028 uint32 password_properties;1137 uint32_t password_properties; 1029 1138 1030 1139 result = get_pwd_properties(domain, state->mem_ctx, &password_properties); … … 1100 1209 1101 1210 if (!contact_domain->initialized) { 1102 init_dc_connection(contact_domain );1211 init_dc_connection(contact_domain, false); 1103 1212 } 1104 1213 … … 1120 1229 1121 1230 static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx, 1231 uint32_t logon_parameters, 1122 1232 const char *domain, const char *user, 1123 1233 const DATA_BLOB *challenge, … … 1126 1236 struct netr_SamInfo3 **pinfo3) 1127 1237 { 1238 struct auth_context *auth_context; 1239 struct auth_serversupplied_info *server_info; 1128 1240 struct auth_usersupplied_info *user_info = NULL; 1241 struct tsocket_address *local; 1242 struct netr_SamInfo3 *info3; 1129 1243 NTSTATUS status; 1130 1131 status = make_user_info(&user_info, user, user, domain, domain, 1132 global_myname(), lm_resp, nt_resp, NULL, NULL, 1244 int rc; 1245 TALLOC_CTX *frame = talloc_stackframe(); 1246 1247 rc = tsocket_address_inet_from_strings(frame, 1248 "ip", 1249 "127.0.0.1", 1250 0, 1251 &local); 1252 if (rc < 0) { 1253 TALLOC_FREE(frame); 1254 return NT_STATUS_NO_MEMORY; 1255 } 1256 status = make_user_info(frame, &user_info, user, user, domain, domain, 1257 lp_netbios_name(), local, lm_resp, nt_resp, NULL, NULL, 1133 1258 NULL, AUTH_PASSWORD_RESPONSE); 1134 1259 if (!NT_STATUS_IS_OK(status)) { 1135 1260 DEBUG(10, ("make_user_info failed: %s\n", nt_errstr(status))); 1261 TALLOC_FREE(frame); 1136 1262 return status; 1137 1263 } 1264 1265 user_info->logon_parameters = logon_parameters; 1138 1266 1139 1267 /* We don't want any more mapping of the username */ 1140 1268 user_info->mapped_state = True; 1141 1269 1142 status = check_sam_security_info3(challenge, talloc_tos(), user_info, 1143 pinfo3); 1144 free_user_info(&user_info); 1270 /* We don't want to come back to winbindd or to do PAM account checks */ 1271 user_info->flags |= USER_INFO_LOCAL_SAM_ONLY | USER_INFO_INFO3_AND_NO_AUTHZ; 1272 1273 status = make_auth_context_fixed(frame, &auth_context, challenge->data); 1274 1275 if (!NT_STATUS_IS_OK(status)) { 1276 DEBUG(0, ("Failed to test authentication with check_sam_security_info3: %s\n", nt_errstr(status))); 1277 TALLOC_FREE(frame); 1278 return status; 1279 } 1280 1281 status = auth_check_ntlm_password(mem_ctx, 1282 auth_context, 1283 user_info, 1284 &server_info); 1285 1286 if (!NT_STATUS_IS_OK(status)) { 1287 TALLOC_FREE(frame); 1288 return status; 1289 } 1290 1291 info3 = talloc_zero(mem_ctx, struct netr_SamInfo3); 1292 if (info3 == NULL) { 1293 TALLOC_FREE(frame); 1294 return NT_STATUS_NO_MEMORY; 1295 } 1296 1297 status = serverinfo_to_SamInfo3(server_info, info3); 1298 if (!NT_STATUS_IS_OK(status)) { 1299 TALLOC_FREE(frame); 1300 TALLOC_FREE(info3); 1301 DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n", 1302 nt_errstr(status))); 1303 return status; 1304 } 1305 1306 *pinfo3 = info3; 1145 1307 DEBUG(10, ("Authenticaticating user %s\\%s returned %s\n", domain, 1146 1308 user, nt_errstr(status))); 1309 TALLOC_FREE(frame); 1147 1310 return status; 1148 1311 } … … 1151 1314 TALLOC_CTX *mem_ctx, 1152 1315 uint32_t logon_parameters, 1153 const char *server,1154 1316 const char *username, 1317 const char *password, 1155 1318 const char *domainname, 1156 1319 const char *workstation, … … 1158 1321 DATA_BLOB lm_response, 1159 1322 DATA_BLOB nt_response, 1323 bool interactive, 1160 1324 struct netr_SamInfo3 **info3) 1161 1325 { … … 1167 1331 do { 1168 1332 struct rpc_pipe_client *netlogon_pipe; 1169 const struct pipe_auth_data *auth;1170 uint32_t neg_flags = 0;1333 uint8_t authoritative = 0; 1334 uint32_t flags = 0; 1171 1335 1172 1336 ZERO_STRUCTP(info3); … … 1185 1349 "particular call, forcing the close " 1186 1350 "of this connection\n")); 1187 invalidate_cm_connection( &domain->conn);1351 invalidate_cm_connection(domain); 1188 1352 } 1189 1353 … … 1216 1380 } 1217 1381 netr_attempts = 0; 1218 1219 auth = netlogon_pipe->auth; 1220 if (netlogon_pipe->dc) { 1221 neg_flags = netlogon_pipe->dc->negotiate_flags; 1222 } 1223 1224 /* It is really important to try SamLogonEx here, 1225 * because in a clustered environment, we want to use 1226 * one machine account from multiple physical 1227 * computers. 1228 * 1229 * With a normal SamLogon call, we must keep the 1230 * credentials chain updated and intact between all 1231 * users of the machine account (which would imply 1232 * cross-node communication for every NTLM logon). 1233 * 1234 * (The credentials chain is not per NETLOGON pipe 1235 * connection, but globally on the server/client pair 1236 * by machine name). 1237 * 1238 * When using SamLogonEx, the credentials are not 1239 * supplied, but the session key is implied by the 1240 * wrapping SamLogon context. 1241 * 1242 * -- abartlet 21 April 2008 1243 * 1244 * It's also important to use NetlogonValidationSamInfo4 (6), 1245 * because it relies on the rpc transport encryption 1246 * and avoids using the global netlogon schannel 1247 * session key to en/decrypt secret information 1248 * like the user_session_key for network logons. 1249 * 1250 * [MS-APDS] 3.1.5.2 NTLM Network Logon 1251 * says NETLOGON_NEG_CROSS_FOREST_TRUSTS and 1252 * NETLOGON_NEG_AUTHENTICATED_RPC set together 1253 * are the indication that the server supports 1254 * NetlogonValidationSamInfo4 (6). And it must only 1255 * be used if "SealSecureChannel" is used. 1256 * 1257 * -- metze 4 February 2011 1258 */ 1259 1260 if (auth == NULL) { 1261 domain->can_do_validation6 = false; 1262 } else if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { 1263 domain->can_do_validation6 = false; 1264 } else if (auth->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { 1265 domain->can_do_validation6 = false; 1266 } else if (!(neg_flags & NETLOGON_NEG_CROSS_FOREST_TRUSTS)) { 1267 domain->can_do_validation6 = false; 1268 } else if (!(neg_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) { 1269 domain->can_do_validation6 = false; 1270 } 1271 1272 if (domain->can_do_samlogon_ex && domain->can_do_validation6) { 1273 result = rpccli_netlogon_sam_network_logon_ex( 1274 netlogon_pipe, 1275 mem_ctx, 1276 logon_parameters, 1277 server, /* server name */ 1278 username, /* user name */ 1279 domainname, /* target domain */ 1280 workstation, /* workstation */ 1281 chal, 1282 6, 1283 lm_response, 1284 nt_response, 1285 info3); 1382 if (domain->conn.netlogon_creds == NULL) { 1383 DBG_NOTICE("No security credentials available for " 1384 "domain [%s]\n", domainname); 1385 result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 1386 } else if (interactive && username != NULL && password != NULL) { 1387 result = rpccli_netlogon_password_logon(domain->conn.netlogon_creds, 1388 netlogon_pipe->binding_handle, 1389 mem_ctx, 1390 logon_parameters, 1391 domainname, 1392 username, 1393 password, 1394 workstation, 1395 NetlogonInteractiveInformation, 1396 info3); 1286 1397 } else { 1287 result = rpccli_netlogon_sam_network_logon( 1288 netlogon_pipe, 1289 mem_ctx, 1290 logon_parameters, 1291 server, /* server name */ 1292 username, /* user name */ 1293 domainname, /* target domain */ 1294 workstation, /* workstation */ 1295 chal, 1296 domain->can_do_validation6 ? 6 : 3, 1297 lm_response, 1298 nt_response, 1299 info3); 1300 } 1301 1302 if (NT_STATUS_EQUAL(result, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) { 1303 1304 /* 1305 * It's likely that the server also does not support 1306 * validation level 6 1307 */ 1308 domain->can_do_validation6 = false; 1309 1310 if (domain->can_do_samlogon_ex) { 1311 DEBUG(3, ("Got a DC that can not do NetSamLogonEx, " 1312 "retrying with NetSamLogon\n")); 1313 domain->can_do_samlogon_ex = false; 1314 retry = true; 1315 continue; 1316 } 1317 1318 1319 /* Got DCERPC_FAULT_OP_RNG_ERROR for SamLogon 1320 * (no Ex). This happens against old Samba 1321 * DCs. Drop the connection. 1322 */ 1323 invalidate_cm_connection(&domain->conn); 1324 result = NT_STATUS_LOGON_FAILURE; 1325 break; 1326 } 1327 1328 if (domain->can_do_validation6 && 1329 (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_INFO_CLASS) || 1330 NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PARAMETER) || 1331 NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL))) { 1332 DEBUG(3,("Got a DC that can not do validation level 6, " 1333 "retrying with level 3\n")); 1334 domain->can_do_validation6 = false; 1335 retry = true; 1336 continue; 1398 result = rpccli_netlogon_network_logon(domain->conn.netlogon_creds, 1399 netlogon_pipe->binding_handle, 1400 mem_ctx, 1401 logon_parameters, 1402 username, 1403 domainname, 1404 workstation, 1405 chal, 1406 lm_response, 1407 nt_response, 1408 &authoritative, 1409 &flags, 1410 info3); 1337 1411 } 1338 1412 … … 1358 1432 1359 1433 if ( NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) ) { 1360 DEBUG(3,("winbind_samlogon_retry_loop: sam_logon returned " 1361 "ACCESS_DENIED. Maybe the trust account " 1434 DEBUG(1,("winbind_samlogon_retry_loop: sam_logon returned " 1435 "ACCESS_DENIED. Maybe the DC has Restrict " 1436 "NTLM set or the trust account " 1362 1437 "password was changed and we didn't know it. " 1363 1438 "Killing connections to domain %s\n", 1364 1439 domainname)); 1365 invalidate_cm_connection( &domain->conn);1440 invalidate_cm_connection(domain); 1366 1441 retry = true; 1442 } 1443 1444 if (NT_STATUS_EQUAL(result, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) { 1445 /* 1446 * Got DCERPC_FAULT_OP_RNG_ERROR for SamLogon 1447 * (no Ex). This happens against old Samba 1448 * DCs, if LogonSamLogonEx() fails with an error 1449 * e.g. NT_STATUS_NO_SUCH_USER or NT_STATUS_WRONG_PASSWORD. 1450 * 1451 * The server will log something like this: 1452 * api_net_sam_logon_ex: Failed to marshall NET_R_SAM_LOGON_EX. 1453 * 1454 * This sets the whole connection into a fault_state mode 1455 * and all following request get NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE. 1456 * 1457 * This also happens to our retry with LogonSamLogonWithFlags() 1458 * and LogonSamLogon(). 1459 * 1460 * In order to recover from this situation, we need to 1461 * drop the connection. 1462 */ 1463 invalidate_cm_connection(domain); 1464 result = NT_STATUS_LOGON_FAILURE; 1465 break; 1367 1466 } 1368 1467 … … 1374 1473 "Killing connections to domain %s\n", 1375 1474 domainname)); 1376 invalidate_cm_connection( &domain->conn);1475 invalidate_cm_connection(domain); 1377 1476 } 1378 1477 return result; … … 1417 1516 */ 1418 1517 names_blob = NTLMv2_generate_names_blob( 1419 mem_ctx, global_myname(), lp_workgroup());1518 mem_ctx, lp_netbios_name(), lp_workgroup()); 1420 1519 1421 1520 if (!SMBNTLMv2encrypt(mem_ctx, name_user, name_domain, … … 1442 1541 1443 1542 result = winbindd_dual_auth_passdb( 1444 mem_ctx, name_domain, name_user,1543 mem_ctx, 0, name_domain, name_user, 1445 1544 &chal_blob, &lm_resp, &nt_resp, info3); 1446 goto done; 1545 1546 /* 1547 * We need to try the remote NETLOGON server if this is NOT_IMPLEMENTED 1548 */ 1549 if (!NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) { 1550 goto done; 1551 } 1447 1552 } 1448 1553 … … 1452 1557 mem_ctx, 1453 1558 0, 1454 domain->dcname,1455 1559 name_user, 1560 pass, 1456 1561 name_domain, 1457 global_myname(),1562 lp_netbios_name(), 1458 1563 chal, 1459 1564 lm_resp, 1460 1565 nt_resp, 1566 true, /* interactive */ 1461 1567 &my_info3); 1462 1568 if (!NT_STATUS_IS_OK(result)) { … … 1475 1581 union samr_UserInfo *info = NULL; 1476 1582 NTSTATUS status_tmp, result_tmp; 1477 uint32 acct_flags;1583 uint32_t acct_flags; 1478 1584 struct dcerpc_binding_handle *b; 1479 1585 1480 status_tmp = cm_connect_sam(domain, mem_ctx, 1586 status_tmp = cm_connect_sam(domain, mem_ctx, false, 1481 1587 &samr_pipe, &samr_domain_handle); 1482 1588 … … 1586 1692 *lp_winbind_separator(), 1587 1693 name_user ); 1588 s afe_strcpy( state->request->data.auth.user, domain_user,1589 sizeof(state->request->data.auth.user) -1);1694 strlcpy( state->request->data.auth.user, domain_user, 1695 sizeof(state->request->data.auth.user)); 1590 1696 } 1591 1697 … … 1601 1707 1602 1708 winbindd_flush_negative_conn_cache(domain); 1603 result = init_dc_connection(domain );1709 result = init_dc_connection(domain, false); 1604 1710 } 1605 1711 } … … 1724 1830 info3->base.rid); 1725 1831 1832 if (info3->base.full_name.string == NULL) { 1833 struct netr_SamInfo3 *cached_info3; 1834 1835 cached_info3 = netsamlogon_cache_get(state->mem_ctx, 1836 &user_sid); 1837 if (cached_info3 != NULL && 1838 cached_info3->base.full_name.string != NULL) { 1839 info3->base.full_name.string = 1840 talloc_strdup(info3, 1841 cached_info3->base.full_name.string); 1842 } else { 1843 1844 /* this might fail so we don't check the return code */ 1845 wcache_query_user_fullname(domain, 1846 info3, 1847 &user_sid, 1848 &info3->base.full_name.string); 1849 } 1850 } 1851 1726 1852 wcache_invalidate_samlogon(find_domain_from_name(name_domain), 1727 1853 &user_sid); … … 1807 1933 1808 1934 return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; 1935 } 1936 1937 NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain, 1938 TALLOC_CTX *mem_ctx, 1939 uint32_t logon_parameters, 1940 const char *name_user, 1941 const char *name_domain, 1942 const char *workstation, 1943 const uint8_t chal[8], 1944 DATA_BLOB lm_response, 1945 DATA_BLOB nt_response, 1946 struct netr_SamInfo3 **info3) 1947 { 1948 NTSTATUS result; 1949 1950 if (strequal(name_domain, get_global_sam_name())) { 1951 DATA_BLOB chal_blob = data_blob_const( 1952 chal, 8); 1953 1954 result = winbindd_dual_auth_passdb( 1955 mem_ctx, 1956 logon_parameters, 1957 name_domain, name_user, 1958 &chal_blob, &lm_response, &nt_response, info3); 1959 1960 /* 1961 * We need to try the remote NETLOGON server if this is NOT_IMPLEMENTED 1962 */ 1963 if (!NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) { 1964 goto process_result; 1965 } 1966 } 1967 1968 result = winbind_samlogon_retry_loop(domain, 1969 mem_ctx, 1970 logon_parameters, 1971 name_user, 1972 NULL, /* password */ 1973 name_domain, 1974 /* Bug #3248 - found by Stefan Burkei. */ 1975 workstation, /* We carefully set this above so use it... */ 1976 chal, 1977 lm_response, 1978 nt_response, 1979 false, /* interactive */ 1980 info3); 1981 if (!NT_STATUS_IS_OK(result)) { 1982 goto done; 1983 } 1984 1985 process_result: 1986 1987 if (NT_STATUS_IS_OK(result)) { 1988 struct dom_sid user_sid; 1989 1990 sid_compose(&user_sid, (*info3)->base.domain_sid, 1991 (*info3)->base.rid); 1992 1993 if ((*info3)->base.full_name.string == NULL) { 1994 struct netr_SamInfo3 *cached_info3; 1995 1996 cached_info3 = netsamlogon_cache_get(mem_ctx, 1997 &user_sid); 1998 if (cached_info3 != NULL && 1999 cached_info3->base.full_name.string != NULL) { 2000 (*info3)->base.full_name.string = 2001 talloc_strdup(*info3, 2002 cached_info3->base.full_name.string); 2003 } else { 2004 2005 /* this might fail so we don't check the return code */ 2006 wcache_query_user_fullname(domain, 2007 *info3, 2008 &user_sid, 2009 &(*info3)->base.full_name.string); 2010 } 2011 } 2012 2013 wcache_invalidate_samlogon(find_domain_from_name(name_domain), 2014 &user_sid); 2015 netsamlogon_cache_store(name_user, *info3); 2016 } 2017 2018 done: 2019 2020 /* give us a more useful (more correct?) error code */ 2021 if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || 2022 (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) { 2023 result = NT_STATUS_NO_LOGON_SERVERS; 2024 } 2025 2026 DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, 2027 ("NTLM CRAP authentication for user [%s]\\[%s] returned %s\n", 2028 name_domain, 2029 name_user, 2030 nt_errstr(result))); 2031 2032 return result; 1809 2033 } 1810 2034 … … 1859 2083 } 1860 2084 1861 if (strequal(name_domain, get_global_sam_name())) { 1862 DATA_BLOB chal_blob = data_blob_const( 1863 state->request->data.auth_crap.chal, 1864 sizeof(state->request->data.auth_crap.chal)); 1865 1866 result = winbindd_dual_auth_passdb( 1867 state->mem_ctx, name_domain, name_user, 1868 &chal_blob, &lm_resp, &nt_resp, &info3); 1869 goto process_result; 1870 } 1871 1872 result = winbind_samlogon_retry_loop(domain, 1873 state->mem_ctx, 1874 state->request->data.auth_crap.logon_parameters, 1875 domain->dcname, 1876 name_user, 1877 name_domain, 1878 /* Bug #3248 - found by Stefan Burkei. */ 1879 workstation, /* We carefully set this above so use it... */ 1880 state->request->data.auth_crap.chal, 1881 lm_resp, 1882 nt_resp, 1883 &info3); 2085 result = winbind_dual_SamLogon(domain, 2086 state->mem_ctx, 2087 state->request->data.auth_crap.logon_parameters, 2088 name_user, 2089 name_domain, 2090 /* Bug #3248 - found by Stefan Burkei. */ 2091 workstation, /* We carefully set this above so use it... */ 2092 state->request->data.auth_crap.chal, 2093 lm_resp, 2094 nt_resp, 2095 &info3); 1884 2096 if (!NT_STATUS_IS_OK(result)) { 1885 2097 goto done; 1886 2098 } 1887 2099 1888 process_result:1889 1890 2100 if (NT_STATUS_IS_OK(result)) { 1891 struct dom_sid user_sid;1892 1893 sid_compose(&user_sid, info3->base.domain_sid,1894 info3->base.rid);1895 wcache_invalidate_samlogon(find_domain_from_name(name_domain),1896 &user_sid);1897 netsamlogon_cache_store(name_user, info3);1898 1899 2101 /* Check if the user is in the right group */ 1900 2102 … … 1920 2122 done: 1921 2123 1922 /* give us a more useful (more correct?) error code */1923 if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) ||1924 (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {1925 result = NT_STATUS_NO_LOGON_SERVERS;1926 }1927 1928 2124 if (state->request->flags & WBFLAG_PAM_NT_STATUS_SQUASH) { 1929 2125 result = nt_status_squash(result); … … 1931 2127 1932 2128 set_auth_errors(state->response, result); 1933 1934 DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,1935 ("NTLM CRAP authentication for user [%s]\\[%s] returned %s (PAM: %d)\n",1936 name_domain,1937 name_user,1938 state->response->data.auth.nt_status_string,1939 state->response->data.auth.pam_error));1940 2129 1941 2130 return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; … … 1975 2164 /* Get sam handle */ 1976 2165 1977 result = cm_connect_sam(contact_domain, state->mem_ctx, &cli,2166 result = cm_connect_sam(contact_domain, state->mem_ctx, true, &cli, 1978 2167 &dom_pol); 1979 2168 if (!NT_STATUS_IS_OK(result)) { … … 2214 2403 2215 2404 if (!*domain && lp_winbind_use_default_domain()) { 2216 fstrcpy(domain, (char *)lp_workgroup());2405 fstrcpy(domain,lp_workgroup()); 2217 2406 } 2218 2407 … … 2242 2431 state->request->data.chng_pswd_auth_crap.old_lm_hash_enc_len); 2243 2432 } else { 2244 new_lm_password .length = 0;2245 old_lm_hash_enc .length = 0;2433 new_lm_password = data_blob_null; 2434 old_lm_hash_enc = data_blob_null; 2246 2435 } 2247 2436 2248 2437 /* Get sam handle */ 2249 2438 2250 result = cm_connect_sam(contact_domain, state->mem_ctx, &cli, &dom_pol);2439 result = cm_connect_sam(contact_domain, state->mem_ctx, true, &cli, &dom_pol); 2251 2440 if (!NT_STATUS_IS_OK(result)) { 2252 2441 DEBUG(1, ("could not get SAM handle on DC for %s\n", domain)); … … 2283 2472 return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; 2284 2473 } 2474 2475 #ifdef HAVE_KRB5 2476 static NTSTATUS extract_pac_vrfy_sigs(TALLOC_CTX *mem_ctx, DATA_BLOB pac_blob, 2477 struct PAC_LOGON_INFO **logon_info) 2478 { 2479 krb5_context krbctx = NULL; 2480 krb5_error_code k5ret; 2481 krb5_keytab keytab; 2482 krb5_kt_cursor cursor; 2483 krb5_keytab_entry entry; 2484 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 2485 2486 ZERO_STRUCT(entry); 2487 ZERO_STRUCT(cursor); 2488 2489 k5ret = krb5_init_context(&krbctx); 2490 if (k5ret) { 2491 DEBUG(1, ("Failed to initialize kerberos context: %s\n", 2492 error_message(k5ret))); 2493 status = krb5_to_nt_status(k5ret); 2494 goto out; 2495 } 2496 2497 k5ret = gse_krb5_get_server_keytab(krbctx, &keytab); 2498 if (k5ret) { 2499 DEBUG(1, ("Failed to get keytab: %s\n", 2500 error_message(k5ret))); 2501 status = krb5_to_nt_status(k5ret); 2502 goto out_free; 2503 } 2504 2505 k5ret = krb5_kt_start_seq_get(krbctx, keytab, &cursor); 2506 if (k5ret) { 2507 DEBUG(1, ("Failed to start seq: %s\n", 2508 error_message(k5ret))); 2509 status = krb5_to_nt_status(k5ret); 2510 goto out_keytab; 2511 } 2512 2513 k5ret = krb5_kt_next_entry(krbctx, keytab, &entry, &cursor); 2514 while (k5ret == 0) { 2515 status = kerberos_pac_logon_info(mem_ctx, pac_blob, 2516 krbctx, NULL, 2517 KRB5_KT_KEY(&entry), NULL, 0, 2518 logon_info); 2519 if (NT_STATUS_IS_OK(status)) { 2520 break; 2521 } 2522 k5ret = smb_krb5_kt_free_entry(krbctx, &entry); 2523 k5ret = krb5_kt_next_entry(krbctx, keytab, &entry, &cursor); 2524 } 2525 2526 k5ret = krb5_kt_end_seq_get(krbctx, keytab, &cursor); 2527 if (k5ret) { 2528 DEBUG(1, ("Failed to end seq: %s\n", 2529 error_message(k5ret))); 2530 } 2531 out_keytab: 2532 k5ret = krb5_kt_close(krbctx, keytab); 2533 if (k5ret) { 2534 DEBUG(1, ("Failed to close keytab: %s\n", 2535 error_message(k5ret))); 2536 } 2537 out_free: 2538 krb5_free_context(krbctx); 2539 out: 2540 return status; 2541 } 2542 2543 NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, 2544 struct netr_SamInfo3 **info3) 2545 { 2546 struct winbindd_request *req = state->request; 2547 DATA_BLOB pac_blob; 2548 struct PAC_LOGON_INFO *logon_info = NULL; 2549 struct netr_SamInfo3 *info3_copy = NULL; 2550 NTSTATUS result; 2551 2552 pac_blob = data_blob_const(req->extra_data.data, req->extra_len); 2553 result = extract_pac_vrfy_sigs(state->mem_ctx, pac_blob, &logon_info); 2554 if (!NT_STATUS_IS_OK(result) && 2555 !NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) { 2556 DEBUG(1, ("Error during PAC signature verification: %s\n", 2557 nt_errstr(result))); 2558 return result; 2559 } 2560 2561 if (logon_info) { 2562 /* Signature verification succeeded, trust the PAC */ 2563 result = create_info3_from_pac_logon_info(state->mem_ctx, 2564 logon_info, 2565 &info3_copy); 2566 if (!NT_STATUS_IS_OK(result)) { 2567 return result; 2568 } 2569 netsamlogon_cache_store(NULL, info3_copy); 2570 2571 } else { 2572 /* Try without signature verification */ 2573 result = kerberos_pac_logon_info(state->mem_ctx, pac_blob, NULL, 2574 NULL, NULL, NULL, 0, 2575 &logon_info); 2576 if (!NT_STATUS_IS_OK(result)) { 2577 DEBUG(10, ("Could not extract PAC: %s\n", 2578 nt_errstr(result))); 2579 return result; 2580 } 2581 if (logon_info) { 2582 /* 2583 * Don't strictly need to copy here, 2584 * but it makes it explicit we're 2585 * returning a copy talloc'ed off 2586 * the state->mem_ctx. 2587 */ 2588 info3_copy = copy_netr_SamInfo3(state->mem_ctx, 2589 &logon_info->info3); 2590 if (info3_copy == NULL) { 2591 return NT_STATUS_NO_MEMORY; 2592 } 2593 } 2594 } 2595 2596 *info3 = info3_copy; 2597 2598 return NT_STATUS_OK; 2599 } 2600 #else /* HAVE_KRB5 */ 2601 NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, 2602 struct netr_SamInfo3 **info3) 2603 { 2604 return NT_STATUS_NO_SUCH_USER; 2605 } 2606 #endif /* HAVE_KRB5 */ -
vendor/current/source3/winbindd/winbindd_pam_auth_crap.c
r740 r988 23 23 struct winbindd_pam_auth_crap_state { 24 24 struct winbindd_response *response; 25 struct netr_SamInfo3 *info3; 26 uint32_t flags; 25 27 }; 26 28 … … 41 43 if (req == NULL) { 42 44 return NULL; 45 } 46 47 if (request->flags & WBFLAG_PAM_AUTH_PAC) { 48 NTSTATUS status; 49 50 state->flags = request->flags; 51 status = winbindd_pam_auth_pac_send(cli, &state->info3); 52 if (NT_STATUS_IS_OK(status)) { 53 /* Defer filling out response to recv */ 54 tevent_req_done(req); 55 } else { 56 tevent_req_nterror(req, status); 57 } 58 59 return tevent_req_post(req, ev); 43 60 } 44 61 … … 75 92 76 93 if (request->data.auth_crap.workstation[0] == '\0') { 77 fstrcpy(request->data.auth_crap.workstation, global_myname());94 fstrcpy(request->data.auth_crap.workstation, lp_netbios_name()); 78 95 } 79 96 … … 115 132 return status; 116 133 } 134 135 if (state->flags & WBFLAG_PAM_AUTH_PAC) { 136 return append_auth_data(response, response, state->flags, 137 state->info3, NULL, NULL); 138 } 139 117 140 *response = *state->response; 118 141 response->result = WINBINDD_PENDING; -
vendor/current/source3/winbindd/winbindd_pam_logoff.c
r740 r988 38 38 fstring name_domain, user; 39 39 uid_t caller_uid; 40 gid_t caller_gid; 40 41 int res; 41 42 … … 72 73 caller_uid = (uid_t)-1; 73 74 74 res = sys_getpeereid(cli->sock, &caller_uid);75 res = getpeereid(cli->sock, &caller_uid, &caller_gid); 75 76 if (res != 0) { 76 77 DEBUG(1,("winbindd_pam_logoff: failed to check peerid: %s\n", -
vendor/current/source3/winbindd/winbindd_ping_dc.c
r740 r988 20 20 #include "includes.h" 21 21 #include "winbindd.h" 22 #include "librpc/gen_ndr/ndr_w bint_c.h"22 #include "librpc/gen_ndr/ndr_winbind_c.h" 23 23 24 24 struct winbindd_ping_dc_state { 25 uint8_t dummy; 25 const char *dcname; 26 NTSTATUS result; 26 27 }; 27 28 … … 47 48 domain = find_our_domain(); 48 49 } else { 49 domain = find_domain_from_name (request->domain_name);50 domain = find_domain_from_name_noinit(request->domain_name); 50 51 } 51 52 if (domain == NULL) { … … 54 55 } 55 56 if (domain->internal) { 57 const char *d = lp_dnsdomain(); 58 const char *n = lp_netbios_name(); 59 56 60 /* 57 61 * Internal domains are passdb based, we can always 58 62 * contact them. 59 63 */ 64 65 if (d != NULL) { 66 char *h; 67 h = strlower_talloc(mem_ctx, n); 68 if (tevent_req_nomem(h, req)) { 69 return tevent_req_post(req, ev); 70 } 71 72 state->dcname = talloc_asprintf(state, "%s.%s", h, d); 73 if (tevent_req_nomem(state->dcname, req)) { 74 return tevent_req_post(req, ev); 75 } 76 } else { 77 state->dcname = talloc_strdup(state, n); 78 if (tevent_req_nomem(state->dcname, req)) { 79 return tevent_req_post(req, ev); 80 } 81 } 82 60 83 tevent_req_done(req); 61 84 return tevent_req_post(req, ev); 62 85 } 63 86 64 subreq = dcerpc_wbint_PingDc_send(state, ev, dom_child_handle(domain)); 87 subreq = dcerpc_wbint_PingDc_send(state, ev, dom_child_handle(domain), 88 &state->dcname); 65 89 if (tevent_req_nomem(subreq, req)) { 66 90 return tevent_req_post(req, ev); … … 79 103 80 104 status = dcerpc_wbint_PingDc_recv(subreq, state, &result); 105 state->result = result; 81 106 if (any_nt_status_not_ok(status, result, &status)) { 82 107 tevent_req_nterror(req, status); … … 89 114 struct winbindd_response *presp) 90 115 { 116 struct winbindd_ping_dc_state *state = tevent_req_data( 117 req, struct winbindd_ping_dc_state); 118 119 if (!NT_STATUS_IS_OK(state->result)) { 120 set_auth_errors(presp, state->result); 121 } 122 123 if (state->dcname) { 124 presp->extra_data.data = talloc_strdup(presp, state->dcname); 125 presp->length += strlen((char *)presp->extra_data.data) + 1; 126 } 127 91 128 return tevent_req_simple_recv_ntstatus(req); 92 129 } -
vendor/current/source3/winbindd/winbindd_proto.h
r860 r988 24 24 #define _WINBINDD_PROTO_H_ 25 25 26 #include "ads.h" 27 26 28 /* The following definitions come from winbindd/winbindd.c */ 27 29 struct messaging_context *winbind_messaging_context(void); 30 struct imessaging_context *winbind_imessaging_context(void); 28 31 void request_error(struct winbindd_cli_state *state); 29 32 void request_ok(struct winbindd_cli_state *state); 30 33 bool winbindd_setup_sig_term_handler(bool parent); 34 bool winbindd_setup_stdin_handler(bool parent, bool foreground); 31 35 bool winbindd_setup_sig_hup_handler(const char *lfile); 32 36 bool winbindd_use_idmap_cache(void); 33 37 bool winbindd_use_cache(void); 34 void winbindd_register_handlers(void);35 const char *get_winbind_pipe_dir(void);36 38 char *get_winbind_priv_pipe_dir(void); 37 int main(int argc, char **argv, char **envp);39 struct tevent_context *winbind_event_context(void); 38 40 39 41 /* The following definitions come from winbindd/winbindd_ads.c */ … … 56 58 /* The following definitions come from winbindd/winbindd_cache.c */ 57 59 58 struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status);59 60 NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const struct dom_sid *sid); 60 61 NTSTATUS wcache_get_creds(struct winbindd_domain *domain, 61 62 TALLOC_CTX *mem_ctx, 62 63 const struct dom_sid *sid, 63 const uint8 **cached_nt_pass,64 const uint8 **cached_salt);64 const uint8_t **cached_nt_pass, 65 const uint8_t **cached_salt); 65 66 NTSTATUS wcache_save_creds(struct winbindd_domain *domain, 66 67 const struct dom_sid *sid, 67 const uint8 nt_pass[NT_HASH_LEN]);68 const uint8_t nt_pass[NT_HASH_LEN]); 68 69 void wcache_invalidate_samlogon(struct winbindd_domain *domain, 69 70 const struct dom_sid *user_sid); … … 73 74 bool initialize_winbindd_cache(void); 74 75 void close_winbindd_cache(void); 75 NTSTATUS wcache_sid_to_name(struct winbindd_domain *domain,76 const struct dom_sid *sid,77 TALLOC_CTX *mem_ctx,78 char **domain_name,79 char **name,80 enum lsa_SidType *type);81 76 NTSTATUS wcache_lookup_groupmem(struct winbindd_domain *domain, 82 77 TALLOC_CTX *mem_ctx, … … 104 99 const struct dom_sid *user_sid, 105 100 struct wbint_userinfo *info); 101 NTSTATUS wcache_query_user_fullname(struct winbindd_domain *domain, 102 TALLOC_CTX *mem_ctx, 103 const struct dom_sid *user_sid, 104 const char **full_name); 106 105 NTSTATUS wcache_lookup_useraliases(struct winbindd_domain *domain, 107 106 TALLOC_CTX *mem_ctx, 108 uint32 num_sids, const struct dom_sid *sids,109 uint32 *pnum_aliases, uint32**paliases);107 uint32_t num_sids, const struct dom_sid *sids, 108 uint32_t *pnum_aliases, uint32_t **paliases); 110 109 NTSTATUS wcache_lookup_usergroups(struct winbindd_domain *domain, 111 110 TALLOC_CTX *mem_ctx, … … 164 163 void set_domain_offline(struct winbindd_domain *domain); 165 164 void set_domain_online_request(struct winbindd_domain *domain); 166 void invalidate_cm_connection(struct winbindd_cm_conn *conn); 165 166 struct ndr_interface_table; 167 NTSTATUS wb_open_internal_pipe(TALLOC_CTX *mem_ctx, 168 const struct ndr_interface_table *table, 169 struct rpc_pipe_client **ret_pipe); 170 void invalidate_cm_connection(struct winbindd_domain *domain); 167 171 void close_conns_after_fork(void); 168 NTSTATUS init_dc_connection(struct winbindd_domain *domain );172 NTSTATUS init_dc_connection(struct winbindd_domain *domain, bool need_rw_dc); 169 173 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, 174 bool need_rw_dc, 170 175 struct rpc_pipe_client **cli, struct policy_handle *sam_handle); 171 176 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, 172 177 struct rpc_pipe_client **cli, struct policy_handle *lsa_policy); 173 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,174 TALLOC_CTX *mem_ctx,175 struct rpc_pipe_client **cli);176 178 NTSTATUS cm_connect_lsat(struct winbindd_domain *domain, 177 179 TALLOC_CTX *mem_ctx, … … 218 220 const struct dom_sid *sid, 219 221 struct netr_SamInfo3 **info3, 220 const uint8 *cached_nt_pass[NT_HASH_LEN],221 const uint8 *cred_salt[NT_HASH_LEN]);222 const uint8_t *cached_nt_pass[NT_HASH_LEN], 223 const uint8_t *cred_salt[NT_HASH_LEN]); 222 224 NTSTATUS winbindd_store_creds(struct winbindd_domain *domain, 223 225 const char *user, … … 327 329 void init_idmap_child(void); 328 330 struct winbindd_child *idmap_child(void); 329 struct idmap_domain *idmap_find_domain(const char *domname); 331 struct idmap_domain *idmap_find_domain_with_sid(const char *domname, 332 const struct dom_sid *sid); 333 bool domain_has_idmap_config(const char *domname); 330 334 331 335 /* The following definitions come from winbindd/winbindd_locator.c */ … … 367 371 368 372 bool check_request_flags(uint32_t flags); 373 NTSTATUS append_auth_data(TALLOC_CTX *mem_ctx, 374 struct winbindd_response *resp, 375 uint32_t request_flags, 376 struct netr_SamInfo3 *info3, 377 const char *name_domain, 378 const char *name_user); 369 379 uid_t get_uid_from_request(struct winbindd_request *request); 370 380 struct winbindd_domain *find_auth_domain(uint8_t flags, … … 379 389 struct winbindd_cli_state *state) ; 380 390 enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state); 391 NTSTATUS winbindd_pam_auth_pac_send(struct winbindd_cli_state *state, 392 struct netr_SamInfo3 **info3); 393 394 NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain, 395 TALLOC_CTX *mem_ctx, 396 uint32_t logon_parameters, 397 const char *name_user, 398 const char *name_domain, 399 const char *workstation, 400 const uint8_t chal[8], 401 DATA_BLOB lm_response, 402 DATA_BLOB nt_response, 403 struct netr_SamInfo3 **info3); 381 404 382 405 /* The following definitions come from winbindd/winbindd_util.c */ 383 406 384 407 struct winbindd_domain *domain_list(void); 408 struct winbindd_domain *wb_next_domain(struct winbindd_domain *domain); 385 409 bool domain_is_forest_root(const struct winbindd_domain *domain); 386 410 void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te, … … 408 432 bool can_assume); 409 433 struct winbindd_cli_state *winbindd_client_list(void); 434 struct winbindd_cli_state *winbindd_client_list_tail(void); 435 struct winbindd_cli_state * 436 winbindd_client_list_prev(struct winbindd_cli_state *cli); 410 437 void winbindd_add_client(struct winbindd_cli_state *cli); 411 438 void winbindd_remove_client(struct winbindd_cli_state *cli); 439 void winbindd_promote_client(struct winbindd_cli_state *cli); 412 440 int winbindd_num_clients(void); 413 441 NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, 414 442 TALLOC_CTX *mem_ctx, 415 443 const struct dom_sid *user_sid, 416 uint32 *p_num_groups, struct dom_sid **user_sids);444 uint32_t *p_num_groups, struct dom_sid **user_sids); 417 445 418 446 NTSTATUS normalize_name_map(TALLOC_CTX *mem_ctx, … … 445 473 /* The following definitions come from winbindd/winbindd_wins.c */ 446 474 447 void winbindd_wins_byip(struct winbindd_cli_state *state);448 475 void winbindd_wins_byname(struct winbindd_cli_state *state); 449 476 … … 498 525 struct winbindd_response *response); 499 526 500 struct tevent_req *wb_sid2uid_send(TALLOC_CTX *mem_ctx,501 struct tevent_context *ev,502 const struct dom_sid *sid);503 NTSTATUS wb_sid2uid_recv(struct tevent_req *req, uid_t *uid);504 505 527 struct tevent_req *winbindd_sid_to_uid_send(TALLOC_CTX *mem_ctx, 506 528 struct tevent_context *ev, … … 509 531 NTSTATUS winbindd_sid_to_uid_recv(struct tevent_req *req, 510 532 struct winbindd_response *response); 511 512 struct tevent_req *wb_sid2gid_send(TALLOC_CTX *mem_ctx,513 struct tevent_context *ev,514 const struct dom_sid *sid);515 NTSTATUS wb_sid2gid_recv(struct tevent_req *req, gid_t *gid);516 533 517 534 struct tevent_req *winbindd_sid_to_gid_send(TALLOC_CTX *mem_ctx, … … 655 672 NTSTATUS wb_group_members_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 656 673 struct talloc_dict **members); 674 NTSTATUS add_wbint_Principal_to_dict(TALLOC_CTX *mem_ctx, 675 struct dom_sid *sid, 676 const char **name, 677 enum lsa_SidType type, 678 struct talloc_dict *dict); 657 679 658 680 struct tevent_req *wb_getgrsid_send(TALLOC_CTX *mem_ctx, … … 698 720 int *num_users, 699 721 struct wbint_userinfo **users); 722 723 struct tevent_req *wb_query_group_list_send(TALLOC_CTX *mem_ctx, 724 struct tevent_context *ev, 725 struct winbindd_domain *domain); 726 NTSTATUS wb_query_group_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, 727 int *num_users, 728 struct wbint_Principal **groups); 729 700 730 701 731 struct tevent_req *wb_fill_pwent_send(TALLOC_CTX *mem_ctx, … … 864 894 struct lsa_TransNameArray **names); 865 895 896 struct tevent_req *wb_sids2xids_send(TALLOC_CTX *mem_ctx, 897 struct tevent_context *ev, 898 const struct dom_sid *sids, 899 const uint32_t num_sids); 900 NTSTATUS wb_sids2xids_recv(struct tevent_req *req, 901 struct unixid xids[], uint32_t num_xids); 866 902 struct tevent_req *winbindd_sids_to_xids_send(TALLOC_CTX *mem_ctx, 867 903 struct tevent_context *ev, … … 870 906 NTSTATUS winbindd_sids_to_xids_recv(struct tevent_req *req, 871 907 struct winbindd_response *response); 908 struct tevent_req *winbindd_wins_byip_send(TALLOC_CTX *mem_ctx, 909 struct tevent_context *ev, 910 struct winbindd_cli_state *cli, 911 struct winbindd_request *request); 912 NTSTATUS winbindd_wins_byip_recv(struct tevent_req *req, 913 struct winbindd_response *presp); 914 struct tevent_req *winbindd_wins_byname_send(TALLOC_CTX *mem_ctx, 915 struct tevent_context *ev, 916 struct winbindd_cli_state *cli, 917 struct winbindd_request *request); 918 NTSTATUS winbindd_wins_byname_recv(struct tevent_req *req, 919 struct winbindd_response *presp); 872 920 873 921 … … 878 926 struct rpc_pipe_client **samr_pipe, 879 927 struct policy_handle *samr_domain_hnd); 928 NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx, 929 struct rpc_pipe_client **lsa_pipe, 930 struct policy_handle *lsa_hnd); 931 932 /* The following definitions come from winbindd/winbindd_ads.c */ 933 ADS_STATUS ads_idmap_cached_connection(ADS_STRUCT **adsp, const char *dom_name); 934 935 /* The following definitions come from winbindd/winbindd_irpc.c */ 936 NTSTATUS wb_irpc_register(void); 937 938 /* The following definitions come from winbindd/winbindd_reconnect.c */ 939 bool reconnect_need_retry(NTSTATUS status, struct winbindd_domain *domain); 880 940 881 941 #endif /* _WINBINDD_PROTO_H_ */ -
vendor/current/source3/winbindd/winbindd_reconnect.c
r740 r988 28 28 extern struct winbindd_methods msrpc_methods; 29 29 30 static bool reconnect_need_retry(NTSTATUS status)30 bool reconnect_need_retry(NTSTATUS status, struct winbindd_domain *domain) 31 31 { 32 32 if (NT_STATUS_IS_OK(status)) { … … 68 68 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) { 69 69 return false; 70 } 71 72 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR)) { 73 /* 74 * RPC call sent on expired session, needs 75 * reauthentication. 76 */ 77 invalidate_cm_connection(domain); 70 78 } 71 79 … … 76 84 static NTSTATUS query_user_list(struct winbindd_domain *domain, 77 85 TALLOC_CTX *mem_ctx, 78 uint32 *num_entries,86 uint32_t *num_entries, 79 87 struct wbint_userinfo **info) 80 88 { … … 84 92 num_entries, info); 85 93 86 if (reconnect_need_retry(result ))94 if (reconnect_need_retry(result, domain)) 87 95 result = msrpc_methods.query_user_list(domain, mem_ctx, 88 96 num_entries, info); … … 93 101 static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, 94 102 TALLOC_CTX *mem_ctx, 95 uint32 *num_entries,103 uint32_t *num_entries, 96 104 struct wb_acct_info **info) 97 105 { … … 101 109 num_entries, info); 102 110 103 if (reconnect_need_retry(result ))111 if (reconnect_need_retry(result, domain)) 104 112 result = msrpc_methods.enum_dom_groups(domain, mem_ctx, 105 113 num_entries, info); … … 111 119 static NTSTATUS enum_local_groups(struct winbindd_domain *domain, 112 120 TALLOC_CTX *mem_ctx, 113 uint32 *num_entries,121 uint32_t *num_entries, 114 122 struct wb_acct_info **info) 115 123 { … … 119 127 num_entries, info); 120 128 121 if (reconnect_need_retry(result ))129 if (reconnect_need_retry(result, domain)) 122 130 result = msrpc_methods.enum_local_groups(domain, mem_ctx, 123 131 num_entries, info); … … 140 148 flags, sid, type); 141 149 142 if (reconnect_need_retry(result ))150 if (reconnect_need_retry(result, domain)) 143 151 result = msrpc_methods.name_to_sid(domain, mem_ctx, 144 152 domain_name, name, flags, … … 163 171 domain_name, name, type); 164 172 165 if (reconnect_need_retry(result ))173 if (reconnect_need_retry(result, domain)) 166 174 result = msrpc_methods.sid_to_name(domain, mem_ctx, sid, 167 175 domain_name, name, type); … … 173 181 TALLOC_CTX *mem_ctx, 174 182 const struct dom_sid *sid, 175 uint32 *rids,183 uint32_t *rids, 176 184 size_t num_rids, 177 185 char **domain_name, … … 184 192 rids, num_rids, 185 193 domain_name, names, types); 186 if (reconnect_need_retry(result )) {194 if (reconnect_need_retry(result, domain)) { 187 195 result = msrpc_methods.rids_to_names(domain, mem_ctx, sid, 188 196 rids, num_rids, … … 205 213 user_info); 206 214 207 if (reconnect_need_retry(result ))215 if (reconnect_need_retry(result, domain)) 208 216 result = msrpc_methods.query_user(domain, mem_ctx, user_sid, 209 217 user_info); … … 216 224 TALLOC_CTX *mem_ctx, 217 225 const struct dom_sid *user_sid, 218 uint32 *num_groups, struct dom_sid **user_gids)226 uint32_t *num_groups, struct dom_sid **user_gids) 219 227 { 220 228 NTSTATUS result; … … 224 232 user_gids); 225 233 226 if (reconnect_need_retry(result ))234 if (reconnect_need_retry(result, domain)) 227 235 result = msrpc_methods.lookup_usergroups(domain, mem_ctx, 228 236 user_sid, num_groups, … … 234 242 static NTSTATUS lookup_useraliases(struct winbindd_domain *domain, 235 243 TALLOC_CTX *mem_ctx, 236 uint32 num_sids, const struct dom_sid *sids,237 uint32 *num_aliases, uint32**alias_rids)244 uint32_t num_sids, const struct dom_sid *sids, 245 uint32_t *num_aliases, uint32_t **alias_rids) 238 246 { 239 247 NTSTATUS result; … … 244 252 alias_rids); 245 253 246 if (reconnect_need_retry(result ))254 if (reconnect_need_retry(result, domain)) 247 255 result = msrpc_methods.lookup_useraliases(domain, mem_ctx, 248 256 num_sids, sids, … … 258 266 const struct dom_sid *group_sid, 259 267 enum lsa_SidType type, 260 uint32 *num_names,268 uint32_t *num_names, 261 269 struct dom_sid **sid_mem, char ***names, 262 uint32 **name_types)270 uint32_t **name_types) 263 271 { 264 272 NTSTATUS result; … … 269 277 name_types); 270 278 271 if (reconnect_need_retry(result ))279 if (reconnect_need_retry(result, domain)) 272 280 result = msrpc_methods.lookup_groupmem(domain, mem_ctx, 273 281 group_sid, type, … … 280 288 281 289 /* find the sequence number for a domain */ 282 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)290 static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32_t *seq) 283 291 { 284 292 NTSTATUS result; … … 286 294 result = msrpc_methods.sequence_number(domain, seq); 287 295 288 if (reconnect_need_retry(result ))296 if (reconnect_need_retry(result, domain)) 289 297 result = msrpc_methods.sequence_number(domain, seq); 290 298 … … 301 309 result = msrpc_methods.lockout_policy(domain, mem_ctx, policy); 302 310 303 if (reconnect_need_retry(result ))311 if (reconnect_need_retry(result, domain)) 304 312 result = msrpc_methods.lockout_policy(domain, mem_ctx, policy); 305 313 … … 316 324 result = msrpc_methods.password_policy(domain, mem_ctx, policy); 317 325 318 if (reconnect_need_retry(result ))326 if (reconnect_need_retry(result, domain)) 319 327 result = msrpc_methods.password_policy(domain, mem_ctx, policy); 320 328 … … 331 339 result = msrpc_methods.trusted_domains(domain, mem_ctx, trusts); 332 340 333 if (reconnect_need_retry(result ))341 if (reconnect_need_retry(result, domain)) 334 342 result = msrpc_methods.trusted_domains(domain, mem_ctx, 335 343 trusts); -
vendor/current/source3/winbindd/winbindd_rpc.c
r860 r988 90 90 num_info += num_dom_users; 91 91 92 info = TALLOC_REALLOC_ARRAY(mem_ctx,92 info = talloc_realloc(mem_ctx, 93 93 info, 94 94 struct wbint_userinfo, … … 121 121 dst->homedir = NULL; 122 122 dst->shell = NULL; 123 123 dst->primary_gid = (gid_t)-1; 124 124 sid_compose(&dst->user_sid, domain_sid, rid); 125 125 … … 182 182 } 183 183 184 info = TALLOC_REALLOC_ARRAY(mem_ctx,184 info = talloc_realloc(mem_ctx, 185 185 info, 186 186 struct wb_acct_info, … … 191 191 192 192 for (g = 0; g < count; g++) { 193 fstrcpy(info[num_info + g].acct_name, 193 struct wb_acct_info *i = &info[num_info + g]; 194 195 fstrcpy(i->acct_name, 194 196 sam_array->entries[g].name.string); 195 196 i nfo[num_info + g].rid = sam_array->entries[g].idx;197 fstrcpy(i->acct_desc, ""); 198 i->rid = sam_array->entries[g].idx; 197 199 } 198 200 … … 242 244 } 243 245 244 info = TALLOC_REALLOC_ARRAY(mem_ctx,246 info = talloc_realloc(mem_ctx, 245 247 info, 246 248 struct wb_acct_info, … … 251 253 252 254 for (g = 0; g < count; g++) { 253 fstrcpy(info[num_info + g].acct_name, 255 struct wb_acct_info *i = &info[num_info + g]; 256 257 fstrcpy(i->acct_name, 254 258 sam_array->entries[g].name.string); 255 info[num_info + g].rid = sam_array->entries[g].idx; 259 fstrcpy(i->acct_desc, ""); 260 i->rid = sam_array->entries[g].idx; 256 261 } 257 262 … … 278 283 struct dom_sid *sids = NULL; 279 284 char *full_name = NULL; 285 const char *names[1]; 280 286 char *mapped_name = NULL; 281 287 NTSTATUS status; … … 302 308 DEBUG(3,("name_to_sid: %s for domain %s\n", 303 309 full_name ? full_name : "", domain_name )); 310 311 names[0] = full_name; 304 312 305 313 /* … … 311 319 lsa_policy, 312 320 1, /* num_names */ 313 (const char **) &full_name,321 names, 314 322 NULL, /* domains */ 315 323 1, /* level */ … … 363 371 map_status = normalize_name_map(mem_ctx, 364 372 domain, 365 *pname,373 names[0], 366 374 &mapped_name); 367 375 if (NT_STATUS_IS_OK(map_status) || … … 372 380 *pname = talloc_strdup(mem_ctx, names[0]); 373 381 } 374 if ( *pname == NULL) {382 if ((names[0] != NULL) && (*pname == NULL)) { 375 383 return NT_STATUS_NO_MEMORY; 376 384 } … … 405 413 406 414 if (num_rids > 0) { 407 sids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_rids);415 sids = talloc_array(mem_ctx, struct dom_sid, num_rids); 408 416 if (sids == NULL) { 409 417 return NT_STATUS_NO_MEMORY; … … 527 535 info->info21.full_name.string); 528 536 if ((info->info21.full_name.string != NULL) && 529 (user_info-> acct_name == NULL))537 (user_info->full_name == NULL)) 530 538 { 531 539 return NT_STATUS_NO_MEMORY; … … 581 589 &rid_array, 582 590 &result); 583 num_groups = rid_array->count;584 585 591 { 586 592 NTSTATUS _result; … … 591 597 return status; 592 598 } 593 if (!NT_STATUS_IS_OK(result) || num_groups == 0) {599 if (!NT_STATUS_IS_OK(result)) { 594 600 return result; 595 601 } 596 602 597 user_grpsids = TALLOC_ARRAY(mem_ctx, struct dom_sid, num_groups); 603 num_groups = rid_array->count; 604 605 user_grpsids = talloc_array(mem_ctx, struct dom_sid, num_groups); 598 606 if (user_grpsids == NULL) { 599 607 status = NT_STATUS_NO_MEMORY; … … 645 653 646 654 if (num_query_sids) { 647 sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);655 sid_array.sids = talloc_zero_array(mem_ctx, struct lsa_SidPtr, num_query_sids); 648 656 if (sid_array.sids == NULL) { 649 657 return NT_STATUS_NO_MEMORY; … … 840 848 */ 841 849 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);850 names = talloc_zero_array(mem_ctx, char *, num_names); 851 name_types = talloc_zero_array(mem_ctx, uint32_t, num_names); 852 sid_mem = talloc_zero_array(mem_ctx, struct dom_sid, num_names); 845 853 if (names == NULL || name_types == NULL || sid_mem == NULL) { 846 854 return NT_STATUS_NO_MEMORY; … … 979 987 do { 980 988 struct lsa_DomainList dom_list; 981 uint32_t start_idx; 989 struct lsa_DomainListEx dom_list_ex; 990 bool has_ex = false; 982 991 uint32_t i; 983 992 … … 986 995 * called in the main function. 987 996 */ 988 status = dcerpc_lsa_EnumTrustDom(b, 989 mem_ctx, 990 lsa_policy, 991 &enum_ctx, 992 &dom_list, 993 (uint32_t) -1, 994 &result); 995 if (!NT_STATUS_IS_OK(status)) { 996 return status; 997 } 998 if (!NT_STATUS_IS_OK(result)) { 999 if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 1000 return result; 997 status = dcerpc_lsa_EnumTrustedDomainsEx(b, 998 mem_ctx, 999 lsa_policy, 1000 &enum_ctx, 1001 &dom_list_ex, 1002 (uint32_t) -1, 1003 &result); 1004 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_ERR(result) && 1005 dom_list_ex.count > 0) { 1006 count += dom_list_ex.count; 1007 has_ex = true; 1008 } else { 1009 status = dcerpc_lsa_EnumTrustDom(b, 1010 mem_ctx, 1011 lsa_policy, 1012 &enum_ctx, 1013 &dom_list, 1014 (uint32_t) -1, 1015 &result); 1016 if (!NT_STATUS_IS_OK(status)) { 1017 return status; 1001 1018 } 1002 } 1003 1004 start_idx = count; 1005 count += dom_list.count; 1019 if (!NT_STATUS_IS_OK(result)) { 1020 if (!NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { 1021 return result; 1022 } 1023 } 1024 1025 count += dom_list.count; 1026 } 1006 1027 1007 1028 array = talloc_realloc(mem_ctx, … … 1013 1034 } 1014 1035 1015 for (i = 0; i < dom_list.count; i++) {1036 for (i = 0; i < count; i++) { 1016 1037 struct netr_DomainTrust *trust = &array[i]; 1017 1038 struct dom_sid *sid; 1018 1039 1019 1040 ZERO_STRUCTP(trust); 1020 1021 trust->netbios_name = talloc_move(array,1022 &dom_list.domains[i].name.string);1023 trust->dns_name = NULL;1024 1041 1025 1042 sid = talloc(array, struct dom_sid); … … 1027 1044 return NT_STATUS_NO_MEMORY; 1028 1045 } 1029 sid_copy(sid, dom_list.domains[i].sid); 1046 1047 if (has_ex) { 1048 trust->netbios_name = talloc_move(array, 1049 &dom_list_ex.domains[i].netbios_name.string); 1050 trust->dns_name = talloc_move(array, 1051 &dom_list_ex.domains[i].domain_name.string); 1052 if (dom_list_ex.domains[i].sid == NULL) { 1053 DEBUG(0, ("Trusted Domain %s has no SID, aborting!\n", trust->dns_name)); 1054 return NT_STATUS_INVALID_NETWORK_RESPONSE; 1055 } 1056 sid_copy(sid, dom_list_ex.domains[i].sid); 1057 } else { 1058 trust->netbios_name = talloc_move(array, 1059 &dom_list.domains[i].name.string); 1060 trust->dns_name = NULL; 1061 1062 if (dom_list.domains[i].sid == NULL) { 1063 DEBUG(0, ("Trusted Domain %s has no SID, aborting!\n", trust->netbios_name)); 1064 return NT_STATUS_INVALID_NETWORK_RESPONSE; 1065 } 1066 1067 sid_copy(sid, dom_list.domains[i].sid); 1068 } 1069 1030 1070 trust->sid = sid; 1031 1071 } … … 1047 1087 struct lsa_TransNameArray2 lsa_names2; 1048 1088 struct lsa_TransNameArray *names = *pnames; 1049 uint32_t i, count ;1089 uint32_t i, count = 0; 1050 1090 NTSTATUS status, result; 1051 1091 -
vendor/current/source3/winbindd/winbindd_samr.c
r740 r988 40 40 #define DBGC_CLASS DBGC_WINBIND 41 41 42 static NTSTATUS open_internal_samr_pipe(TALLOC_CTX *mem_ctx,43 struct rpc_pipe_client **samr_pipe)44 {45 struct rpc_pipe_client *cli = NULL;46 struct auth_serversupplied_info *session_info = NULL;47 NTSTATUS status;48 49 if (session_info == NULL) {50 status = make_session_info_system(mem_ctx, &session_info);51 if (!NT_STATUS_IS_OK(status)) {52 DEBUG(0, ("open_samr_pipe: Could not create auth_serversupplied_info: %s\n",53 nt_errstr(status)));54 return status;55 }56 }57 58 /* create a samr connection */59 status = rpc_pipe_open_interface(mem_ctx,60 &ndr_table_samr.syntax_id,61 session_info,62 NULL,63 winbind_messaging_context(),64 &cli);65 if (!NT_STATUS_IS_OK(status)) {66 DEBUG(0, ("open_samr_pipe: Could not connect to samr_pipe: %s\n",67 nt_errstr(status)));68 return status;69 }70 71 if (samr_pipe) {72 *samr_pipe = cli;73 }74 75 return NT_STATUS_OK;76 }77 78 42 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx, 79 43 struct winbindd_domain *domain, … … 85 49 struct dcerpc_binding_handle *b; 86 50 87 status = open_internal_samr_pipe(mem_ctx, samr_pipe);51 status = wb_open_internal_pipe(mem_ctx, &ndr_table_samr, samr_pipe); 88 52 if (!NT_STATUS_IS_OK(status)) { 89 53 return status; … … 117 81 } 118 82 119 static NTSTATUS open_internal_lsa_pipe(TALLOC_CTX *mem_ctx, 120 struct rpc_pipe_client **lsa_pipe) 121 { 122 struct rpc_pipe_client *cli = NULL; 123 struct auth_serversupplied_info *session_info = NULL; 83 NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx, 84 struct rpc_pipe_client **lsa_pipe, 85 struct policy_handle *lsa_hnd) 86 { 124 87 NTSTATUS status; 125 88 126 if (session_info == NULL) { 127 status = make_session_info_system(mem_ctx, &session_info); 128 if (!NT_STATUS_IS_OK(status)) { 129 DEBUG(0, ("open_lsa_pipe: Could not create auth_serversupplied_info: %s\n", 130 nt_errstr(status))); 131 return status; 132 } 133 } 134 135 /* create a lsa connection */ 136 status = rpc_pipe_open_interface(mem_ctx, 137 &ndr_table_lsarpc.syntax_id, 138 session_info, 139 NULL, 140 winbind_messaging_context(), 141 &cli); 142 if (!NT_STATUS_IS_OK(status)) { 143 DEBUG(0, ("open_lsa_pipe: Could not connect to lsa_pipe: %s\n", 144 nt_errstr(status))); 145 return status; 146 } 147 148 if (lsa_pipe) { 149 *lsa_pipe = cli; 150 } 151 152 return NT_STATUS_OK; 153 } 154 155 static NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx, 156 struct rpc_pipe_client **lsa_pipe, 157 struct policy_handle *lsa_hnd) 158 { 159 NTSTATUS status; 160 161 status = open_internal_lsa_pipe(mem_ctx, lsa_pipe); 89 status = wb_open_internal_pipe(mem_ctx, &ndr_table_lsarpc, lsa_pipe); 162 90 if (!NT_STATUS_IS_OK(status)) { 163 91 return status; … … 314 242 315 243 /* Paranoia check */ 316 if (!sid_check_is_in_our_ domain(user_sid)) {244 if (!sid_check_is_in_our_sam(user_sid)) { 317 245 return NT_STATUS_NO_SUCH_USER; 318 246 } 319 247 320 if (user_info) { 321 user_info->homedir = NULL; 322 user_info->shell = NULL; 323 user_info->primary_gid = (gid_t) -1; 324 } 248 user_info->homedir = NULL; 249 user_info->shell = NULL; 250 user_info->primary_gid = (gid_t) -1; 325 251 326 252 tmp_ctx = talloc_stackframe(); … … 441 367 442 368 if (pnum_names) { 443 pnum_names = 0;369 *pnum_names = 0; 444 370 } 445 371 … … 500 426 static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain, 501 427 TALLOC_CTX *mem_ctx, 502 uint32 *num_entries,428 uint32_t *num_entries, 503 429 struct wb_acct_info **info) 504 430 { … … 512 438 static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain, 513 439 TALLOC_CTX *mem_ctx, 514 uint32 *num_entries,440 uint32_t *num_entries, 515 441 struct wbint_userinfo **info) 516 442 { … … 687 613 /* Paranoia check */ 688 614 if (!sid_check_is_in_builtin(sid) && 689 !sid_check_is_in_our_domain(sid) && 615 !sid_check_is_builtin(sid) && 616 !sid_check_is_in_our_sam(sid) && 617 !sid_check_is_our_sam(sid) && 690 618 !sid_check_is_in_unix_users(sid) && 691 619 !sid_check_is_unix_users(sid) && … … 743 671 TALLOC_CTX *mem_ctx, 744 672 const struct dom_sid *domain_sid, 745 uint32 *rids,673 uint32_t *rids, 746 674 size_t num_rids, 747 675 char **pdomain_name, … … 764 692 /* Paranoia check */ 765 693 if (!sid_check_is_builtin(domain_sid) && 766 !sid_check_is_ domain(domain_sid) &&694 !sid_check_is_our_sam(domain_sid) && 767 695 !sid_check_is_unix_users(domain_sid) && 768 696 !sid_check_is_unix_groups(domain_sid) && … … 850 778 mem_ctx, 851 779 &dom_pol, 852 12,780 DomainLockoutInformation, 853 781 &info, 854 782 &result); … … 902 830 mem_ctx, 903 831 &dom_pol, 904 1,832 DomainPasswordInformation, 905 833 &info, 906 834 &result); … … 1056 984 struct rpc_pipe_client *samr_pipe; 1057 985 struct policy_handle dom_pol; 1058 uint32_t seq ;986 uint32_t seq = DOM_SEQUENCE_NONE; 1059 987 TALLOC_CTX *tmp_ctx; 1060 988 NTSTATUS status, result; -
vendor/current/source3/winbindd/winbindd_sid_to_gid.c
r740 r988 55 55 } 56 56 57 subreq = wb_sid 2gid_send(state, ev, &state->sid);57 subreq = wb_sids2xids_send(state, ev, &state->sid, 1); 58 58 if (tevent_req_nomem(subreq, req)) { 59 59 return tevent_req_post(req, ev); … … 70 70 req, struct winbindd_sid_to_gid_state); 71 71 NTSTATUS status; 72 struct unixid xids[1]; 72 73 73 status = wb_sid 2gid_recv(subreq, &state->gid);74 status = wb_sids2xids_recv(subreq, xids, ARRAY_SIZE(xids)); 74 75 TALLOC_FREE(subreq); 75 76 if (tevent_req_nterror(req, status)) { 76 77 return; 77 78 } 79 80 /* 81 * We are filtering further down in sids2xids, but that filtering 82 * depends on the actual type of the sid handed in (as determined 83 * by lookupsids). Here we need to filter for the type of object 84 * actually requested, in this case gid. 85 */ 86 if (!(xids[0].type == ID_TYPE_GID || xids[0].type == ID_TYPE_BOTH)) { 87 tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); 88 return; 89 } 90 91 state->gid = (gid_t)xids[0].id; 78 92 tevent_req_done(req); 79 93 } -
vendor/current/source3/winbindd/winbindd_sid_to_uid.c
r740 r988 55 55 } 56 56 57 subreq = wb_sid 2uid_send(state, ev, &state->sid);57 subreq = wb_sids2xids_send(state, ev, &state->sid, 1); 58 58 if (tevent_req_nomem(subreq, req)) { 59 59 return tevent_req_post(req, ev); … … 70 70 req, struct winbindd_sid_to_uid_state); 71 71 NTSTATUS status; 72 struct unixid xids[1]; 72 73 73 status = wb_sid 2uid_recv(subreq, &state->uid);74 status = wb_sids2xids_recv(subreq, xids, ARRAY_SIZE(xids)); 74 75 TALLOC_FREE(subreq); 75 76 if (tevent_req_nterror(req, status)) { 76 77 return; 77 78 } 79 80 /* 81 * We are filtering further down in sids2xids, but that filtering 82 * depends on the actual type of the sid handed in (as determined 83 * by lookupsids). Here we need to filter for the type of object 84 * actually requested, in this case uid. 85 */ 86 if (!(xids[0].type == ID_TYPE_UID || xids[0].type == ID_TYPE_BOTH)) { 87 tevent_req_nterror(req, NT_STATUS_NONE_MAPPED); 88 return; 89 } 90 91 state->uid = (uid_t)xids[0].id; 78 92 tevent_req_done(req); 79 93 } -
vendor/current/source3/winbindd/winbindd_sids_to_xids.c
r746 r988 3 3 async implementation of WINBINDD_SIDS_TO_XIDS 4 4 Copyright (C) Volker Lendecke 2011 5 Copyright (C) Michael Adam 2012 5 6 6 7 This program is free software; you can redistribute it and/or modify … … 21 22 #include "winbindd.h" 22 23 #include "../libcli/security/security.h" 23 #include "librpc/gen_ndr/ndr_wbint_c.h" 24 #include "idmap_cache.h" 24 25 25 26 26 struct winbindd_sids_to_xids_state { … … 28 28 struct dom_sid *sids; 29 29 uint32_t num_sids; 30 31 struct id_map *cached; 32 33 struct dom_sid *non_cached; 34 uint32_t num_non_cached; 35 36 struct lsa_RefDomainList *domains; 37 struct lsa_TransNameArray *names; 38 39 struct wbint_TransIDArray ids; 30 struct unixid *xids; 40 31 }; 41 32 42 static bool winbindd_sids_to_xids_in_cache(struct dom_sid *sid,43 struct id_map *map);44 static void winbindd_sids_to_xids_lookupsids_done(struct tevent_req *subreq);45 33 static void winbindd_sids_to_xids_done(struct tevent_req *subreq); 46 34 … … 52 40 struct tevent_req *req, *subreq; 53 41 struct winbindd_sids_to_xids_state *state; 54 uint32_t i;55 42 56 43 req = tevent_req_create(mem_ctx, &state, … … 81 68 DEBUG(10, ("num_sids: %d\n", (int)state->num_sids)); 82 69 83 state->cached = TALLOC_ZERO_ARRAY(state, struct id_map, 84 state->num_sids); 85 if (tevent_req_nomem(state->cached, req)) { 86 return tevent_req_post(req, ev); 87 } 88 state->non_cached = TALLOC_ARRAY(state, struct dom_sid, 89 state->num_sids); 90 if (tevent_req_nomem(state->non_cached, req)) { 70 subreq = wb_sids2xids_send(state, ev, state->sids, state->num_sids); 71 if (tevent_req_nomem(subreq, req)) { 91 72 return tevent_req_post(req, ev); 92 73 } 93 74 94 for (i=0; i<state->num_sids; i++) { 95 96 DEBUG(10, ("SID %d: %s\n", (int)i, 97 sid_string_dbg(&state->sids[i]))); 98 99 if (winbindd_sids_to_xids_in_cache(&state->sids[i], 100 &state->cached[i])) { 101 continue; 102 } 103 sid_copy(&state->non_cached[state->num_non_cached], 104 &state->sids[i]); 105 state->num_non_cached += 1; 106 } 107 108 if (state->num_non_cached == 0) { 109 tevent_req_done(req); 110 return tevent_req_post(req, ev); 111 } 112 113 subreq = wb_lookupsids_send(state, ev, state->non_cached, 114 state->num_non_cached); 115 if (tevent_req_nomem(subreq, req)) { 116 return tevent_req_post(req, ev); 117 } 118 tevent_req_set_callback(subreq, winbindd_sids_to_xids_lookupsids_done, 119 req); 75 tevent_req_set_callback(subreq, winbindd_sids_to_xids_done, req); 120 76 return req; 121 }122 123 static bool winbindd_sids_to_xids_in_cache(struct dom_sid *sid,124 struct id_map *map)125 {126 bool is_online = is_domain_online(find_our_domain());127 gid_t gid = (gid_t)-1;128 bool gid_expired = false;129 bool gid_cached = false;130 bool gid_negative = false;131 uid_t uid = (uid_t)-1;132 bool uid_expired = false;133 bool uid_cached = false;134 bool uid_negative = false;135 136 if (!winbindd_use_idmap_cache()) {137 return false;138 }139 140 /*141 * SIDS_TO_XIDS is primarily used to resolve the user's group142 * sids. So we check groups before users.143 */144 gid_cached = idmap_cache_find_sid2gid(sid, &gid, &gid_expired);145 if (!is_online) {146 gid_expired = false;147 }148 if (gid_cached && !gid_expired) {149 if (gid != (gid_t)-1) {150 map->sid = sid;151 map->xid.id = gid;152 map->xid.type = ID_TYPE_GID;153 map->status = ID_MAPPED;154 return true;155 }156 gid_negative = true;157 }158 uid_cached = idmap_cache_find_sid2uid(sid, &uid, &uid_expired);159 if (!is_online) {160 uid_expired = false;161 }162 if (uid_cached && !uid_expired) {163 if (uid != (uid_t)-1) {164 map->sid = sid;165 map->xid.id = uid;166 map->xid.type = ID_TYPE_UID;167 map->status = ID_MAPPED;168 return true;169 }170 uid_negative = true;171 }172 173 /*174 * Here we know that we only have negative175 * or no entries.176 *177 * All valid cases already returned to the caller.178 */179 180 if (gid_negative && uid_negative) {181 map->sid = sid;182 map->xid.id = UINT32_MAX;183 map->xid.type = ID_TYPE_NOT_SPECIFIED;184 map->status = ID_MAPPED;185 return true;186 }187 188 if (gid_negative) {189 map->sid = sid;190 map->xid.id = gid; /* this is (gid_t)-1 */191 map->xid.type = ID_TYPE_GID;192 map->status = ID_MAPPED;193 return true;194 }195 196 if (uid_negative) {197 map->sid = sid;198 map->xid.id = uid; /* this is (uid_t)-1 */199 map->xid.type = ID_TYPE_UID;200 map->status = ID_MAPPED;201 return true;202 }203 204 return false;205 }206 207 static void winbindd_sids_to_xids_lookupsids_done(struct tevent_req *subreq)208 {209 struct tevent_req *req = tevent_req_callback_data(210 subreq, struct tevent_req);211 struct winbindd_sids_to_xids_state *state = tevent_req_data(212 req, struct winbindd_sids_to_xids_state);213 struct winbindd_child *child;214 NTSTATUS status;215 int i;216 217 status = wb_lookupsids_recv(subreq, state, &state->domains,218 &state->names);219 TALLOC_FREE(subreq);220 if (tevent_req_nterror(req, status)) {221 return;222 }223 224 state->ids.num_ids = state->num_non_cached;225 state->ids.ids = TALLOC_ARRAY(state, struct wbint_TransID,226 state->num_non_cached);227 if (tevent_req_nomem(state->ids.ids, req)) {228 return;229 }230 231 for (i=0; i<state->num_non_cached; i++) {232 struct lsa_TranslatedName *n = &state->names->names[i];233 struct wbint_TransID *t = &state->ids.ids[i];234 235 switch (n->sid_type) {236 case SID_NAME_USER:237 case SID_NAME_COMPUTER:238 t->type = WBC_ID_TYPE_UID;239 break;240 case SID_NAME_DOM_GRP:241 case SID_NAME_ALIAS:242 case SID_NAME_WKN_GRP:243 t->type = WBC_ID_TYPE_GID;244 break;245 default:246 t->type = WBC_ID_TYPE_NOT_SPECIFIED;247 break;248 };249 t->domain_index = n->sid_index;250 sid_peek_rid(&state->non_cached[i], &t->rid);251 t->unix_id = (uint64_t)-1;252 }253 254 child = idmap_child();255 256 subreq = dcerpc_wbint_Sids2UnixIDs_send(257 state, state->ev, child->binding_handle, state->domains,258 &state->ids);259 if (tevent_req_nomem(subreq, req)) {260 return;261 }262 tevent_req_set_callback(subreq, winbindd_sids_to_xids_done, req);263 77 } 264 78 … … 269 83 struct winbindd_sids_to_xids_state *state = tevent_req_data( 270 84 req, struct winbindd_sids_to_xids_state); 271 NTSTATUS status , result;85 NTSTATUS status; 272 86 273 status = dcerpc_wbint_Sids2UnixIDs_recv(subreq, state, &result); 87 state->xids = talloc_zero_array(state, struct unixid, state->num_sids); 88 if (tevent_req_nomem(state->xids, req)) { 89 return; 90 } 91 92 status = wb_sids2xids_recv(subreq, state->xids, state->num_sids); 274 93 TALLOC_FREE(subreq); 275 if (any_nt_status_not_ok(status, result, &status)) { 276 tevent_req_nterror(req, status); 94 if (tevent_req_nterror(req, status)) { 277 95 return; 278 96 } … … 286 104 req, struct winbindd_sids_to_xids_state); 287 105 NTSTATUS status; 288 char *result ;289 uint32_t i , num_non_cached;106 char *result = NULL; 107 uint32_t i; 290 108 291 109 if (tevent_req_is_nterror(req, &status)) { 292 DEBUG(5, (" wb_sids_to_xids failed: %s\n", nt_errstr(status)));110 DEBUG(5, ("Could not convert sids: %s\n", nt_errstr(status))); 293 111 return status; 294 112 } … … 299 117 } 300 118 301 num_non_cached = 0; 119 for (i=0; i<state->num_sids; i++) { 120 char type = '\0'; 121 bool found = true; 122 struct unixid xid; 302 123 303 for (i=0; i<state->num_sids; i++) { 304 char type; 305 uint32_t unix_id = UINT32_MAX; 306 bool found = true; 124 xid = state->xids[i]; 307 125 308 if (state->cached[i].sid != NULL) { 309 unix_id = state->cached[i].xid.id; 310 311 switch (state->cached[i].xid.type) { 312 case ID_TYPE_UID: 313 type = 'U'; 314 break; 315 case ID_TYPE_GID: 316 type = 'G'; 317 break; 318 default: 319 found = false; 320 break; 321 } 322 } else { 323 unix_id = state->ids.ids[num_non_cached].unix_id; 324 325 switch(state->ids.ids[num_non_cached].type) { 326 case WBC_ID_TYPE_UID: 327 type = 'U'; 328 idmap_cache_set_sid2uid( 329 &state->non_cached[num_non_cached], 330 unix_id); 331 break; 332 case WBC_ID_TYPE_GID: 333 type = 'G'; 334 idmap_cache_set_sid2gid( 335 &state->non_cached[num_non_cached], 336 unix_id); 337 break; 338 default: 339 found = false; 340 break; 341 } 342 num_non_cached += 1; 126 switch (xid.type) { 127 case ID_TYPE_UID: 128 type = 'U'; 129 break; 130 case ID_TYPE_GID: 131 type = 'G'; 132 break; 133 case ID_TYPE_BOTH: 134 type = 'B'; 135 break; 136 default: 137 found = false; 138 break; 343 139 } 344 140 345 if ( unix_id == UINT32_MAX) {141 if (xid.id == UINT32_MAX) { 346 142 found = false; 347 143 } … … 350 146 result = talloc_asprintf_append_buffer( 351 147 result, "%c%lu\n", type, 352 (unsigned long) unix_id);148 (unsigned long)xid.id); 353 149 } else { 354 150 result = talloc_asprintf_append_buffer(result, "\n"); … … 361 157 response->extra_data.data = result; 362 158 response->length += talloc_get_size(result); 159 363 160 return NT_STATUS_OK; 364 161 } -
vendor/current/source3/winbindd/winbindd_util.c
r746 r988 27 27 #include "../libcli/auth/pam_errors.h" 28 28 #include "passdb/machine_sid.h" 29 #include "passdb.h" 30 #include "source4/lib/messaging/messaging.h" 31 #include "librpc/gen_ndr/ndr_lsa.h" 32 #include "auth/credentials/credentials.h" 29 33 30 34 #undef DBGC_CLASS 31 35 #define DBGC_CLASS DBGC_WINBIND 32 36 37 static struct winbindd_domain * 38 add_trusted_domain_from_tdc(const struct winbindd_tdc_domain *tdc, 39 struct winbindd_methods *methods); 40 33 41 extern struct winbindd_methods cache_methods; 34 42 35 43 /** 36 * @file winbindd_util.c q44 * @file winbindd_util.c 37 45 * 38 46 * Winbind daemon for NT domain authentication nss module. … … 68 76 69 77 DLIST_REMOVE(_domain_list, domain); 70 SAFE_FREE(domain);78 TALLOC_FREE(domain); 71 79 domain = next; 72 80 } 81 } 82 83 /** 84 * Iterator for winbindd's domain list. 85 * To be used (e.g.) in tevent based loops. 86 */ 87 struct winbindd_domain *wb_next_domain(struct winbindd_domain *domain) 88 { 89 if (domain == NULL) { 90 domain = domain_list(); 91 } else { 92 domain = domain->next; 93 } 94 95 if ((domain != NULL) && 96 (lp_server_role() != ROLE_ACTIVE_DIRECTORY_DC) && 97 sid_check_is_our_sam(&domain->sid)) 98 { 99 domain = domain->next; 100 } 101 102 return domain; 73 103 } 74 104 … … 78 108 return False; 79 109 80 return (sid_check_is_ domain(sid) || sid_check_is_builtin(sid));110 return (sid_check_is_our_sam(sid) || sid_check_is_builtin(sid)); 81 111 } 82 112 … … 86 116 return False; 87 117 88 return (sid_check_is_in_our_domain(sid) || sid_check_is_in_builtin(sid)); 89 } 90 91 92 /* Add a trusted domain to our list of domains */ 93 static struct winbindd_domain *add_trusted_domain(const char *domain_name, const char *alt_name, 94 struct winbindd_methods *methods, 95 const struct dom_sid *sid) 118 return (sid_check_is_in_our_sam(sid) || sid_check_is_in_builtin(sid)); 119 } 120 121 122 /* Add a trusted domain to our list of domains. 123 If the domain already exists in the list, 124 return it and don't re-initialize. */ 125 126 static struct winbindd_domain * 127 add_trusted_domain(const char *domain_name, const char *alt_name, 128 struct winbindd_methods *methods, const struct dom_sid *sid) 129 { 130 struct winbindd_tdc_domain tdc; 131 132 ZERO_STRUCT(tdc); 133 134 tdc.domain_name = domain_name; 135 tdc.dns_name = alt_name; 136 if (sid) { 137 sid_copy(&tdc.sid, sid); 138 } 139 140 return add_trusted_domain_from_tdc(&tdc, methods); 141 } 142 143 /* Add a trusted domain out of a trusted domain cache 144 entry 145 */ 146 static struct winbindd_domain * 147 add_trusted_domain_from_tdc(const struct winbindd_tdc_domain *tdc, 148 struct winbindd_methods *methods) 96 149 { 97 150 struct winbindd_domain *domain; 98 151 const char *alternative_name = NULL; 99 char *idmap_config_option;100 const char *param;101 152 const char **ignored_domains, **dom; 153 int role = lp_server_role(); 154 const char *domain_name = tdc->domain_name; 155 const struct dom_sid *sid = &tdc->sid; 156 157 if (is_null_sid(sid)) { 158 sid = NULL; 159 } 102 160 103 161 ignored_domains = lp_parm_string_list(-1, "winbind", "ignore domains", NULL); … … 109 167 } 110 168 111 /* ignore alt_name if we are not in an AD domain*/112 113 if ( (lp_security() == SEC_ADS) && alt_name && *alt_name) {114 alternative_name = alt_name;169 /* use alt_name if available to allow DNS lookups */ 170 171 if (tdc->dns_name && *tdc->dns_name) { 172 alternative_name = tdc->dns_name; 115 173 } 116 174 … … 124 182 } 125 183 126 if (alternative_name && *alternative_name) 127 { 184 if (alternative_name) { 128 185 if (strequal(alternative_name, domain->name) || 129 186 strequal(alternative_name, domain->alt_name)) … … 133 190 } 134 191 135 if (sid) 136 { 137 if (is_null_sid(sid)) { 138 continue; 139 } 140 192 if (sid != NULL) { 141 193 if (dom_sid_equal(sid, &domain->sid)) { 142 194 break; … … 147 199 if (domain != NULL) { 148 200 /* 149 * We found a match. Possibly update the SID 201 * We found a match on domain->name or 202 * domain->alt_name. Possibly update the SID 203 * if the stored SID was the NULL SID 204 * and return the matching entry. 150 205 */ 151 206 if ((sid != NULL) … … 157 212 158 213 /* Create new domain entry */ 159 160 if ( (domain = SMB_MALLOC_P(struct winbindd_domain)) == NULL)214 domain = talloc_zero(NULL, struct winbindd_domain); 215 if (domain == NULL) { 161 216 return NULL; 162 163 /* Fill in fields */ 164 165 ZERO_STRUCTP(domain); 166 167 domain->children = SMB_MALLOC_ARRAY( 168 struct winbindd_child, lp_winbind_max_domain_connections()); 217 } 218 219 domain->children = talloc_zero_array(domain, 220 struct winbindd_child, 221 lp_winbind_max_domain_connections()); 169 222 if (domain->children == NULL) { 170 SAFE_FREE(domain);223 TALLOC_FREE(domain); 171 224 return NULL; 172 225 } 173 memset(domain->children, 0, 174 sizeof(struct winbindd_child) 175 * lp_winbind_max_domain_connections()); 176 177 fstrcpy(domain->name, domain_name); 226 227 domain->name = talloc_strdup(domain, domain_name); 228 if (domain->name == NULL) { 229 TALLOC_FREE(domain); 230 return NULL; 231 } 232 178 233 if (alternative_name) { 179 fstrcpy(domain->alt_name, alternative_name); 234 domain->alt_name = talloc_strdup(domain, alternative_name); 235 if (domain->alt_name == NULL) { 236 TALLOC_FREE(domain); 237 return NULL; 238 } 180 239 } 181 240 … … 185 244 domain->sequence_number = DOM_SEQUENCE_NONE; 186 245 domain->last_seq_check = 0; 187 domain->initialized = False;246 domain->initialized = false; 188 247 domain->online = is_internal_domain(sid); 189 248 domain->check_online_timeout = 0; 190 249 domain->dc_probe_pid = (pid_t)-1; 191 if (sid ) {250 if (sid != NULL) { 192 251 sid_copy(&domain->sid, sid); 193 252 } 253 domain->domain_flags = tdc->trust_flags; 254 domain->domain_type = tdc->trust_type; 255 domain->domain_trust_attribs = tdc->trust_attribs; 256 257 /* Is this our primary domain ? */ 258 if (strequal(domain_name, get_global_sam_name()) && 259 (role != ROLE_DOMAIN_MEMBER)) { 260 domain->primary = true; 261 } else if (strequal(domain_name, lp_workgroup()) && 262 (role == ROLE_DOMAIN_MEMBER)) { 263 domain->primary = true; 264 } 265 266 if (domain->primary) { 267 if (role == ROLE_ACTIVE_DIRECTORY_DC) { 268 domain->active_directory = true; 269 } 270 if (lp_security() == SEC_ADS) { 271 domain->active_directory = true; 272 } 273 } else if (!domain->internal) { 274 if (domain->domain_type == LSA_TRUST_TYPE_UPLEVEL) { 275 domain->active_directory = true; 276 } 277 } 194 278 195 279 /* Link to domain list */ 196 DLIST_ADD_END(_domain_list, domain , struct winbindd_domain *);280 DLIST_ADD_END(_domain_list, domain); 197 281 198 282 wcache_tdc_add_domain( domain ); 199 283 200 idmap_config_option = talloc_asprintf(talloc_tos(), "idmap config %s", 201 domain->name); 202 if (idmap_config_option == NULL) { 203 DEBUG(0, ("talloc failed, not looking for idmap config\n")); 204 goto done; 205 } 206 207 param = lp_parm_const_string(-1, idmap_config_option, "range", NULL); 208 209 DEBUG(10, ("%s : range = %s\n", idmap_config_option, 210 param ? param : "not defined")); 211 212 if (param != NULL) { 213 unsigned low_id, high_id; 214 if (sscanf(param, "%u - %u", &low_id, &high_id) != 2) { 215 DEBUG(1, ("invalid range syntax in %s: %s\n", 216 idmap_config_option, param)); 217 goto done; 218 } 219 if (low_id > high_id) { 220 DEBUG(1, ("invalid range in %s: %s\n", 221 idmap_config_option, param)); 222 goto done; 223 } 224 domain->have_idmap_config = true; 225 domain->id_range_low = low_id; 226 domain->id_range_high = high_id; 227 } 228 229 done: 230 231 DEBUG(2,("Added domain %s %s %s\n", 232 domain->name, domain->alt_name, 233 &domain->sid?sid_string_dbg(&domain->sid):"")); 284 setup_domain_child(domain); 285 286 DEBUG(2, 287 ("Added domain %s %s %s\n", domain->name, domain->alt_name, 288 !is_null_sid(&domain->sid) ? sid_string_dbg(&domain->sid) : "")); 234 289 235 290 return domain; … … 262 317 struct tevent_req *req; 263 318 264 state = TALLOC_ZERO_P(NULL, struct trustdom_state);319 state = talloc_zero(NULL, struct trustdom_state); 265 320 if (state == NULL) { 266 321 DEBUG(0, ("talloc failed\n")); … … 289 344 int res, err; 290 345 char *p; 346 struct winbindd_tdc_domain trust_params = {0}; 347 ptrdiff_t extra_len; 291 348 292 349 res = wb_domain_request_recv(req, state, &response, &err); 293 350 if ((res == -1) || (response->result != WINBINDD_OK)) { 294 D EBUG(1, ("Could not receive trustdoms\n"));351 DBG_WARNING("Could not receive trustdoms\n"); 295 352 TALLOC_FREE(state); 296 353 return; 297 354 } 298 355 356 if (response->length < sizeof(struct winbindd_response)) { 357 DBG_ERR("ill-formed trustdom response - short length\n"); 358 TALLOC_FREE(state); 359 return; 360 } 361 362 extra_len = response->length - sizeof(struct winbindd_response); 363 299 364 p = (char *)response->extra_data.data; 300 365 301 while ((p != NULL) && (*p != '\0')) {366 while ((p - (char *)response->extra_data.data) < extra_len) { 302 367 char *q, *sidstr, *alt_name; 303 struct dom_sid sid; 304 struct winbindd_domain *domain; 305 char *alternate_name = NULL; 368 369 DBG_DEBUG("parsing response line '%s'\n", p); 370 371 ZERO_STRUCT(trust_params); 372 trust_params.domain_name = p; 306 373 307 374 alt_name = strchr(p, '\\'); 308 375 if (alt_name == NULL) { 376 DBG_ERR("Got invalid trustdom response\n"); 377 break; 378 } 379 380 *alt_name = '\0'; 381 alt_name += 1; 382 383 sidstr = strchr(alt_name, '\\'); 384 if (sidstr == NULL) { 385 DBG_ERR("Got invalid trustdom response\n"); 386 break; 387 } 388 389 *sidstr = '\0'; 390 sidstr += 1; 391 392 /* use the real alt_name if we have one, else pass in NULL */ 393 if (!strequal(alt_name, "(null)")) { 394 trust_params.dns_name = alt_name; 395 } 396 397 q = strtok(sidstr, "\\"); 398 if (q == NULL) { 399 DBG_ERR("Got invalid trustdom response\n"); 400 break; 401 } 402 403 if (!string_to_sid(&trust_params.sid, sidstr)) { 309 404 DEBUG(0, ("Got invalid trustdom response\n")); 310 405 break; 311 406 } 312 407 313 *alt_name = '\0'; 314 alt_name += 1; 315 316 sidstr = strchr(alt_name, '\\'); 317 if (sidstr == NULL) { 318 DEBUG(0, ("Got invalid trustdom response\n")); 408 q = strtok(NULL, "\\"); 409 if (q == NULL) { 410 DBG_ERR("Got invalid trustdom response\n"); 319 411 break; 320 412 } 321 413 322 *sidstr = '\0'; 323 sidstr += 1; 324 325 q = strchr(sidstr, '\n'); 326 if (q != NULL) 327 *q = '\0'; 328 329 if (!string_to_sid(&sid, sidstr)) { 330 DEBUG(0, ("Got invalid trustdom response\n")); 414 trust_params.trust_flags = (uint32_t)strtoul(q, NULL, 10); 415 416 q = strtok(NULL, "\\"); 417 if (q == NULL) { 418 DBG_ERR("Got invalid trustdom response\n"); 331 419 break; 332 420 } 333 421 334 /* use the real alt_name if we have one, else pass in NULL */ 335 336 if ( !strequal( alt_name, "(null)" ) ) 337 alternate_name = alt_name; 338 339 /* If we have an existing domain structure, calling 340 add_trusted_domain() will update the SID if 341 necessary. This is important because we need the 342 SID for sibling domains */ 343 344 if ( find_domain_from_name_noinit(p) != NULL ) { 345 domain = add_trusted_domain(p, alternate_name, 346 &cache_methods, 347 &sid); 348 } else { 349 domain = add_trusted_domain(p, alternate_name, 350 &cache_methods, 351 &sid); 352 if (domain) { 353 setup_domain_child(domain); 354 } 355 } 356 p=q; 357 if (p != NULL) 358 p += 1; 422 trust_params.trust_type = (uint32_t)strtoul(q, NULL, 10); 423 424 q = strtok(NULL, "\n"); 425 if (q == NULL) { 426 DBG_ERR("Got invalid trustdom response\n"); 427 break; 428 } 429 430 trust_params.trust_attribs = (uint32_t)strtoul(q, NULL, 10); 431 432 /* 433 * We always call add_trusted_domain() cause on an existing 434 * domain structure, it will update the SID if necessary. 435 * This is important because we need the SID for sibling 436 * domains. 437 */ 438 (void)add_trusted_domain_from_tdc(&trust_params, 439 &cache_methods); 440 441 p = q + strlen(q) + 1; 359 442 } 360 443 … … 423 506 424 507 if ( !d ) { 425 d = add_trusted_domain( dom_list[i].domain_name, 426 dom_list[i].dns_name, 427 &cache_methods, 428 &dom_list[i].sid ); 429 if (d != NULL) { 430 setup_domain_child(d); 431 } 508 d = add_trusted_domain_from_tdc(&dom_list[i], 509 &cache_methods); 432 510 } 433 511 … … 476 554 477 555 for ( i=0; i<num_trusts; i++ ) { 478 uint32 flags = dom_list[i].trust_flags;479 uint32 type = dom_list[i].trust_type;480 uint32 attribs = dom_list[i].trust_attribs;556 uint32_t flags = dom_list[i].trust_flags; 557 uint32_t type = dom_list[i].trust_type; 558 uint32_t attribs = dom_list[i].trust_attribs; 481 559 482 560 d = find_domain_from_name_noinit( dom_list[i].domain_name ); … … 488 566 489 567 if ( (flags & NETR_TRUST_FLAG_INBOUND) && 490 (type == NETR_TRUST_TYPE_UPLEVEL) &&491 (attribs == NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) )568 (type == LSA_TRUST_TYPE_UPLEVEL) && 569 (attribs == LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) ) 492 570 { 493 571 /* add the trusted domain if we don't know … … 495 573 496 574 if ( !d ) { 497 d = add_trusted_domain( dom_list[i].domain_name, 498 dom_list[i].dns_name, 499 &cache_methods, 500 &dom_list[i].sid ); 501 if (d != NULL) { 502 setup_domain_child(d); 503 } 575 d = add_trusted_domain_from_tdc(&dom_list[i], 576 &cache_methods); 504 577 } 505 578 … … 569 642 } 570 643 571 if (domain->internal) { 572 domain->initialized = true; 573 } else { 574 init_dc_connection(domain); 575 } 644 init_dc_connection(domain, false); 576 645 577 646 if (!domain->initialized) { … … 599 668 } 600 669 670 static void wb_imsg_new_trusted_domain(struct imessaging_context *msg, 671 void *private_data, 672 uint32_t msg_type, 673 struct server_id server_id, 674 DATA_BLOB *data) 675 { 676 TALLOC_CTX *frame = talloc_stackframe(); 677 struct lsa_TrustDomainInfoInfoEx info; 678 enum ndr_err_code ndr_err; 679 struct winbindd_domain *d = NULL; 680 681 DEBUG(5, ("wb_imsg_new_trusted_domain\n")); 682 683 if (data == NULL) { 684 TALLOC_FREE(frame); 685 return; 686 } 687 688 ndr_err = ndr_pull_struct_blob_all(data, frame, &info, 689 (ndr_pull_flags_fn_t)ndr_pull_lsa_TrustDomainInfoInfoEx); 690 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 691 TALLOC_FREE(frame); 692 return; 693 } 694 695 d = find_domain_from_name_noinit(info.netbios_name.string); 696 if (d != NULL) { 697 TALLOC_FREE(frame); 698 return; 699 } 700 701 d = add_trusted_domain(info.netbios_name.string, 702 info.domain_name.string, 703 &cache_methods, 704 info.sid); 705 if (d == NULL) { 706 TALLOC_FREE(frame); 707 return; 708 } 709 710 if (d->internal) { 711 TALLOC_FREE(frame); 712 return; 713 } 714 715 if (d->primary) { 716 TALLOC_FREE(frame); 717 return; 718 } 719 720 if (info.trust_direction & LSA_TRUST_DIRECTION_INBOUND) { 721 d->domain_flags |= NETR_TRUST_FLAG_INBOUND; 722 } 723 if (info.trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) { 724 d->domain_flags |= NETR_TRUST_FLAG_OUTBOUND; 725 } 726 if (info.trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) { 727 d->domain_flags |= NETR_TRUST_FLAG_IN_FOREST; 728 } 729 d->domain_type = info.trust_type; 730 d->domain_trust_attribs = info.trust_attributes; 731 732 TALLOC_FREE(frame); 733 } 734 735 /* 736 * We did not get the secret when we queried secrets.tdb, so read it 737 * from secrets.tdb and re-sync the databases 738 */ 739 static bool migrate_secrets_tdb_to_ldb(struct winbindd_domain *domain) 740 { 741 bool ok; 742 struct cli_credentials *creds; 743 NTSTATUS can_migrate = pdb_get_trust_credentials(domain->name, 744 NULL, domain, &creds); 745 if (!NT_STATUS_IS_OK(can_migrate)) { 746 DEBUG(0, ("Failed to fetch our own, local AD domain join " 747 "password for winbindd's internal use, both from " 748 "secrets.tdb and secrets.ldb: %s\n", 749 nt_errstr(can_migrate))); 750 return false; 751 } 752 753 /* 754 * NOTE: It is very unlikely we end up here if there is an 755 * oldpass, because a new password is created at 756 * classicupgrade, so this is not a concern. 757 */ 758 ok = secrets_store_machine_pw_sync(cli_credentials_get_password(creds), 759 NULL /* oldpass */, 760 cli_credentials_get_domain(creds), 761 cli_credentials_get_realm(creds), 762 cli_credentials_get_salt_principal(creds), 763 0, /* Supported enc types, unused */ 764 &domain->sid, 765 cli_credentials_get_password_last_changed_time(creds), 766 cli_credentials_get_secure_channel_type(creds), 767 false /* do_delete: Do not delete */); 768 TALLOC_FREE(creds); 769 if (ok == false) { 770 DEBUG(0, ("Failed to write our our own, " 771 "local AD domain join password for " 772 "winbindd's internal use into secrets.tdb\n")); 773 return false; 774 } 775 return true; 776 } 777 601 778 /* Look up global info for the winbind daemon */ 602 779 bool init_domain_list(void) 603 780 { 604 struct winbindd_domain *domain;605 781 int role = lp_server_role(); 782 NTSTATUS status; 606 783 607 784 /* Free existing list */ … … 610 787 /* BUILTIN domain */ 611 788 612 domain =add_trusted_domain("BUILTIN", NULL, &cache_methods,789 (void)add_trusted_domain("BUILTIN", NULL, &cache_methods, 613 790 &global_sid_Builtin); 614 if (domain) {615 setup_domain_child(domain);616 }617 791 618 792 /* Local SAM */ 619 793 620 domain = add_trusted_domain(get_global_sam_name(), NULL, 621 &cache_methods, get_global_sam_sid()); 622 if (domain) { 623 if ( role != ROLE_DOMAIN_MEMBER ) { 624 domain->primary = True; 625 } 626 setup_domain_child(domain); 627 } 628 794 if ( role == ROLE_ACTIVE_DIRECTORY_DC ) { 795 struct winbindd_domain *domain; 796 enum netr_SchannelType sec_chan_type; 797 const char *account_name; 798 struct samr_Password current_nt_hash; 799 struct pdb_domain_info *pdb_domain_info; 800 bool ok; 801 802 pdb_domain_info = pdb_get_domain_info(talloc_tos()); 803 if (pdb_domain_info == NULL) { 804 DEBUG(0, ("Failed to fetch our own, local AD " 805 "domain info from sam.ldb\n")); 806 return false; 807 } 808 domain = add_trusted_domain(pdb_domain_info->name, 809 pdb_domain_info->dns_domain, 810 &cache_methods, 811 &pdb_domain_info->sid); 812 TALLOC_FREE(pdb_domain_info); 813 if (domain == NULL) { 814 DEBUG(0, ("Failed to add our own, local AD " 815 "domain to winbindd's internal list\n")); 816 return false; 817 } 818 819 /* 820 * We need to call this to find out if we are an RODC 821 */ 822 ok = get_trust_pw_hash(domain->name, 823 current_nt_hash.hash, 824 &account_name, 825 &sec_chan_type); 826 if (!ok) { 827 /* 828 * If get_trust_pw_hash() fails, then try and 829 * fetch the password from the more recent of 830 * secrets.{ldb,tdb} using the 831 * pdb_get_trust_credentials() 832 */ 833 ok = migrate_secrets_tdb_to_ldb(domain); 834 835 if (ok == false) { 836 DEBUG(0, ("Failed to migrate our own, " 837 "local AD domain join password for " 838 "winbindd's internal use into " 839 "secrets.tdb\n")); 840 return false; 841 } 842 ok = get_trust_pw_hash(domain->name, 843 current_nt_hash.hash, 844 &account_name, 845 &sec_chan_type); 846 if (ok == false) { 847 DEBUG(0, ("Failed to find our our own, just " 848 "written local AD domain join " 849 "password for winbindd's internal " 850 "use in secrets.tdb\n")); 851 return false; 852 } 853 } 854 if (sec_chan_type == SEC_CHAN_RODC) { 855 domain->rodc = true; 856 } 857 858 } else { 859 (void)add_trusted_domain(get_global_sam_name(), NULL, 860 &cache_methods, get_global_sam_sid()); 861 } 629 862 /* Add ourselves as the first entry. */ 630 863 631 864 if ( role == ROLE_DOMAIN_MEMBER ) { 865 struct winbindd_domain *domain; 632 866 struct dom_sid our_sid; 633 867 … … 640 874 &cache_methods, &our_sid); 641 875 if (domain) { 642 domain->primary = True;643 setup_domain_child(domain);644 645 876 /* Even in the parent winbindd we'll need to 646 877 talk to the DC, so try and see if we can … … 651 882 set_domain_online_request(domain); 652 883 } 884 } 885 886 status = imessaging_register(winbind_imessaging_context(), NULL, 887 MSG_WINBIND_NEW_TRUSTED_DOMAIN, 888 wb_imsg_new_trusted_domain); 889 if (!NT_STATUS_IS_OK(status)) { 890 DEBUG(0, ("imessaging_register(MSG_WINBIND_NEW_TRUSTED_DOMAIN) - %s\n", 891 nt_errstr(status))); 892 return false; 653 893 } 654 894 … … 676 916 for (domain = domain_list(); domain != NULL; domain = domain->next) { 677 917 if (strequal(domain_name, domain->name) || 678 (domain->alt_name [0]&&918 (domain->alt_name != NULL && 679 919 strequal(domain_name, domain->alt_name))) { 680 920 return domain; … … 697 937 698 938 if (!domain->initialized) 699 init_dc_connection(domain );939 init_dc_connection(domain, false); 700 940 701 941 return domain; … … 732 972 733 973 if (!domain->initialized) 734 init_dc_connection(domain );974 init_dc_connection(domain, false); 735 975 736 976 return domain; … … 756 996 struct winbindd_domain *ours = find_our_domain(); 757 997 758 if (ours->forest_name [0] == '\0') {998 if (ours->forest_name == NULL) { 759 999 return NULL; 760 1000 } … … 878 1118 } 879 1119 880 strupper_m(domain); 881 882 return True; 1120 return strupper_m(domain); 883 1121 } 884 1122 … … 927 1165 username is then unqualified in unix 928 1166 1167 On an AD DC we always fill DOMAIN\\USERNAME. 1168 929 1169 We always canonicalize as UPPERCASE DOMAIN, lowercase username. 930 1170 */ … … 933 1173 fstring tmp_user; 934 1174 1175 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) { 1176 can_assume = false; 1177 } 1178 935 1179 fstrcpy(tmp_user, user); 936 strlower_m(tmp_user);1180 (void)strlower_m(tmp_user); 937 1181 938 1182 if (can_assume && assume_domain(domain)) { … … 956 1200 char *tmp_user, *name; 957 1201 1202 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) { 1203 can_assume = false; 1204 } 1205 958 1206 tmp_user = talloc_strdup(mem_ctx, user); 959 strlower_m(tmp_user); 1207 if (!strlower_m(tmp_user)) { 1208 TALLOC_FREE(tmp_user); 1209 return NULL; 1210 } 960 1211 961 1212 if (can_assume && assume_domain(domain)) { … … 986 1237 } 987 1238 1239 /* Return list-tail of all connected clients */ 1240 1241 struct winbindd_cli_state *winbindd_client_list_tail(void) 1242 { 1243 return DLIST_TAIL(_client_list); 1244 } 1245 1246 /* Return previous (read:newer) client in list */ 1247 1248 struct winbindd_cli_state * 1249 winbindd_client_list_prev(struct winbindd_cli_state *cli) 1250 { 1251 return DLIST_PREV(cli); 1252 } 1253 988 1254 /* Add a connection to the list */ 989 1255 990 1256 void winbindd_add_client(struct winbindd_cli_state *cli) 991 1257 { 1258 cli->last_access = time(NULL); 992 1259 DLIST_ADD(_client_list, cli); 993 1260 _num_clients++; … … 1000 1267 DLIST_REMOVE(_client_list, cli); 1001 1268 _num_clients--; 1269 } 1270 1271 /* Move a client to head or list */ 1272 1273 void winbindd_promote_client(struct winbindd_cli_state *cli) 1274 { 1275 cli->last_access = time(NULL); 1276 DLIST_PROMOTE(_client_list, cli); 1002 1277 } 1003 1278 … … 1180 1455 1181 1456 if (domain->primary) { 1182 return true; 1457 ret = true; 1458 goto done; 1183 1459 } 1184 1460 … … 1188 1464 DEBUG(10,("winbindd_can_contact_domain: %s not found in cache\n", 1189 1465 domain->name)); 1190 return false; 1466 ret = false; 1467 goto done; 1191 1468 } 1192 1469 … … 1358 1635 } 1359 1636 1637 /** 1638 * Parse an char array into a list of sids. 1639 * 1640 * The input sidstr should consist of 0-terminated strings 1641 * representing sids, separated by newline characters '\n'. 1642 * The list is terminated by an empty string, i.e. 1643 * character '\0' directly following a character '\n' 1644 * (or '\0' right at the start of sidstr). 1645 */ 1360 1646 bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr, 1361 1647 struct dom_sid **sids, uint32_t *num_sids) -
vendor/current/source3/winbindd/wscript_build
r740 r988 1 1 #!/usr/bin/env python 2 2 3 IDMAP_AD_SRC = '''idmap_ad.c''' 4 IDMAP_RID_SRC = '''idmap_rid.c''' 5 IDMAP_PASSDB_SRC = '''idmap_passdb.c''' 6 IDMAP_LDAP_SRC = '''idmap_ldap.c''' 7 IDMAP_NSS_SRC = '''idmap_nss.c''' 8 IDMAP_TDB_SRC = '''idmap_tdb.c''' 9 IDMAP_TDB2_SRC = '''idmap_tdb2.c''' 3 bld.SAMBA3_LIBRARY('idmap', 4 source='idmap.c idmap_util.c', 5 deps='samba-util pdb', 6 allow_undefined_symbols=True, 7 private_library=True) 10 8 11 IDMAP_HASH_SRC = '''idmap_hash/idmap_hash.c 12 idmap_hash/mapfile.c''' 9 bld.SAMBA3_SUBSYSTEM('IDMAP_RW', 10 source='idmap_rw.c', 11 deps='samba-util') 13 12 14 IDMAP_ADEX_SRC = '''idmap_adex/idmap_adex.c 15 idmap_adex/cell_util.c 16 idmap_adex/likewise_cell.c 17 idmap_adex/provider_unified.c 18 idmap_adex/gc_util.c 19 idmap_adex/domain_util.c''' 20 IDMAP_AUTORID_SRC = '''idmap_autorid.c''' 21 22 IDMAP_RW_SRC = 'idmap_rw.c' 23 IDMAP_SRC = 'idmap.c idmap_util.c ${IDMAP_RW_SRC}' 24 25 bld.SAMBA3_SUBSYSTEM('idmap', 26 source=IDMAP_SRC, 27 vars=locals()) 28 29 bld.SAMBA3_SUBSYSTEM('IDMAP_ADEX', 30 source=IDMAP_ADEX_SRC, 31 vars=locals(), 32 enabled=bld.env.HAVE_LDAP) 13 bld.SAMBA3_SUBSYSTEM('IDMAP_TDB_COMMON', 14 source='idmap_tdb_common.c', 15 deps='tdb IDMAP_RW') 33 16 34 17 bld.SAMBA3_SUBSYSTEM('IDMAP_HASH', 35 source=IDMAP_HASH_SRC, 36 vars=locals()) 18 source='idmap_hash/idmap_hash.c idmap_hash/mapfile.c', 19 deps='samba-util krb5samba', 20 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_hash')) 37 21 38 22 bld.SAMBA3_SUBSYSTEM('IDMAP_AD', 39 source= IDMAP_AD_SRC,40 vars=locals(),41 enabled=bld. env.HAVE_LDAP)23 source='idmap_ad.c', 24 deps='ads nss_info', 25 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad')) 42 26 43 27 bld.SAMBA3_MODULE('idmap_ad', 44 28 subsystem='idmap', 29 allow_undefined_symbols=True, 45 30 source='', 46 31 deps='IDMAP_AD', 47 32 init_function='', 48 33 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_ad'), 49 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad' and bld.env.HAVE_LDAP)) 34 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad')) 35 36 bld.SAMBA3_MODULE('idmap_rfc2307', 37 subsystem='idmap', 38 allow_undefined_symbols=True, 39 source='idmap_rfc2307.c', 40 init_function='', 41 deps='ads', 42 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_rfc2307'), 43 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_rfc2307')) 50 44 51 45 bld.SAMBA3_MODULE('idmap_rid', 52 46 subsystem='idmap', 53 source=IDMAP_RID_SRC, 47 allow_undefined_symbols=True, 48 source='idmap_rid.c', 54 49 init_function='', 55 50 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_rid'), … … 58 53 bld.SAMBA3_MODULE('idmap_passdb', 59 54 subsystem='idmap', 60 source=IDMAP_PASSDB_SRC, 55 source='idmap_passdb.c', 56 deps='samba-util samba-passdb', 61 57 init_function='', 62 58 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_passdb'), … … 65 61 bld.SAMBA3_MODULE('idmap_ldap', 66 62 subsystem='idmap', 67 source=IDMAP_LDAP_SRC, 63 source='idmap_ldap.c', 64 deps='smbldap smbldaphelper pdb IDMAP_RW', 68 65 init_function='', 69 66 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_ldap'), 70 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ldap') and bld.env.HAVE_LDAP) 67 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ldap') and bld.CONFIG_SET("HAVE_LDAP"), 68 allow_undefined_symbols=True) 71 69 72 70 bld.SAMBA3_MODULE('idmap_nss', 73 71 subsystem='idmap', 74 source=IDMAP_NSS_SRC, 72 source='idmap_nss.c', 73 deps='samba-util', 75 74 init_function='', 76 75 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_nss'), … … 79 78 bld.SAMBA3_MODULE('idmap_tdb', 80 79 subsystem='idmap', 81 source=IDMAP_TDB_SRC, 80 source='idmap_tdb.c', 81 deps='samba-util tdb IDMAP_TDB_COMMON', 82 82 init_function='', 83 allow_undefined_symbols=True, 83 84 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_tdb'), 84 85 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_tdb')) … … 86 87 bld.SAMBA3_MODULE('idmap_tdb2', 87 88 subsystem='idmap', 88 source=IDMAP_TDB2_SRC, 89 source='idmap_tdb2.c', 90 deps='samba-util tdb IDMAP_TDB_COMMON', 89 91 init_function='', 90 92 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_tdb2'), … … 95 97 source='', 96 98 deps='IDMAP_HASH', 99 allow_undefined_symbols=True, 97 100 init_function='', 98 101 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_hash'), 99 102 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_hash')) 100 103 101 bld.SAMBA3_MODULE('idmap_adex', 102 subsystem='idmap', 103 source='', 104 deps='IDMAP_ADEX', 105 init_function='', 106 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_adex'), 107 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_adex') and bld.env.HAVE_LDAP) 104 bld.SAMBA3_SUBSYSTEM('IDMAP_AUTORID_TDB', 105 source='idmap_autorid_tdb.c', 106 deps='tdb') 108 107 109 108 bld.SAMBA3_MODULE('idmap_autorid', 110 109 subsystem='idmap', 111 source=IDMAP_AUTORID_SRC, 110 source='idmap_autorid.c', 111 deps='samba-util tdb IDMAP_TDB_COMMON IDMAP_AUTORID_TDB', 112 112 init_function='', 113 113 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_autorid'), 114 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_autorid')) 114 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_autorid'), 115 allow_undefined_symbols=True) 115 116 116 117 NSS_INFO_TEMPLATE_SRC = 'nss_info_template.c' 118 NSS_INFO_SRC = 'nss_info.c' 119 120 bld.SAMBA3_SUBSYSTEM('nss_info', 121 source=NSS_INFO_SRC, 122 vars=locals()) 117 bld.SAMBA3_LIBRARY('nss_info', 118 source='nss_info.c', 119 deps='samba-util param', 120 private_library=True) 123 121 124 122 bld.SAMBA3_MODULE('nss_info_template', 125 123 subsystem='nss_info', 126 source=NSS_INFO_TEMPLATE_SRC, 124 source='nss_info_template.c', 125 deps='samba-util krb5samba', 127 126 init_function='', 128 127 internal_module=bld.SAMBA3_IS_STATIC_MODULE('nss_info_template'), 129 128 enabled=bld.SAMBA3_IS_ENABLED_MODULE('nss_info_template')) 130 131 bld.SAMBA3_MODULE('nss_info_adex',132 subsystem='nss_info',133 source='',134 deps='IDMAP_ADEX',135 init_function='',136 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_adex'),137 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_adex') and bld.env.HAVE_LDAP)138 129 139 130 bld.SAMBA3_MODULE('nss_info_hash', … … 141 132 source='', 142 133 deps='IDMAP_HASH', 134 allow_undefined_symbols=True, 143 135 init_function='', 144 136 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_hash'), … … 149 141 source='', 150 142 deps='IDMAP_AD', 143 allow_undefined_symbols=True, 151 144 init_function='', 152 145 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_ad'), 153 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad') and bld.env.HAVE_LDAP)146 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad')) 154 147 155 148 bld.SAMBA3_MODULE('nss_info_sfu20', … … 157 150 source='', 158 151 deps='IDMAP_AD', 152 allow_undefined_symbols=True, 159 153 init_function='', 160 154 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_ad'), 161 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad') and bld.env.HAVE_LDAP)155 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad')) 162 156 163 157 bld.SAMBA3_MODULE('nss_info_sfu', … … 165 159 source='', 166 160 deps='IDMAP_AD', 161 allow_undefined_symbols=True, 167 162 init_function='', 168 163 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_ad'), 169 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad') and bld.env.HAVE_LDAP) 164 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_ad') and bld.CONFIG_SET("HAVE_LDAP")) 165 166 bld.SAMBA3_MODULE('idmap_script', 167 subsystem='idmap', 168 allow_undefined_symbols=True, 169 source='idmap_script.c', 170 init_function='', 171 internal_module=bld.SAMBA3_IS_STATIC_MODULE('idmap_script'), 172 enabled=bld.SAMBA3_IS_ENABLED_MODULE('idmap_script'))
Note:
See TracChangeset
for help on using the changeset viewer.