1/* 2 Unix SMB/CIFS implementation. 3 Password and authentication handling 4 Copyright (C) Andrew Bartlett 2002 5 Copyright (C) Jelmer Vernooij 2002 6 Copyright (C) Simo Sorce 2003 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 2 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21*/ 22 23#include "includes.h" 24 25#undef DBGC_CLASS 26#define DBGC_CLASS DBGC_PASSDB 27 28static struct pdb_init_function_entry *backends = NULL; 29 30static void lazy_initialize_passdb(void) 31{ 32 static BOOL initialized = False; 33 if(initialized)return; 34 static_init_pdb; 35 initialized = True; 36} 37 38static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name); 39 40/******************************************************************* 41 Clean up uninitialised passwords. The only way to tell 42 that these values are not 'real' is that they do not 43 have a valid last set time. Instead, the value is fixed at 0. 44 Therefore we use that as the key for 'is this a valid password'. 45 However, it is perfectly valid to have a 'default' last change 46 time, such LDAP with a missing attribute would produce. 47********************************************************************/ 48 49static void pdb_force_pw_initialization(SAM_ACCOUNT *pass) 50{ 51 const char *lm_pwd, *nt_pwd; 52 53 /* only reset a password if the last set time has been 54 explicitly been set to zero. A default last set time 55 is ignored */ 56 57 if ( (pdb_get_init_flags(pass, PDB_PASSLASTSET) != PDB_DEFAULT) 58 && (pdb_get_pass_last_set_time(pass) == 0) ) 59 { 60 61 if (pdb_get_init_flags(pass, PDB_LMPASSWD) != PDB_DEFAULT) 62 { 63 lm_pwd = pdb_get_lanman_passwd(pass); 64 if (lm_pwd) 65 pdb_set_lanman_passwd(pass, NULL, PDB_CHANGED); 66 } 67 if (pdb_get_init_flags(pass, PDB_NTPASSWD) != PDB_DEFAULT) 68 { 69 nt_pwd = pdb_get_nt_passwd(pass); 70 if (nt_pwd) 71 pdb_set_nt_passwd(pass, NULL, PDB_CHANGED); 72 } 73 } 74 75 return; 76} 77 78NTSTATUS smb_register_passdb(int version, const char *name, pdb_init_function init) 79{ 80 struct pdb_init_function_entry *entry = backends; 81 82 if(version != PASSDB_INTERFACE_VERSION) { 83 DEBUG(0,("Can't register passdb backend!\n" 84 "You tried to register a passdb module with PASSDB_INTERFACE_VERSION %d, " 85 "while this version of samba uses version %d\n", 86 version,PASSDB_INTERFACE_VERSION)); 87 return NT_STATUS_OBJECT_TYPE_MISMATCH; 88 } 89 90 if (!name || !init) { 91 return NT_STATUS_INVALID_PARAMETER; 92 } 93 94 DEBUG(5,("Attempting to register passdb backend %s\n", name)); 95 96 /* Check for duplicates */ 97 if (pdb_find_backend_entry(name)) { 98 DEBUG(0,("There already is a passdb backend registered with the name %s!\n", name)); 99 return NT_STATUS_OBJECT_NAME_COLLISION; 100 } 101 102 entry = SMB_XMALLOC_P(struct pdb_init_function_entry); 103 entry->name = smb_xstrdup(name); 104 entry->init = init; 105 106 DLIST_ADD(backends, entry); 107 DEBUG(5,("Successfully added passdb backend '%s'\n", name)); 108 return NT_STATUS_OK; 109} 110 111static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name) 112{ 113 struct pdb_init_function_entry *entry = backends; 114 115 while(entry) { 116 if (strcmp(entry->name, name)==0) return entry; 117 entry = entry->next; 118 } 119 120 return NULL; 121} 122 123static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update, uint16 acb_mask) 124{ 125 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 126 127 if (!context) { 128 DEBUG(0, ("invalid pdb_context specified!\n")); 129 return ret; 130 } 131 132 context->pwent_methods = context->pdb_methods; 133 134 if (!context->pwent_methods) { 135 /* No passdbs at all */ 136 return ret; 137 } 138 139 while (NT_STATUS_IS_ERR(ret = context->pwent_methods->setsampwent(context->pwent_methods, update, acb_mask))) { 140 context->pwent_methods = context->pwent_methods->next; 141 if (context->pwent_methods == NULL) 142 return NT_STATUS_UNSUCCESSFUL; 143 } 144 return ret; 145} 146 147static void context_endsampwent(struct pdb_context *context) 148{ 149 if ((!context)){ 150 DEBUG(0, ("invalid pdb_context specified!\n")); 151 return; 152 } 153 154 if (context->pwent_methods && context->pwent_methods->endsampwent) 155 context->pwent_methods->endsampwent(context->pwent_methods); 156 157 /* So we won't get strange data when calling getsampwent now */ 158 context->pwent_methods = NULL; 159} 160 161static NTSTATUS context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user) 162{ 163 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 164 165 if ((!context) || (!context->pwent_methods)) { 166 DEBUG(0, ("invalid pdb_context specified!\n")); 167 return ret; 168 } 169 /* Loop until we find something useful */ 170 while (NT_STATUS_IS_ERR(ret = context->pwent_methods->getsampwent(context->pwent_methods, user))) { 171 172 context->pwent_methods->endsampwent(context->pwent_methods); 173 174 context->pwent_methods = context->pwent_methods->next; 175 176 /* All methods are checked now. There are no more entries */ 177 if (context->pwent_methods == NULL) 178 return ret; 179 180 context->pwent_methods->setsampwent(context->pwent_methods, False, 0); 181 } 182 user->methods = context->pwent_methods; 183 pdb_force_pw_initialization(user); 184 return ret; 185} 186 187static NTSTATUS context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username) 188{ 189 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 190 191 struct pdb_methods *curmethods; 192 if ((!context)) { 193 DEBUG(0, ("invalid pdb_context specified!\n")); 194 return ret; 195 } 196 curmethods = context->pdb_methods; 197 while (curmethods){ 198 if (NT_STATUS_IS_OK(ret = curmethods->getsampwnam(curmethods, sam_acct, username))) { 199 pdb_force_pw_initialization(sam_acct); 200 sam_acct->methods = curmethods; 201 return ret; 202 } 203 curmethods = curmethods->next; 204 } 205 206 return ret; 207} 208 209static NTSTATUS context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const DOM_SID *sid) 210{ 211 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 212 213 struct pdb_methods *curmethods; 214 if ((!context)) { 215 DEBUG(0, ("invalid pdb_context specified!\n")); 216 return ret; 217 } 218 219 curmethods = context->pdb_methods; 220 221 while (curmethods){ 222 if (NT_STATUS_IS_OK(ret = curmethods->getsampwsid(curmethods, sam_acct, sid))) { 223 pdb_force_pw_initialization(sam_acct); 224 sam_acct->methods = curmethods; 225 return ret; 226 } 227 curmethods = curmethods->next; 228 } 229 230 return ret; 231} 232 233static NTSTATUS context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct) 234{ 235 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 236 const char *lm_pw, *nt_pw; 237 uint16 acb_flags; 238 239 if ((!context) || (!context->pdb_methods)) { 240 DEBUG(0, ("invalid pdb_context specified!\n")); 241 return ret; 242 } 243 244 /* disable acccounts with no passwords (that has not 245 been allowed by the ACB_PWNOTREQ bit */ 246 247 lm_pw = pdb_get_lanman_passwd( sam_acct ); 248 nt_pw = pdb_get_nt_passwd( sam_acct ); 249 acb_flags = pdb_get_acct_ctrl( sam_acct ); 250 if ( !lm_pw && !nt_pw && !(acb_flags&ACB_PWNOTREQ) ) { 251 acb_flags |= ACB_DISABLED; 252 pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_CHANGED ); 253 } 254 255 /** @todo This is where a 're-read on add' should be done */ 256 /* We now add a new account to the first database listed. 257 * Should we? */ 258 259 return context->pdb_methods->add_sam_account(context->pdb_methods, sam_acct); 260} 261 262static NTSTATUS context_update_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct) 263{ 264 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 265 const char *lm_pw, *nt_pw; 266 uint16 acb_flags; 267 268 if (!context) { 269 DEBUG(0, ("invalid pdb_context specified!\n")); 270 return ret; 271 } 272 273 if (!sam_acct || !sam_acct->methods){ 274 DEBUG(0, ("invalid sam_acct specified\n")); 275 return ret; 276 } 277 278 /* disable acccounts with no passwords (that has not 279 been allowed by the ACB_PWNOTREQ bit */ 280 281 lm_pw = pdb_get_lanman_passwd( sam_acct ); 282 nt_pw = pdb_get_nt_passwd( sam_acct ); 283 acb_flags = pdb_get_acct_ctrl( sam_acct ); 284 if ( !lm_pw && !nt_pw && !(acb_flags&ACB_PWNOTREQ) ) { 285 acb_flags |= ACB_DISABLED; 286 pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_CHANGED ); 287 } 288 289 /** @todo This is where a 're-read on update' should be done */ 290 291 return sam_acct->methods->update_sam_account(sam_acct->methods, sam_acct); 292} 293 294static NTSTATUS context_delete_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct) 295{ 296 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 297 298 struct pdb_methods *pdb_selected; 299 if (!context) { 300 DEBUG(0, ("invalid pdb_context specified!\n")); 301 return ret; 302 } 303 304 if (!sam_acct->methods){ 305 pdb_selected = context->pdb_methods; 306 /* There's no passdb backend specified for this account. 307 * Try to delete it in every passdb available 308 * Needed to delete accounts in smbpasswd that are not 309 * in /etc/passwd. 310 */ 311 while (pdb_selected){ 312 if (NT_STATUS_IS_OK(ret = pdb_selected->delete_sam_account(pdb_selected, sam_acct))) { 313 return ret; 314 } 315 pdb_selected = pdb_selected->next; 316 } 317 return ret; 318 } 319 320 if (!sam_acct->methods->delete_sam_account){ 321 DEBUG(0,("invalid sam_acct->methods->delete_sam_account\n")); 322 return ret; 323 } 324 325 return sam_acct->methods->delete_sam_account(sam_acct->methods, sam_acct); 326} 327 328static NTSTATUS context_update_login_attempts(struct pdb_context *context, 329 SAM_ACCOUNT *sam_acct, BOOL success) 330{ 331 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 332 333 if (!context) { 334 DEBUG(0, ("invalid pdb_context specified!\n")); 335 return ret; 336 } 337 338 if (!sam_acct || !sam_acct->methods){ 339 DEBUG(0, ("invalid sam_acct specified\n")); 340 return ret; 341 } 342 343 return sam_acct->methods->update_login_attempts(sam_acct->methods, sam_acct, success); 344} 345 346static NTSTATUS context_getgrsid(struct pdb_context *context, 347 GROUP_MAP *map, DOM_SID sid) 348{ 349 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 350 351 struct pdb_methods *curmethods; 352 if ((!context)) { 353 DEBUG(0, ("invalid pdb_context specified!\n")); 354 return ret; 355 } 356 curmethods = context->pdb_methods; 357 while (curmethods){ 358 ret = curmethods->getgrsid(curmethods, map, sid); 359 if (NT_STATUS_IS_OK(ret)) { 360 map->methods = curmethods; 361 return ret; 362 } 363 curmethods = curmethods->next; 364 } 365 366 return ret; 367} 368 369static NTSTATUS context_getgrgid(struct pdb_context *context, 370 GROUP_MAP *map, gid_t gid) 371{ 372 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 373 374 struct pdb_methods *curmethods; 375 if ((!context)) { 376 DEBUG(0, ("invalid pdb_context specified!\n")); 377 return ret; 378 } 379 curmethods = context->pdb_methods; 380 while (curmethods){ 381 ret = curmethods->getgrgid(curmethods, map, gid); 382 if (NT_STATUS_IS_OK(ret)) { 383 map->methods = curmethods; 384 return ret; 385 } 386 curmethods = curmethods->next; 387 } 388 389 return ret; 390} 391 392static NTSTATUS context_getgrnam(struct pdb_context *context, 393 GROUP_MAP *map, const char *name) 394{ 395 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 396 397 struct pdb_methods *curmethods; 398 if ((!context)) { 399 DEBUG(0, ("invalid pdb_context specified!\n")); 400 return ret; 401 } 402 curmethods = context->pdb_methods; 403 while (curmethods){ 404 ret = curmethods->getgrnam(curmethods, map, name); 405 if (NT_STATUS_IS_OK(ret)) { 406 map->methods = curmethods; 407 return ret; 408 } 409 curmethods = curmethods->next; 410 } 411 412 return ret; 413} 414 415static NTSTATUS context_add_group_mapping_entry(struct pdb_context *context, 416 GROUP_MAP *map) 417{ 418 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 419 420 if ((!context) || (!context->pdb_methods)) { 421 DEBUG(0, ("invalid pdb_context specified!\n")); 422 return ret; 423 } 424 425 return context->pdb_methods->add_group_mapping_entry(context->pdb_methods, 426 map); 427} 428 429static NTSTATUS context_update_group_mapping_entry(struct pdb_context *context, 430 GROUP_MAP *map) 431{ 432 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 433 434 if ((!context) || (!context->pdb_methods)) { 435 DEBUG(0, ("invalid pdb_context specified!\n")); 436 return ret; 437 } 438 439 return context-> 440 pdb_methods->update_group_mapping_entry(context->pdb_methods, map); 441} 442 443static NTSTATUS context_delete_group_mapping_entry(struct pdb_context *context, 444 DOM_SID sid) 445{ 446 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 447 448 if ((!context) || (!context->pdb_methods)) { 449 DEBUG(0, ("invalid pdb_context specified!\n")); 450 return ret; 451 } 452 453 return context-> 454 pdb_methods->delete_group_mapping_entry(context->pdb_methods, sid); 455} 456 457static NTSTATUS context_enum_group_mapping(struct pdb_context *context, 458 enum SID_NAME_USE sid_name_use, 459 GROUP_MAP **rmap, int *num_entries, 460 BOOL unix_only) 461{ 462 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 463 464 if ((!context) || (!context->pdb_methods)) { 465 DEBUG(0, ("invalid pdb_context specified!\n")); 466 return ret; 467 } 468 469 return context->pdb_methods->enum_group_mapping(context->pdb_methods, 470 sid_name_use, rmap, 471 num_entries, unix_only); 472} 473 474static NTSTATUS context_enum_group_members(struct pdb_context *context, 475 TALLOC_CTX *mem_ctx, 476 const DOM_SID *group, 477 uint32 **member_rids, 478 int *num_members) 479{ 480 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 481 482 if ((!context) || (!context->pdb_methods)) { 483 DEBUG(0, ("invalid pdb_context specified!\n")); 484 return ret; 485 } 486 487 return context->pdb_methods->enum_group_members(context->pdb_methods, 488 mem_ctx, group, 489 member_rids, 490 num_members); 491} 492 493static NTSTATUS context_enum_group_memberships(struct pdb_context *context, 494 const char *username, 495 gid_t primary_gid, 496 DOM_SID **sids, gid_t **gids, 497 int *num_groups) 498{ 499 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 500 501 if ((!context) || (!context->pdb_methods)) { 502 DEBUG(0, ("invalid pdb_context specified!\n")); 503 return ret; 504 } 505 506 return context->pdb_methods-> 507 enum_group_memberships(context->pdb_methods, username, 508 primary_gid, sids, gids, num_groups); 509} 510 511static NTSTATUS context_find_alias(struct pdb_context *context, 512 const char *name, DOM_SID *sid) 513{ 514 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 515 516 if ((!context) || (!context->pdb_methods)) { 517 DEBUG(0, ("invalid pdb_context specified!\n")); 518 return ret; 519 } 520 521 return context->pdb_methods->find_alias(context->pdb_methods, 522 name, sid); 523} 524 525static NTSTATUS context_create_alias(struct pdb_context *context, 526 const char *name, uint32 *rid) 527{ 528 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 529 530 if ((!context) || (!context->pdb_methods)) { 531 DEBUG(0, ("invalid pdb_context specified!\n")); 532 return ret; 533 } 534 535 return context->pdb_methods->create_alias(context->pdb_methods, 536 name, rid); 537} 538 539static NTSTATUS context_delete_alias(struct pdb_context *context, 540 const DOM_SID *sid) 541{ 542 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 543 544 if ((!context) || (!context->pdb_methods)) { 545 DEBUG(0, ("invalid pdb_context specified!\n")); 546 return ret; 547 } 548 549 return context->pdb_methods->delete_alias(context->pdb_methods, sid); 550} 551 552static NTSTATUS context_enum_aliases(struct pdb_context *context, 553 const DOM_SID *sid, 554 uint32 start_idx, uint32 max_entries, 555 uint32 *num_aliases, 556 struct acct_info **info) 557{ 558 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 559 560 if ((!context) || (!context->pdb_methods)) { 561 DEBUG(0, ("invalid pdb_context specified!\n")); 562 return ret; 563 } 564 565 return context->pdb_methods->enum_aliases(context->pdb_methods, 566 sid, start_idx, max_entries, 567 num_aliases, info); 568} 569 570static NTSTATUS context_get_aliasinfo(struct pdb_context *context, 571 const DOM_SID *sid, 572 struct acct_info *info) 573{ 574 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 575 576 if ((!context) || (!context->pdb_methods)) { 577 DEBUG(0, ("invalid pdb_context specified!\n")); 578 return ret; 579 } 580 581 return context->pdb_methods->get_aliasinfo(context->pdb_methods, 582 sid, info); 583} 584 585static NTSTATUS context_set_aliasinfo(struct pdb_context *context, 586 const DOM_SID *sid, 587 struct acct_info *info) 588{ 589 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 590 591 if ((!context) || (!context->pdb_methods)) { 592 DEBUG(0, ("invalid pdb_context specified!\n")); 593 return ret; 594 } 595 596 return context->pdb_methods->set_aliasinfo(context->pdb_methods, 597 sid, info); 598} 599 600static NTSTATUS context_add_aliasmem(struct pdb_context *context, 601 const DOM_SID *alias, 602 const DOM_SID *member) 603{ 604 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 605 606 if ((!context) || (!context->pdb_methods)) { 607 DEBUG(0, ("invalid pdb_context specified!\n")); 608 return ret; 609 } 610 611 return context->pdb_methods->add_aliasmem(context->pdb_methods, 612 alias, member); 613} 614 615static NTSTATUS context_del_aliasmem(struct pdb_context *context, 616 const DOM_SID *alias, 617 const DOM_SID *member) 618{ 619 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 620 621 if ((!context) || (!context->pdb_methods)) { 622 DEBUG(0, ("invalid pdb_context specified!\n")); 623 return ret; 624 } 625 626 return context->pdb_methods->del_aliasmem(context->pdb_methods, 627 alias, member); 628} 629 630static NTSTATUS context_enum_aliasmem(struct pdb_context *context, 631 const DOM_SID *alias, DOM_SID **members, 632 int *num) 633{ 634 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 635 636 if ((!context) || (!context->pdb_methods)) { 637 DEBUG(0, ("invalid pdb_context specified!\n")); 638 return ret; 639 } 640 641 return context->pdb_methods->enum_aliasmem(context->pdb_methods, 642 alias, members, num); 643} 644 645static NTSTATUS context_enum_alias_memberships(struct pdb_context *context, 646 const DOM_SID *members, 647 int num_members, 648 DOM_SID **aliases, int *num) 649{ 650 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 651 652 if ((!context) || (!context->pdb_methods)) { 653 DEBUG(0, ("invalid pdb_context specified!\n")); 654 return ret; 655 } 656 657 return context->pdb_methods-> 658 enum_alias_memberships(context->pdb_methods, members, 659 num_members, aliases, num); 660} 661 662/****************************************************************** 663 Free and cleanup a pdb context, any associated data and anything 664 that the attached modules might have associated. 665 *******************************************************************/ 666 667static void free_pdb_context(struct pdb_context **context) 668{ 669 struct pdb_methods *pdb_selected = (*context)->pdb_methods; 670 671 while (pdb_selected){ 672 if(pdb_selected->free_private_data) 673 pdb_selected->free_private_data(&(pdb_selected->private_data)); 674 pdb_selected = pdb_selected->next; 675 } 676 677 talloc_destroy((*context)->mem_ctx); 678 *context = NULL; 679} 680 681/****************************************************************** 682 Make a pdb_methods from scratch 683 *******************************************************************/ 684 685static NTSTATUS make_pdb_methods_name(struct pdb_methods **methods, struct pdb_context *context, const char *selected) 686{ 687 char *module_name = smb_xstrdup(selected); 688 char *module_location = NULL, *p; 689 struct pdb_init_function_entry *entry; 690 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; 691 692 lazy_initialize_passdb(); 693 694 p = strchr(module_name, ':'); 695 696 if (p) { 697 *p = 0; 698 module_location = p+1; 699 trim_char(module_location, ' ', ' '); 700 } 701 702 trim_char(module_name, ' ', ' '); 703 704 705 DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name)); 706 707 entry = pdb_find_backend_entry(module_name); 708 709 /* Try to find a module that contains this module */ 710 if (!entry) { 711 DEBUG(2,("No builtin backend found, trying to load plugin\n")); 712 if(NT_STATUS_IS_OK(smb_probe_module("pdb", module_name)) && !(entry = pdb_find_backend_entry(module_name))) { 713 DEBUG(0,("Plugin is available, but doesn't register passdb backend %s\n", module_name)); 714 SAFE_FREE(module_name); 715 return NT_STATUS_UNSUCCESSFUL; 716 } 717 } 718 719 /* No such backend found */ 720 if(!entry) { 721 DEBUG(0,("No builtin nor plugin backend for %s found\n", module_name)); 722 SAFE_FREE(module_name); 723 return NT_STATUS_INVALID_PARAMETER; 724 } 725 726 DEBUG(5,("Found pdb backend %s\n", module_name)); 727 nt_status = entry->init(context, methods, module_location); 728 if (NT_STATUS_IS_OK(nt_status)) { 729 DEBUG(5,("pdb backend %s has a valid init\n", selected)); 730 } else { 731 DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", selected, nt_errstr(nt_status))); 732 } 733 SAFE_FREE(module_name); 734 return nt_status; 735} 736 737/****************************************************************** 738 Make a pdb_context from scratch. 739 *******************************************************************/ 740 741static NTSTATUS make_pdb_context(struct pdb_context **context) 742{ 743 TALLOC_CTX *mem_ctx; 744 745 mem_ctx = talloc_init("pdb_context internal allocation context"); 746 747 if (!mem_ctx) { 748 DEBUG(0, ("make_pdb_context: talloc init failed!\n")); 749 return NT_STATUS_NO_MEMORY; 750 } 751 752 *context = TALLOC_P(mem_ctx, struct pdb_context); 753 if (!*context) { 754 DEBUG(0, ("make_pdb_context: talloc failed!\n")); 755 return NT_STATUS_NO_MEMORY; 756 } 757 758 ZERO_STRUCTP(*context); 759 760 (*context)->mem_ctx = mem_ctx; 761 762 (*context)->pdb_setsampwent = context_setsampwent; 763 (*context)->pdb_endsampwent = context_endsampwent; 764 (*context)->pdb_getsampwent = context_getsampwent; 765 (*context)->pdb_getsampwnam = context_getsampwnam; 766 (*context)->pdb_getsampwsid = context_getsampwsid; 767 (*context)->pdb_add_sam_account = context_add_sam_account; 768 (*context)->pdb_update_sam_account = context_update_sam_account; 769 (*context)->pdb_delete_sam_account = context_delete_sam_account; 770 (*context)->pdb_update_login_attempts = context_update_login_attempts; 771 (*context)->pdb_getgrsid = context_getgrsid; 772 (*context)->pdb_getgrgid = context_getgrgid; 773 (*context)->pdb_getgrnam = context_getgrnam; 774 (*context)->pdb_add_group_mapping_entry = context_add_group_mapping_entry; 775 (*context)->pdb_update_group_mapping_entry = context_update_group_mapping_entry; 776 (*context)->pdb_delete_group_mapping_entry = context_delete_group_mapping_entry; 777 (*context)->pdb_enum_group_mapping = context_enum_group_mapping; 778 (*context)->pdb_enum_group_members = context_enum_group_members; 779 (*context)->pdb_enum_group_memberships = context_enum_group_memberships; 780 781 (*context)->pdb_find_alias = context_find_alias; 782 (*context)->pdb_create_alias = context_create_alias; 783 (*context)->pdb_delete_alias = context_delete_alias; 784 (*context)->pdb_enum_aliases = context_enum_aliases; 785 (*context)->pdb_get_aliasinfo = context_get_aliasinfo; 786 (*context)->pdb_set_aliasinfo = context_set_aliasinfo; 787 (*context)->pdb_add_aliasmem = context_add_aliasmem; 788 (*context)->pdb_del_aliasmem = context_del_aliasmem; 789 (*context)->pdb_enum_aliasmem = context_enum_aliasmem; 790 (*context)->pdb_enum_alias_memberships = context_enum_alias_memberships; 791 792 (*context)->free_fn = free_pdb_context; 793 794 return NT_STATUS_OK; 795} 796 797 798/****************************************************************** 799 Make a pdb_context, given an array of strings 800 *******************************************************************/ 801 802NTSTATUS make_pdb_context_list(struct pdb_context **context, const char **selected) 803{ 804 int i = 0; 805 struct pdb_methods *curmethods, *tmpmethods; 806 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; 807 BOOL have_guest = False; 808 809 if (!NT_STATUS_IS_OK(nt_status = make_pdb_context(context))) { 810 return nt_status; 811 } 812 813 if (!selected) { 814 DEBUG(0, ("ERROR: empty passdb backend list!\n")); 815 return nt_status; 816 } 817 818 while (selected[i]){ 819 if (strcmp(selected[i], "guest") == 0) { 820 have_guest = True; 821 } 822 /* Try to initialise pdb */ 823 DEBUG(5,("Trying to load: %s\n", selected[i])); 824 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods_name(&curmethods, *context, selected[i]))) { 825 DEBUG(1, ("Loading %s failed!\n", selected[i])); 826 free_pdb_context(context); 827 return nt_status; 828 } 829 curmethods->parent = *context; 830 DLIST_ADD_END((*context)->pdb_methods, curmethods, tmpmethods); 831 i++; 832 } 833 834 if (have_guest) 835 return NT_STATUS_OK; 836 837 if ( (lp_guestaccount() == NULL) || 838 (*lp_guestaccount() == '\0') ) { 839 /* We explicitly don't want guest access. No idea what 840 else that breaks, but be it that way. */ 841 return NT_STATUS_OK; 842 } 843 844 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods_name(&curmethods, 845 *context, 846 "guest"))) { 847 DEBUG(1, ("Loading guest module failed!\n")); 848 free_pdb_context(context); 849 return nt_status; 850 } 851 852 curmethods->parent = *context; 853 DLIST_ADD_END((*context)->pdb_methods, curmethods, tmpmethods); 854 855 return NT_STATUS_OK; 856} 857 858/****************************************************************** 859 Make a pdb_context, given a text string. 860 *******************************************************************/ 861 862NTSTATUS make_pdb_context_string(struct pdb_context **context, const char *selected) 863{ 864 NTSTATUS ret; 865 char **newsel = str_list_make(selected, NULL); 866 ret = make_pdb_context_list(context, (const char **)newsel); 867 str_list_free(&newsel); 868 return ret; 869} 870 871/****************************************************************** 872 Return an already initialised pdb_context, to facilitate backward 873 compatibility (see functions below). 874*******************************************************************/ 875 876static struct pdb_context *pdb_get_static_context(BOOL reload) 877{ 878 static struct pdb_context *pdb_context = NULL; 879 880 if ((pdb_context) && (reload)) { 881 pdb_context->free_fn(&pdb_context); 882 if (!NT_STATUS_IS_OK(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) { 883 return NULL; 884 } 885 } 886 887 if (!pdb_context) { 888 if (!NT_STATUS_IS_OK(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) { 889 return NULL; 890 } 891 } 892 893 return pdb_context; 894} 895 896/****************************************************************** 897 Backward compatibility functions for the original passdb interface 898*******************************************************************/ 899 900BOOL pdb_setsampwent(BOOL update, uint16 acb_mask) 901{ 902 struct pdb_context *pdb_context = pdb_get_static_context(False); 903 904 if (!pdb_context) { 905 return False; 906 } 907 908 return NT_STATUS_IS_OK(pdb_context->pdb_setsampwent(pdb_context, update, acb_mask)); 909} 910 911void pdb_endsampwent(void) 912{ 913 struct pdb_context *pdb_context = pdb_get_static_context(False); 914 915 if (!pdb_context) { 916 return; 917 } 918 919 pdb_context->pdb_endsampwent(pdb_context); 920} 921 922BOOL pdb_getsampwent(SAM_ACCOUNT *user) 923{ 924 struct pdb_context *pdb_context = pdb_get_static_context(False); 925 926 if (!pdb_context) { 927 return False; 928 } 929 930 return NT_STATUS_IS_OK(pdb_context->pdb_getsampwent(pdb_context, user)); 931} 932 933static SAM_ACCOUNT *sam_account_cache = NULL; 934 935BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username) 936{ 937 struct pdb_context *pdb_context = pdb_get_static_context(False); 938 939 if (!pdb_context) { 940 return False; 941 } 942 943 if (!NT_STATUS_IS_OK(pdb_context->pdb_getsampwnam(pdb_context, 944 sam_acct, username))) 945 return False; 946 947 if (sam_account_cache != NULL) { 948 pdb_free_sam(&sam_account_cache); 949 sam_account_cache = NULL; 950 } 951 952 pdb_copy_sam_account(sam_acct, &sam_account_cache); 953 return True; 954} 955 956BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid) 957{ 958 struct pdb_context *pdb_context = pdb_get_static_context(False); 959 960 if (!pdb_context) { 961 return False; 962 } 963 964 if ((sam_account_cache != NULL) && 965 (sid_equal(sid, pdb_get_user_sid(sam_account_cache)))) 966 return pdb_copy_sam_account(sam_account_cache, &sam_acct); 967 968 return NT_STATUS_IS_OK(pdb_context->pdb_getsampwsid(pdb_context, sam_acct, sid)); 969} 970 971BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct) 972{ 973 struct pdb_context *pdb_context = pdb_get_static_context(False); 974 975 if (!pdb_context) { 976 return False; 977 } 978 979 return NT_STATUS_IS_OK(pdb_context->pdb_add_sam_account(pdb_context, sam_acct)); 980} 981 982BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct) 983{ 984 struct pdb_context *pdb_context = pdb_get_static_context(False); 985 986 if (!pdb_context) { 987 return False; 988 } 989 990 if (sam_account_cache != NULL) { 991 pdb_free_sam(&sam_account_cache); 992 sam_account_cache = NULL; 993 } 994 995 return NT_STATUS_IS_OK(pdb_context->pdb_update_sam_account(pdb_context, sam_acct)); 996} 997 998BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct) 999{ 1000 struct pdb_context *pdb_context = pdb_get_static_context(False); 1001 1002 if (!pdb_context) { 1003 return False; 1004 } 1005 1006 if (sam_account_cache != NULL) { 1007 pdb_free_sam(&sam_account_cache); 1008 sam_account_cache = NULL; 1009 } 1010 1011 return NT_STATUS_IS_OK(pdb_context->pdb_delete_sam_account(pdb_context, sam_acct)); 1012} 1013 1014NTSTATUS pdb_update_login_attempts(SAM_ACCOUNT *sam_acct, BOOL success) 1015{ 1016 struct pdb_context *pdb_context = pdb_get_static_context(False); 1017 1018 if (!pdb_context) { 1019 return NT_STATUS_NOT_IMPLEMENTED; 1020 } 1021 1022 return pdb_context->pdb_update_login_attempts(pdb_context, sam_acct, success); 1023} 1024 1025BOOL pdb_getgrsid(GROUP_MAP *map, DOM_SID sid) 1026{ 1027 struct pdb_context *pdb_context = pdb_get_static_context(False); 1028 1029 if (!pdb_context) { 1030 return False; 1031 } 1032 1033 return NT_STATUS_IS_OK(pdb_context-> 1034 pdb_getgrsid(pdb_context, map, sid)); 1035} 1036 1037BOOL pdb_getgrgid(GROUP_MAP *map, gid_t gid) 1038{ 1039 struct pdb_context *pdb_context = pdb_get_static_context(False); 1040 1041 if (!pdb_context) { 1042 return False; 1043 } 1044 1045 return NT_STATUS_IS_OK(pdb_context-> 1046 pdb_getgrgid(pdb_context, map, gid)); 1047} 1048 1049BOOL pdb_getgrnam(GROUP_MAP *map, const char *name) 1050{ 1051 struct pdb_context *pdb_context = pdb_get_static_context(False); 1052 1053 if (!pdb_context) { 1054 return False; 1055 } 1056 1057 return NT_STATUS_IS_OK(pdb_context-> 1058 pdb_getgrnam(pdb_context, map, name)); 1059} 1060 1061BOOL pdb_add_group_mapping_entry(GROUP_MAP *map) 1062{ 1063 struct pdb_context *pdb_context = pdb_get_static_context(False); 1064 1065 if (!pdb_context) { 1066 return False; 1067 } 1068 1069 return NT_STATUS_IS_OK(pdb_context-> 1070 pdb_add_group_mapping_entry(pdb_context, map)); 1071} 1072 1073BOOL pdb_update_group_mapping_entry(GROUP_MAP *map) 1074{ 1075 struct pdb_context *pdb_context = pdb_get_static_context(False); 1076 1077 if (!pdb_context) { 1078 return False; 1079 } 1080 1081 return NT_STATUS_IS_OK(pdb_context-> 1082 pdb_update_group_mapping_entry(pdb_context, map)); 1083} 1084 1085BOOL pdb_delete_group_mapping_entry(DOM_SID sid) 1086{ 1087 struct pdb_context *pdb_context = pdb_get_static_context(False); 1088 1089 if (!pdb_context) { 1090 return False; 1091 } 1092 1093 return NT_STATUS_IS_OK(pdb_context-> 1094 pdb_delete_group_mapping_entry(pdb_context, sid)); 1095} 1096 1097BOOL pdb_enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap, 1098 int *num_entries, BOOL unix_only) 1099{ 1100 struct pdb_context *pdb_context = pdb_get_static_context(False); 1101 1102 if (!pdb_context) { 1103 return False; 1104 } 1105 1106 return NT_STATUS_IS_OK(pdb_context-> 1107 pdb_enum_group_mapping(pdb_context, sid_name_use, 1108 rmap, num_entries, unix_only)); 1109} 1110 1111NTSTATUS pdb_enum_group_members(TALLOC_CTX *mem_ctx, 1112 const DOM_SID *sid, 1113 uint32 **member_rids, 1114 int *num_members) 1115{ 1116 struct pdb_context *pdb_context = pdb_get_static_context(False); 1117 1118 if (!pdb_context) { 1119 return NT_STATUS_UNSUCCESSFUL; 1120 } 1121 1122 return pdb_context->pdb_enum_group_members(pdb_context, mem_ctx, sid, 1123 member_rids, num_members); 1124} 1125 1126NTSTATUS pdb_enum_group_memberships(const char *username, gid_t primary_gid, 1127 DOM_SID **sids, gid_t **gids, 1128 int *num_groups) 1129{ 1130 struct pdb_context *pdb_context = pdb_get_static_context(False); 1131 1132 if (!pdb_context) { 1133 return NT_STATUS_UNSUCCESSFUL; 1134 } 1135 1136 return pdb_context->pdb_enum_group_memberships(pdb_context, username, 1137 primary_gid, sids, gids, 1138 num_groups); 1139} 1140 1141BOOL pdb_find_alias(const char *name, DOM_SID *sid) 1142{ 1143 struct pdb_context *pdb_context = pdb_get_static_context(False); 1144 1145 if (!pdb_context) { 1146 return False; 1147 } 1148 1149 return NT_STATUS_IS_OK(pdb_context->pdb_find_alias(pdb_context, 1150 name, sid)); 1151} 1152 1153NTSTATUS pdb_create_alias(const char *name, uint32 *rid) 1154{ 1155 struct pdb_context *pdb_context = pdb_get_static_context(False); 1156 1157 if (!pdb_context) { 1158 return NT_STATUS_NOT_IMPLEMENTED; 1159 } 1160 1161 return pdb_context->pdb_create_alias(pdb_context, name, rid); 1162} 1163 1164BOOL pdb_delete_alias(const DOM_SID *sid) 1165{ 1166 struct pdb_context *pdb_context = pdb_get_static_context(False); 1167 1168 if (!pdb_context) { 1169 return False; 1170 } 1171 1172 return NT_STATUS_IS_OK(pdb_context->pdb_delete_alias(pdb_context, 1173 sid)); 1174 1175} 1176 1177BOOL pdb_enum_aliases(const DOM_SID *sid, uint32 start_idx, uint32 max_entries, 1178 uint32 *num_aliases, struct acct_info **info) 1179{ 1180 struct pdb_context *pdb_context = pdb_get_static_context(False); 1181 1182 if (!pdb_context) { 1183 return False; 1184 } 1185 1186 return NT_STATUS_IS_OK(pdb_context->pdb_enum_aliases(pdb_context, sid, 1187 start_idx, 1188 max_entries, 1189 num_aliases, 1190 info)); 1191} 1192 1193BOOL pdb_get_aliasinfo(const DOM_SID *sid, struct acct_info *info) 1194{ 1195 struct pdb_context *pdb_context = pdb_get_static_context(False); 1196 1197 if (!pdb_context) { 1198 return False; 1199 } 1200 1201 return NT_STATUS_IS_OK(pdb_context->pdb_get_aliasinfo(pdb_context, sid, 1202 info)); 1203} 1204 1205BOOL pdb_set_aliasinfo(const DOM_SID *sid, struct acct_info *info) 1206{ 1207 struct pdb_context *pdb_context = pdb_get_static_context(False); 1208 1209 if (!pdb_context) { 1210 return False; 1211 } 1212 1213 return NT_STATUS_IS_OK(pdb_context->pdb_set_aliasinfo(pdb_context, sid, 1214 info)); 1215} 1216 1217BOOL pdb_add_aliasmem(const DOM_SID *alias, const DOM_SID *member) 1218{ 1219 struct pdb_context *pdb_context = pdb_get_static_context(False); 1220 1221 if (!pdb_context) { 1222 return False; 1223 } 1224 1225 return NT_STATUS_IS_OK(pdb_context-> 1226 pdb_add_aliasmem(pdb_context, alias, member)); 1227} 1228 1229BOOL pdb_del_aliasmem(const DOM_SID *alias, const DOM_SID *member) 1230{ 1231 struct pdb_context *pdb_context = pdb_get_static_context(False); 1232 1233 if (!pdb_context) { 1234 return False; 1235 } 1236 1237 return NT_STATUS_IS_OK(pdb_context-> 1238 pdb_del_aliasmem(pdb_context, alias, member)); 1239} 1240 1241BOOL pdb_enum_aliasmem(const DOM_SID *alias, 1242 DOM_SID **members, int *num_members) 1243{ 1244 struct pdb_context *pdb_context = pdb_get_static_context(False); 1245 1246 if (!pdb_context) { 1247 return False; 1248 } 1249 1250 return NT_STATUS_IS_OK(pdb_context-> 1251 pdb_enum_aliasmem(pdb_context, alias, 1252 members, num_members)); 1253} 1254 1255BOOL pdb_enum_alias_memberships(const DOM_SID *members, int num_members, 1256 DOM_SID **aliases, int *num) 1257{ 1258 struct pdb_context *pdb_context = pdb_get_static_context(False); 1259 1260 if (!pdb_context) { 1261 return False; 1262 } 1263 1264 return NT_STATUS_IS_OK(pdb_context-> 1265 pdb_enum_alias_memberships(pdb_context, members, 1266 num_members, 1267 aliases, num)); 1268} 1269 1270/*************************************************************** 1271 Initialize the static context (at smbd startup etc). 1272 1273 If uninitialised, context will auto-init on first use. 1274 ***************************************************************/ 1275 1276BOOL initialize_password_db(BOOL reload) 1277{ 1278 return (pdb_get_static_context(reload) != NULL); 1279} 1280 1281 1282/*************************************************************************** 1283 Default implementations of some functions. 1284 ****************************************************************************/ 1285 1286static NTSTATUS pdb_default_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname) 1287{ 1288 return NT_STATUS_NO_SUCH_USER; 1289} 1290 1291static NTSTATUS pdb_default_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid) 1292{ 1293 return NT_STATUS_NO_SUCH_USER; 1294} 1295 1296static NTSTATUS pdb_default_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd) 1297{ 1298 DEBUG(0,("this backend (%s) should not be listed as the first passdb backend! You can't add users to it.\n", methods->name)); 1299 return NT_STATUS_NOT_IMPLEMENTED; 1300} 1301 1302static NTSTATUS pdb_default_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd) 1303{ 1304 return NT_STATUS_NOT_IMPLEMENTED; 1305} 1306 1307static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *pwd) 1308{ 1309 return NT_STATUS_NOT_IMPLEMENTED; 1310} 1311 1312static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, SAM_ACCOUNT *newpwd, BOOL success) 1313{ 1314 return NT_STATUS_OK; 1315} 1316 1317static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask) 1318{ 1319 return NT_STATUS_NOT_IMPLEMENTED; 1320} 1321 1322static NTSTATUS pdb_default_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT *user) 1323{ 1324 return NT_STATUS_NOT_IMPLEMENTED; 1325} 1326 1327static void pdb_default_endsampwent(struct pdb_methods *methods) 1328{ 1329 return; /* NT_STATUS_NOT_IMPLEMENTED; */ 1330} 1331 1332static void add_uid_to_array_unique(TALLOC_CTX *mem_ctx, 1333 uid_t uid, uid_t **uids, int *num) 1334{ 1335 int i; 1336 1337 for (i=0; i<*num; i++) { 1338 if ((*uids)[i] == uid) 1339 return; 1340 } 1341 1342 *uids = TALLOC_REALLOC_ARRAY(mem_ctx, *uids, uid_t, *num+1); 1343 1344 if (*uids == NULL) 1345 return; 1346 1347 (*uids)[*num] = uid; 1348 *num += 1; 1349} 1350 1351static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **uids, 1352 int *num) 1353{ 1354 struct group *grp; 1355 char **gr; 1356 struct sys_pwent *userlist, *user; 1357 1358 *uids = NULL; 1359 *num = 0; 1360 1361 /* We only look at our own sam, so don't care about imported stuff */ 1362 1363 winbind_off(); 1364 1365 if ((grp = getgrgid(gid)) == NULL) { 1366 winbind_on(); 1367 return False; 1368 } 1369 1370 /* Primary group members */ 1371 1372 userlist = getpwent_list(); 1373 1374 for (user = userlist; user != NULL; user = user->next) { 1375 if (user->pw_gid != gid) 1376 continue; 1377 add_uid_to_array_unique(mem_ctx, user->pw_uid, uids, num); 1378 } 1379 1380 pwent_free(userlist); 1381 1382 /* Secondary group members */ 1383 1384 for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) { 1385 struct passwd *pw = getpwnam(*gr); 1386 1387 if (pw == NULL) 1388 continue; 1389 add_uid_to_array_unique(mem_ctx, pw->pw_uid, uids, num); 1390 } 1391 1392 winbind_on(); 1393 1394 return True; 1395} 1396 1397NTSTATUS pdb_default_enum_group_members(struct pdb_methods *methods, 1398 TALLOC_CTX *mem_ctx, 1399 const DOM_SID *group, 1400 uint32 **member_rids, 1401 int *num_members) 1402{ 1403 gid_t gid; 1404 uid_t *uids; 1405 int i, num_uids; 1406 1407 *member_rids = NULL; 1408 *num_members = 0; 1409 1410 if (!NT_STATUS_IS_OK(sid_to_gid(group, &gid))) 1411 return NT_STATUS_NO_SUCH_GROUP; 1412 1413 if(!get_memberuids(mem_ctx, gid, &uids, &num_uids)) 1414 return NT_STATUS_NO_SUCH_GROUP; 1415 1416 if (num_uids == 0) 1417 return NT_STATUS_OK; 1418 1419 *member_rids = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_uids); 1420 1421 for (i=0; i<num_uids; i++) { 1422 DOM_SID sid; 1423 1424 if (!NT_STATUS_IS_OK(uid_to_sid(&sid, uids[i]))) { 1425 DEBUG(1, ("Could not map member uid to SID\n")); 1426 continue; 1427 } 1428 1429 if (!sid_check_is_in_our_domain(&sid)) { 1430 DEBUG(1, ("Inconsistent SAM -- group member uid not " 1431 "in our domain\n")); 1432 continue; 1433 } 1434 1435 sid_peek_rid(&sid, &(*member_rids)[*num_members]); 1436 *num_members += 1; 1437 } 1438 1439 return NT_STATUS_OK; 1440} 1441 1442NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) 1443{ 1444 *methods = TALLOC_P(mem_ctx, struct pdb_methods); 1445 1446 if (!*methods) { 1447 return NT_STATUS_NO_MEMORY; 1448 } 1449 1450 ZERO_STRUCTP(*methods); 1451 1452 (*methods)->setsampwent = pdb_default_setsampwent; 1453 (*methods)->endsampwent = pdb_default_endsampwent; 1454 (*methods)->getsampwent = pdb_default_getsampwent; 1455 (*methods)->getsampwnam = pdb_default_getsampwnam; 1456 (*methods)->getsampwsid = pdb_default_getsampwsid; 1457 (*methods)->add_sam_account = pdb_default_add_sam_account; 1458 (*methods)->update_sam_account = pdb_default_update_sam_account; 1459 (*methods)->delete_sam_account = pdb_default_delete_sam_account; 1460 (*methods)->update_login_attempts = pdb_default_update_login_attempts; 1461 1462 (*methods)->getgrsid = pdb_default_getgrsid; 1463 (*methods)->getgrgid = pdb_default_getgrgid; 1464 (*methods)->getgrnam = pdb_default_getgrnam; 1465 (*methods)->add_group_mapping_entry = pdb_default_add_group_mapping_entry; 1466 (*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry; 1467 (*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry; 1468 (*methods)->enum_group_mapping = pdb_default_enum_group_mapping; 1469 (*methods)->enum_group_members = pdb_default_enum_group_members; 1470 (*methods)->enum_group_memberships = pdb_default_enum_group_memberships; 1471 (*methods)->find_alias = pdb_default_find_alias; 1472 (*methods)->create_alias = pdb_default_create_alias; 1473 (*methods)->delete_alias = pdb_default_delete_alias; 1474 (*methods)->enum_aliases = pdb_default_enum_aliases; 1475 (*methods)->get_aliasinfo = pdb_default_get_aliasinfo; 1476 (*methods)->set_aliasinfo = pdb_default_set_aliasinfo; 1477 (*methods)->add_aliasmem = pdb_default_add_aliasmem; 1478 (*methods)->del_aliasmem = pdb_default_del_aliasmem; 1479 (*methods)->enum_aliasmem = pdb_default_enum_aliasmem; 1480 (*methods)->enum_alias_memberships = pdb_default_alias_memberships; 1481 1482 return NT_STATUS_OK; 1483} 1484