Apply my experimental aliases support to HEAD. This will be a bit difficult to
[Samba/gebeck_regimport.git] / source / passdb / pdb_interface.c
blob83aebf654ad2500bfb2565578e31f9464a7fa450
1 /*
2 Unix SMB/CIFS implementation.
3 Password and authentication handling
4 Copyright (C) Andrew Bartlett 2002
5 Copyright (C) Jelmer Vernooij 2002
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 #undef DBGC_CLASS
25 #define DBGC_CLASS DBGC_PASSDB
27 static struct pdb_init_function_entry *backends = NULL;
29 static void lazy_initialize_passdb(void)
31 static BOOL initialized = False;
32 if(initialized)return;
33 static_init_pdb;
34 initialized = True;
37 static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name);
39 /*******************************************************************
40 Clean up uninitialised passwords. The only way to tell
41 that these values are not 'real' is that they do not
42 have a valid last set time. Instead, the value is fixed at 0.
43 Therefore we use that as the key for 'is this a valid password'.
44 However, it is perfectly valid to have a 'default' last change
45 time, such LDAP with a missing attribute would produce.
46 ********************************************************************/
48 static void pdb_force_pw_initialization(SAM_ACCOUNT *pass)
50 const char *lm_pwd, *nt_pwd;
52 /* only reset a password if the last set time has been
53 explicitly been set to zero. A default last set time
54 is ignored */
56 if ( (pdb_get_init_flags(pass, PDB_PASSLASTSET) != PDB_DEFAULT)
57 && (pdb_get_pass_last_set_time(pass) == 0) )
60 if (pdb_get_init_flags(pass, PDB_LMPASSWD) != PDB_DEFAULT)
62 lm_pwd = pdb_get_lanman_passwd(pass);
63 if (lm_pwd)
64 pdb_set_lanman_passwd(pass, NULL, PDB_CHANGED);
66 if (pdb_get_init_flags(pass, PDB_NTPASSWD) != PDB_DEFAULT)
68 nt_pwd = pdb_get_nt_passwd(pass);
69 if (nt_pwd)
70 pdb_set_nt_passwd(pass, NULL, PDB_CHANGED);
74 return;
77 NTSTATUS smb_register_passdb(int version, const char *name, pdb_init_function init)
79 struct pdb_init_function_entry *entry = backends;
81 if(version != PASSDB_INTERFACE_VERSION) {
82 DEBUG(0,("Can't register passdb backend!\n"
83 "You tried to register a passdb module with PASSDB_INTERFACE_VERSION %d, "
84 "while this version of samba uses version %d\n",
85 version,PASSDB_INTERFACE_VERSION));
86 return NT_STATUS_OBJECT_TYPE_MISMATCH;
89 if (!name || !init) {
90 return NT_STATUS_INVALID_PARAMETER;
93 DEBUG(5,("Attempting to register passdb backend %s\n", name));
95 /* Check for duplicates */
96 if (pdb_find_backend_entry(name)) {
97 DEBUG(0,("There already is a passdb backend registered with the name %s!\n", name));
98 return NT_STATUS_OBJECT_NAME_COLLISION;
101 entry = smb_xmalloc(sizeof(struct pdb_init_function_entry));
102 entry->name = smb_xstrdup(name);
103 entry->init = init;
105 DLIST_ADD(backends, entry);
106 DEBUG(5,("Successfully added passdb backend '%s'\n", name));
107 return NT_STATUS_OK;
110 static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name)
112 struct pdb_init_function_entry *entry = backends;
114 while(entry) {
115 if (strcmp(entry->name, name)==0) return entry;
116 entry = entry->next;
119 return NULL;
122 static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update)
124 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
126 if (!context) {
127 DEBUG(0, ("invalid pdb_context specified!\n"));
128 return ret;
131 context->pwent_methods = context->pdb_methods;
133 if (!context->pwent_methods) {
134 /* No passdbs at all */
135 return ret;
138 while (NT_STATUS_IS_ERR(ret = context->pwent_methods->setsampwent(context->pwent_methods, update))) {
139 context->pwent_methods = context->pwent_methods->next;
140 if (context->pwent_methods == NULL)
141 return NT_STATUS_UNSUCCESSFUL;
143 return ret;
146 static void context_endsampwent(struct pdb_context *context)
148 if ((!context)){
149 DEBUG(0, ("invalid pdb_context specified!\n"));
150 return;
153 if (context->pwent_methods && context->pwent_methods->endsampwent)
154 context->pwent_methods->endsampwent(context->pwent_methods);
156 /* So we won't get strange data when calling getsampwent now */
157 context->pwent_methods = NULL;
160 static NTSTATUS context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
162 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
164 if ((!context) || (!context->pwent_methods)) {
165 DEBUG(0, ("invalid pdb_context specified!\n"));
166 return ret;
168 /* Loop until we find something useful */
169 while (NT_STATUS_IS_ERR(ret = context->pwent_methods->getsampwent(context->pwent_methods, user))) {
171 context->pwent_methods->endsampwent(context->pwent_methods);
173 context->pwent_methods = context->pwent_methods->next;
175 /* All methods are checked now. There are no more entries */
176 if (context->pwent_methods == NULL)
177 return ret;
179 context->pwent_methods->setsampwent(context->pwent_methods, False);
181 user->methods = context->pwent_methods;
182 pdb_force_pw_initialization(user);
183 return ret;
186 static NTSTATUS context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username)
188 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
190 struct pdb_methods *curmethods;
191 if ((!context)) {
192 DEBUG(0, ("invalid pdb_context specified!\n"));
193 return ret;
195 curmethods = context->pdb_methods;
196 while (curmethods){
197 if (NT_STATUS_IS_OK(ret = curmethods->getsampwnam(curmethods, sam_acct, username))) {
198 pdb_force_pw_initialization(sam_acct);
199 sam_acct->methods = curmethods;
200 return ret;
202 curmethods = curmethods->next;
205 return ret;
208 static NTSTATUS context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
210 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
212 struct pdb_methods *curmethods;
213 if ((!context)) {
214 DEBUG(0, ("invalid pdb_context specified!\n"));
215 return ret;
218 curmethods = context->pdb_methods;
220 while (curmethods){
221 if (NT_STATUS_IS_OK(ret = curmethods->getsampwsid(curmethods, sam_acct, sid))) {
222 pdb_force_pw_initialization(sam_acct);
223 sam_acct->methods = curmethods;
224 return ret;
226 curmethods = curmethods->next;
229 return ret;
232 static NTSTATUS context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
234 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
236 if ((!context) || (!context->pdb_methods)) {
237 DEBUG(0, ("invalid pdb_context specified!\n"));
238 return ret;
241 /** @todo This is where a 're-read on add' should be done */
242 /* We now add a new account to the first database listed.
243 * Should we? */
245 return context->pdb_methods->add_sam_account(context->pdb_methods, sam_acct);
248 static NTSTATUS context_update_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
250 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
252 if (!context) {
253 DEBUG(0, ("invalid pdb_context specified!\n"));
254 return ret;
257 if (!sam_acct || !sam_acct->methods){
258 DEBUG(0, ("invalid sam_acct specified\n"));
259 return ret;
262 /** @todo This is where a 're-read on update' should be done */
264 return sam_acct->methods->update_sam_account(sam_acct->methods, sam_acct);
267 static NTSTATUS context_delete_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
269 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
271 struct pdb_methods *pdb_selected;
272 if (!context) {
273 DEBUG(0, ("invalid pdb_context specified!\n"));
274 return ret;
277 if (!sam_acct->methods){
278 pdb_selected = context->pdb_methods;
279 /* There's no passdb backend specified for this account.
280 * Try to delete it in every passdb available
281 * Needed to delete accounts in smbpasswd that are not
282 * in /etc/passwd.
284 while (pdb_selected){
285 if (NT_STATUS_IS_OK(ret = pdb_selected->delete_sam_account(pdb_selected, sam_acct))) {
286 return ret;
288 pdb_selected = pdb_selected->next;
290 return ret;
293 if (!sam_acct->methods->delete_sam_account){
294 DEBUG(0,("invalid sam_acct->methods->delete_sam_account\n"));
295 return ret;
298 return sam_acct->methods->delete_sam_account(sam_acct->methods, sam_acct);
301 static NTSTATUS context_getgrsid(struct pdb_context *context,
302 GROUP_MAP *map, DOM_SID sid)
304 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
306 struct pdb_methods *curmethods;
307 if ((!context)) {
308 DEBUG(0, ("invalid pdb_context specified!\n"));
309 return ret;
311 curmethods = context->pdb_methods;
312 while (curmethods){
313 ret = curmethods->getgrsid(curmethods, map, sid);
314 if (NT_STATUS_IS_OK(ret)) {
315 map->methods = curmethods;
316 return ret;
318 curmethods = curmethods->next;
321 return ret;
324 static NTSTATUS context_getgrgid(struct pdb_context *context,
325 GROUP_MAP *map, gid_t gid)
327 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
329 struct pdb_methods *curmethods;
330 if ((!context)) {
331 DEBUG(0, ("invalid pdb_context specified!\n"));
332 return ret;
334 curmethods = context->pdb_methods;
335 while (curmethods){
336 ret = curmethods->getgrgid(curmethods, map, gid);
337 if (NT_STATUS_IS_OK(ret)) {
338 map->methods = curmethods;
339 return ret;
341 curmethods = curmethods->next;
344 return ret;
347 static NTSTATUS context_getgrnam(struct pdb_context *context,
348 GROUP_MAP *map, const char *name)
350 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
352 struct pdb_methods *curmethods;
353 if ((!context)) {
354 DEBUG(0, ("invalid pdb_context specified!\n"));
355 return ret;
357 curmethods = context->pdb_methods;
358 while (curmethods){
359 ret = curmethods->getgrnam(curmethods, map, name);
360 if (NT_STATUS_IS_OK(ret)) {
361 map->methods = curmethods;
362 return ret;
364 curmethods = curmethods->next;
367 return ret;
370 static NTSTATUS context_add_group_mapping_entry(struct pdb_context *context,
371 GROUP_MAP *map)
373 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
375 if ((!context) || (!context->pdb_methods)) {
376 DEBUG(0, ("invalid pdb_context specified!\n"));
377 return ret;
380 return context->pdb_methods->add_group_mapping_entry(context->pdb_methods,
381 map);
384 static NTSTATUS context_update_group_mapping_entry(struct pdb_context *context,
385 GROUP_MAP *map)
387 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
389 if ((!context) || (!context->pdb_methods)) {
390 DEBUG(0, ("invalid pdb_context specified!\n"));
391 return ret;
394 return context->
395 pdb_methods->update_group_mapping_entry(context->pdb_methods, map);
398 static NTSTATUS context_delete_group_mapping_entry(struct pdb_context *context,
399 DOM_SID sid)
401 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
403 if ((!context) || (!context->pdb_methods)) {
404 DEBUG(0, ("invalid pdb_context specified!\n"));
405 return ret;
408 return context->
409 pdb_methods->delete_group_mapping_entry(context->pdb_methods, sid);
412 static NTSTATUS context_enum_group_mapping(struct pdb_context *context,
413 enum SID_NAME_USE sid_name_use,
414 GROUP_MAP **rmap, int *num_entries,
415 BOOL unix_only)
417 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
419 if ((!context) || (!context->pdb_methods)) {
420 DEBUG(0, ("invalid pdb_context specified!\n"));
421 return ret;
424 return context->pdb_methods->enum_group_mapping(context->pdb_methods,
425 sid_name_use, rmap,
426 num_entries, unix_only);
429 static NTSTATUS context_add_aliasmem(struct pdb_context *context,
430 const DOM_SID *alias,
431 const DOM_SID *member)
433 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
435 if ((!context) || (!context->pdb_methods)) {
436 DEBUG(0, ("invalid pdb_context specified!\n"));
437 return ret;
440 return context->pdb_methods->add_aliasmem(context->pdb_methods,
441 alias, member);
444 static NTSTATUS context_del_aliasmem(struct pdb_context *context,
445 const DOM_SID *alias,
446 const DOM_SID *member)
448 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
450 if ((!context) || (!context->pdb_methods)) {
451 DEBUG(0, ("invalid pdb_context specified!\n"));
452 return ret;
455 return context->pdb_methods->del_aliasmem(context->pdb_methods,
456 alias, member);
459 static NTSTATUS context_enum_aliasmem(struct pdb_context *context,
460 const DOM_SID *alias, DOM_SID **members,
461 int *num)
463 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
465 if ((!context) || (!context->pdb_methods)) {
466 DEBUG(0, ("invalid pdb_context specified!\n"));
467 return ret;
470 return context->pdb_methods->enum_aliasmem(context->pdb_methods,
471 alias, members, num);
474 static NTSTATUS context_enum_alias_memberships(struct pdb_context *context,
475 const DOM_SID *sid,
476 DOM_SID **aliases, int *num)
478 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
480 if ((!context) || (!context->pdb_methods)) {
481 DEBUG(0, ("invalid pdb_context specified!\n"));
482 return ret;
485 return context->pdb_methods->
486 enum_alias_memberships(context->pdb_methods, sid, aliases,
487 num);
490 static NTSTATUS context_gettrustpwent(struct pdb_context *context,
491 SAM_TRUST_PASSWD *trust)
493 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
494 struct pdb_methods *cur_methods;
496 if (!context) {
497 DEBUG(0, ("invalid pdb_context specified!\n"));
498 return ret;
501 cur_methods = context->pdb_methods;
503 while (cur_methods) {
504 ret = cur_methods->gettrustpwent(cur_methods, trust);
505 if (NT_STATUS_IS_OK(ret)) {
506 trust->methods = cur_methods;
507 return ret;
509 cur_methods = cur_methods->next;
512 return ret;
515 static NTSTATUS context_gettrustpwsid(struct pdb_context *context,
516 SAM_TRUST_PASSWD *trust,
517 const DOM_SID *sid)
519 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
520 struct pdb_methods *cur_methods;
522 if (!context) {
523 DEBUG(0, ("invalid pdb_context specified!\n"));
524 return ret;
527 cur_methods = context->pdb_methods;
529 while (cur_methods) {
530 ret = cur_methods->gettrustpwsid(cur_methods, trust, sid);
531 if (NT_STATUS_IS_OK(ret)) {
532 trust->methods = cur_methods;
533 return ret;
535 cur_methods = cur_methods->next;
538 return ret;
541 static NTSTATUS context_add_trust_passwd(struct pdb_context *context,
542 SAM_TRUST_PASSWD *trust)
544 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
546 if (!context) {
547 DEBUG(0, ("invalid pdb_context specified!\n"));
548 return ret;
551 return context->pdb_methods->add_trust_passwd(context->pdb_methods, trust);
554 static NTSTATUS context_update_trust_passwd(struct pdb_context *context,
555 SAM_TRUST_PASSWD *trust)
557 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
559 if (!context) {
560 DEBUG(0, ("invalid pdb_context specified!\n"));
561 return ret;
564 if (!trust || !trust->methods) {
565 DEBUG(0, ("invalid trust pointer specified!\n"));
566 return ret;
569 return trust->methods->update_trust_passwd(trust->methods, trust);
572 static NTSTATUS context_delete_trust_passwd(struct pdb_context *context,
573 SAM_TRUST_PASSWD *trust)
575 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
577 if (!context) {
578 DEBUG(0, ("invalid pdb_context specified!\n"));
579 return ret;
582 if (!trust || !trust->methods) {
583 DEBUG(0, ("invalid trust pointer specified!\n"));
584 return ret;
587 return trust->methods->delete_trust_passwd(trust->methods, trust);
590 /******************************************************************
591 Free and cleanup a pdb context, any associated data and anything
592 that the attached modules might have associated.
593 *******************************************************************/
595 static void free_pdb_context(struct pdb_context **context)
597 struct pdb_methods *pdb_selected = (*context)->pdb_methods;
599 while (pdb_selected){
600 if(pdb_selected->free_private_data)
601 pdb_selected->free_private_data(&(pdb_selected->private_data));
602 pdb_selected = pdb_selected->next;
605 talloc_destroy((*context)->mem_ctx);
606 *context = NULL;
609 /******************************************************************
610 Make a pdb_methods from scratch
611 *******************************************************************/
613 static NTSTATUS make_pdb_methods_name(struct pdb_methods **methods, struct pdb_context *context, const char *selected)
615 char *module_name = smb_xstrdup(selected);
616 char *module_location = NULL, *p;
617 struct pdb_init_function_entry *entry;
618 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
620 lazy_initialize_passdb();
622 p = strchr(module_name, ':');
624 if (p) {
625 *p = 0;
626 module_location = p+1;
627 trim_char(module_location, ' ', ' ');
630 trim_char(module_name, ' ', ' ');
633 DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name));
635 entry = pdb_find_backend_entry(module_name);
637 /* Try to find a module that contains this module */
638 if (!entry) {
639 DEBUG(2,("No builtin backend found, trying to load plugin\n"));
640 if(NT_STATUS_IS_OK(smb_probe_module("pdb", module_name)) && !(entry = pdb_find_backend_entry(module_name))) {
641 DEBUG(0,("Plugin is available, but doesn't register passdb backend %s\n", module_name));
642 SAFE_FREE(module_name);
643 return NT_STATUS_UNSUCCESSFUL;
647 /* No such backend found */
648 if(!entry) {
649 DEBUG(0,("No builtin nor plugin backend for %s found\n", module_name));
650 SAFE_FREE(module_name);
651 return NT_STATUS_INVALID_PARAMETER;
654 DEBUG(5,("Found pdb backend %s\n", module_name));
655 nt_status = entry->init(context, methods, module_location);
656 if (NT_STATUS_IS_OK(nt_status)) {
657 DEBUG(5,("pdb backend %s has a valid init\n", selected));
658 } else {
659 DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", selected, nt_errstr(nt_status)));
661 SAFE_FREE(module_name);
662 return nt_status;
665 /******************************************************************
666 Make a pdb_context from scratch.
667 *******************************************************************/
669 static NTSTATUS make_pdb_context(struct pdb_context **context)
671 TALLOC_CTX *mem_ctx;
673 mem_ctx = talloc_init("pdb_context internal allocation context");
675 if (!mem_ctx) {
676 DEBUG(0, ("make_pdb_context: talloc init failed!\n"));
677 return NT_STATUS_NO_MEMORY;
680 *context = talloc(mem_ctx, sizeof(**context));
681 if (!*context) {
682 DEBUG(0, ("make_pdb_context: talloc failed!\n"));
683 return NT_STATUS_NO_MEMORY;
686 ZERO_STRUCTP(*context);
688 (*context)->mem_ctx = mem_ctx;
690 (*context)->pdb_setsampwent = context_setsampwent;
691 (*context)->pdb_endsampwent = context_endsampwent;
692 (*context)->pdb_getsampwent = context_getsampwent;
693 (*context)->pdb_getsampwnam = context_getsampwnam;
694 (*context)->pdb_getsampwsid = context_getsampwsid;
695 (*context)->pdb_add_sam_account = context_add_sam_account;
696 (*context)->pdb_update_sam_account = context_update_sam_account;
697 (*context)->pdb_delete_sam_account = context_delete_sam_account;
698 (*context)->pdb_getgrsid = context_getgrsid;
699 (*context)->pdb_getgrgid = context_getgrgid;
700 (*context)->pdb_getgrnam = context_getgrnam;
701 (*context)->pdb_add_group_mapping_entry = context_add_group_mapping_entry;
702 (*context)->pdb_update_group_mapping_entry = context_update_group_mapping_entry;
703 (*context)->pdb_delete_group_mapping_entry = context_delete_group_mapping_entry;
704 (*context)->pdb_enum_group_mapping = context_enum_group_mapping;
705 (*context)->pdb_add_aliasmem = context_add_aliasmem;
706 (*context)->pdb_del_aliasmem = context_del_aliasmem;
707 (*context)->pdb_enum_aliasmem = context_enum_aliasmem;
708 (*context)->pdb_enum_alias_memberships = context_enum_alias_memberships;
709 (*context)->pdb_gettrustpwent = context_gettrustpwent;
710 (*context)->pdb_gettrustpwsid = context_gettrustpwsid;
711 (*context)->pdb_add_trust_passwd = context_add_trust_passwd;
712 (*context)->pdb_update_trust_passwd = context_update_trust_passwd;
713 (*context)->pdb_delete_trust_passwd = context_delete_trust_passwd;
715 (*context)->free_fn = free_pdb_context;
717 return NT_STATUS_OK;
721 /******************************************************************
722 Make a pdb_context, given an array of strings
723 *******************************************************************/
725 NTSTATUS make_pdb_context_list(struct pdb_context **context, const char **selected)
727 int i = 0;
728 struct pdb_methods *curmethods, *tmpmethods;
729 NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
730 BOOL have_guest = False;
732 if (!NT_STATUS_IS_OK(nt_status = make_pdb_context(context))) {
733 return nt_status;
736 if (!selected) {
737 DEBUG(0, ("ERROR: empty passdb backend list!\n"));
738 return nt_status;
741 while (selected[i]){
742 if (strcmp(selected[i], "guest") == 0) {
743 have_guest = True;
745 /* Try to initialise pdb */
746 DEBUG(5,("Trying to load: %s\n", selected[i]));
747 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods_name(&curmethods, *context, selected[i]))) {
748 DEBUG(1, ("Loading %s failed!\n", selected[i]));
749 free_pdb_context(context);
750 return nt_status;
752 curmethods->parent = *context;
753 DLIST_ADD_END((*context)->pdb_methods, curmethods, tmpmethods);
754 i++;
757 if (have_guest)
758 return NT_STATUS_OK;
760 if ( (lp_guestaccount() == NULL) ||
761 (*lp_guestaccount() == '\0') ) {
762 /* We explicitly don't want guest access. No idea what
763 else that breaks, but be it that way. */
764 return NT_STATUS_OK;
767 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods_name(&curmethods,
768 *context,
769 "guest"))) {
770 DEBUG(1, ("Loading guest module failed!\n"));
771 free_pdb_context(context);
772 return nt_status;
775 curmethods->parent = *context;
776 DLIST_ADD_END((*context)->pdb_methods, curmethods, tmpmethods);
778 return NT_STATUS_OK;
781 /******************************************************************
782 Make a pdb_context, given a text string.
783 *******************************************************************/
785 NTSTATUS make_pdb_context_string(struct pdb_context **context, const char *selected)
787 NTSTATUS ret;
788 char **newsel = str_list_make(selected, NULL);
789 ret = make_pdb_context_list(context, (const char **)newsel);
790 str_list_free(&newsel);
791 return ret;
794 /******************************************************************
795 Return an already initialised pdb_context, to facilitate backward
796 compatibility (see functions below).
797 *******************************************************************/
799 static struct pdb_context *pdb_get_static_context(BOOL reload)
801 static struct pdb_context *pdb_context = NULL;
803 if ((pdb_context) && (reload)) {
804 pdb_context->free_fn(&pdb_context);
805 if (!NT_STATUS_IS_OK(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) {
806 return NULL;
810 if (!pdb_context) {
811 if (!NT_STATUS_IS_OK(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) {
812 return NULL;
816 return pdb_context;
819 /******************************************************************
820 Backward compatibility functions for the original passdb interface
821 *******************************************************************/
823 BOOL pdb_setsampwent(BOOL update)
825 struct pdb_context *pdb_context = pdb_get_static_context(False);
827 if (!pdb_context) {
828 return False;
831 return NT_STATUS_IS_OK(pdb_context->pdb_setsampwent(pdb_context, update));
834 void pdb_endsampwent(void)
836 struct pdb_context *pdb_context = pdb_get_static_context(False);
838 if (!pdb_context) {
839 return;
842 pdb_context->pdb_endsampwent(pdb_context);
845 BOOL pdb_getsampwent(SAM_ACCOUNT *user)
847 struct pdb_context *pdb_context = pdb_get_static_context(False);
849 if (!pdb_context) {
850 return False;
853 return NT_STATUS_IS_OK(pdb_context->pdb_getsampwent(pdb_context, user));
856 BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
858 struct pdb_context *pdb_context = pdb_get_static_context(False);
860 if (!pdb_context) {
861 return False;
864 return NT_STATUS_IS_OK(pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username));
867 BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
869 struct pdb_context *pdb_context = pdb_get_static_context(False);
871 if (!pdb_context) {
872 return False;
875 return NT_STATUS_IS_OK(pdb_context->pdb_getsampwsid(pdb_context, sam_acct, sid));
878 BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct)
880 struct pdb_context *pdb_context = pdb_get_static_context(False);
881 const char *lm_pw, *nt_pw;
882 uint16 acb_flags;
884 if (!pdb_context) {
885 return False;
888 /* disable acccounts with no passwords (that has not
889 been allowed by the ACB_PWNOTREQ bit */
891 lm_pw = pdb_get_lanman_passwd( sam_acct );
892 nt_pw = pdb_get_nt_passwd( sam_acct );
893 acb_flags = pdb_get_acct_ctrl( sam_acct );
894 if ( !lm_pw && !nt_pw && !(acb_flags&ACB_PWNOTREQ) ) {
895 acb_flags |= ACB_DISABLED;
896 pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_CHANGED );
899 return NT_STATUS_IS_OK(pdb_context->pdb_add_sam_account(pdb_context, sam_acct));
902 BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct)
904 struct pdb_context *pdb_context = pdb_get_static_context(False);
905 const char *lm_pw, *nt_pw;
906 uint16 acb_flags;
908 if (!pdb_context) {
909 return False;
912 /* disable acccounts with no passwords (that has not
913 been allowed by the ACB_PWNOTREQ bit */
915 lm_pw = pdb_get_lanman_passwd( sam_acct );
916 nt_pw = pdb_get_nt_passwd( sam_acct );
917 acb_flags = pdb_get_acct_ctrl( sam_acct );
918 if ( !lm_pw && !nt_pw && !(acb_flags&ACB_PWNOTREQ) ) {
919 acb_flags |= ACB_DISABLED;
920 pdb_set_acct_ctrl( sam_acct, acb_flags, PDB_CHANGED );
923 return NT_STATUS_IS_OK(pdb_context->pdb_update_sam_account(pdb_context, sam_acct));
926 BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct)
928 struct pdb_context *pdb_context = pdb_get_static_context(False);
930 if (!pdb_context) {
931 return False;
934 return NT_STATUS_IS_OK(pdb_context->pdb_delete_sam_account(pdb_context, sam_acct));
937 BOOL pdb_getgrsid(GROUP_MAP *map, DOM_SID sid)
939 struct pdb_context *pdb_context = pdb_get_static_context(False);
941 if (!pdb_context) {
942 return False;
945 return NT_STATUS_IS_OK(pdb_context->
946 pdb_getgrsid(pdb_context, map, sid));
949 BOOL pdb_getgrgid(GROUP_MAP *map, gid_t gid)
951 struct pdb_context *pdb_context = pdb_get_static_context(False);
953 if (!pdb_context) {
954 return False;
957 return NT_STATUS_IS_OK(pdb_context->
958 pdb_getgrgid(pdb_context, map, gid));
961 BOOL pdb_getgrnam(GROUP_MAP *map, const char *name)
963 struct pdb_context *pdb_context = pdb_get_static_context(False);
965 if (!pdb_context) {
966 return False;
969 return NT_STATUS_IS_OK(pdb_context->
970 pdb_getgrnam(pdb_context, map, name));
973 BOOL pdb_add_group_mapping_entry(GROUP_MAP *map)
975 struct pdb_context *pdb_context = pdb_get_static_context(False);
977 if (!pdb_context) {
978 return False;
981 return NT_STATUS_IS_OK(pdb_context->
982 pdb_add_group_mapping_entry(pdb_context, map));
985 BOOL pdb_update_group_mapping_entry(GROUP_MAP *map)
987 struct pdb_context *pdb_context = pdb_get_static_context(False);
989 if (!pdb_context) {
990 return False;
993 return NT_STATUS_IS_OK(pdb_context->
994 pdb_update_group_mapping_entry(pdb_context, map));
997 BOOL pdb_delete_group_mapping_entry(DOM_SID sid)
999 struct pdb_context *pdb_context = pdb_get_static_context(False);
1001 if (!pdb_context) {
1002 return False;
1005 return NT_STATUS_IS_OK(pdb_context->
1006 pdb_delete_group_mapping_entry(pdb_context, sid));
1009 BOOL pdb_enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
1010 int *num_entries, BOOL unix_only)
1012 struct pdb_context *pdb_context = pdb_get_static_context(False);
1014 if (!pdb_context) {
1015 return False;
1018 return NT_STATUS_IS_OK(pdb_context->
1019 pdb_enum_group_mapping(pdb_context, sid_name_use,
1020 rmap, num_entries, unix_only));
1023 BOOL pdb_add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
1025 struct pdb_context *pdb_context = pdb_get_static_context(False);
1027 if (!pdb_context) {
1028 return False;
1031 return NT_STATUS_IS_OK(pdb_context->
1032 pdb_add_aliasmem(pdb_context, alias, member));
1035 BOOL pdb_del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
1037 struct pdb_context *pdb_context = pdb_get_static_context(False);
1039 if (!pdb_context) {
1040 return False;
1043 return NT_STATUS_IS_OK(pdb_context->
1044 pdb_add_aliasmem(pdb_context, alias, member));
1047 BOOL pdb_enum_aliasmem(const DOM_SID *alias,
1048 DOM_SID **members, int *num_members)
1050 struct pdb_context *pdb_context = pdb_get_static_context(False);
1052 if (!pdb_context) {
1053 return False;
1056 return NT_STATUS_IS_OK(pdb_context->
1057 pdb_enum_aliasmem(pdb_context, alias,
1058 members, num_members));
1061 BOOL pdb_enum_alias_memberships(const DOM_SID *sid,
1062 DOM_SID **aliases, int *num)
1064 struct pdb_context *pdb_context = pdb_get_static_context(False);
1066 if (!pdb_context) {
1067 return False;
1070 return NT_STATUS_IS_OK(pdb_context->
1071 pdb_enum_alias_memberships(pdb_context, sid,
1072 aliases, num));
1075 /***************************************************************
1076 Initialize the static context (at smbd startup etc).
1078 If uninitialised, context will auto-init on first use.
1079 ***************************************************************/
1081 BOOL initialize_password_db(BOOL reload)
1083 return (pdb_get_static_context(reload) != NULL);
1087 /***************************************************************************
1088 Default implementations of some functions.
1089 ****************************************************************************/
1091 static NTSTATUS pdb_default_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname)
1093 return NT_STATUS_NO_SUCH_USER;
1096 static NTSTATUS pdb_default_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
1098 return NT_STATUS_NO_SUCH_USER;
1101 static NTSTATUS pdb_default_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
1103 DEBUG(0,("this backend (%s) should not be listed as the first passdb backend! You can't add users to it.\n", methods->name));
1104 return NT_STATUS_NOT_IMPLEMENTED;
1107 static NTSTATUS pdb_default_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
1109 return NT_STATUS_NOT_IMPLEMENTED;
1112 static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *pwd)
1114 return NT_STATUS_NOT_IMPLEMENTED;
1117 static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update)
1119 return NT_STATUS_NOT_IMPLEMENTED;
1122 static NTSTATUS pdb_default_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT *user)
1124 return NT_STATUS_NOT_IMPLEMENTED;
1127 static void pdb_default_endsampwent(struct pdb_methods *methods)
1129 return; /* NT_STATUS_NOT_IMPLEMENTED; */
1132 static NTSTATUS pdb_default_gettrustpwent(struct pdb_methods *methods, SAM_TRUST_PASSWD* trust)
1134 return NT_STATUS_NOT_IMPLEMENTED;
1137 static NTSTATUS pdb_default_gettrustpwsid(struct pdb_methods *methods, SAM_TRUST_PASSWD* trust,
1138 const DOM_SID* sid)
1140 return NT_STATUS_NOT_IMPLEMENTED;
1143 static NTSTATUS pdb_default_add_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust)
1145 return NT_STATUS_NOT_IMPLEMENTED;
1148 static NTSTATUS pdb_default_update_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust)
1150 return NT_STATUS_NOT_IMPLEMENTED;
1153 static NTSTATUS pdb_default_delete_trust_passwd(struct pdb_methods *methods, const SAM_TRUST_PASSWD* trust)
1155 return NT_STATUS_NOT_IMPLEMENTED;
1159 NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
1161 *methods = talloc(mem_ctx, sizeof(struct pdb_methods));
1163 if (!*methods) {
1164 return NT_STATUS_NO_MEMORY;
1167 ZERO_STRUCTP(*methods);
1169 (*methods)->setsampwent = pdb_default_setsampwent;
1170 (*methods)->endsampwent = pdb_default_endsampwent;
1171 (*methods)->getsampwent = pdb_default_getsampwent;
1172 (*methods)->getsampwnam = pdb_default_getsampwnam;
1173 (*methods)->getsampwsid = pdb_default_getsampwsid;
1174 (*methods)->add_sam_account = pdb_default_add_sam_account;
1175 (*methods)->update_sam_account = pdb_default_update_sam_account;
1176 (*methods)->delete_sam_account = pdb_default_delete_sam_account;
1178 (*methods)->getgrsid = pdb_default_getgrsid;
1179 (*methods)->getgrgid = pdb_default_getgrgid;
1180 (*methods)->getgrnam = pdb_default_getgrnam;
1181 (*methods)->add_group_mapping_entry = pdb_default_add_group_mapping_entry;
1182 (*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry;
1183 (*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry;
1184 (*methods)->enum_group_mapping = pdb_default_enum_group_mapping;
1185 (*methods)->add_aliasmem = pdb_default_add_aliasmem;
1186 (*methods)->del_aliasmem = pdb_default_del_aliasmem;
1187 (*methods)->enum_aliasmem = pdb_default_enum_aliasmem;
1188 (*methods)->enum_alias_memberships = pdb_default_alias_memberships;
1190 (*methods)->gettrustpwent = pdb_default_gettrustpwent;
1191 (*methods)->gettrustpwsid = pdb_default_gettrustpwsid;
1192 (*methods)->add_trust_passwd = pdb_default_add_trust_passwd;
1193 (*methods)->update_trust_passwd = pdb_default_update_trust_passwd;
1194 (*methods)->delete_trust_passwd = pdb_default_delete_trust_passwd;
1196 return NT_STATUS_OK;