summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/passdb')
-rw-r--r--source3/passdb/passdb.c314
-rw-r--r--source3/passdb/pdb_get_set.c42
-rw-r--r--source3/passdb/pdb_guest.c70
-rw-r--r--source3/passdb/pdb_ldap.c94
-rw-r--r--source3/passdb/pdb_nisplus.c80
-rw-r--r--source3/passdb/pdb_plugin.c78
-rw-r--r--source3/passdb/pdb_smbpasswd.c57
-rw-r--r--source3/passdb/pdb_tdb.c188
-rw-r--r--source3/passdb/pdb_unix.c131
-rw-r--r--source3/passdb/pdb_xml.c2
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;