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
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.
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.
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.
26 #define DBGC_CLASS DBGC_PASSDB
28 /* Cache of latest SAM lookup query */
30 static SAM_ACCOUNT *csamuser = NULL;
32 static struct pdb_init_function_entry *backends = NULL;
34 static void lazy_initialize_passdb(void)
36 static BOOL initialized = False;
37 if(initialized)return;
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,
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 ********************************************************************/
56 static void pdb_force_pw_initialization(SAM_ACCOUNT *pass)
58 const uint8 *lm_pwd, *nt_pwd;
60 /* only reset a password if the last set time has been
61 explicitly been set to zero. A default last set time
64 if ( (pdb_get_init_flags(pass, PDB_PASSLASTSET) != PDB_DEFAULT)
65 && (pdb_get_pass_last_set_time(pass) == 0) )
68 if (pdb_get_init_flags(pass, PDB_LMPASSWD) != PDB_DEFAULT)
70 lm_pwd = pdb_get_lanman_passwd(pass);
72 pdb_set_lanman_passwd(pass, NULL, PDB_CHANGED);
74 if (pdb_get_init_flags(pass, PDB_NTPASSWD) != PDB_DEFAULT)
76 nt_pwd = pdb_get_nt_passwd(pass);
78 pdb_set_nt_passwd(pass, NULL, PDB_CHANGED);
85 NTSTATUS smb_register_passdb(int version, const char *name, pdb_init_function init)
87 struct pdb_init_function_entry *entry = backends;
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;
98 return NT_STATUS_INVALID_PARAMETER;
101 DEBUG(5,("Attempting to register passdb backend %s\n", name));
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;
109 entry = SMB_XMALLOC_P(struct pdb_init_function_entry);
110 entry->name = smb_xstrdup(name);
113 DLIST_ADD(backends, entry);
114 DEBUG(5,("Successfully added passdb backend '%s'\n", name));
118 static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name)
120 struct pdb_init_function_entry *entry = backends;
123 if (strcmp(entry->name, name)==0) return entry;
130 /******************************************************************
131 Make a pdb_methods from scratch
132 *******************************************************************/
134 NTSTATUS make_pdb_method_name(struct pdb_methods **methods, const char *selected)
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;
141 lazy_initialize_passdb();
143 p = strchr(module_name, ':');
147 module_location = p+1;
148 trim_char(module_location, ' ', ' ');
151 trim_char(module_name, ' ', ' ');
154 DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name));
156 entry = pdb_find_backend_entry(module_name);
158 /* Try to find a module that contains this module */
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;
168 /* No such backend found */
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;
175 DEBUG(5,("Found pdb backend %s\n", module_name));
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);
184 SAFE_FREE(module_name);
186 DEBUG(5,("pdb backend %s has a valid init\n", selected));
191 /******************************************************************
192 Return an already initialised pdn_methods structure
193 *******************************************************************/
195 static struct pdb_methods *pdb_get_methods( BOOL reload )
197 static struct pdb_methods *pdb = NULL;
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() ) ) ) {
207 if ( !NT_STATUS_IS_OK( make_pdb_method_name( &pdb, lp_passdb_backend() ) ) ) {
215 /******************************************************************
216 Backward compatibility functions for the original passdb interface
217 *******************************************************************/
219 BOOL pdb_setsampwent(BOOL update, uint16 acb_mask)
221 struct pdb_methods *pdb = pdb_get_methods(False);
227 return NT_STATUS_IS_OK(pdb->setsampwent(pdb, update, acb_mask));
230 void pdb_endsampwent(void)
232 struct pdb_methods *pdb = pdb_get_methods(False);
238 pdb->endsampwent(pdb);
241 BOOL pdb_getsampwent(SAM_ACCOUNT *user)
243 struct pdb_methods *pdb = pdb_get_methods(False);
249 if ( !NT_STATUS_IS_OK(pdb->getsampwent(pdb, user) ) ) {
253 pdb_force_pw_initialization( user );
258 BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
260 struct pdb_methods *pdb = pdb_get_methods(False);
266 if (!NT_STATUS_IS_OK(pdb->getsampwnam(pdb, sam_acct, username))) {
270 if (csamuser != NULL) {
271 pdb_free_sam(&csamuser);
275 pdb_force_pw_initialization( sam_acct );
276 pdb_copy_sam_account(sam_acct, &csamuser);
281 /**********************************************************************
282 **********************************************************************/
284 BOOL guest_user_info( SAM_ACCOUNT *user )
288 const char *guestname = lp_guestaccount();
290 if ( !(pwd = getpwnam_alloc( NULL, guestname ) ) ) {
291 DEBUG(0,("guest_user_info: Unable to locate guest account [%s]!\n",
296 /* fill in from the users information */
298 ntstatus = pdb_fill_sam_pw( user, pwd );
300 return NT_STATUS_IS_OK(ntstatus);
304 /**********************************************************************
305 **********************************************************************/
307 BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, const DOM_SID *sid)
309 struct pdb_methods *pdb;
312 if ( !(pdb = pdb_get_methods(False)) ) {
316 /* hard code the Guest RID of 501 */
318 if ( !sid_peek_check_rid( get_global_sam_sid(), sid, &rid ) )
321 if ( rid == DOMAIN_USER_RID_GUEST ) {
322 DEBUG(6,("pdb_getsampwsid: Building guest account\n"));
323 return guest_user_info( sam_acct );
326 /* check the cache first */
328 if ( csamuser && sid_equal(sid, pdb_get_user_sid(csamuser) ) )
329 return pdb_copy_sam_account(csamuser, &sam_acct);
331 return NT_STATUS_IS_OK(pdb->getsampwsid(pdb, sam_acct, sid));
334 BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct)
336 struct pdb_methods *pdb = pdb_get_methods(False);
342 return NT_STATUS_IS_OK(pdb->add_sam_account(pdb, sam_acct));
345 NTSTATUS pdb_update_sam_account(SAM_ACCOUNT *sam_acct)
347 struct pdb_methods *pdb = pdb_get_methods(False);
350 return NT_STATUS_UNSUCCESSFUL;
353 if (csamuser != NULL) {
354 pdb_free_sam(&csamuser);
358 return pdb->update_sam_account(pdb, sam_acct);
361 BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct)
363 struct pdb_methods *pdb = pdb_get_methods(False);
369 if (csamuser != NULL) {
370 pdb_free_sam(&csamuser);
374 return NT_STATUS_IS_OK(pdb->delete_sam_account(pdb, sam_acct));
377 NTSTATUS pdb_rename_sam_account(SAM_ACCOUNT *oldname, const char *newname)
379 struct pdb_methods *pdb = pdb_get_methods(False);
382 return NT_STATUS_NOT_IMPLEMENTED;
385 if (csamuser != NULL) {
386 pdb_free_sam(&csamuser);
390 return pdb->rename_sam_account(pdb, oldname, newname);
393 NTSTATUS pdb_update_login_attempts(SAM_ACCOUNT *sam_acct, BOOL success)
395 struct pdb_methods *pdb = pdb_get_methods(False);
398 return NT_STATUS_NOT_IMPLEMENTED;
401 return pdb->update_login_attempts(pdb, sam_acct, success);
404 BOOL pdb_getgrsid(GROUP_MAP *map, DOM_SID sid)
406 struct pdb_methods *pdb = pdb_get_methods(False);
412 return NT_STATUS_IS_OK(pdb->getgrsid(pdb, map, sid));
415 BOOL pdb_getgrgid(GROUP_MAP *map, gid_t gid)
417 struct pdb_methods *pdb = pdb_get_methods(False);
423 return NT_STATUS_IS_OK(pdb->getgrgid(pdb, map, gid));
426 BOOL pdb_getgrnam(GROUP_MAP *map, const char *name)
428 struct pdb_methods *pdb = pdb_get_methods(False);
434 return NT_STATUS_IS_OK(pdb->getgrnam(pdb, map, name));
437 NTSTATUS pdb_add_group_mapping_entry(GROUP_MAP *map)
439 struct pdb_methods *pdb = pdb_get_methods(False);
442 return NT_STATUS_UNSUCCESSFUL;
445 return pdb->add_group_mapping_entry(pdb, map);
448 NTSTATUS pdb_update_group_mapping_entry(GROUP_MAP *map)
450 struct pdb_methods *pdb = pdb_get_methods(False);
453 return NT_STATUS_UNSUCCESSFUL;
456 return pdb->update_group_mapping_entry(pdb, map);
459 BOOL pdb_delete_group_mapping_entry(DOM_SID sid)
461 struct pdb_methods *pdb = pdb_get_methods(False);
467 return NT_STATUS_IS_OK(pdb->delete_group_mapping_entry(pdb, sid));
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)
473 struct pdb_methods *pdb = pdb_get_methods(False);
479 return NT_STATUS_IS_OK(pdb-> enum_group_mapping(pdb, sid_name_use,
480 pp_rmap, p_num_entries, unix_only));
483 NTSTATUS pdb_enum_group_members(TALLOC_CTX *mem_ctx,
485 uint32 **pp_member_rids,
486 size_t *p_num_members)
488 struct pdb_methods *pdb = pdb_get_methods(False);
491 return NT_STATUS_UNSUCCESSFUL;
494 return pdb->enum_group_members(pdb, mem_ctx, sid,
495 pp_member_rids, p_num_members);
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)
502 struct pdb_methods *pdb = pdb_get_methods(False);
505 return NT_STATUS_UNSUCCESSFUL;
508 return pdb->enum_group_memberships(
510 pp_sids, pp_gids, p_num_groups);
513 BOOL pdb_find_alias(const char *name, DOM_SID *sid)
515 struct pdb_methods *pdb = pdb_get_methods(False);
521 return NT_STATUS_IS_OK(pdb->find_alias(pdb,
525 NTSTATUS pdb_create_alias(const char *name, uint32 *rid)
527 struct pdb_methods *pdb = pdb_get_methods(False);
530 return NT_STATUS_NOT_IMPLEMENTED;
533 return pdb->create_alias(pdb, name, rid);
536 BOOL pdb_delete_alias(const DOM_SID *sid)
538 struct pdb_methods *pdb = pdb_get_methods(False);
544 return NT_STATUS_IS_OK(pdb->delete_alias(pdb,
549 BOOL pdb_get_aliasinfo(const DOM_SID *sid, struct acct_info *info)
551 struct pdb_methods *pdb = pdb_get_methods(False);
557 return NT_STATUS_IS_OK(pdb->get_aliasinfo(pdb, sid,
561 BOOL pdb_set_aliasinfo(const DOM_SID *sid, struct acct_info *info)
563 struct pdb_methods *pdb = pdb_get_methods(False);
569 return NT_STATUS_IS_OK(pdb->set_aliasinfo(pdb, sid,
573 NTSTATUS pdb_add_aliasmem(const DOM_SID *alias, const DOM_SID *member)
575 struct pdb_methods *pdb = pdb_get_methods(False);
578 return NT_STATUS_UNSUCCESSFUL;
581 return pdb->add_aliasmem(pdb, alias, member);
584 NTSTATUS pdb_del_aliasmem(const DOM_SID *alias, const DOM_SID *member)
586 struct pdb_methods *pdb = pdb_get_methods(False);
589 return NT_STATUS_UNSUCCESSFUL;
592 return pdb->del_aliasmem(pdb, alias, member);
595 NTSTATUS pdb_enum_aliasmem(const DOM_SID *alias,
596 DOM_SID **pp_members, size_t *p_num_members)
598 struct pdb_methods *pdb = pdb_get_methods(False);
601 return NT_STATUS_UNSUCCESSFUL;
604 return pdb->enum_aliasmem(pdb, alias,
605 pp_members, p_num_members);
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)
614 struct pdb_methods *pdb = pdb_get_methods(False);
617 return NT_STATUS_NOT_IMPLEMENTED;
620 return pdb->enum_alias_memberships(pdb, mem_ctx,
622 members, num_members,
627 NTSTATUS pdb_lookup_rids(const DOM_SID *domain_sid,
633 struct pdb_methods *pdb = pdb_get_methods(False);
636 return NT_STATUS_NOT_IMPLEMENTED;
639 return pdb->lookup_rids(pdb, domain_sid,
640 num_rids, rids, names, attrs);
643 NTSTATUS pdb_lookup_names(const DOM_SID *domain_sid,
649 struct pdb_methods *pdb = pdb_get_methods(False);
652 return NT_STATUS_NOT_IMPLEMENTED;
655 return pdb->lookup_names(pdb, domain_sid,
656 num_names, names, rids, attrs);
659 BOOL pdb_get_account_policy(int policy_index, uint32 *value)
661 struct pdb_methods *pdb = pdb_get_methods(False);
667 return NT_STATUS_IS_OK(pdb->get_account_policy(pdb, policy_index, value));
670 BOOL pdb_set_account_policy(int policy_index, uint32 value)
672 struct pdb_methods *pdb = pdb_get_methods(False);
678 return NT_STATUS_IS_OK(pdb->set_account_policy(pdb, policy_index, value));
681 BOOL pdb_get_seq_num(time_t *seq_num)
683 struct pdb_methods *pdb = pdb_get_methods(False);
689 return NT_STATUS_IS_OK(pdb->get_seq_num(pdb, seq_num));
692 BOOL pdb_uid_to_rid(uid_t uid, uint32 *rid)
694 struct pdb_methods *pdb = pdb_get_methods(False);
700 return pdb->uid_to_rid(pdb, uid, rid);
703 BOOL pdb_gid_to_sid(gid_t gid, DOM_SID *sid)
705 struct pdb_methods *pdb = pdb_get_methods(False);
711 return pdb->gid_to_sid(pdb, gid, sid);
714 BOOL pdb_sid_to_id(const DOM_SID *sid, union unid_t *id,
715 enum SID_NAME_USE *type)
717 struct pdb_methods *pdb = pdb_get_methods(False);
723 return pdb->sid_to_id(pdb, sid, id, type);
726 BOOL pdb_rid_algorithm(void)
728 struct pdb_methods *pdb = pdb_get_methods(False);
734 return pdb->rid_algorithm(pdb);
737 BOOL pdb_new_rid(uint32 *rid)
739 struct pdb_methods *pdb = pdb_get_methods(False);
745 if (pdb_rid_algorithm()) {
746 DEBUG(0, ("Trying to allocate a RID when algorithmic RIDs "
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"));
760 return pdb->new_rid(pdb, rid);
763 /***************************************************************
764 Initialize the static context (at smbd startup etc).
766 If uninitialised, context will auto-init on first use.
767 ***************************************************************/
769 BOOL initialize_password_db(BOOL reload)
771 return (pdb_get_methods(reload) != NULL);
775 /***************************************************************************
776 Default implementations of some functions.
777 ****************************************************************************/
779 static NTSTATUS pdb_default_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname)
781 return NT_STATUS_NO_SUCH_USER;
784 static NTSTATUS pdb_default_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid)
786 return NT_STATUS_NO_SUCH_USER;
789 static NTSTATUS pdb_default_add_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
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;
795 static NTSTATUS pdb_default_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd)
797 return NT_STATUS_NOT_IMPLEMENTED;
800 static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *pwd)
802 return NT_STATUS_NOT_IMPLEMENTED;
805 static NTSTATUS pdb_default_rename_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *pwd, const char *newname)
807 return NT_STATUS_NOT_IMPLEMENTED;
810 static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, SAM_ACCOUNT *newpwd, BOOL success)
815 static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
817 return NT_STATUS_NOT_IMPLEMENTED;
820 static NTSTATUS pdb_default_getsampwent(struct pdb_methods *methods, SAM_ACCOUNT *user)
822 return NT_STATUS_NOT_IMPLEMENTED;
825 static void pdb_default_endsampwent(struct pdb_methods *methods)
827 return; /* NT_STATUS_NOT_IMPLEMENTED; */
830 static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value)
832 return account_policy_get(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
835 static NTSTATUS pdb_default_set_account_policy(struct pdb_methods *methods, int policy_index, uint32 value)
837 return account_policy_set(policy_index, value) ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
840 static NTSTATUS pdb_default_get_seq_num(struct pdb_methods *methods, time_t *seq_num)
842 *seq_num = time(NULL);
846 static BOOL pdb_default_uid_to_rid(struct pdb_methods *methods, uid_t uid,
849 SAM_ACCOUNT *sampw = NULL;
850 struct passwd *unix_pw;
853 unix_pw = sys_getpwuid( uid );
856 DEBUG(4,("pdb_default_uid_to_rid: host has no idea of uid "
857 "%lu\n", (unsigned long)uid));
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"));
868 ret = NT_STATUS_IS_OK(
869 methods->getsampwnam(methods, sampw, unix_pw->pw_name ));
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);
879 ret = sid_peek_check_rid(get_global_sam_sid(),
880 pdb_get_user_sid(sampw), rid);
883 DEBUG(1, ("Could not peek rid out of sid %s\n",
884 sid_string_static(pdb_get_user_sid(sampw))));
887 pdb_free_sam(&sampw);
891 static BOOL pdb_default_gid_to_sid(struct pdb_methods *methods, gid_t gid,
896 if (!NT_STATUS_IS_OK(methods->getgrgid(methods, &map, gid))) {
900 sid_copy(sid, &map.sid);
904 static BOOL pdb_default_sid_to_id(struct pdb_methods *methods,
906 union unid_t *id, enum SID_NAME_USE *type)
913 mem_ctx = talloc_new(NULL);
915 if (mem_ctx == NULL) {
916 DEBUG(0, ("talloc_new failed\n"));
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);
926 if (sid_peek_check_rid(&global_sid_Builtin, sid, &rid)) {
927 /* Here we only have aliases */
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)));
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)));
943 *type = SID_NAME_ALIAS;
948 DEBUG(5, ("Sid %s is neither ours nor builtin, don't know it\n",
949 sid_string_static(sid)));
953 talloc_free(mem_ctx);
957 static void add_uid_to_array_unique(TALLOC_CTX *mem_ctx,
958 uid_t uid, uid_t **pp_uids, size_t *p_num)
962 for (i=0; i<*p_num; i++) {
963 if ((*pp_uids)[i] == uid)
967 *pp_uids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_uids, uid_t, *p_num+1);
969 if (*pp_uids == NULL)
972 (*pp_uids)[*p_num] = uid;
976 static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size_t *p_num)
980 struct sys_pwent *userlist, *user;
985 /* We only look at our own sam, so don't care about imported stuff */
989 if ((grp = getgrgid(gid)) == NULL) {
994 /* Primary group members */
996 userlist = getpwent_list();
998 for (user = userlist; user != NULL; user = user->next) {
999 if (user->pw_gid != gid)
1001 add_uid_to_array_unique(mem_ctx, user->pw_uid, pp_uids, p_num);
1004 pwent_free(userlist);
1006 /* Secondary group members */
1008 for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
1009 struct passwd *pw = getpwnam(*gr);
1013 add_uid_to_array_unique(mem_ctx, pw->pw_uid, pp_uids, p_num);
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)
1031 *pp_member_rids = NULL;
1034 if (!sid_to_gid(group, &gid))
1035 return NT_STATUS_NO_SUCH_GROUP;
1037 if(!get_memberuids(mem_ctx, gid, &uids, &num_uids))
1038 return NT_STATUS_NO_SUCH_GROUP;
1041 return NT_STATUS_OK;
1043 *pp_member_rids = TALLOC_ZERO_ARRAY(mem_ctx, uint32, num_uids);
1045 for (i=0; i<num_uids; i++) {
1048 uid_to_sid(&sid, uids[i]);
1050 if (!sid_check_is_in_our_domain(&sid)) {
1051 DEBUG(1, ("Inconsistent SAM -- group member uid not "
1052 "in our domain\n"));
1056 sid_peek_rid(&sid, &(*pp_member_rids)[*p_num_members]);
1057 *p_num_members += 1;
1060 return NT_STATUS_OK;
1063 /*******************************************************************
1064 Look up a rid in the SAM we're responsible for (i.e. passdb)
1065 ********************************************************************/
1067 static BOOL lookup_global_sam_rid(TALLOC_CTX *mem_ctx, uint32 rid,
1069 enum SID_NAME_USE *psid_name_use,
1070 union unid_t *unix_id)
1072 SAM_ACCOUNT *sam_account = NULL;
1077 *psid_name_use = SID_NAME_UNKNOWN;
1079 DEBUG(5,("lookup_global_sam_rid: looking up RID %u.\n",
1080 (unsigned int)rid));
1082 sid_copy(&sid, get_global_sam_sid());
1083 sid_append_rid(&sid, rid);
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))) {
1090 /* BEING ROOT BLLOCK */
1092 if (pdb_getsampwsid(sam_account, &sid)) {
1095 unbecome_root(); /* -----> EXIT BECOME_ROOT() */
1096 *name = talloc_strdup(mem_ctx, pdb_get_username(sam_account));
1097 *psid_name_use = SID_NAME_USER;
1099 pdb_free_sam(&sam_account);
1101 if (unix_id == NULL) {
1105 pw = Get_Pwnam(*name);
1109 unix_id->uid = pw->pw_uid;
1112 pdb_free_sam(&sam_account);
1114 ret = pdb_getgrsid(&map, sid);
1116 /* END BECOME_ROOT BLOCK */
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));
1124 DEBUG(5,("lookup_global_sam_rid: mapped group %s to "
1125 "no unix gid. Returning name.\n",
1129 *name = talloc_strdup(mem_ctx, map.nt_name);
1130 *psid_name_use = map.sid_name_use;
1132 if (unix_id == NULL) {
1136 if (map.gid == (gid_t)-1) {
1137 DEBUG(5, ("Can't find a unix id for an unmapped "
1142 unix_id->gid = map.gid;
1149 NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
1150 const DOM_SID *domain_sid,
1158 BOOL have_mapped = False;
1159 BOOL have_unmapped = False;
1161 if (sid_check_is_builtin(domain_sid)) {
1163 for (i=0; i<num_rids; i++) {
1166 if (lookup_builtin_rid(names, rids[i], &name)) {
1167 attrs[i] = SID_NAME_ALIAS;
1169 DEBUG(5,("lookup_rids: %s:%d\n",
1170 names[i], attrs[i]));
1173 have_unmapped = True;
1174 attrs[i] = SID_NAME_UNKNOWN;
1180 /* Should not happen, but better check once too many */
1181 if (!sid_check_is_domain(domain_sid)) {
1182 return NT_STATUS_INVALID_HANDLE;
1185 for (i = 0; i < num_rids; i++) {
1188 if (lookup_global_sam_rid(names, rids[i], &name, &attrs[i],
1191 DEBUG(5,("lookup_rids: %s:%d\n", names[i], attrs[i]));
1194 have_unmapped = True;
1195 attrs[i] = SID_NAME_UNKNOWN;
1201 result = NT_STATUS_NONE_MAPPED;
1204 result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
1209 NTSTATUS pdb_default_lookup_names(struct pdb_methods *methods,
1210 const DOM_SID *domain_sid,
1218 BOOL have_mapped = False;
1219 BOOL have_unmapped = False;
1221 if (sid_check_is_builtin(domain_sid)) {
1223 for (i=0; i<num_names; i++) {
1226 if (lookup_builtin_name(names[i], &rid)) {
1227 attrs[i] = SID_NAME_ALIAS;
1229 DEBUG(5,("lookup_rids: %s:%d\n",
1230 names[i], attrs[i]));
1233 have_unmapped = True;
1234 attrs[i] = SID_NAME_UNKNOWN;
1240 /* Should not happen, but better check once too many */
1241 if (!sid_check_is_domain(domain_sid)) {
1242 return NT_STATUS_INVALID_HANDLE;
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]));
1251 have_unmapped = True;
1252 attrs[i] = SID_NAME_UNKNOWN;
1258 result = NT_STATUS_NONE_MAPPED;
1261 result = have_unmapped ? STATUS_SOME_UNMAPPED : NT_STATUS_OK;
1266 static struct pdb_search *pdb_search_init(enum pdb_search_type type)
1268 TALLOC_CTX *mem_ctx;
1269 struct pdb_search *result;
1271 mem_ctx = talloc_init("pdb_search");
1272 if (mem_ctx == NULL) {
1273 DEBUG(0, ("talloc_init failed\n"));
1277 result = TALLOC_P(mem_ctx, struct pdb_search);
1278 if (result == NULL) {
1279 DEBUG(0, ("talloc failed\n"));
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;
1290 /* Segfault appropriately if not initialized */
1291 result->next_entry = NULL;
1292 result->search_end = NULL;
1297 static void fill_displayentry(TALLOC_CTX *mem_ctx, uint32 rid,
1299 const char *account_name,
1300 const char *fullname,
1301 const char *description,
1302 struct samr_displayentry *entry)
1305 entry->acct_flags = acct_flags;
1307 if (account_name != NULL)
1308 entry->account_name = talloc_strdup(mem_ctx, account_name);
1310 entry->account_name = "";
1312 if (fullname != NULL)
1313 entry->fullname = talloc_strdup(mem_ctx, fullname);
1315 entry->fullname = "";
1317 if (description != NULL)
1318 entry->description = talloc_strdup(mem_ctx, description);
1320 entry->description = "";
1323 static BOOL user_search_in_progress = False;
1324 struct user_search {
1328 static BOOL next_entry_users(struct pdb_search *s,
1329 struct samr_displayentry *entry)
1331 struct user_search *state = s->private_data;
1332 SAM_ACCOUNT *user = NULL;
1336 status = pdb_init_sam(&user);
1337 if (!NT_STATUS_IS_OK(status)) {
1338 DEBUG(0, ("Could not pdb_init_sam\n"));
1342 if (!pdb_getsampwent(user)) {
1343 pdb_free_sam(&user);
1347 if ((state->acct_flags != 0) &&
1348 ((pdb_get_acct_ctrl(user) & state->acct_flags) == 0)) {
1349 pdb_free_sam(&user);
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),
1358 pdb_free_sam(&user);
1362 static void search_end_users(struct pdb_search *search)
1365 user_search_in_progress = False;
1368 static BOOL pdb_default_search_users(struct pdb_methods *methods,
1369 struct pdb_search *search,
1372 struct user_search *state;
1374 if (user_search_in_progress) {
1375 DEBUG(1, ("user search in progress\n"));
1379 if (!pdb_setsampwent(False, acct_flags)) {
1380 DEBUG(5, ("Could not start search\n"));
1384 user_search_in_progress = True;
1386 state = TALLOC_P(search->mem_ctx, struct user_search);
1387 if (state == NULL) {
1388 DEBUG(0, ("talloc failed\n"));
1392 state->acct_flags = acct_flags;
1394 search->private_data = state;
1395 search->next_entry = next_entry_users;
1396 search->search_end = search_end_users;
1400 struct group_search {
1402 size_t num_groups, current_group;
1405 static BOOL next_entry_groups(struct pdb_search *s,
1406 struct samr_displayentry *entry)
1408 struct group_search *state = s->private_data;
1410 GROUP_MAP *map = &state->groups[state->current_group];
1412 if (state->current_group == state->num_groups)
1415 sid_peek_rid(&map->sid, &rid);
1417 fill_displayentry(s->mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
1420 state->current_group += 1;
1424 static void search_end_groups(struct pdb_search *search)
1426 struct group_search *state = search->private_data;
1427 SAFE_FREE(state->groups);
1430 static BOOL pdb_search_grouptype(struct pdb_search *search,
1431 enum SID_NAME_USE type)
1433 struct group_search *state;
1435 state = TALLOC_P(search->mem_ctx, struct group_search);
1436 if (state == NULL) {
1437 DEBUG(0, ("talloc failed\n"));
1441 if (!pdb_enum_group_mapping(type, &state->groups, &state->num_groups,
1443 DEBUG(0, ("Could not enum groups\n"));
1447 state->current_group = 0;
1448 search->private_data = state;
1449 search->next_entry = next_entry_groups;
1450 search->search_end = search_end_groups;
1454 static BOOL pdb_default_search_groups(struct pdb_methods *methods,
1455 struct pdb_search *search)
1457 return pdb_search_grouptype(search, SID_NAME_DOM_GRP);
1460 static BOOL pdb_default_search_aliases(struct pdb_methods *methods,
1461 struct pdb_search *search,
1465 if (sid_equal(sid, get_global_sam_sid()))
1466 return pdb_search_grouptype(search, SID_NAME_ALIAS);
1468 if (sid_equal(sid, &global_sid_Builtin))
1469 return pdb_search_grouptype(search, SID_NAME_WKN_GRP);
1471 DEBUG(3, ("unknown domain sid: %s\n", sid_string_static(sid)));
1475 static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
1478 if (idx < search->num_entries)
1479 return &search->cache[idx];
1481 if (search->search_ended)
1484 while (idx >= search->num_entries) {
1485 struct samr_displayentry entry;
1487 if (!search->next_entry(search, &entry)) {
1488 search->search_end(search);
1489 search->search_ended = True;
1493 ADD_TO_LARGE_ARRAY(search->mem_ctx, struct samr_displayentry,
1494 entry, &search->cache, &search->num_entries,
1495 &search->cache_size);
1498 return (search->num_entries > idx) ? &search->cache[idx] : NULL;
1501 struct pdb_search *pdb_search_users(uint16 acct_flags)
1503 struct pdb_methods *pdb = pdb_get_methods(False);
1504 struct pdb_search *result;
1506 if (pdb == NULL) return NULL;
1508 result = pdb_search_init(PDB_USER_SEARCH);
1509 if (result == NULL) return NULL;
1511 if (!pdb->search_users(pdb, result, acct_flags)) {
1512 talloc_destroy(result->mem_ctx);
1518 struct pdb_search *pdb_search_groups(void)
1520 struct pdb_methods *pdb = pdb_get_methods(False);
1521 struct pdb_search *result;
1523 if (pdb == NULL) return NULL;
1525 result = pdb_search_init(PDB_GROUP_SEARCH);
1526 if (result == NULL) return NULL;
1528 if (!pdb->search_groups(pdb, result)) {
1529 talloc_destroy(result->mem_ctx);
1535 struct pdb_search *pdb_search_aliases(const DOM_SID *sid)
1537 struct pdb_methods *pdb = pdb_get_methods(False);
1538 struct pdb_search *result;
1540 if (pdb == NULL) return NULL;
1542 result = pdb_search_init(PDB_ALIAS_SEARCH);
1543 if (result == NULL) return NULL;
1545 if (!pdb->search_aliases(pdb, result, sid)) {
1546 talloc_destroy(result->mem_ctx);
1552 uint32 pdb_search_entries(struct pdb_search *search,
1553 uint32 start_idx, uint32 max_entries,
1554 struct samr_displayentry **result)
1556 struct samr_displayentry *end_entry;
1557 uint32 end_idx = start_idx+max_entries-1;
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. */
1563 end_entry = pdb_search_getentry(search, end_idx);
1564 *result = pdb_search_getentry(search, start_idx);
1566 if (end_entry != NULL)
1569 if (start_idx >= search->num_entries)
1572 return search->num_entries - start_idx;
1575 void pdb_search_destroy(struct pdb_search *search)
1580 if (!search->search_ended)
1581 search->search_end(search);
1583 talloc_destroy(search->mem_ctx);
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 *******************************************************************/
1593 NTSTATUS make_pdb_method( struct pdb_methods **methods )
1595 /* allocate memory for the structure as its own talloc CTX */
1597 if ( !(*methods = TALLOC_ZERO_P(NULL, struct pdb_methods) ) ) {
1598 return NT_STATUS_NO_MEMORY;
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;
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;
1638 (*methods)->search_users = pdb_default_search_users;
1639 (*methods)->search_groups = pdb_default_search_groups;
1640 (*methods)->search_aliases = pdb_default_search_aliases;
1642 return NT_STATUS_OK;