diff options
Diffstat (limited to 'source3/passdb')
-rw-r--r-- | source3/passdb/passdb.c | 314 | ||||
-rw-r--r-- | source3/passdb/pdb_get_set.c | 42 | ||||
-rw-r--r-- | source3/passdb/pdb_guest.c | 70 | ||||
-rw-r--r-- | source3/passdb/pdb_ldap.c | 94 | ||||
-rw-r--r-- | source3/passdb/pdb_nisplus.c | 80 | ||||
-rw-r--r-- | source3/passdb/pdb_plugin.c | 78 | ||||
-rw-r--r-- | source3/passdb/pdb_smbpasswd.c | 57 | ||||
-rw-r--r-- | source3/passdb/pdb_tdb.c | 188 | ||||
-rw-r--r-- | source3/passdb/pdb_unix.c | 131 | ||||
-rw-r--r-- | source3/passdb/pdb_xml.c | 2 |
10 files changed, 660 insertions, 396 deletions
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index aa378ecd6e..bbccb86d82 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -5,7 +5,6 @@ Copyright (C) Luke Kenneth Casson Leighton 1996-1998 Copyright (C) Gerald (Jerry) Carter 2000-2001 Copyright (C) Andrew Bartlett 2001-2002 - Copyright (C) Simo Sorce 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -37,7 +36,7 @@ Fill the SAM_ACCOUNT with default values. ***********************************************************/ -void pdb_fill_default_sam(SAM_ACCOUNT *user) +static void pdb_fill_default_sam(SAM_ACCOUNT *user) { ZERO_STRUCT(user->private); /* Don't touch the talloc context */ @@ -47,6 +46,8 @@ void pdb_fill_default_sam(SAM_ACCOUNT *user) /* Don't change these timestamp settings without a good reason. They are important for NT member server compatibility. */ + user->private.uid = user->private.gid = -1; + user->private.logon_time = (time_t)0; user->private.pass_last_set_time = (time_t)0; user->private.pass_can_change_time = (time_t)0; @@ -162,7 +163,13 @@ NTSTATUS pdb_init_sam(SAM_ACCOUNT **user) NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd) { - NTSTATUS ret; + GROUP_MAP map; + + const char *guest_account = lp_guestaccount(); + if (!(guest_account && *guest_account)) { + DEBUG(1, ("NULL guest account!?!?\n")); + return NT_STATUS_UNSUCCESSFUL; + } if (!pwd) { return NT_STATUS_UNSUCCESSFUL; @@ -176,6 +183,9 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd) pdb_set_unix_homedir(sam_account, pwd->pw_dir, PDB_SET); pdb_set_domain (sam_account, lp_workgroup(), PDB_DEFAULT); + + pdb_set_uid(sam_account, pwd->pw_uid, PDB_SET); + pdb_set_gid(sam_account, pwd->pw_gid, PDB_SET); /* When we get a proper uid -> SID and SID -> uid allocation mechinism, we should call it here. @@ -187,8 +197,37 @@ NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd) -- abartlet 11-May-02 */ - ret = pdb_set_sam_sids(sam_account, pwd); - if (NT_STATUS_IS_ERR(ret)) return ret; + + /* Ensure this *must* be set right */ + if (strcmp(pwd->pw_name, guest_account) == 0) { + if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST, PDB_SET)) { + return NT_STATUS_UNSUCCESSFUL; + } + if (!pdb_set_group_sid_from_rid(sam_account, DOMAIN_GROUP_RID_GUESTS, PDB_SET)) { + return NT_STATUS_UNSUCCESSFUL; + } + } else { + + if (!pdb_set_user_sid_from_rid(sam_account, + fallback_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) { + DEBUG(0,("Can't set User SID from RID!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + /* call the mapping code here */ + if(pdb_getgrgid(&map, pwd->pw_gid, MAPPING_WITHOUT_PRIV)) { + if (!pdb_set_group_sid(sam_account,&map.sid, PDB_SET)){ + DEBUG(0,("Can't set Group SID!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + } + else { + if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) { + DEBUG(0,("Can't set Group SID\n")); + return NT_STATUS_INVALID_PARAMETER; + } + } + } /* check if this is a user account or a machine account */ if (pwd->pw_name[strlen(pwd->pw_name)-1] != '$') @@ -281,7 +320,6 @@ NTSTATUS pdb_init_sam_new(SAM_ACCOUNT **new_sam_acct, const char *username) return nt_status; } } else { - DOM_SID g_sid; if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) { *new_sam_acct = NULL; return nt_status; @@ -290,13 +328,6 @@ NTSTATUS pdb_init_sam_new(SAM_ACCOUNT **new_sam_acct, const char *username) pdb_free_sam(new_sam_acct); return nt_status; } - - pdb_set_domain (*new_sam_acct, lp_workgroup(), PDB_DEFAULT); - - /* set Domain Users by default ! */ - sid_copy(&g_sid, get_global_sam_sid()); - sid_append_rid(&g_sid, DOMAIN_GROUP_RID_USERS); - pdb_set_group_sid(*new_sam_acct, &g_sid, PDB_SET); } return NT_STATUS_OK; } @@ -369,63 +400,6 @@ NTSTATUS pdb_free_sam(SAM_ACCOUNT **user) return NT_STATUS_OK; } -/************************************************************************** - * This function will take care of all the steps needed to correctly - * allocate and set the user SID, please do use this function to create new - * users, messing with SIDs is not good. - * - * account_data must be provided initialized, pwd may be null. - * SSS - ***************************************************************************/ - -NTSTATUS pdb_set_sam_sids(SAM_ACCOUNT *account_data, const struct passwd *pwd) -{ - const char *guest_account = lp_guestaccount(); - GROUP_MAP map; - - if (!account_data || !pwd) { - return NT_STATUS_INVALID_PARAMETER; - } - - /* this is a hack this thing should not be set - this way --SSS */ - if (!(guest_account && *guest_account)) { - DEBUG(1, ("NULL guest account!?!?\n")); - return NT_STATUS_UNSUCCESSFUL; - } else { - /* Ensure this *must* be set right */ - if (strcmp(pwd->pw_name, guest_account) == 0) { - if (!pdb_set_user_sid_from_rid(account_data, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) { - return NT_STATUS_UNSUCCESSFUL; - } - if (!pdb_set_group_sid_from_rid(account_data, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT)) { - return NT_STATUS_UNSUCCESSFUL; - } - return NT_STATUS_OK; - } - } - - if (!pdb_set_user_sid_from_rid(account_data, fallback_pdb_uid_to_user_rid(pwd->pw_uid), PDB_SET)) { - DEBUG(0,("Can't set User SID from RID!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - - /* call the mapping code here */ - if(pdb_getgrgid(&map, pwd->pw_gid, MAPPING_WITHOUT_PRIV)) { - if (!pdb_set_group_sid(account_data, &map.sid, PDB_SET)){ - DEBUG(0,("Can't set Group SID!\n")); - return NT_STATUS_INVALID_PARAMETER; - } - } - else { - if (!pdb_set_group_sid_from_rid(account_data, pdb_gid_to_group_rid(pwd->pw_gid), PDB_SET)) { - DEBUG(0,("Can't set Group SID\n")); - return NT_STATUS_INVALID_PARAMETER; - } - } - - return NT_STATUS_OK; -} /********************************************************** Encode the account control bits into a string. @@ -555,6 +529,10 @@ BOOL pdb_gethexpwd(const char *p, unsigned char *pwd) return (True); } +/******************************************************************* + Converts NT user RID to a UNIX uid. + ********************************************************************/ + static int algorithmic_rid_base(void) { static int rid_offset = 0; @@ -577,16 +555,14 @@ static int algorithmic_rid_base(void) return rid_offset; } -/******************************************************************* - Converts NT user RID to a UNIX uid. - ********************************************************************/ uid_t fallback_pdb_user_rid_to_uid(uint32 user_rid) { int rid_offset = algorithmic_rid_base(); - return (uid_t)(((user_rid & (~USER_RID_TYPE)) - rid_offset)/RID_MULTIPLIER); + return (uid_t)(((user_rid & (~USER_RID_TYPE))- rid_offset)/RID_MULTIPLIER); } + /******************************************************************* converts UNIX uid to an NT User RID. ********************************************************************/ @@ -637,7 +613,7 @@ static BOOL pdb_rid_is_well_known(uint32 rid) Decides if a RID is a user or group RID. ********************************************************************/ -BOOL fallback_pdb_rid_is_user(uint32 rid) +BOOL pdb_rid_is_user(uint32 rid) { /* lkcl i understand that NT attaches an enumeration to a RID * such that it can be identified as either a user, group etc @@ -670,7 +646,7 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use GROUP_MAP map; if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){ - DEBUG(0,("local_lookup_sid: sid_peek_check_rid return False! SID: %s\n", + DEBUG(0,("local_sid_to_gid: sid_peek_check_rid return False! SID: %s\n", sid_string_static(&map.sid))); return False; } @@ -727,7 +703,7 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use return True; } - if (fallback_pdb_rid_is_user(rid)) { + if (pdb_rid_is_user(rid)) { uid_t uid; DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid)); @@ -860,6 +836,190 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi return True; } +/**************************************************************************** + Convert a uid to SID - locally. +****************************************************************************/ + +DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid) +{ + struct passwd *pass; + SAM_ACCOUNT *sam_user = NULL; + fstring str; /* sid string buffer */ + + sid_copy(psid, get_global_sam_sid()); + + if((pass = getpwuid_alloc(uid))) { + + if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user))) { + passwd_free(&pass); + return NULL; + } + + if (pdb_getsampwnam(sam_user, pass->pw_name)) { + sid_copy(psid, pdb_get_user_sid(sam_user)); + } else { + sid_append_rid(psid, fallback_pdb_uid_to_user_rid(uid)); + } + + DEBUG(10,("local_uid_to_sid: uid %u -> SID (%s) (%s).\n", + (unsigned)uid, sid_to_string( str, psid), + pass->pw_name )); + + passwd_free(&pass); + pdb_free_sam(&sam_user); + + } else { + sid_append_rid(psid, fallback_pdb_uid_to_user_rid(uid)); + + DEBUG(10,("local_uid_to_sid: uid %u -> SID (%s) (unknown user).\n", + (unsigned)uid, sid_to_string( str, psid))); + } + + return psid; +} + +/**************************************************************************** + Convert a SID to uid - locally. +****************************************************************************/ + +BOOL local_sid_to_uid(uid_t *puid, const DOM_SID *psid, enum SID_NAME_USE *name_type) +{ + fstring str; + SAM_ACCOUNT *sam_user = NULL; + + *name_type = SID_NAME_UNKNOWN; + + if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user))) + return False; + + if (pdb_getsampwsid(sam_user, psid)) { + + if (!IS_SAM_SET(sam_user,PDB_UID)&&!IS_SAM_CHANGED(sam_user,PDB_UID)) { + pdb_free_sam(&sam_user); + return False; + } + + *puid = pdb_get_uid(sam_user); + + DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid), + (unsigned int)*puid, pdb_get_username(sam_user))); + pdb_free_sam(&sam_user); + } else { + + DOM_SID dom_sid; + uint32 rid; + GROUP_MAP map; + + pdb_free_sam(&sam_user); + + if (pdb_getgrsid(&map, *psid, MAPPING_WITHOUT_PRIV)) { + DEBUG(3, ("local_sid_to_uid: SID '%s' is a group, not a user... \n", sid_to_string(str, psid))); + /* It's a group, not a user... */ + return False; + } + + sid_copy(&dom_sid, psid); + if (!sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) { + DEBUG(3, ("sid_peek_rid failed - sid '%s' is not in our domain\n", sid_to_string(str, psid))); + return False; + } + + if (!pdb_rid_is_user(rid)) { + DEBUG(3, ("local_sid_to_uid: sid '%s' cannot be mapped to a uid algorithmicly becouse it is a group\n", sid_to_string(str, psid))); + return False; + } + + *puid = fallback_pdb_user_rid_to_uid(rid); + + DEBUG(5,("local_sid_to_uid: SID %s algorithmicly mapped to %ld mapped becouse SID was not found in passdb.\n", + sid_to_string(str, psid), (signed long int)(*puid))); + } + + *name_type = SID_NAME_USER; + + return True; +} + +/**************************************************************************** + Convert a gid to SID - locally. +****************************************************************************/ + +DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid) +{ + GROUP_MAP map; + + sid_copy(psid, get_global_sam_sid()); + + if (pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) { + sid_copy(psid, &map.sid); + } + else { + sid_append_rid(psid, pdb_gid_to_group_rid(gid)); + } + + return psid; +} + +/**************************************************************************** + Convert a SID to gid - locally. +****************************************************************************/ + +BOOL local_sid_to_gid(gid_t *pgid, const DOM_SID *psid, enum SID_NAME_USE *name_type) +{ + fstring str; + GROUP_MAP map; + + *name_type = SID_NAME_UNKNOWN; + + /* + * We can only convert to a gid if this is our local + * Domain SID (ie. we are the controling authority). + * + * Or in the Builtin SID too. JFM, 11/30/2001 + */ + + if (pdb_getgrsid(&map, *psid, MAPPING_WITHOUT_PRIV)) { + + /* the SID is in the mapping table but not mapped */ + if (map.gid==(gid_t)-1) + return False; + + *pgid = map.gid; + *name_type = map.sid_name_use; + DEBUG(10,("local_sid_to_gid: mapped SID %s (%s) -> gid (%u).\n", + sid_to_string( str, psid), + map.nt_name, (unsigned int)*pgid)); + + } else { + uint32 rid; + SAM_ACCOUNT *sam_user = NULL; + if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user))) + return False; + + if (pdb_getsampwsid(sam_user, psid)) { + return False; + pdb_free_sam(&sam_user); + } + + pdb_free_sam(&sam_user); + + if (!sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) { + DEBUG(3, ("sid_peek_rid failed - sid '%s' is not in our domain\n", sid_to_string(str, psid))); + return False; + } + + if (pdb_rid_is_user(rid)) + return False; + + *pgid = pdb_group_rid_to_gid(rid); + *name_type = SID_NAME_ALIAS; + DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u).\n", sid_to_string( str, psid), + (unsigned int)*pgid)); + } + + return True; +} + /************************************************************* Change a password entry in the local smbpasswd file. diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index 4370dc2c36..a86d936263 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -202,6 +202,22 @@ enum pdb_value_state pdb_get_init_flags (const SAM_ACCOUNT *sampass, enum pdb_el return ret; } +uid_t pdb_get_uid (const SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->private.uid); + else + return (-1); +} + +gid_t pdb_get_gid (const SAM_ACCOUNT *sampass) +{ + if (sampass) + return (sampass->private.gid); + else + return (-1); +} + const char* pdb_get_username (const SAM_ACCOUNT *sampass) { if (sampass) @@ -493,6 +509,32 @@ BOOL pdb_set_init_flags (SAM_ACCOUNT *sampass, enum pdb_elements element, enum p return True; } +BOOL pdb_set_uid (SAM_ACCOUNT *sampass, const uid_t uid, enum pdb_value_state flag) +{ + if (!sampass) + return False; + + DEBUG(10, ("pdb_set_uid: setting uid %d, was %d\n", + (int)uid, (int)sampass->private.uid)); + + sampass->private.uid = uid; + + return pdb_set_init_flags(sampass, PDB_UID, flag); +} + +BOOL pdb_set_gid (SAM_ACCOUNT *sampass, const gid_t gid, enum pdb_value_state flag) +{ + if (!sampass) + return False; + + DEBUG(10, ("pdb_set_gid: setting gid %d, was %d\n", + (int)gid, (int)sampass->private.gid)); + + sampass->private.gid = gid; + + return pdb_set_init_flags(sampass, PDB_GID, flag); +} + BOOL pdb_set_user_sid (SAM_ACCOUNT *sampass, DOM_SID *u_sid, enum pdb_value_state flag) { if (!sampass || !u_sid) diff --git a/source3/passdb/pdb_guest.c b/source3/passdb/pdb_guest.c index 9bcdccc7e7..7ecfa7d4c3 100644 --- a/source3/passdb/pdb_guest.c +++ b/source3/passdb/pdb_guest.c @@ -24,16 +24,11 @@ Lookup a name in the SAM database ******************************************************************/ -static NTSTATUS guestsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *sam_account, const char *sname) +static NTSTATUS guestsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname) { NTSTATUS nt_status; + struct passwd *pass; const char *guest_account = lp_guestaccount(); - - if (!sam_account || !sname) { - DEBUG(0,("invalid name specified")); - return NT_STATUS_UNSUCCESSFUL; - } - if (!(guest_account && *guest_account)) { DEBUG(1, ("NULL guest account!?!?\n")); return NT_STATUS_UNSUCCESSFUL; @@ -43,31 +38,21 @@ static NTSTATUS guestsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT * DEBUG(0,("invalid methods\n")); return NT_STATUS_UNSUCCESSFUL; } + if (!sname) { + DEBUG(0,("invalid name specified")); + return NT_STATUS_UNSUCCESSFUL; + } + if (!strequal(guest_account, sname)) { return NT_STATUS_NO_SUCH_USER; } - pdb_fill_default_sam(sam_account); - - if (!pdb_set_username(sam_account, guest_account, PDB_SET)) - return NT_STATUS_UNSUCCESSFUL; - - if (!pdb_set_fullname(sam_account, guest_account, PDB_SET)) - return NT_STATUS_UNSUCCESSFUL; - - if (!pdb_set_domain(sam_account, lp_workgroup(), PDB_DEFAULT)) - return NT_STATUS_UNSUCCESSFUL; - - if (!pdb_set_acct_ctrl(sam_account, ACB_NORMAL, PDB_DEFAULT)) - return NT_STATUS_UNSUCCESSFUL; - - if (!pdb_set_user_sid_from_rid(sam_account, DOMAIN_USER_RID_GUEST, PDB_DEFAULT)) - return NT_STATUS_UNSUCCESSFUL; - - if (!pdb_set_group_sid_from_rid(sam_account, DOMAIN_GROUP_RID_GUESTS, PDB_DEFAULT)) - return NT_STATUS_UNSUCCESSFUL; + pass = getpwnam_alloc(guest_account); - return NT_STATUS_OK; + nt_status = pdb_fill_sam_pw(user, pass); + + passwd_free(&pass); + return nt_status; } @@ -76,17 +61,35 @@ static NTSTATUS guestsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT * **************************************************************************/ static NTSTATUS guestsam_getsampwrid (struct pdb_methods *methods, - SAM_ACCOUNT *sam_account, uint32 rid) + SAM_ACCOUNT *user, uint32 rid) { - if (rid != DOMAIN_USER_RID_GUEST) { - return NT_STATUS_NO_SUCH_USER; + NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct passwd *pass = NULL; + const char *guest_account = lp_guestaccount(); + if (!(guest_account && *guest_account)) { + DEBUG(1, ("NULL guest account!?!?\n")); + return nt_status; } - if (!sam_account) { - return NT_STATUS_INVALID_PARAMETER; + if (!methods) { + DEBUG(0,("invalid methods\n")); + return nt_status; + } + + if (rid == DOMAIN_USER_RID_GUEST) { + pass = getpwnam_alloc(guest_account); + if (!pass) { + DEBUG(1, ("guest account %s does not seem to exist...\n", guest_account)); + return NT_STATUS_NO_SUCH_USER; + } + } else { + return NT_STATUS_NO_SUCH_USER; } - return guestsam_getsampwnam (methods, sam_account, lp_guestaccount()); + nt_status = pdb_fill_sam_pw(user, pass); + passwd_free(&pass); + + return nt_status; } static NTSTATUS guestsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid) @@ -94,7 +97,6 @@ static NTSTATUS guestsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT uint32 rid; if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) return NT_STATUS_NO_SUCH_USER; - return guestsam_getsampwrid(my_methods, user, rid); } diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index b23b7286ea..4abc7b569c 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -1533,11 +1533,12 @@ Initialize SAM_ACCOUNT from an LDAP query (unix attributes only) *********************************************************************/ static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state, SAM_ACCOUNT * sampass, - LDAPMessage * entry, - gid_t *gid) + LDAPMessage * entry) { pstring homedir; pstring temp; + uid_t uid; + gid_t gid; char **ldap_values; char **values; @@ -1562,12 +1563,19 @@ static BOOL get_unix_attributes (struct ldapsam_privates *ldap_state, if (!get_single_attribute(ldap_state->ldap_struct, entry, "homeDirectory", homedir)) return False; + if (!get_single_attribute(ldap_state->ldap_struct, entry, "uidNumber", temp)) + return False; + + uid = (uid_t)atol(temp); + if (!get_single_attribute(ldap_state->ldap_struct, entry, "gidNumber", temp)) return False; gid = (gid_t)atol(temp); pdb_set_unix_homedir(sampass, homedir, PDB_SET); + pdb_set_uid(sampass, uid, PDB_SET); + pdb_set_gid(sampass, gid, PDB_SET); DEBUG(10, ("user has posixAcccount attributes\n")); return True; @@ -1609,7 +1617,8 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, uint8 hours[MAX_HOURS_LEN]; pstring temp; uid_t uid = -1; - gid_t gid = getegid(); + gid_t gid = getegid(); + /* * do a little initialization @@ -1681,17 +1690,40 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state, * If so configured, try and get the values from LDAP */ - if (!lp_ldap_trust_ids() && (get_unix_attributes(ldap_state, sampass, entry, &gid))) { + if (!lp_ldap_trust_ids() || (!get_unix_attributes(ldap_state, sampass, entry))) { - if (pdb_get_init_flags(sampass,PDB_GROUPSID) == PDB_DEFAULT) { - GROUP_MAP map; - /* call the mapping code here */ - if(pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) { - pdb_set_group_sid(sampass, &map.sid, PDB_SET); - } - else { - pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid), PDB_SET); + /* + * Otherwise just ask the system getpw() calls. + */ + + pw = getpwnam_alloc(username); + if (pw == NULL) { + if (! ldap_state->permit_non_unix_accounts) { + DEBUG (2,("init_sam_from_ldap: User [%s] does not exist via system getpwnam!\n", username)); + return False; } + } else { + uid = pw->pw_uid; + pdb_set_uid(sampass, uid, PDB_SET); + gid = pw->pw_gid; + pdb_set_gid(sampass, gid, PDB_SET); + + pdb_set_unix_homedir(sampass, pw->pw_dir, PDB_SET); + + passwd_free(&pw); + } + } + + if ((pdb_get_init_flags(sampass,PDB_GROUPSID) == PDB_DEFAULT) + && (pdb_get_init_flags(sampass,PDB_GID) != PDB_DEFAULT)) { + GROUP_MAP map; + gid = pdb_get_gid(sampass); + /* call the mapping code here */ + if(pdb_getgrgid(&map, gid, MAPPING_WITHOUT_PRIV)) { + pdb_set_group_sid(sampass, &map.sid, PDB_SET); + } + else { + pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid), PDB_SET); } } @@ -3069,7 +3101,7 @@ static NTSTATUS ldapsam_enum_group_mapping(struct pdb_methods *methods, return NT_STATUS_OK; } -static NTSTATUS pdb_init_ldapsam_common(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { NTSTATUS nt_status; struct ldapsam_privates *ldap_state; @@ -3133,7 +3165,7 @@ static NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS ** NTSTATUS nt_status; struct ldapsam_privates *ldap_state; - if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) { + if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location))) { return nt_status; } @@ -3165,54 +3197,50 @@ static NTSTATUS pdb_init_ldapsam_compat(PDB_CONTEXT *pdb_context, PDB_METHODS ** return NT_STATUS_OK; } -static NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +static NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { NTSTATUS nt_status; struct ldapsam_privates *ldap_state; - uint32 low_idmap_uid, high_idmap_uid; - uint32 low_idmap_gid, high_idmap_gid; + uint32 low_winbind_uid, high_winbind_uid; + uint32 low_winbind_gid, high_winbind_gid; - if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam_common(pdb_context, pdb_method, location))) { + if (!NT_STATUS_IS_OK(nt_status = pdb_init_ldapsam(pdb_context, pdb_method, location))) { return nt_status; } - (*pdb_method)->name = "ldapsam"; + (*pdb_method)->name = "ldapsam_nua"; ldap_state = (*pdb_method)->private_data; ldap_state->permit_non_unix_accounts = True; /* We know these uids can't turn up as allogorithmic RIDs */ - if (!lp_idmap_uid(&low_idmap_uid, &high_idmap_uid)) { - DEBUG(0, ("cannot use ldapsam_nua without 'idmap uid' range in smb.conf!\n")); + if (!lp_winbind_uid(&low_winbind_uid, &high_winbind_uid)) { + DEBUG(0, ("cannot use ldapsam_nua without 'winbind uid' range in smb.conf!\n")); return NT_STATUS_UNSUCCESSFUL; } /* We know these gids can't turn up as allogorithmic RIDs */ - if (!lp_idmap_gid(&low_idmap_gid, &high_idmap_gid)) { + if (!lp_winbind_gid(&low_winbind_gid, &high_winbind_gid)) { DEBUG(0, ("cannot use ldapsam_nua without 'wibnind gid' range in smb.conf!\n")); return NT_STATUS_UNSUCCESSFUL; } - ldap_state->low_allocated_user_rid=fallback_pdb_uid_to_user_rid(low_idmap_uid); + ldap_state->low_allocated_user_rid=fallback_pdb_uid_to_user_rid(low_winbind_uid); - ldap_state->high_allocated_user_rid=fallback_pdb_uid_to_user_rid(high_idmap_uid); + ldap_state->high_allocated_user_rid=fallback_pdb_uid_to_user_rid(high_winbind_uid); - ldap_state->low_allocated_group_rid=pdb_gid_to_group_rid(low_idmap_gid); + ldap_state->low_allocated_group_rid=pdb_gid_to_group_rid(low_winbind_gid); - ldap_state->high_allocated_group_rid=pdb_gid_to_group_rid(high_idmap_gid); + ldap_state->high_allocated_group_rid=pdb_gid_to_group_rid(high_winbind_gid); return NT_STATUS_OK; } NTSTATUS pdb_ldap_init(void) { - NTSTATUS nt_status; - if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam", pdb_init_ldapsam))) - return nt_status; - - if (!NT_STATUS_IS_OK(nt_status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam_compat", pdb_init_ldapsam_compat))) - return nt_status; - + smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam", pdb_init_ldapsam); + smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam_compat", pdb_init_ldapsam_compat); + smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam_nua", pdb_init_ldapsam_nua); return NT_STATUS_OK; } diff --git a/source3/passdb/pdb_nisplus.c b/source3/passdb/pdb_nisplus.c index 4e4aaed02b..cd9288fed0 100644 --- a/source3/passdb/pdb_nisplus.c +++ b/source3/passdb/pdb_nisplus.c @@ -876,6 +876,8 @@ static BOOL make_sam_from_nisp_object (SAM_ACCOUNT * pw_buf, pdb_set_workstations (pw_buf, ENTRY_VAL (obj, NPF_WORKSTATIONS), PDB_SET); pdb_set_munged_dial (pw_buf, NULL, PDB_DEFAULT); + pdb_set_uid (pw_buf, atoi (ENTRY_VAL (obj, NPF_UID)), PDB_SET); + pdb_set_gid (pw_buf, atoi (ENTRY_VAL (obj, NPF_SMB_GRPID)), PDB_SET); pdb_set_user_sid_from_rid (pw_buf, atoi (ENTRY_VAL (obj, NPF_USER_RID)), PDB_SET); pdb_set_group_sid_from_rid (pw_buf, @@ -947,8 +949,8 @@ static BOOL make_sam_from_nisp_object (SAM_ACCOUNT * pw_buf, if (!(pdb_get_acct_ctrl (pw_buf) & ACB_PWNOTREQ) && strncasecmp (ptr, "NO PASSWORD", 11)) { if (strlen (ptr) != 32 || !pdb_gethexpwd (ptr, smbntpwd)) { - DEBUG (0, ("malformed NT pwd entry:\ %s.\n", - pdb_get_username (pw_buf))); + DEBUG (0, ("malformed NT pwd entry:\ + uid = %d.\n", pdb_get_uid (pw_buf))); return False; } if (!pdb_set_nt_passwd (pw_buf, smbntpwd, PDB_SET)) @@ -1045,8 +1047,6 @@ static BOOL init_nisp_from_sam (nis_object * obj, const SAM_ACCOUNT * sampass, BOOL need_to_modify = False; const char *name = pdb_get_username (sampass); /* from SAM */ - uint32 u_rid; - uint32 g_rid; /* these must be static or allocate and free entry columns! */ static fstring uid; /* from SAM */ static fstring user_rid; /* from SAM */ @@ -1065,15 +1065,31 @@ static BOOL init_nisp_from_sam (nis_object * obj, const SAM_ACCOUNT * sampass, static fstring acct_desc; /* from SAM */ static char empty[1]; /* just an empty string */ - if (!(u_rid = pdb_get_user_rid (sampass))) - return False; - if (!(g_rid = pdb_get_group_rid (sampass))) - return False; + slprintf (uid, sizeof (uid) - 1, "%u", pdb_get_uid (sampass)); + slprintf (user_rid, sizeof (user_rid) - 1, "%u", + pdb_get_user_rid (sampass) ? pdb_get_user_rid (sampass) : + fallback_pdb_uid_to_user_rid (pdb_get_uid (sampass))); + slprintf (gid, sizeof (gid) - 1, "%u", pdb_get_gid (sampass)); + + { + uint32 rid; + GROUP_MAP map; + + rid = pdb_get_group_rid (sampass); + + if (rid == 0) { + if (pdb_getgrgid(&map, pdb_get_gid (sampass), + MAPPING_WITHOUT_PRIV)) { + if (!sid_peek_check_rid + (get_global_sam_sid (), &map.sid, &rid)) + return False; + } else + rid = pdb_gid_to_group_rid (pdb_get_gid + (sampass)); + } - slprintf (uid, sizeof (uid) - 1, "%u", fallback_pdb_user_rid_to_uid (u_rid)); - slprintf (user_rid, sizeof (user_rid) - 1, "%u", u_rid); - slprintf (gid, sizeof (gid) - 1, "%u", fallback_pdb_group_rid_to_uid (g_rid)); - slprintf (group_rid, sizeof (group_rid) - 1, "%u", g_rid); + slprintf (group_rid, sizeof (group_rid) - 1, "%u", rid); + } acb = pdb_encode_acct_ctrl (pdb_get_acct_ctrl (sampass), NEW_PW_FORMAT_SPACE_PADDED_LEN); @@ -1117,27 +1133,51 @@ static BOOL init_nisp_from_sam (nis_object * obj, const SAM_ACCOUNT * sampass, /* uid */ - if (!ENTRY_VAL (old, NPF_UID) || strcmp (ENTRY_VAL (old, NPF_UID), uid)) { + if (pdb_get_uid (sampass) != -1) { + if (!ENTRY_VAL (old, NPF_UID) + || strcmp (ENTRY_VAL (old, NPF_UID), uid)) { need_to_modify = True; - set_single_attribute (obj, NPF_UID, uid, strlen (uid), EN_MODIFIED); + set_single_attribute (obj, NPF_UID, uid, + strlen (uid), + EN_MODIFIED); + } } /* user_rid */ - if (!ENTRY_VAL (old, NPF_USER_RID) || strcmp (ENTRY_VAL (old, NPF_USER_RID), user_rid)) { + if (pdb_get_user_rid (sampass)) { + if (!ENTRY_VAL (old, NPF_USER_RID) || + strcmp (ENTRY_VAL (old, NPF_USER_RID), + user_rid)) { need_to_modify = True; - set_single_attribute (obj, NPF_USER_RID, user_rid, strlen (user_rid), EN_MODIFIED); + set_single_attribute (obj, NPF_USER_RID, + user_rid, + strlen (user_rid), + EN_MODIFIED); + } } /* smb_grpid */ - if (!ENTRY_VAL (old, NPF_SMB_GRPID) || strcmp (ENTRY_VAL (old, NPF_SMB_GRPID), gid)) { + if (pdb_get_gid (sampass) != -1) { + if (!ENTRY_VAL (old, NPF_SMB_GRPID) || + strcmp (ENTRY_VAL (old, NPF_SMB_GRPID), gid)) { need_to_modify = True; - set_single_attribute (obj, NPF_SMB_GRPID, gid, strlen (gid), EN_MODIFIED); + set_single_attribute (obj, NPF_SMB_GRPID, gid, + strlen (gid), + EN_MODIFIED); + } } /* group_rid */ - if (!ENTRY_VAL (old, NPF_GROUP_RID) || strcmp (ENTRY_VAL (old, NPF_GROUP_RID), group_rid)) { + if (pdb_get_group_rid (sampass)) { + if (!ENTRY_VAL (old, NPF_GROUP_RID) || + strcmp (ENTRY_VAL (old, NPF_GROUP_RID), + group_rid)) { need_to_modify = True; - set_single_attribute (obj, NPF_GROUP_RID, group_rid, strlen (group_rid), EN_MODIFIED); + set_single_attribute (obj, NPF_GROUP_RID, + group_rid, + strlen (group_rid), + EN_MODIFIED); + } } /* acb */ diff --git a/source3/passdb/pdb_plugin.c b/source3/passdb/pdb_plugin.c new file mode 100644 index 0000000000..ea67da23a5 --- /dev/null +++ b/source3/passdb/pdb_plugin.c @@ -0,0 +1,78 @@ +/* + Unix SMB/CIFS implementation. + Loadable passdb module interface. + Copyright (C) Jelmer Vernooij 2002 + Copyright (C) Andrew Bartlett 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_PASSDB + +NTSTATUS pdb_init_plugin(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +{ + void * dl_handle; + char *plugin_location, *plugin_name, *p; + pdb_init_function plugin_init; + int (*plugin_version)(void); + + if (location == NULL) { + DEBUG(0, ("The plugin module needs an argument!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + plugin_name = smb_xstrdup(location); + p = strchr(plugin_name, ':'); + if (p) { + *p = 0; + plugin_location = p+1; + trim_string(plugin_location, " ", " "); + } else plugin_location = NULL; + trim_string(plugin_name, " ", " "); + + DEBUG(5, ("Trying to load sam plugin %s\n", plugin_name)); + dl_handle = sys_dlopen(plugin_name, RTLD_NOW ); + if (!dl_handle) { + DEBUG(0, ("Failed to load sam plugin %s using sys_dlopen (%s)\n", plugin_name, sys_dlerror())); + return NT_STATUS_UNSUCCESSFUL; + } + + plugin_version = sys_dlsym(dl_handle, "pdb_version"); + if (!plugin_version) { + sys_dlclose(dl_handle); + DEBUG(0, ("Failed to find function 'pdb_version' using sys_dlsym in sam plugin %s (%s)\n", plugin_name, sys_dlerror())); + return NT_STATUS_UNSUCCESSFUL; + } + + if (plugin_version() != PASSDB_INTERFACE_VERSION) { + sys_dlclose(dl_handle); + DEBUG(0, ("Wrong PASSDB_INTERFACE_VERSION! sam plugin has version %d and version %d is needed! Please update!\n", + plugin_version(),PASSDB_INTERFACE_VERSION)); + return NT_STATUS_UNSUCCESSFUL; + } + + plugin_init = sys_dlsym(dl_handle, "pdb_init"); + if (!plugin_init) { + sys_dlclose(dl_handle); + DEBUG(0, ("Failed to find function 'pdb_init' using sys_dlsym in sam plugin %s (%s)\n", plugin_name, sys_dlerror())); + return NT_STATUS_UNSUCCESSFUL; + } + + DEBUG(5, ("Starting sam plugin %s with location %s\n", plugin_name, plugin_location)); + return plugin_init(pdb_context, pdb_method, plugin_location); +} diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index 91fc7bc8e0..cd66cf269c 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -1134,23 +1134,28 @@ Error was %s\n", pwd->smb_name, pfile2, strerror(errno))); static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampass) { uid_t uid; - uint32 rid; if (sampass == NULL) return False; - rid = pdb_get_user_rid(sampass); - - /* If the user specified a RID, make sure its able to be both stored and retreived */ - if (rid && rid != DOMAIN_USER_RID_GUEST && uid != fallback_pdb_user_rid_to_uid(rid)) { - DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n")); - return False; - } - ZERO_STRUCTP(smb_pw); + + if (!IS_SAM_UNIX_USER(sampass)) { + smb_pw->smb_userid_set = False; + DEBUG(5,("build_smb_pass: storing user without a UNIX uid or gid. \n")); + } else { + uint32 rid = pdb_get_user_rid(sampass); + smb_pw->smb_userid_set = True; + uid = pdb_get_uid(sampass); - smb_pw->smb_userid_set = True; - smb_pw->smb_userid=uid; + /* If the user specified a RID, make sure its able to be both stored and retreived */ + if (rid && rid != DOMAIN_USER_RID_GUEST && uid != fallback_pdb_user_rid_to_uid(rid)) { + DEBUG(0,("build_sam_pass: Failing attempt to store user with non-uid based user RID. \n")); + return False; + } + + smb_pw->smb_userid=uid; + } smb_pw->smb_name=(const char*)pdb_get_username(sampass); @@ -1502,6 +1507,7 @@ static void free_private_data(void **vp) /* No need to free any further, as it is talloc()ed */ } + NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) { NTSTATUS nt_status; @@ -1548,16 +1554,35 @@ NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, (*pdb_method)->free_private_data = free_private_data; - if (lp_idmap_uid(&privates->low_nua_userid, &privates->high_nua_userid)) { - DEBUG(0, ("idmap uid range defined, non unix accounts enabled\n")); - privates->permit_non_unix_accounts = True; + return NT_STATUS_OK; +} + +NTSTATUS pdb_init_smbpasswd_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +{ + NTSTATUS nt_status; + struct smbpasswd_privates *privates; + + if (!NT_STATUS_IS_OK(nt_status = pdb_init_smbpasswd(pdb_context, pdb_method, location))) { + return nt_status; + } + + (*pdb_method)->name = "smbpasswd_nua"; + + privates = (*pdb_method)->private_data; + + privates->permit_non_unix_accounts = True; + + if (!lp_winbind_uid(&privates->low_nua_userid, &privates->high_nua_userid)) { + DEBUG(0, ("cannot use smbpasswd_nua without 'winbind uid' range in smb.conf!\n")); + return NT_STATUS_UNSUCCESSFUL; } return NT_STATUS_OK; } -int pdb_smbpasswd_init(void) +NTSTATUS pdb_smbpasswd_init(void) { smb_register_passdb(PASSDB_INTERFACE_VERSION, "smbpasswd", pdb_init_smbpasswd); - return True; + smb_register_passdb(PASSDB_INTERFACE_VERSION, "smbpasswd_nua", pdb_init_smbpasswd_nua); + return NT_STATUS_OK; } diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 74437cba6f..c3538042ee 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -101,7 +101,7 @@ static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state, BOOL ret = True; struct passwd *pw; uid_t uid = -1; - gid_t gid = -1; + gid_t gid = -1; /* This is what standard sub advanced expects if no gid is known */ if(sampass == NULL || buf == NULL) { DEBUG(0, ("init_sam_from_buffer: NULL parameters found!\n")); @@ -145,6 +145,30 @@ static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state, goto done; } + /* validate the account and fill in UNIX uid and gid. Standard + * getpwnam() is used instead of Get_Pwnam() as we do not need + * to try case permutations + */ + if (!username || !(pw = getpwnam_alloc(username))) { + if (!(tdb_state->permit_non_unix_accounts)) { + DEBUG(0,("tdbsam: getpwnam_alloc(%s) return NULL. User does not exist!\n", username)); + ret = False; + goto done; + } + } + + if (pw) { + uid = pw->pw_uid; + gid = pw->pw_gid; + + pdb_set_unix_homedir(sampass, pw->pw_dir, PDB_SET); + + passwd_free(&pw); + + pdb_set_uid(sampass, uid, PDB_SET); + pdb_set_gid(sampass, gid, PDB_SET); + } + pdb_set_logon_time(sampass, logon_time, PDB_SET); pdb_set_logoff_time(sampass, logoff_time, PDB_SET); pdb_set_kickoff_time(sampass, kickoff_time, PDB_SET); @@ -640,7 +664,7 @@ static NTSTATUS tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT return nt_status; } - fstrcpy(name, data.dptr); + fstrcpy (name, data.dptr); SAFE_FREE(data.dptr); tdb_close (pwd_tdb); @@ -744,40 +768,54 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, return False; } - if (!pdb_get_group_rid(newpwd)) { - DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",pdb_get_username(newpwd))); - ret = False; - goto done; - } - /* if flag == TDB_INSERT then make up a new RID else throw an error. */ if (!(user_rid = pdb_get_user_rid(newpwd))) { - if ((flag & TDB_INSERT) && tdb_state->permit_non_unix_accounts) { - uint32 lowrid, highrid; - if (!idmap_get_free_rid_range(&lowrid, &highrid)) { - /* should never happen */ - DEBUG(0, ("tdbsam: something messed up, no high/low rids but nua enabled ?!\n")); - ret = False; - goto done; - } - user_rid = lowrid; - tdb_ret = tdb_change_uint32_atomic(pwd_tdb, "RID_COUNTER", &user_rid, RID_MULTIPLIER); - if (!tdb_ret) { - ret = False; - goto done; + if (flag & TDB_INSERT) { + if (IS_SAM_UNIX_USER(newpwd)) { + if (tdb_state->algorithmic_rids) { + user_rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(newpwd)); + } else { + user_rid = BASE_RID; + tdb_ret = tdb_change_uint32_atomic(pwd_tdb, "RID_COUNTER", &user_rid, RID_MULTIPLIER); + if (!tdb_ret) { + ret = False; + goto done; + } + } + pdb_set_user_sid_from_rid(newpwd, user_rid, PDB_CHANGED); + } else { + user_rid = tdb_state->low_nua_rid; + tdb_ret = tdb_change_uint32_atomic(pwd_tdb, "NUA_RID_COUNTER", &user_rid, RID_MULTIPLIER); + if (!tdb_ret) { + ret = False; + goto done; + } + if (user_rid > tdb_state->high_nua_rid) { + DEBUG(0, ("tdbsam: no NUA rids available, cannot add user %s!\n", pdb_get_username(newpwd))); + ret = False; + goto done; + } + pdb_set_user_sid_from_rid(newpwd, user_rid, PDB_CHANGED); } - if (user_rid > highrid) { - DEBUG(0, ("tdbsam: no NUA rids available, cannot add user %s!\n", pdb_get_username(newpwd))); - ret = False; - goto done; - } - if (!pdb_set_user_sid_from_rid(newpwd, user_rid, PDB_CHANGED)) { - DEBUG(0, ("tdbsam: not able to set new allocated user RID into sam account!\n")); + } else { + DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a RID\n",pdb_get_username(newpwd))); + ret = False; + goto done; + } + } + + if (!pdb_get_group_rid(newpwd)) { + if (flag & TDB_INSERT) { + if (!tdb_state->permit_non_unix_accounts) { + DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",pdb_get_username(newpwd))); ret = False; goto done; + } else { + /* This seems like a good default choice for non-unix users */ + pdb_set_group_sid_from_rid(newpwd, DOMAIN_GROUP_RID_USERS, PDB_DEFAULT); } } else { - DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a RID\n",pdb_get_username(newpwd))); + DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",pdb_get_username(newpwd))); ret = False; goto done; } @@ -799,7 +837,7 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, /* setup the USER index key */ slprintf(keystr, sizeof(keystr)-1, "%s%s", USERPREFIX, name); key.dptr = keystr; - key.dsize = strlen(keystr) + 1; + key.dsize = strlen (keystr) + 1; /* add the account */ if (tdb_store(pwd_tdb, key, data, flag) != TDB_SUCCESS) { @@ -811,7 +849,7 @@ static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, } /* setup RID data */ - data.dsize = strlen(name) + 1; + data.dsize = sizeof(fstring); data.dptr = name; /* setup the RID index key */ @@ -836,49 +874,6 @@ done: return (ret); } -#if 0 -/*************************************************************************** - Allocates a new RID and returns it to the caller as a domain sid - - NOTE: Use carefullt, do not waste RIDs they are a limited resource! - - SSS - ***************************************************************************/ - -static NTSTATUS tdbsam_get_next_sid (struct pdb_methods *my_methods, DOM_SID *sid) -{ - NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; - struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data; - TDB_CONTEXT *pwd_tdb; - uint32 rid; - - if (sid == NULL) { - return NT_STATUS_INVALID_PARAMETER; - } - - pwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0600); - if (!pwd_tdb) - { - DEBUG(0, ("tdbsam_get_next_sid: Unable to open TDB passwd (%s)!\n", tdb_state->tdbsam_location)); - return NT_STATUS_UNSUCCESSFUL; - } - - rid = BASE_RID; - if (tdb_change_uint32_atomic(pwd_tdb, "RID_COUNTER", &rid, 1)) { - - sid_copy(sid, get_global_sam_sid()); - if (!sid_append_rid(sid, rid)) { - goto done; - } - - ret = NT_STATUS_OK; - } - -done: - tdb_close (pwd_tdb); - return ret; -} -#endif - /*************************************************************************** Modifies an existing SAM_ACCOUNT ****************************************************************************/ @@ -917,7 +912,14 @@ NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con { NTSTATUS nt_status; struct tdbsam_privates *tdb_state; - uint32 low_nua_uid, high_nua_uid; + +#if 0 /* when made a module use this */ + tdbsam_debug_level = debug_add_class("tdbsam"); + if(tdbsam_debug_level == -1) { + tdbsam_debug_level = DBGC_ALL; + DEBUG(0, ("tdbsam: Couldn't register custom debugging class!\n")); + } +#endif if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) { return nt_status; @@ -951,29 +953,47 @@ NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con tdb_state->tdbsam_location = talloc_strdup(pdb_context->mem_ctx, tdbfile); } + tdb_state->algorithmic_rids = True; + (*pdb_method)->private_data = tdb_state; (*pdb_method)->free_private_data = free_private_data; - if (lp_idmap_uid(&low_nua_uid, &high_nua_uid)) { - DEBUG(0, ("idmap uid range defined, non unix accounts enabled\n")); + return NT_STATUS_OK; +} - tdb_state->permit_non_unix_accounts = True; +NTSTATUS pdb_init_tdbsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) +{ + NTSTATUS nt_status; + struct tdbsam_privates *tdb_state; + uint32 low_nua_uid, high_nua_uid; - tdb_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid); + if (!NT_STATUS_IS_OK(nt_status = pdb_init_tdbsam(pdb_context, pdb_method, location))) { + return nt_status; + } - tdb_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid); + (*pdb_method)->name = "tdbsam_nua"; - } else { - tdb_state->algorithmic_rids = True; + tdb_state = (*pdb_method)->private_data; + + tdb_state->permit_non_unix_accounts = True; + + if (!lp_winbind_uid(&low_nua_uid, &high_nua_uid)) { + DEBUG(0, ("cannot use tdbsam_nua without 'winbind uid' range in smb.conf!\n")); + return NT_STATUS_UNSUCCESSFUL; } + tdb_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid); + + tdb_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid); + return NT_STATUS_OK; } -int pdb_tdbsam_init(void) +NTSTATUS pdb_tdbsam_init(void) { smb_register_passdb(PASSDB_INTERFACE_VERSION, "tdbsam", pdb_init_tdbsam); - return True; + smb_register_passdb(PASSDB_INTERFACE_VERSION, "tdbsam_nua", pdb_init_tdbsam_nua); + return NT_STATUS_OK; } diff --git a/source3/passdb/pdb_unix.c b/source3/passdb/pdb_unix.c deleted file mode 100644 index 395795758f..0000000000 --- a/source3/passdb/pdb_unix.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Unix password backend for samba - * Copyright (C) Jelmer Vernooij 2002 - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 675 - * Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "includes.h" - -/****************************************************************** - Lookup a name in the SAM database - ******************************************************************/ - -static NTSTATUS unixsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname) -{ - struct passwd *pass; - if (!methods) { - DEBUG(0,("invalid methods\n")); - return NT_STATUS_UNSUCCESSFUL; - } - if (!sname) { - DEBUG(0,("invalid name specified")); - return NT_STATUS_UNSUCCESSFUL; - } - pass = Get_Pwnam(sname); - - return pdb_fill_sam_pw(user, pass); -} - - -/*************************************************************************** - Search by rid - **************************************************************************/ - -static NTSTATUS unixsam_getsampwrid (struct pdb_methods *methods, - SAM_ACCOUNT *user, uint32 rid) -{ - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - struct passwd *pass = NULL; - const char *guest_account = lp_guestaccount(); - if (!(guest_account && *guest_account)) { - DEBUG(1, ("NULL guest account!?!?\n")); - return nt_status; - } - - if (!methods) { - DEBUG(0,("invalid methods\n")); - return nt_status; - } - - if (rid == DOMAIN_USER_RID_GUEST) { - pass = getpwnam_alloc(guest_account); - if (!pass) { - DEBUG(1, ("guest account %s does not seem to exist...\n", guest_account)); - return nt_status; - } - } else if (fallback_pdb_rid_is_user(rid)) { - pass = getpwuid_alloc(fallback_pdb_user_rid_to_uid (rid)); - } - - if (pass == NULL) { - return nt_status; - } - - nt_status = pdb_fill_sam_pw(user, pass); - passwd_free(&pass); - - return nt_status; -} - -static NTSTATUS unixsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const DOM_SID *sid) -{ - uint32 rid; - if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)) - return NT_STATUS_UNSUCCESSFUL; - return unixsam_getsampwrid(my_methods, user, rid); -} - -/*************************************************************************** - Updates a SAM_ACCOUNT - - This isn't a particulary practical option for pdb_unix. We certainly don't - want to twidde the filesystem, so what should we do? - - Current plan is to transparently add the account. It should appear - as if the pdb_unix version was modified, but its actually stored somehwere. - ****************************************************************************/ - -static NTSTATUS unixsam_update_sam_account (struct pdb_methods *methods, SAM_ACCOUNT *newpwd) -{ - return methods->parent->pdb_add_sam_account(methods->parent, newpwd); -} - -NTSTATUS pdb_init_unixsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location) -{ - NTSTATUS nt_status; - - if (!pdb_context) { - DEBUG(0, ("invalid pdb_context specified\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) { - return nt_status; - } - - (*pdb_method)->name = "unixsam"; - (*pdb_method)->update_sam_account = unixsam_update_sam_account; - (*pdb_method)->getsampwnam = unixsam_getsampwnam; - (*pdb_method)->getsampwsid = unixsam_getsampwsid; - - /* There's not very much to initialise here */ - return NT_STATUS_OK; -} - -NTSTATUS pdb_unix_init(void) -{ - return smb_register_passdb(PASSDB_INTERFACE_VERSION, "unixsam", pdb_init_unixsam); -} diff --git a/source3/passdb/pdb_xml.c b/source3/passdb/pdb_xml.c index 7a5c0e2b53..de2ee4594c 100644 --- a/source3/passdb/pdb_xml.c +++ b/source3/passdb/pdb_xml.c @@ -524,7 +524,7 @@ static NTSTATUS xmlsam_init(PDB_CONTEXT * pdb_context, PDB_METHODS ** pdb_method return nt_status; } - (*pdb_method)->name = "xmlsam"; + (*pdb_method)->name = "xml"; (*pdb_method)->setsampwent = xmlsam_setsampwent; (*pdb_method)->endsampwent = xmlsam_endsampwent; |