Merge passdb from HEAD -> 3.0
[samba.git] / source / passdb / pdb_interface.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Password and authentication handling
4    Copyright (C) Andrew Bartlett                        2002
5    Copyright (C) Jelmer Vernooij                        2002
6
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.
11
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.
16
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.
20 */
21
22 #include "includes.h"
23
24 #undef DBGC_CLASS
25 #define DBGC_CLASS DBGC_PASSDB
26
27 /** List of various built-in passdb modules */
28
29 const struct pdb_init_function_entry builtin_pdb_init_functions[] = {
30         { "smbpasswd", pdb_init_smbpasswd },
31         { "smbpasswd_nua", pdb_init_smbpasswd_nua },
32         { "tdbsam", pdb_init_tdbsam },
33         { "tdbsam_nua", pdb_init_tdbsam_nua },
34         { "ldapsam", pdb_init_ldapsam },
35         { "ldapsam_nua", pdb_init_ldapsam_nua },
36         { "unixsam", pdb_init_unixsam },
37         { "nisplussam", pdb_init_nisplussam },
38         { "plugin", pdb_init_plugin },
39         { NULL, NULL}
40 };
41
42 static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update)
43 {
44         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
45
46         if (!context) {
47                 DEBUG(0, ("invalid pdb_context specified!\n"));
48                 return ret;
49         }
50
51         context->pwent_methods = context->pdb_methods;
52
53         if (!context->pwent_methods) {
54                 /* No passdbs at all */
55                 return ret;
56         }
57
58         while (NT_STATUS_IS_ERR(ret = context->pwent_methods->setsampwent(context->pwent_methods, update))) {
59                 context->pwent_methods = context->pwent_methods->next;
60                 if (context->pwent_methods == NULL) 
61                         return NT_STATUS_UNSUCCESSFUL;
62         }
63         return ret;
64 }
65
66 static void context_endsampwent(struct pdb_context *context)
67 {
68         if ((!context)){
69                 DEBUG(0, ("invalid pdb_context specified!\n"));
70                 return;
71         }
72
73         if (context->pwent_methods && context->pwent_methods->endsampwent)
74                 context->pwent_methods->endsampwent(context->pwent_methods);
75
76         /* So we won't get strange data when calling getsampwent now */
77         context->pwent_methods = NULL;
78 }
79
80 static NTSTATUS context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
81 {
82         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
83
84         if ((!context) || (!context->pwent_methods)) {
85                 DEBUG(0, ("invalid pdb_context specified!\n"));
86                 return ret;
87         }
88         /* Loop until we find something useful */
89         while (NT_STATUS_IS_ERR(ret = context->pwent_methods->getsampwent(context->pwent_methods, user))) {
90
91                 context->pwent_methods->endsampwent(context->pwent_methods);
92
93                 context->pwent_methods = context->pwent_methods->next;
94
95                 /* All methods are checked now. There are no more entries */
96                 if (context->pwent_methods == NULL)
97                         return ret;
98         
99                 context->pwent_methods->setsampwent(context->pwent_methods, False);
100         }
101         user->methods = context->pwent_methods;
102         return ret;
103 }
104
105 static NTSTATUS context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username)
106 {
107         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
108
109         struct pdb_methods *curmethods;
110         if ((!context)) {
111                 DEBUG(0, ("invalid pdb_context specified!\n"));
112                 return ret;
113         }
114         curmethods = context->pdb_methods;
115         while (curmethods){
116                 if (NT_STATUS_IS_OK(ret = curmethods->getsampwnam(curmethods, sam_acct, username))) {
117                         sam_acct->methods = curmethods;
118                         return ret;
119                 }
120                 curmethods = curmethods->next;
121         }
122
123         return ret;
124 }
125
126 static NTSTATUS context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
127 {
128         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
129
130         struct pdb_methods *curmethods;
131         if ((!context)) {
132                 DEBUG(0, ("invalid pdb_context specified!\n"));
133                 return ret;
134         }
135         
136         curmethods = context->pdb_methods;
137
138         while (curmethods){
139                 if (NT_STATUS_IS_OK(ret = curmethods->getsampwsid(curmethods, sam_acct, sid))) {
140                         sam_acct->methods = curmethods;
141                         return ret;
142                 }
143                 curmethods = curmethods->next;
144         }
145
146         return ret;
147 }
148
149 static NTSTATUS context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
150 {
151         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
152
153         if ((!context) || (!context->pdb_methods)) {
154                 DEBUG(0, ("invalid pdb_context specified!\n"));
155                 return ret;
156         }
157
158         /** @todo  This is where a 're-read on add' should be done */
159         /* We now add a new account to the first database listed. 
160          * Should we? */
161
162         return context->pdb_methods->add_sam_account(context->pdb_methods, sam_acct);
163 }
164
165 static NTSTATUS context_update_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
166 {
167         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
168
169         if (!context) {
170                 DEBUG(0, ("invalid pdb_context specified!\n"));
171                 return ret;
172         }
173
174         if (!sam_acct || !sam_acct->methods){
175                 DEBUG(0, ("invalid sam_acct specified\n"));
176                 return ret;
177         }
178
179         /** @todo  This is where a 're-read on update' should be done */
180
181         return sam_acct->methods->update_sam_account(sam_acct->methods, sam_acct);
182 }
183
184 static NTSTATUS context_delete_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
185 {
186         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
187
188         struct pdb_methods *pdb_selected;
189         if (!context) {
190                 DEBUG(0, ("invalid pdb_context specified!\n"));
191                 return ret;
192         }
193
194         if (!sam_acct->methods){
195                 pdb_selected = context->pdb_methods;
196                 /* There's no passdb backend specified for this account.
197                  * Try to delete it in every passdb available 
198                  * Needed to delete accounts in smbpasswd that are not
199                  * in /etc/passwd.
200                  */
201                 while (pdb_selected){
202                         if (NT_STATUS_IS_OK(ret = pdb_selected->delete_sam_account(pdb_selected, sam_acct))) {
203                                 return ret;
204                         }
205                         pdb_selected = pdb_selected->next;
206                 }
207                 return ret;
208         }
209
210         if (!sam_acct->methods->delete_sam_account){
211                 DEBUG(0,("invalid sam_acct->methods->delete_sam_account\n"));
212                 return ret;
213         }
214         
215         return sam_acct->methods->delete_sam_account(sam_acct->methods, sam_acct);
216 }
217
218 static NTSTATUS context_getgrsid(struct pdb_context *context,
219                                  GROUP_MAP *map, DOM_SID sid, BOOL with_priv)
220 {
221         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
222
223         struct pdb_methods *curmethods;
224         if ((!context)) {
225                 DEBUG(0, ("invalid pdb_context specified!\n"));
226                 return ret;
227         }
228         curmethods = context->pdb_methods;
229         while (curmethods){
230                 ret = curmethods->getgrsid(curmethods, map, sid, with_priv);
231                 if (NT_STATUS_IS_OK(ret)) {
232                         map->methods = curmethods;
233                         return ret;
234                 }
235                 curmethods = curmethods->next;
236         }
237
238         return ret;
239 }
240
241 static NTSTATUS context_getgrgid(struct pdb_context *context,
242                                  GROUP_MAP *map, gid_t gid, BOOL with_priv)
243 {
244         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
245
246         struct pdb_methods *curmethods;
247         if ((!context)) {
248                 DEBUG(0, ("invalid pdb_context specified!\n"));
249                 return ret;
250         }
251         curmethods = context->pdb_methods;
252         while (curmethods){
253                 ret = curmethods->getgrgid(curmethods, map, gid, with_priv);
254                 if (NT_STATUS_IS_OK(ret)) {
255                         map->methods = curmethods;
256                         return ret;
257                 }
258                 curmethods = curmethods->next;
259         }
260
261         return ret;
262 }
263
264 static NTSTATUS context_getgrnam(struct pdb_context *context,
265                                  GROUP_MAP *map, char *name, BOOL with_priv)
266 {
267         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
268
269         struct pdb_methods *curmethods;
270         if ((!context)) {
271                 DEBUG(0, ("invalid pdb_context specified!\n"));
272                 return ret;
273         }
274         curmethods = context->pdb_methods;
275         while (curmethods){
276                 ret = curmethods->getgrnam(curmethods, map, name, with_priv);
277                 if (NT_STATUS_IS_OK(ret)) {
278                         map->methods = curmethods;
279                         return ret;
280                 }
281                 curmethods = curmethods->next;
282         }
283
284         return ret;
285 }
286
287 static NTSTATUS context_add_group_mapping_entry(struct pdb_context *context,
288                                                 GROUP_MAP *map)
289 {
290         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
291
292         if ((!context) || (!context->pdb_methods)) {
293                 DEBUG(0, ("invalid pdb_context specified!\n"));
294                 return ret;
295         }
296
297         return context->pdb_methods->add_group_mapping_entry(context->pdb_methods,
298                                                              map);
299 }
300
301 static NTSTATUS context_update_group_mapping_entry(struct pdb_context *context,
302                                                    GROUP_MAP *map)
303 {
304         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
305
306         if ((!context) || (!context->pdb_methods)) {
307                 DEBUG(0, ("invalid pdb_context specified!\n"));
308                 return ret;
309         }
310
311         return context->
312                 pdb_methods->update_group_mapping_entry(context->pdb_methods, map);
313 }
314
315 static NTSTATUS context_delete_group_mapping_entry(struct pdb_context *context,
316                                                    DOM_SID sid)
317 {
318         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
319
320         if ((!context) || (!context->pdb_methods)) {
321                 DEBUG(0, ("invalid pdb_context specified!\n"));
322                 return ret;
323         }
324
325         return context->
326                 pdb_methods->delete_group_mapping_entry(context->pdb_methods, sid);
327 }
328
329 static NTSTATUS context_enum_group_mapping(struct pdb_context *context,
330                                            enum SID_NAME_USE sid_name_use,
331                                            GROUP_MAP **rmap, int *num_entries,
332                                            BOOL unix_only, BOOL with_priv)
333 {
334         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
335
336         if ((!context) || (!context->pdb_methods)) {
337                 DEBUG(0, ("invalid pdb_context specified!\n"));
338                 return ret;
339         }
340
341         return context->pdb_methods->enum_group_mapping(context->pdb_methods,
342                                                         sid_name_use, rmap,
343                                                         num_entries, unix_only,
344                                                         with_priv);
345 }
346
347 /******************************************************************
348   Free and cleanup a pdb context, any associated data and anything
349   that the attached modules might have associated.
350  *******************************************************************/
351
352 static void free_pdb_context(struct pdb_context **context)
353 {
354         struct pdb_methods *pdb_selected = (*context)->pdb_methods;
355
356         while (pdb_selected){
357                 if(pdb_selected->free_private_data)
358                         pdb_selected->free_private_data(&(pdb_selected->private_data));
359                 pdb_selected = pdb_selected->next;
360         }
361
362         talloc_destroy((*context)->mem_ctx);
363         *context = NULL;
364 }
365
366 /******************************************************************
367   Make a pdb_methods from scratch
368  *******************************************************************/
369
370 static NTSTATUS make_pdb_methods_name(struct pdb_methods **methods, struct pdb_context *context, const char *selected)
371 {
372         char *module_name = smb_xstrdup(selected);
373         char *module_location = NULL, *p;
374         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
375         int i;
376
377         p = strchr(module_name, ':');
378
379         if (p) {
380                 *p = 0;
381                 module_location = p+1;
382                 trim_string(module_location, " ", " ");
383         }
384
385         trim_string(module_name, " ", " ");
386
387         DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name));
388         for (i = 0; builtin_pdb_init_functions[i].name; i++)
389         {
390                 if (strequal(builtin_pdb_init_functions[i].name, module_name))
391                 {
392                         DEBUG(5,("Found pdb backend %s (at pos %d)\n", module_name, i));
393                         nt_status = builtin_pdb_init_functions[i].init(context, methods, module_location);
394                         if (NT_STATUS_IS_OK(nt_status)) {
395                                 DEBUG(5,("pdb backend %s has a valid init\n", selected));
396                         } else {
397                                 DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", selected, nt_errstr(nt_status)));
398                         }
399                         SAFE_FREE(module_name);
400                         return nt_status;
401                         break; /* unreached */
402                 }
403         }
404
405         /* No such backend found */
406         SAFE_FREE(module_name);
407         return NT_STATUS_INVALID_PARAMETER;
408 }
409
410 /******************************************************************
411   Make a pdb_context from scratch.
412  *******************************************************************/
413
414 static NTSTATUS make_pdb_context(struct pdb_context **context) 
415 {
416         TALLOC_CTX *mem_ctx;
417
418         mem_ctx = talloc_init_named("pdb_context internal allocation context");
419
420         if (!mem_ctx) {
421                 DEBUG(0, ("make_pdb_context: talloc init failed!\n"));
422                 return NT_STATUS_NO_MEMORY;
423         }               
424
425         *context = talloc(mem_ctx, sizeof(**context));
426         if (!*context) {
427                 DEBUG(0, ("make_pdb_context: talloc failed!\n"));
428                 return NT_STATUS_NO_MEMORY;
429         }
430
431         ZERO_STRUCTP(*context);
432
433         (*context)->mem_ctx = mem_ctx;
434
435         (*context)->pdb_setsampwent = context_setsampwent;
436         (*context)->pdb_endsampwent = context_endsampwent;
437         (*context)->pdb_getsampwent = context_getsampwent;
438         (*context)->pdb_getsampwnam = context_getsampwnam;
439         (*context)->pdb_getsampwsid = context_getsampwsid;
440         (*context)->pdb_add_sam_account = context_add_sam_account;
441         (*context)->pdb_update_sam_account = context_update_sam_account;
442         (*context)->pdb_delete_sam_account = context_delete_sam_account;
443         (*context)->pdb_getgrsid = context_getgrsid;
444         (*context)->pdb_getgrgid = context_getgrgid;
445         (*context)->pdb_getgrnam = context_getgrnam;
446         (*context)->pdb_add_group_mapping_entry = context_add_group_mapping_entry;
447         (*context)->pdb_update_group_mapping_entry = context_update_group_mapping_entry;
448         (*context)->pdb_delete_group_mapping_entry = context_delete_group_mapping_entry;
449         (*context)->pdb_enum_group_mapping = context_enum_group_mapping;
450
451         (*context)->free_fn = free_pdb_context;
452
453         return NT_STATUS_OK;
454 }
455
456
457 /******************************************************************
458   Make a pdb_context, given an array of strings
459  *******************************************************************/
460
461 NTSTATUS make_pdb_context_list(struct pdb_context **context, char **selected) 
462 {
463         int i = 0;
464         struct pdb_methods *curmethods, *tmpmethods;
465         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
466
467         if (!NT_STATUS_IS_OK(nt_status = make_pdb_context(context))) {
468                 return nt_status;
469         }
470
471         while (selected[i]){
472                 /* Try to initialise pdb */
473                 DEBUG(5,("Trying to load: %s\n", selected[i]));
474                 if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods_name(&curmethods, *context, selected[i]))) {
475                         DEBUG(1, ("Loading %s failed!\n", selected[i]));
476                         free_pdb_context(context);
477                         return nt_status;
478                 }
479                 curmethods->parent = *context;
480                 DLIST_ADD_END((*context)->pdb_methods, curmethods, tmpmethods);
481                 i++;
482         }
483
484         return NT_STATUS_OK;
485 }
486
487 /******************************************************************
488   Make a pdb_context, given a text string.
489  *******************************************************************/
490
491 NTSTATUS make_pdb_context_string(struct pdb_context **context, const char *selected) 
492 {
493         NTSTATUS ret;
494         char **newsel = str_list_make(selected, NULL);
495         ret = make_pdb_context_list(context, newsel);
496         str_list_free(&newsel);
497         return ret;
498 }
499
500 /******************************************************************
501  Return an already initialised pdb_context, to facilitate backward 
502  compatibility (see functions below).
503 *******************************************************************/
504
505 static struct pdb_context *pdb_get_static_context(BOOL reload) 
506 {
507         static struct pdb_context *pdb_context = NULL;
508
509         if ((pdb_context) && (reload)) {
510                 pdb_context->free_fn(&pdb_context);
511                 if (NT_STATUS_IS_ERR(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) {
512                         return NULL;
513                 }
514         }
515
516         if (!pdb_context) {
517                 if (NT_STATUS_IS_ERR(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) {
518                         return NULL;
519                 }
520         }
521
522         return pdb_context;
523 }
524
525 #if !defined(WITH_NISPLUS_SAM)
526
527 /******************************************************************
528  Backward compatibility functions for the original passdb interface
529 *******************************************************************/
530
531 BOOL pdb_setsampwent(BOOL update) 
532 {
533         struct pdb_context *pdb_context = pdb_get_static_context(False);
534
535         if (!pdb_context) {
536                 return False;
537         }
538
539         return NT_STATUS_IS_OK(pdb_context->pdb_setsampwent(pdb_context, update));
540 }
541
542 void pdb_endsampwent(void) 
543 {
544         struct pdb_context *pdb_context = pdb_get_static_context(False);
545
546         if (!pdb_context) {
547                 return;
548         }
549
550         pdb_context->pdb_endsampwent(pdb_context);
551 }
552
553 BOOL pdb_getsampwent(SAM_ACCOUNT *user) 
554 {
555         struct pdb_context *pdb_context = pdb_get_static_context(False);
556
557         if (!pdb_context) {
558                 return False;
559         }
560
561         return NT_STATUS_IS_OK(pdb_context->pdb_getsampwent(pdb_context, user));
562 }
563
564 BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username) 
565 {
566         struct pdb_context *pdb_context = pdb_get_static_context(False);
567
568         if (!pdb_context) {
569                 return False;
570         }
571
572         return NT_STATUS_IS_OK(pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username));
573 }
574
575 BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid) 
576 {
577         struct pdb_context *pdb_context = pdb_get_static_context(False);
578
579         if (!pdb_context) {
580                 return False;
581         }
582
583         return NT_STATUS_IS_OK(pdb_context->pdb_getsampwsid(pdb_context, sam_acct, sid));
584 }
585
586 BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct) 
587 {
588         struct pdb_context *pdb_context = pdb_get_static_context(False);
589
590         if (!pdb_context) {
591                 return False;
592         }
593
594         return NT_STATUS_IS_OK(pdb_context->pdb_add_sam_account(pdb_context, sam_acct));
595 }
596
597 BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct) 
598 {
599         struct pdb_context *pdb_context = pdb_get_static_context(False);
600
601         if (!pdb_context) {
602                 return False;
603         }
604
605         return NT_STATUS_IS_OK(pdb_context->pdb_update_sam_account(pdb_context, sam_acct));
606 }
607
608 BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct) 
609 {
610         struct pdb_context *pdb_context = pdb_get_static_context(False);
611
612         if (!pdb_context) {
613                 return False;
614         }
615
616         return NT_STATUS_IS_OK(pdb_context->pdb_delete_sam_account(pdb_context, sam_acct));
617 }
618
619 BOOL pdb_getgrsid(GROUP_MAP *map, DOM_SID sid, BOOL with_priv)
620 {
621         struct pdb_context *pdb_context = pdb_get_static_context(False);
622
623         if (!pdb_context) {
624                 return False;
625         }
626
627         return NT_STATUS_IS_OK(pdb_context->
628                                pdb_getgrsid(pdb_context, map, sid, with_priv));
629 }
630
631 BOOL pdb_getgrgid(GROUP_MAP *map, gid_t gid, BOOL with_priv)
632 {
633         struct pdb_context *pdb_context = pdb_get_static_context(False);
634
635         if (!pdb_context) {
636                 return False;
637         }
638
639         return NT_STATUS_IS_OK(pdb_context->
640                                pdb_getgrgid(pdb_context, map, gid, with_priv));
641 }
642
643 BOOL pdb_getgrnam(GROUP_MAP *map, char *name, BOOL with_priv)
644 {
645         struct pdb_context *pdb_context = pdb_get_static_context(False);
646
647         if (!pdb_context) {
648                 return False;
649         }
650
651         return NT_STATUS_IS_OK(pdb_context->
652                                pdb_getgrnam(pdb_context, map, name, with_priv));
653 }
654
655 BOOL pdb_add_group_mapping_entry(GROUP_MAP *map)
656 {
657         struct pdb_context *pdb_context = pdb_get_static_context(False);
658
659         if (!pdb_context) {
660                 return False;
661         }
662
663         return NT_STATUS_IS_OK(pdb_context->
664                                pdb_add_group_mapping_entry(pdb_context, map));
665 }
666
667 BOOL pdb_update_group_mapping_entry(GROUP_MAP *map)
668 {
669         struct pdb_context *pdb_context = pdb_get_static_context(False);
670
671         if (!pdb_context) {
672                 return False;
673         }
674
675         return NT_STATUS_IS_OK(pdb_context->
676                                pdb_update_group_mapping_entry(pdb_context, map));
677 }
678
679 BOOL pdb_delete_group_mapping_entry(DOM_SID sid)
680 {
681         struct pdb_context *pdb_context = pdb_get_static_context(False);
682
683         if (!pdb_context) {
684                 return False;
685         }
686
687         return NT_STATUS_IS_OK(pdb_context->
688                                pdb_delete_group_mapping_entry(pdb_context, sid));
689 }
690
691 BOOL pdb_enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **rmap,
692                             int *num_entries, BOOL unix_only, BOOL with_priv)
693 {
694         struct pdb_context *pdb_context = pdb_get_static_context(False);
695
696         if (!pdb_context) {
697                 return False;
698         }
699
700         return NT_STATUS_IS_OK(pdb_context->
701                                pdb_enum_group_mapping(pdb_context, sid_name_use,
702                                                       rmap, num_entries, unix_only,
703                                                       with_priv));
704 }
705
706 #endif /* !defined(WITH_NISPLUS_SAM) */
707
708 /***************************************************************
709   Initialize the static context (at smbd startup etc). 
710
711   If uninitialised, context will auto-init on first use.
712  ***************************************************************/
713
714 BOOL initialize_password_db(BOOL reload)
715 {       
716         return (pdb_get_static_context(reload) != NULL);
717 }
718
719
720 NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) 
721 {
722         *methods = talloc(mem_ctx, sizeof(struct pdb_methods));
723
724         if (!*methods) {
725                 return NT_STATUS_NO_MEMORY;
726         }
727
728         ZERO_STRUCTP(*methods);
729
730         return NT_STATUS_OK;
731 }