r13493: module_name and module_location are the same string. Fix a valgrind
[vlendec/samba-autobuild/.git] / source3 / 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    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
28 /* Cache of latest SAM lookup query */
29
30 static SAM_ACCOUNT *csamuser = NULL;
31
32 static struct pdb_init_function_entry *backends = NULL;
33
34 static void lazy_initialize_passdb(void)
35 {
36         static BOOL initialized = False;
37         if(initialized)return;
38         static_init_pdb;
39         initialized = True;
40 }
41
42 static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name);
43 static BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid,
44                                   const char **name,
45                                   enum SID_NAME_USE *psid_name_use,
46                                   union unid_t *unix_id);
47 /*******************************************************************
48  Clean up uninitialised passwords.  The only way to tell 
49  that these values are not 'real' is that they do not
50  have a valid last set time.  Instead, the value is fixed at 0. 
51  Therefore we use that as the key for 'is this a valid password'.
52  However, it is perfectly valid to have a 'default' last change
53  time, such LDAP with a missing attribute would produce.
54 ********************************************************************/
55
56 static void pdb_force_pw_initialization(SAM_ACCOUNT *pass) 
57 {
58         const uint8 *lm_pwd, *nt_pwd;
59         
60         /* only reset a password if the last set time has been 
61            explicitly been set to zero.  A default last set time 
62            is ignored */
63
64         if ( (pdb_get_init_flags(pass, PDB_PASSLASTSET) != PDB_DEFAULT) 
65                 && (pdb_get_pass_last_set_time(pass) == 0) ) 
66         {
67                 
68                 if (pdb_get_init_flags(pass, PDB_LMPASSWD) != PDB_DEFAULT) 
69                 {
70                         lm_pwd = pdb_get_lanman_passwd(pass);
71                         if (lm_pwd) 
72                                 pdb_set_lanman_passwd(pass, NULL, PDB_CHANGED);
73                 }
74                 if (pdb_get_init_flags(pass, PDB_NTPASSWD) != PDB_DEFAULT) 
75                 {
76                         nt_pwd = pdb_get_nt_passwd(pass);
77                         if (nt_pwd) 
78                                 pdb_set_nt_passwd(pass, NULL, PDB_CHANGED);
79                 }
80         }
81
82         return;
83 }
84
85 NTSTATUS smb_register_passdb(int version, const char *name, pdb_init_function init) 
86 {
87         struct pdb_init_function_entry *entry = backends;
88
89         if(version != PASSDB_INTERFACE_VERSION) {
90                 DEBUG(0,("Can't register passdb backend!\n"
91                          "You tried to register a passdb module with PASSDB_INTERFACE_VERSION %d, "
92                          "while this version of samba uses version %d\n", 
93                          version,PASSDB_INTERFACE_VERSION));
94                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
95         }
96
97         if (!name || !init) {
98                 return NT_STATUS_INVALID_PARAMETER;
99         }
100
101         DEBUG(5,("Attempting to register passdb backend %s\n", name));
102
103         /* Check for duplicates */
104         if (pdb_find_backend_entry(name)) {
105                 DEBUG(0,("There already is a passdb backend registered with the name %s!\n", name));
106                 return NT_STATUS_OBJECT_NAME_COLLISION;
107         }
108
109         entry = SMB_XMALLOC_P(struct pdb_init_function_entry);
110         entry->name = smb_xstrdup(name);
111         entry->init = init;
112
113         DLIST_ADD(backends, entry);
114         DEBUG(5,("Successfully added passdb backend '%s'\n", name));
115         return NT_STATUS_OK;
116 }
117
118 static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name)
119 {
120         struct pdb_init_function_entry *entry = backends;
121
122         while(entry) {
123                 if (strcmp(entry->name, name)==0) return entry;
124                 entry = entry->next;
125         }
126
127         return NULL;
128 }
129
130 /******************************************************************
131   Make a pdb_methods from scratch
132  *******************************************************************/
133
134 NTSTATUS make_pdb_method_name(struct pdb_methods **methods, const char *selected)
135 {
136         char *module_name = smb_xstrdup(selected);
137         char *module_location = NULL, *p;
138         struct pdb_init_function_entry *entry;
139         NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
140
141         lazy_initialize_passdb();
142
143         p = strchr(module_name, ':');
144
145         if (p) {
146                 *p = 0;
147                 module_location = p+1;
148                 trim_char(module_location, ' ', ' ');
149         }
150
151         trim_char(module_name, ' ', ' ');
152
153
154         DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name));
155
156         entry = pdb_find_backend_entry(module_name);
157         
158         /* Try to find a module that contains this module */
159         if (!entry) { 
160                 DEBUG(2,("No builtin backend found, trying to load plugin\n"));
161                 if(NT_STATUS_IS_OK(smb_probe_module("pdb", module_name)) && !(entry = pdb_find_backend_entry(module_name))) {
162                         DEBUG(0,("Plugin is available, but doesn't register passdb backend %s\n", module_name));
163                         SAFE_FREE(module_name);
164                         return NT_STATUS_UNSUCCESSFUL;
165                 }
166         }
167         
168         /* No such backend found */
169         if(!entry) { 
170                 DEBUG(0,("No builtin nor plugin backend for %s found\n", module_name));
171                 SAFE_FREE(module_name);
172                 return NT_STATUS_INVALID_PARAMETER;
173         }
174
175         DEBUG(5,("Found pdb backend %s\n", module_name));
176
177         if ( !NT_STATUS_IS_OK( nt_status = entry->init(methods, module_location) ) ) {
178                 DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", 
179                         selected, nt_errstr(nt_status)));
180                 SAFE_FREE(module_name);
181                 return nt_status;
182         }
183
184         SAFE_FREE(module_name);
185
186         DEBUG(5,("pdb backend %s has a valid init\n", selected));
187
188         return nt_status;
189 }
190
191 /******************************************************************
192  Return an already initialised pdn_methods structure
193 *******************************************************************/
194
195 static struct pdb_methods *pdb_get_methods( BOOL reload ) 
196 {
197         static struct pdb_methods *pdb = NULL;
198
199         if ( pdb && reload ) {
200                 pdb->free_private_data( &(pdb->private_data) );
201                 if ( !NT_STATUS_IS_OK( make_pdb_method_name( &pdb, lp_passdb_backend() ) ) ) {
202                         return NULL;
203                 }
204         }
205
206         if ( !pdb ) {
207                 if ( !NT_STATUS_IS_OK( make_pdb_method_name( &pdb, lp_passdb_backend() ) ) ) {
208                         return NULL;
209                 }
210         }
211
212         return pdb;
213 }
214
215 /******************************************************************
216  Backward compatibility functions for the original passdb interface
217 *******************************************************************/
218
219 BOOL pdb_setsampwent(BOOL update, uint16 acb_mask) 
220 {
221         struct pdb_methods *pdb = pdb_get_methods(False);
222
223         if ( !pdb ) {
224                 return False;
225         }
226
227         return NT_STATUS_IS_OK(pdb->setsampwent(pdb, update, acb_mask));
228 }
229
230 void pdb_endsampwent(void) 
231 {
232         struct pdb_methods *pdb = pdb_get_methods(False);
233
234         if ( !pdb ) {
235                 return;
236         }
237
238         pdb->endsampwent(pdb);
239 }
240
241 BOOL pdb_getsampwent(SAM_ACCOUNT *user) 
242 {
243         struct pdb_methods *pdb = pdb_get_methods(False);
244
245         if ( !pdb ) {
246                 return False;
247         }
248
249         if ( !NT_STATUS_IS_OK(pdb->getsampwent(pdb, user) ) ) {
250                 return False;
251         }
252
253         pdb_force_pw_initialization( user );
254
255         return True;
256 }
257
258 BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username) 
259 {
260         struct pdb_methods *pdb = pdb_get_methods(False);
261
262         if ( !pdb ) {
263                 return False;
264         }
265
266         if (!NT_STATUS_IS_OK(pdb->getsampwnam(pdb, sam_acct, username))) {
267                 return False;
268         }
269
270         if (csamuser != NULL) {
271                 pdb_free_sam(&csamuser);
272                 csamuser = NULL;
273         }
274
275         pdb_force_pw_initialization( sam_acct );
276         pdb_copy_sam_account(sam_acct, &csamuser);
277
278         return True;
279 }
280
281 /**********************************************************************
282 **********************************************************************/
283
284 BOOL guest_user_info( SAM_ACCOUNT *user )
285 {
286         struct passwd *pwd;
287         NTSTATUS ntstatus;
288         const char *guestname = lp_guestaccount();
289         
290         if ( !(pwd = getpwnam_alloc( NULL, guestname ) ) ) {
291                 DEBUG(0,("guest_user_info: Unable to locate guest account [%s]!\n", 
292                         guestname));
293                 return False;
294         }
295         
296         /* fill in from the users information */
297         
298         ntstatus = pdb_fill_sam_pw( user, pwd );
299         
300         return NT_STATUS_IS_OK(ntstatus);
301
302 }
303
304 /**********************************************************************
305 **********************************************************************/
306
307 BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid) 
308 {
309         struct pdb_methods *pdb;
310         uint32 rid;
311
312         if ( !(pdb = pdb_get_methods(False)) ) {
313                 return False;
314         }
315
316         /* hard code the Guest RID of 501 */
317
318         if ( !sid_peek_check_rid( get_global_sam_sid(), sid, &rid ) )
319                 return False;
320
321         if ( rid == DOMAIN_USER_RID_GUEST ) {
322                 DEBUG(6,("pdb_getsampwsid: Building guest account\n"));
323                 return guest_user_info( sam_acct );
324         }
325         
326         /* check the cache first */
327         
328         if ( csamuser && sid_equal(sid, pdb_get_user_sid(csamuser) ) )
329                 return pdb_copy_sam_account(csamuser, &sam_acct);
330
331         return NT_STATUS_IS_OK(pdb->getsampwsid(pdb, sam_acct, sid));
332 }
333
334 BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct) 
335 {
336         struct pdb_methods *pdb = pdb_get_methods(False);
337
338         if ( !pdb ) {
339                 return False;
340         }
341         
342         return NT_STATUS_IS_OK(pdb->add_sam_account(pdb, sam_acct));
343 }
344
345 NTSTATUS pdb_update_sam_account(SAM_ACCOUNT *sam_acct) 
346 {
347         struct pdb_methods *pdb = pdb_get_methods(False);
348
349         if ( !pdb ) {
350                 return NT_STATUS_UNSUCCESSFUL;
351         }
352
353         if (csamuser != NULL) {
354                 pdb_free_sam(&csamuser);
355                 csamuser = NULL;
356         }
357
358         return pdb->update_sam_account(pdb, sam_acct);
359 }
360
361 BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct) 
362 {
363         struct pdb_methods *pdb = pdb_get_methods(False);
364
365         if ( !pdb ) {
366                 return False;
367         }
368
369         if (csamuser != NULL) {
370                 pdb_free_sam(&csamuser);
371                 csamuser = NULL;
372         }
373
374         return NT_STATUS_IS_OK(pdb->delete_sam_account(pdb, sam_acct));
375 }
376
377 NTSTATUS pdb_rename_sam_account(SAM_ACCOUNT *oldname, const char *newname)
378 {
379         struct pdb_methods *pdb = pdb_get_methods(False);
380
381         if ( !pdb ) {
382                 return NT_STATUS_NOT_IMPLEMENTED;
383         }
384
385         if (csamuser != NULL) {
386                 pdb_free_sam(&csamuser);
387                 csamuser = NULL;
388         }
389
390         return pdb->rename_sam_account(pdb, oldname, newname);
391 }
392
393 NTSTATUS pdb_update_login_attempts(SAM_ACCOUNT *sam_acct, BOOL success)
394 {
395         struct pdb_methods *pdb = pdb_get_methods(False);
396
397         if ( !pdb ) {
398                 return NT_STATUS_NOT_IMPLEMENTED;
399         }
400
401         return pdb->update_login_attempts(pdb, sam_acct, success);
402 }
403
404 BOOL pdb_getgrsid(GROUP_MAP *map, DOM_SID sid)
405 {
406         struct pdb_methods *pdb = pdb_get_methods(False);
407
408         if ( !pdb ) {
409                 return False;
410         }
411
412         return NT_STATUS_IS_OK(pdb->getgrsid(pdb, map, sid));
413 }
414
415 BOOL pdb_getgrgid(GROUP_MAP *map, gid_t gid)
416 {
417         struct pdb_methods *pdb = pdb_get_methods(False);
418
419         if ( !pdb ) {
420                 return False;
421         }
422
423         return NT_STATUS_IS_OK(pdb->getgrgid(pdb, map, gid));
424 }
425
426 BOOL pdb_getgrnam(GROUP_MAP *map, const char *name)
427 {
428         struct pdb_methods *pdb = pdb_get_methods(False);
429
430         if ( !pdb ) {
431                 return False;
432         }
433
434         return NT_STATUS_IS_OK(pdb->getgrnam(pdb, map, name));
435 }
436
437 NTSTATUS pdb_add_group_mapping_entry(GROUP_MAP *map)
438 {
439         struct pdb_methods *pdb = pdb_get_methods(False);
440
441         if ( !pdb ) {
442                 return NT_STATUS_UNSUCCESSFUL;
443         }
444
445         return pdb->add_group_mapping_entry(pdb, map);
446 }
447
448 NTSTATUS pdb_update_group_mapping_entry(GROUP_MAP *map)
449 {
450         struct pdb_methods *pdb = pdb_get_methods(False);
451
452         if ( !pdb ) {
453                 return NT_STATUS_UNSUCCESSFUL;
454         }
455
456         return pdb->update_group_mapping_entry(pdb, map);
457 }
458
459 BOOL pdb_delete_group_mapping_entry(DOM_SID sid)
460 {
461         struct pdb_methods *pdb = pdb_get_methods(False);
462
463         if ( !pdb ) {
464                 return False;
465         }
466
467         return NT_STATUS_IS_OK(pdb->delete_group_mapping_entry(pdb, sid));
468 }
469
470 BOOL pdb_enum_group_mapping(enum SID_NAME_USE sid_name_use, GROUP_MAP **pp_rmap,
471                             size_t *p_num_entries, BOOL unix_only)
472 {
473         struct pdb_methods *pdb = pdb_get_methods(False);
474
475         if ( !pdb ) {
476                 return False;
477         }
478
479         return NT_STATUS_IS_OK(pdb-> enum_group_mapping(pdb, sid_name_use,
480                 pp_rmap, p_num_entries, unix_only));
481 }
482
483 NTSTATUS pdb_enum_group_members(TALLOC_CTX *mem_ctx,
484                                 const DOM_SID *sid,
485                                 uint32 **pp_member_rids,
486                                 size_t *p_num_members)
487 {
488         struct pdb_methods *pdb = pdb_get_methods(False);
489
490         if ( !pdb ) {
491                 return NT_STATUS_UNSUCCESSFUL;
492         }
493
494         return pdb->enum_group_members(pdb, mem_ctx, sid, 
495                                                    pp_member_rids, p_num_members);
496 }
497
498 NTSTATUS pdb_enum_group_memberships(TALLOC_CTX *mem_ctx, SAM_ACCOUNT *user,
499                                     DOM_SID **pp_sids, gid_t **pp_gids,
500                                     size_t *p_num_groups)
501 {
502         struct pdb_methods *pdb = pdb_get_methods(False);
503
504         if ( !pdb ) {
505                 return NT_STATUS_UNSUCCESSFUL;
506         }
507
508         return pdb->enum_group_memberships(
509                 pdb, mem_ctx, user,
510                 pp_sids, pp_gids, p_num_groups);
511 }
512
513 BOOL pdb_find_alias(const char *name, DOM_SID *sid)
514 {
515         struct pdb_methods *pdb = pdb_get_methods(False);
516
517         if ( !pdb ) {
518                 return False;
519         }
520
521         return NT_STATUS_IS_OK(pdb->find_alias(pdb,
522                                                              name, sid));
523 }
524
525 NTSTATUS pdb_create_alias(const char *name, uint32 *rid)
526 {
527         struct pdb_methods *pdb = pdb_get_methods(False);
528
529         if ( !pdb ) {
530                 return NT_STATUS_NOT_IMPLEMENTED;
531         }
532
533         return pdb->create_alias(pdb, name, rid);
534 }
535
536 BOOL pdb_delete_alias(const DOM_SID *sid)
537 {
538         struct pdb_methods *pdb = pdb_get_methods(False);
539
540         if ( !pdb ) {
541                 return False;
542         }
543
544         return NT_STATUS_IS_OK(pdb->delete_alias(pdb,
545                                                              sid));
546                                                             
547 }
548
549 BOOL pdb_get_aliasinfo(const DOM_SID *sid, struct acct_info *info)
550 {
551         struct pdb_methods *pdb = pdb_get_methods(False);
552
553         if ( !pdb ) {
554                 return False;
555         }
556
557         return NT_STATUS_IS_OK(pdb->get_aliasinfo(pdb, sid,
558                                                               info));
559 }
560
561 BOOL pdb_set_aliasinfo(const DOM_SID *sid, struct acct_info *info)
562 {
563         struct pdb_methods *pdb = pdb_get_methods(False);
564
565         if ( !pdb ) {
566                 return False;
567         }
568
569         return NT_STATUS_IS_OK(pdb->set_aliasinfo(pdb, sid,
570                                                               info));
571 }
572
573 NTSTATUS pdb_add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
574 {
575         struct pdb_methods *pdb = pdb_get_methods(False);
576
577         if ( !pdb ) {
578                 return NT_STATUS_UNSUCCESSFUL;
579         }
580
581         return pdb->add_aliasmem(pdb, alias, member);
582 }
583
584 NTSTATUS pdb_del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
585 {
586         struct pdb_methods *pdb = pdb_get_methods(False);
587
588         if ( !pdb ) {
589                 return NT_STATUS_UNSUCCESSFUL;
590         }
591
592         return pdb->del_aliasmem(pdb, alias, member);
593 }
594
595 NTSTATUS pdb_enum_aliasmem(const DOM_SID *alias,
596                            DOM_SID **pp_members, size_t *p_num_members)
597 {
598         struct pdb_methods *pdb = pdb_get_methods(False);
599
600         if ( !pdb ) {
601                 return NT_STATUS_UNSUCCESSFUL;
602         }
603
604         return pdb->enum_aliasmem(pdb, alias,
605                                               pp_members, p_num_members);
606 }
607
608 NTSTATUS pdb_enum_alias_memberships(TALLOC_CTX *mem_ctx,
609                                     const DOM_SID *domain_sid,
610                                     const DOM_SID *members, size_t num_members,
611                                     uint32 **pp_alias_rids,
612                                     size_t *p_num_alias_rids)
613 {
614         struct pdb_methods *pdb = pdb_get_methods(False);
615
616         if ( !pdb ) {
617                 return NT_STATUS_NOT_IMPLEMENTED;
618         }
619
620         return pdb->enum_alias_memberships(pdb, mem_ctx,
621                                                        domain_sid,
622                                                        members, num_members,
623                                                        pp_alias_rids,
624                                                        p_num_alias_rids);
625 }
626
627 NTSTATUS pdb_lookup_rids(const DOM_SID *domain_sid,
628                          int num_rids,
629                          uint32 *rids,
630                          const char **names,
631                          uint32 *attrs)
632 {
633         struct pdb_methods *pdb = pdb_get_methods(False);
634
635         if ( !pdb ) {
636                 return NT_STATUS_NOT_IMPLEMENTED;
637         }
638
639         return pdb->lookup_rids(pdb, domain_sid,
640                                             num_rids, rids, names, attrs);
641 }
642
643 NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid,
644                           int num_names,
645                           const char **names,
646                           uint32 *rids,
647                           uint32 *attrs)
648 {
649         struct pdb_methods *pdb = pdb_get_methods(False);
650
651         if ( !pdb ) {
652                 return NT_STATUS_NOT_IMPLEMENTED;
653         }
654
655         return pdb->lookup_names(pdb, domain_sid,
656                                              num_names, names, rids, attrs);
657 }
658
659 BOOL pdb_get_account_policy(int policy_index, uint32 *value)
660 {
661         struct pdb_methods *pdb = pdb_get_methods(False);
662
663         if ( !pdb ) {
664                 return False;
665         }
666
667         return NT_STATUS_IS_OK(pdb->get_account_policy(pdb, policy_index, value));
668 }
669
670 BOOL pdb_set_account_policy(int policy_index, uint32 value)
671 {
672         struct pdb_methods *pdb = pdb_get_methods(False);
673
674         if ( !pdb ) {
675                 return False;
676         }
677
678         return NT_STATUS_IS_OK(pdb->set_account_policy(pdb, policy_index, value));
679 }
680
681 BOOL pdb_get_seq_num(time_t *seq_num)
682 {
683         struct pdb_methods *pdb = pdb_get_methods(False);
684
685         if ( !pdb ) {
686                 return False;
687         }
688
689         return NT_STATUS_IS_OK(pdb->get_seq_num(pdb, seq_num));
690 }
691
692 BOOL pdb_uid_to_rid(uid_t uid, uint32 *rid)
693 {
694         struct pdb_methods *pdb = pdb_get_methods(False);
695
696         if ( !pdb ) {
697                 return False;
698         }
699
700         return pdb->uid_to_rid(pdb, uid, rid);
701 }
702
703 BOOL pdb_gid_to_sid(gid_t gid, DOM_SID *sid)
704 {
705         struct pdb_methods *pdb = pdb_get_methods(False);
706
707         if ( !pdb ) {
708                 return False;
709         }
710
711         return pdb->gid_to_sid(pdb, gid, sid);
712 }
713
714 BOOL pdb_sid_to_id(const DOM_SID *sid, union unid_t *id,
715                    enum SID_NAME_USE *type)
716 {
717         struct pdb_methods *pdb = pdb_get_methods(False);
718
719         if ( !pdb ) {
720                 return False;
721         }
722
723         return pdb->sid_to_id(pdb, sid, id, type);
724 }
725
726 BOOL pdb_rid_algorithm(void)
727 {
728         struct pdb_methods *pdb = pdb_get_methods(False);
729
730         if ( !pdb ) {
731                 return False;
732         }
733
734         return pdb->rid_algorithm(pdb);
735 }
736
737 BOOL pdb_new_rid(uint32 *rid)
738 {
739         struct pdb_methods *pdb = pdb_get_methods(False);
740
741         if ( !pdb ) {
742                 return False;
743         }
744
745         if (pdb_rid_algorithm()) {
746                 DEBUG(0, ("Trying to allocate a RID when algorithmic RIDs "
747                           "are active\n"));
748                 return False;
749         }
750
751         if (algorithmic_rid_base() != BASE_RID) {
752                 DEBUG(0, ("'algorithmic rid base' is set but a passdb backend "
753                           "without algorithmic RIDs is chosen.\n"));
754                 DEBUGADD(0, ("Please map all used groups using 'net groupmap "
755                              "add', set the maximum used RID using\n"));
756                 DEBUGADD(0, ("'net setmaxrid' and remove the parameter\n"));
757                 return False;
758         }
759
760         return pdb->new_rid(pdb, rid);
761 }
762
763 /***************************************************************
764   Initialize the static context (at smbd startup etc). 
765
766   If uninitialised, context will auto-init on first use.
767  ***************************************************************/
768
769 BOOL initialize_password_db(BOOL reload)
770 {       
771         return (pdb_get_methods(reload) != NULL);
772 }
773
774
775 /***************************************************************************
776   Default implementations of some functions.
777  ****************************************************************************/
778
779 static NTSTATUS pdb_default_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname)
780 {
781         return NT_STATUS_NO_SUCH_USER;
782 }
783
784 static NTSTATUS pdb_default_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
785 {
786         return NT_STATUS_NO_SUCH_USER;
787 }
788
789 static NTSTATUS pdb_default_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
790 {
791         DEBUG(0,("this backend (%s) should not be listed as the first passdb backend! You can't add users to it.\n", methods->name));
792         return NT_STATUS_NOT_IMPLEMENTED;
793 }
794
795 static NTSTATUS pdb_default_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
796 {
797         return NT_STATUS_NOT_IMPLEMENTED;
798 }
799
800 static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *pwd)
801 {
802         return NT_STATUS_NOT_IMPLEMENTED;
803 }
804
805 static NTSTATUS pdb_default_rename_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *pwd, const char *newname)
806 {
807         return NT_STATUS_NOT_IMPLEMENTED;
808 }
809
810 static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, SAM_ACCOUNT *newpwd, BOOL success)
811 {
812         return NT_STATUS_OK;
813 }
814
815 static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
816 {
817         return NT_STATUS_NOT_IMPLEMENTED;
818 }
819
820 static NTSTATUS pdb_default_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT *user)
821 {
822         return NT_STATUS_NOT_IMPLEMENTED;
823 }
824
825 static void pdb_default_endsampwent(struct pdb_methods *methods)
826 {
827         return; /* NT_STATUS_NOT_IMPLEMENTED; */
828 }
829
830 static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
831 {
832         return account_policy_get(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
833 }
834
835 static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
836 {
837         return account_policy_set(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
838 }
839
840 static NTSTATUS pdb_default_get_seq_num(struct pdb_methods *methods, time_t *seq_num)
841 {
842         *seq_num = time(NULL);
843         return NT_STATUS_OK;
844 }
845
846 static BOOL pdb_default_uid_to_rid(struct pdb_methods *methods, uid_t uid,
847                                    uint32 *rid)
848 {
849         SAM_ACCOUNT *sampw = NULL;
850         struct passwd *unix_pw;
851         BOOL ret;
852         
853         unix_pw = sys_getpwuid( uid );
854
855         if ( !unix_pw ) {
856                 DEBUG(4,("pdb_default_uid_to_rid: host has no idea of uid "
857                          "%lu\n", (unsigned long)uid));
858                 return False;
859         }
860         
861         if ( !NT_STATUS_IS_OK(pdb_init_sam(&sampw)) ) {
862                 DEBUG(0,("pdb_default_uid_to_rid: failed to allocate "
863                          "SAM_ACCOUNT object\n"));
864                 return False;
865         }
866         
867         become_root();
868         ret = NT_STATUS_IS_OK(
869                 methods->getsampwnam(methods, sampw, unix_pw->pw_name ));
870         unbecome_root();
871
872         if (!ret) {
873                 DEBUG(5, ("pdb_default_uid_to_rid: Did not find user "
874                           "%s (%d)\n", unix_pw->pw_name, uid));
875                 pdb_free_sam(&sampw);
876                 return False;
877         }
878
879         ret = sid_peek_check_rid(get_global_sam_sid(),
880                                  pdb_get_user_sid(sampw), rid);
881
882         if (!ret) {
883                 DEBUG(1, ("Could not peek rid out of sid %s\n",
884                           sid_string_static(pdb_get_user_sid(sampw))));
885         }
886
887         pdb_free_sam(&sampw);
888         return ret;
889 }
890
891 static BOOL pdb_default_gid_to_sid(struct pdb_methods *methods, gid_t gid,
892                                    DOM_SID *sid)
893 {
894         GROUP_MAP map;
895
896         if (!NT_STATUS_IS_OK(methods->getgrgid(methods, &map, gid))) {
897                 return False;
898         }
899
900         sid_copy(sid, &map.sid);
901         return True;
902 }
903
904 static BOOL pdb_default_sid_to_id(struct pdb_methods *methods,
905                                   const DOM_SID *sid,
906                                   union unid_t *id, enum SID_NAME_USE *type)
907 {
908         TALLOC_CTX *mem_ctx;
909         BOOL ret = False;
910         const char *name;
911         uint32 rid;
912
913         mem_ctx = talloc_new(NULL);
914
915         if (mem_ctx == NULL) {
916                 DEBUG(0, ("talloc_new failed\n"));
917                 return False;
918         }
919
920         if (sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) {
921                 /* Here we might have users as well as groups and aliases */
922                 ret = lookup_global_sam_rid(mem_ctx, rid, &name, type, id);
923                 goto done;
924         }
925
926         if (sid_peek_check_rid(&global_sid_Builtin, sid, &rid)) {
927                 /* Here we only have aliases */
928                 GROUP_MAP map;
929                 if (!NT_STATUS_IS_OK(methods->getgrsid(methods, &map, *sid))) {
930                         DEBUG(10, ("Could not find map for sid %s\n",
931                                    sid_string_static(sid)));
932                         goto done;
933                 }
934                 if ((map.sid_name_use != SID_NAME_ALIAS) &&
935                     (map.sid_name_use != SID_NAME_WKN_GRP)) {
936                         DEBUG(10, ("Map for sid %s is a %s, expected an "
937                                    "alias\n", sid_string_static(sid),
938                                    sid_type_lookup(map.sid_name_use)));
939                         goto done;
940                 }
941
942                 id->gid = map.gid;
943                 *type = SID_NAME_ALIAS;
944                 ret = True;
945                 goto done;
946         }
947
948         DEBUG(5, ("Sid %s is neither ours nor builtin, don't know it\n",
949                   sid_string_static(sid)));
950
951  done:
952
953         talloc_free(mem_ctx);
954         return ret;
955 }
956
957 static void add_uid_to_array_unique(TALLOC_CTX *mem_ctx,
958                                     uid_t uid, uid_t **pp_uids, size_t *p_num)
959 {
960         size_t i;
961
962         for (i=0; i<*p_num; i++) {
963                 if ((*pp_uids)[i] == uid)
964                         return;
965         }
966         
967         *pp_uids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_uids, uid_t, *p_num+1);
968
969         if (*pp_uids == NULL)
970                 return;
971
972         (*pp_uids)[*p_num] = uid;
973         *p_num += 1;
974 }
975
976 static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size_t *p_num)
977 {
978         struct group *grp;
979         char **gr;
980         struct sys_pwent *userlist, *user;
981  
982         *pp_uids = NULL;
983         *p_num = 0;
984
985         /* We only look at our own sam, so don't care about imported stuff */
986
987         winbind_off();
988
989         if ((grp = getgrgid(gid)) == NULL) {
990                 winbind_on();
991                 return False;
992         }
993
994         /* Primary group members */
995
996         userlist = getpwent_list();
997
998         for (user = userlist; user != NULL; user = user->next) {
999                 if (user->pw_gid != gid)
1000                         continue;
1001                 add_uid_to_array_unique(mem_ctx, user->pw_uid, pp_uids, p_num);
1002         }
1003
1004         pwent_free(userlist);
1005
1006         /* Secondary group members */
1007
1008         for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
1009                 struct passwd *pw = getpwnam(*gr);
1010
1011                 if (pw == NULL)
1012                         continue;
1013                 add_uid_to_array_unique(mem_ctx, pw->pw_uid, pp_uids, p_num);
1014         }
1015
1016         winbind_on();
1017
1018         return True;
1019 }
1020
1021 NTSTATUS pdb_default_enum_group_members(struct pdb_methods *methods,
1022                                         TALLOC_CTX *mem_ctx,
1023                                         const DOM_SID *group,
1024                                         uint32 **pp_member_rids,
1025                                         size_t *p_num_members)
1026 {
1027         gid_t gid;
1028         uid_t *uids;
1029         size_t i, num_uids;
1030
1031         *pp_member_rids = NULL;
1032         *p_num_members = 0;
1033
1034         if (!sid_to_gid(group, &gid))
1035                 return NT_STATUS_NO_SUCH_GROUP;
1036
1037         if(!get_memberuids(mem_ctx, gid, &uids, &num_uids))
1038                 return NT_STATUS_NO_SUCH_GROUP;
1039
1040         if (num_uids == 0)
1041                 return NT_STATUS_OK;
1042
1043         *pp_member_rids = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_uids);
1044
1045         for (i=0; i<num_uids; i++) {
1046                 DOM_SID sid;
1047
1048                 uid_to_sid(&sid, uids[i]);
1049
1050                 if (!sid_check_is_in_our_domain(&sid)) {
1051                         DEBUG(1, ("Inconsistent SAM -- group member uid not "
1052                                   "in our domain\n"));
1053                         continue;
1054                 }
1055
1056                 sid_peek_rid(&sid, &(*pp_member_rids)[*p_num_members]);
1057                 *p_num_members += 1;
1058         }
1059
1060         return NT_STATUS_OK;
1061 }
1062
1063 /*******************************************************************
1064  Look up a rid in the SAM we're responsible for (i.e. passdb)
1065  ********************************************************************/
1066
1067 static BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid,
1068                                   const char **name,
1069                                   enum SID_NAME_USE *psid_name_use,
1070                                   union unid_t *unix_id)
1071 {
1072         SAM_ACCOUNT *sam_account = NULL;
1073         GROUP_MAP map;
1074         BOOL ret;
1075         DOM_SID sid;
1076
1077         *psid_name_use = SID_NAME_UNKNOWN;
1078         
1079         DEBUG(5,("lookup_global_sam_rid: looking up RID %u.\n",
1080                  (unsigned int)rid));
1081
1082         sid_copy(&sid, get_global_sam_sid());
1083         sid_append_rid(&sid, rid);
1084         
1085         /* see if the passdb can help us with the name of the user */
1086         if (!NT_STATUS_IS_OK(pdb_init_sam(&sam_account))) {
1087                 return False;
1088         }
1089
1090         /* BEING ROOT BLLOCK */
1091         become_root();
1092         if (pdb_getsampwsid(sam_account, &sid)) {
1093                 struct passwd *pw;
1094
1095                 unbecome_root();                /* -----> EXIT BECOME_ROOT() */
1096                 *name = talloc_strdup(mem_ctx, pdb_get_username(sam_account));
1097                 *psid_name_use = SID_NAME_USER;
1098
1099                 pdb_free_sam(&sam_account);
1100
1101                 if (unix_id == NULL) {
1102                         return True;
1103                 }
1104
1105                 pw = Get_Pwnam(*name);
1106                 if (pw == NULL) {
1107                         return False;
1108                 }
1109                 unix_id->uid = pw->pw_uid;
1110                 return True;
1111         }
1112         pdb_free_sam(&sam_account);
1113         
1114         ret = pdb_getgrsid(&map, sid);
1115         unbecome_root();
1116         /* END BECOME_ROOT BLOCK */
1117         
1118         if ( ret ) {
1119                 if (map.gid!=(gid_t)-1) {
1120                         DEBUG(5,("lookup_global_sam_rid: mapped group %s to "
1121                                  "gid %u\n", map.nt_name,
1122                                  (unsigned int)map.gid));
1123                 } else {
1124                         DEBUG(5,("lookup_global_sam_rid: mapped group %s to "
1125                                  "no unix gid.  Returning name.\n",
1126                                  map.nt_name));
1127                 }
1128
1129                 *name = talloc_strdup(mem_ctx, map.nt_name);
1130                 *psid_name_use = map.sid_name_use;
1131
1132                 if (unix_id == NULL) {
1133                         return True;
1134                 }
1135
1136                 if (map.gid == (gid_t)-1) {
1137                         DEBUG(5, ("Can't find a unix id for an unmapped "
1138                                   "group\n"));
1139                         return False;
1140                 }
1141
1142                 unix_id->gid = map.gid;
1143                 return True;
1144         }
1145
1146         return False;
1147 }
1148
1149 NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
1150                                  const DOM_SID *domain_sid,
1151                                  int num_rids,
1152                                  uint32 *rids,
1153                                  const char **names,
1154                                  uint32 *attrs)
1155 {
1156         int i;
1157         NTSTATUS result;
1158         BOOL have_mapped = False;
1159         BOOL have_unmapped = False;
1160
1161         if (sid_check_is_builtin(domain_sid)) {
1162
1163                 for (i=0; i<num_rids; i++) {
1164                         const char *name;
1165
1166                         if (lookup_builtin_rid(names, rids[i], &name)) {
1167                                 attrs[i] = SID_NAME_ALIAS;
1168                                 names[i] = name;
1169                                 DEBUG(5,("lookup_rids: %s:%d\n",
1170                                          names[i], attrs[i]));
1171                                 have_mapped = True;
1172                         } else {
1173                                 have_unmapped = True;
1174                                 attrs[i] = SID_NAME_UNKNOWN;
1175                         }
1176                 }
1177                 goto done;
1178         }
1179
1180         /* Should not happen, but better check once too many */
1181         if (!sid_check_is_domain(domain_sid)) {
1182                 return NT_STATUS_INVALID_HANDLE;
1183         }
1184
1185         for (i = 0; i < num_rids; i++) {
1186                 const char *name;
1187
1188                 if (lookup_global_sam_rid(names, rids[i], &name, &attrs[i],
1189                                           NULL)) {
1190                         names[i] = name;
1191                         DEBUG(5,("lookup_rids: %s:%d\n", names[i], attrs[i]));
1192                         have_mapped = True;
1193                 } else {
1194                         have_unmapped = True;
1195                         attrs[i] = SID_NAME_UNKNOWN;
1196                 }
1197         }
1198
1199  done:
1200
1201         result = NT_STATUS_NONE_MAPPED;
1202
1203         if (have_mapped)
1204                 result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
1205
1206         return result;
1207 }
1208
1209 NTSTATUS pdb_default_lookup_names(struct pdb_methods *methods,
1210                                   const DOM_SID *domain_sid,
1211                                   int num_names,
1212                                   const char **names,
1213                                   uint32 *rids,
1214                                   uint32 *attrs)
1215 {
1216         int i;
1217         NTSTATUS result;
1218         BOOL have_mapped = False;
1219         BOOL have_unmapped = False;
1220
1221         if (sid_check_is_builtin(domain_sid)) {
1222
1223                 for (i=0; i<num_names; i++) {
1224                         uint32 rid;
1225
1226                         if (lookup_builtin_name(names[i], &rid)) {
1227                                 attrs[i] = SID_NAME_ALIAS;
1228                                 rids[i] = rid;
1229                                 DEBUG(5,("lookup_rids: %s:%d\n",
1230                                          names[i], attrs[i]));
1231                                 have_mapped = True;
1232                         } else {
1233                                 have_unmapped = True;
1234                                 attrs[i] = SID_NAME_UNKNOWN;
1235                         }
1236                 }
1237                 goto done;
1238         }
1239
1240         /* Should not happen, but better check once too many */
1241         if (!sid_check_is_domain(domain_sid)) {
1242                 return NT_STATUS_INVALID_HANDLE;
1243         }
1244
1245         for (i = 0; i < num_names; i++) {
1246                 if (lookup_global_sam_name(names[i], 0, &rids[i], &attrs[i])) {
1247                         DEBUG(5,("lookup_names: %s-> %d:%d\n", names[i],
1248                                  rids[i], attrs[i]));
1249                         have_mapped = True;
1250                 } else {
1251                         have_unmapped = True;
1252                         attrs[i] = SID_NAME_UNKNOWN;
1253                 }
1254         }
1255
1256  done:
1257
1258         result = NT_STATUS_NONE_MAPPED;
1259
1260         if (have_mapped)
1261                 result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
1262
1263         return result;
1264 }
1265
1266 static struct pdb_search *pdb_search_init(enum pdb_search_type type)
1267 {
1268         TALLOC_CTX *mem_ctx;
1269         struct pdb_search *result;
1270
1271         mem_ctx = talloc_init("pdb_search");
1272         if (mem_ctx == NULL) {
1273                 DEBUG(0, ("talloc_init failed\n"));
1274                 return NULL;
1275         }
1276
1277         result = TALLOC_P(mem_ctx, struct pdb_search);
1278         if (result == NULL) {
1279                 DEBUG(0, ("talloc failed\n"));
1280                 return NULL;
1281         }
1282
1283         result->mem_ctx = mem_ctx;
1284         result->type = type;
1285         result->cache = NULL;
1286         result->num_entries = 0;
1287         result->cache_size = 0;
1288         result->search_ended = False;
1289
1290         /* Segfault appropriately if not initialized */
1291         result->next_entry = NULL;
1292         result->search_end = NULL;
1293
1294         return result;
1295 }
1296
1297 static void fill_displayentry(TALLOC_CTX *mem_ctx, uint32 rid,
1298                               uint16 acct_flags,
1299                               const char *account_name,
1300                               const char *fullname,
1301                               const char *description,
1302                               struct samr_displayentry *entry)
1303 {
1304         entry->rid = rid;
1305         entry->acct_flags = acct_flags;
1306
1307         if (account_name != NULL)
1308                 entry->account_name = talloc_strdup(mem_ctx, account_name);
1309         else
1310                 entry->account_name = "";
1311
1312         if (fullname != NULL)
1313                 entry->fullname = talloc_strdup(mem_ctx, fullname);
1314         else
1315                 entry->fullname = "";
1316
1317         if (description != NULL)
1318                 entry->description = talloc_strdup(mem_ctx, description);
1319         else
1320                 entry->description = "";
1321 }
1322
1323 static BOOL user_search_in_progress = False;
1324 struct user_search {
1325         uint16 acct_flags;
1326 };
1327
1328 static BOOL next_entry_users(struct pdb_search *s,
1329                              struct samr_displayentry *entry)
1330 {
1331         struct user_search *state = s->private_data;
1332         SAM_ACCOUNT *user = NULL;
1333         NTSTATUS status;
1334
1335  next:
1336         status = pdb_init_sam(&user);
1337         if (!NT_STATUS_IS_OK(status)) {
1338                 DEBUG(0, ("Could not pdb_init_sam\n"));
1339                 return False;
1340         }
1341
1342         if (!pdb_getsampwent(user)) {
1343                 pdb_free_sam(&user);
1344                 return False;
1345         }
1346
1347         if ((state->acct_flags != 0) &&
1348             ((pdb_get_acct_ctrl(user) & state->acct_flags) == 0)) {
1349                 pdb_free_sam(&user);
1350                 goto next;
1351         }
1352
1353         fill_displayentry(s->mem_ctx, pdb_get_user_rid(user),
1354                           pdb_get_acct_ctrl(user), pdb_get_username(user),
1355                           pdb_get_fullname(user), pdb_get_acct_desc(user),
1356                           entry);
1357
1358         pdb_free_sam(&user);
1359         return True;
1360 }
1361
1362 static void search_end_users(struct pdb_search *search)
1363 {
1364         pdb_endsampwent();
1365         user_search_in_progress = False;
1366 }
1367
1368 static BOOL pdb_default_search_users(struct pdb_methods *methods,
1369                                      struct pdb_search *search,
1370                                      uint16 acct_flags)
1371 {
1372         struct user_search *state;
1373
1374         if (user_search_in_progress) {
1375                 DEBUG(1, ("user search in progress\n"));
1376                 return False;
1377         }
1378
1379         if (!pdb_setsampwent(False, acct_flags)) {
1380                 DEBUG(5, ("Could not start search\n"));
1381                 return False;
1382         }
1383
1384         user_search_in_progress = True;
1385
1386         state = TALLOC_P(search->mem_ctx, struct user_search);
1387         if (state == NULL) {
1388                 DEBUG(0, ("talloc failed\n"));
1389                 return False;
1390         }
1391
1392         state->acct_flags = acct_flags;
1393
1394         search->private_data = state;
1395         search->next_entry = next_entry_users;
1396         search->search_end = search_end_users;
1397         return True;
1398 }
1399
1400 struct group_search {
1401         GROUP_MAP *groups;
1402         size_t num_groups, current_group;
1403 };
1404
1405 static BOOL next_entry_groups(struct pdb_search *s,
1406                               struct samr_displayentry *entry)
1407 {
1408         struct group_search *state = s->private_data;
1409         uint32 rid;
1410         GROUP_MAP *map = &state->groups[state->current_group];
1411
1412         if (state->current_group == state->num_groups)
1413                 return False;
1414
1415         sid_peek_rid(&map->sid, &rid);
1416
1417         fill_displayentry(s->mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
1418                           entry);
1419
1420         state->current_group += 1;
1421         return True;
1422 }
1423
1424 static void search_end_groups(struct pdb_search *search)
1425 {
1426         struct group_search *state = search->private_data;
1427         SAFE_FREE(state->groups);
1428 }
1429
1430 static BOOL pdb_search_grouptype(struct pdb_search *search,
1431                                  enum SID_NAME_USE type)
1432 {
1433         struct group_search *state;
1434
1435         state = TALLOC_P(search->mem_ctx, struct group_search);
1436         if (state == NULL) {
1437                 DEBUG(0, ("talloc failed\n"));
1438                 return False;
1439         }
1440
1441         if (!pdb_enum_group_mapping(type, &state->groups, &state->num_groups,
1442                                     True)) {
1443                 DEBUG(0, ("Could not enum groups\n"));
1444                 return False;
1445         }
1446
1447         state->current_group = 0;
1448         search->private_data = state;
1449         search->next_entry = next_entry_groups;
1450         search->search_end = search_end_groups;
1451         return True;
1452 }
1453
1454 static BOOL pdb_default_search_groups(struct pdb_methods *methods,
1455                                       struct pdb_search *search)
1456 {
1457         return pdb_search_grouptype(search, SID_NAME_DOM_GRP);
1458 }
1459
1460 static BOOL pdb_default_search_aliases(struct pdb_methods *methods,
1461                                        struct pdb_search *search,
1462                                        const DOM_SID *sid)
1463 {
1464
1465         if (sid_equal(sid, get_global_sam_sid()))
1466                 return pdb_search_grouptype(search, SID_NAME_ALIAS);
1467
1468         if (sid_equal(sid, &global_sid_Builtin))
1469                 return pdb_search_grouptype(search, SID_NAME_WKN_GRP);
1470
1471         DEBUG(3, ("unknown domain sid: %s\n", sid_string_static(sid)));
1472         return False;
1473 }
1474
1475 static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
1476                                                      uint32 idx)
1477 {
1478         if (idx < search->num_entries)
1479                 return &search->cache[idx];
1480
1481         if (search->search_ended)
1482                 return NULL;
1483
1484         while (idx >= search->num_entries) {
1485                 struct samr_displayentry entry;
1486
1487                 if (!search->next_entry(search, &entry)) {
1488                         search->search_end(search);
1489                         search->search_ended = True;
1490                         break;
1491                 }
1492
1493                 ADD_TO_LARGE_ARRAY(search->mem_ctx, struct samr_displayentry,
1494                                    entry, &search->cache, &search->num_entries,
1495                                    &search->cache_size);
1496         }
1497
1498         return (search->num_entries > idx) ? &search->cache[idx] : NULL;
1499 }
1500
1501 struct pdb_search *pdb_search_users(uint16 acct_flags)
1502 {
1503         struct pdb_methods *pdb = pdb_get_methods(False);
1504         struct pdb_search *result;
1505
1506         if (pdb == NULL) return NULL;
1507
1508         result = pdb_search_init(PDB_USER_SEARCH);
1509         if (result == NULL) return NULL;
1510
1511         if (!pdb->search_users(pdb, result, acct_flags)) {
1512                 talloc_destroy(result->mem_ctx);
1513                 return NULL;
1514         }
1515         return result;
1516 }
1517
1518 struct pdb_search *pdb_search_groups(void)
1519 {
1520         struct pdb_methods *pdb = pdb_get_methods(False);
1521         struct pdb_search *result;
1522
1523         if (pdb == NULL) return NULL;
1524
1525         result = pdb_search_init(PDB_GROUP_SEARCH);
1526         if (result == NULL) return NULL;
1527
1528         if (!pdb->search_groups(pdb, result)) {
1529                 talloc_destroy(result->mem_ctx);
1530                 return NULL;
1531         }
1532         return result;
1533 }
1534
1535 struct pdb_search *pdb_search_aliases(const DOM_SID *sid)
1536 {
1537         struct pdb_methods *pdb = pdb_get_methods(False);
1538         struct pdb_search *result;
1539
1540         if (pdb == NULL) return NULL;
1541
1542         result = pdb_search_init(PDB_ALIAS_SEARCH);
1543         if (result == NULL) return NULL;
1544
1545         if (!pdb->search_aliases(pdb, result, sid)) {
1546                 talloc_destroy(result->mem_ctx);
1547                 return NULL;
1548         }
1549         return result;
1550 }
1551
1552 uint32 pdb_search_entries(struct pdb_search *search,
1553                           uint32 start_idx, uint32 max_entries,
1554                           struct samr_displayentry **result)
1555 {
1556         struct samr_displayentry *end_entry;
1557         uint32 end_idx = start_idx+max_entries-1;
1558
1559         /* The first entry needs to be searched after the last. Otherwise the
1560          * first entry might have moved due to a realloc during the search for
1561          * the last entry. */
1562
1563         end_entry = pdb_search_getentry(search, end_idx);
1564         *result = pdb_search_getentry(search, start_idx);
1565
1566         if (end_entry != NULL)
1567                 return max_entries;
1568
1569         if (start_idx >= search->num_entries)
1570                 return 0;
1571
1572         return search->num_entries - start_idx;
1573 }
1574
1575 void pdb_search_destroy(struct pdb_search *search)
1576 {
1577         if (search == NULL)
1578                 return;
1579
1580         if (!search->search_ended)
1581                 search->search_end(search);
1582
1583         talloc_destroy(search->mem_ctx);
1584 }
1585
1586 /*******************************************************************
1587  Create a pdb_methods structure and initialize it with the default
1588  operations.  In this way a passdb module can simply implement
1589  the functionality it cares about.  However, normally this is done 
1590  in groups of related functions.
1591 *******************************************************************/
1592
1593 NTSTATUS make_pdb_method( struct pdb_methods **methods ) 
1594 {
1595         /* allocate memory for the structure as its own talloc CTX */
1596
1597         if ( !(*methods = TALLOC_ZERO_P(NULL, struct pdb_methods) ) ) {
1598                 return NT_STATUS_NO_MEMORY;
1599         }
1600
1601         (*methods)->setsampwent = pdb_default_setsampwent;
1602         (*methods)->endsampwent = pdb_default_endsampwent;
1603         (*methods)->getsampwent = pdb_default_getsampwent;
1604         (*methods)->getsampwnam = pdb_default_getsampwnam;
1605         (*methods)->getsampwsid = pdb_default_getsampwsid;
1606         (*methods)->add_sam_account = pdb_default_add_sam_account;
1607         (*methods)->update_sam_account = pdb_default_update_sam_account;
1608         (*methods)->delete_sam_account = pdb_default_delete_sam_account;
1609         (*methods)->rename_sam_account = pdb_default_rename_sam_account;
1610         (*methods)->update_login_attempts = pdb_default_update_login_attempts;
1611
1612         (*methods)->getgrsid = pdb_default_getgrsid;
1613         (*methods)->getgrgid = pdb_default_getgrgid;
1614         (*methods)->getgrnam = pdb_default_getgrnam;
1615         (*methods)->add_group_mapping_entry = pdb_default_add_group_mapping_entry;
1616         (*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry;
1617         (*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry;
1618         (*methods)->enum_group_mapping = pdb_default_enum_group_mapping;
1619         (*methods)->enum_group_members = pdb_default_enum_group_members;
1620         (*methods)->enum_group_memberships = pdb_default_enum_group_memberships;
1621         (*methods)->find_alias = pdb_default_find_alias;
1622         (*methods)->create_alias = pdb_default_create_alias;
1623         (*methods)->delete_alias = pdb_default_delete_alias;
1624         (*methods)->get_aliasinfo = pdb_default_get_aliasinfo;
1625         (*methods)->set_aliasinfo = pdb_default_set_aliasinfo;
1626         (*methods)->add_aliasmem = pdb_default_add_aliasmem;
1627         (*methods)->del_aliasmem = pdb_default_del_aliasmem;
1628         (*methods)->enum_aliasmem = pdb_default_enum_aliasmem;
1629         (*methods)->enum_alias_memberships = pdb_default_alias_memberships;
1630         (*methods)->lookup_rids = pdb_default_lookup_rids;
1631         (*methods)->get_account_policy = pdb_default_get_account_policy;
1632         (*methods)->set_account_policy = pdb_default_set_account_policy;
1633         (*methods)->get_seq_num = pdb_default_get_seq_num;
1634         (*methods)->uid_to_rid = pdb_default_uid_to_rid;
1635         (*methods)->gid_to_sid = pdb_default_gid_to_sid;
1636         (*methods)->sid_to_id = pdb_default_sid_to_id;
1637
1638         (*methods)->search_users = pdb_default_search_users;
1639         (*methods)->search_groups = pdb_default_search_groups;
1640         (*methods)->search_aliases = pdb_default_search_aliases;
1641
1642         return NT_STATUS_OK;
1643 }