summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/passdb')
-rw-r--r--source3/passdb/passdb.c310
-rw-r--r--source3/passdb/pdb_get_set.c76
-rw-r--r--source3/passdb/pdb_interface.c16
-rw-r--r--source3/passdb/pdb_ldap.c50
-rw-r--r--source3/passdb/pdb_smbpasswd.c55
-rw-r--r--source3/passdb/pdb_tdb.c99
-rw-r--r--source3/passdb/pdb_unix.c126
7 files changed, 465 insertions, 267 deletions
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index d34866fa63..edae00389e 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -30,6 +30,7 @@
*/
extern DOM_SID global_sam_sid;
+extern pstring global_myname;
/************************************************************
Fill the SAM_ACCOUNT with default values.
@@ -150,32 +151,39 @@ NTSTATUS pdb_init_sam(SAM_ACCOUNT **user)
Initialises a struct sam_passwd with sane values.
************************************************************/
-NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
+NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
{
- pstring str;
GROUP_MAP map;
uint32 rid;
- NTSTATUS nt_status;
if (!pwd) {
- new_sam_acct = NULL;
return NT_STATUS_UNSUCCESSFUL;
}
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) {
- new_sam_acct = NULL;
- return nt_status;
- }
+ pdb_fill_default_sam(sam_account);
- pdb_set_username(*new_sam_acct, pwd->pw_name);
- pdb_set_fullname(*new_sam_acct, pwd->pw_gecos);
+ pdb_set_username(sam_account, pwd->pw_name);
+ pdb_set_fullname(sam_account, pwd->pw_gecos);
- pdb_set_uid(*new_sam_acct, pwd->pw_uid);
- pdb_set_gid(*new_sam_acct, pwd->pw_gid);
+ pdb_set_unix_homedir(sam_account, pwd->pw_dir);
+
+ pdb_set_domain (sam_account, lp_workgroup());
+
+ pdb_set_uid(sam_account, pwd->pw_uid);
+ pdb_set_gid(sam_account, pwd->pw_gid);
- /* let the backends set the rid!!
- pdb_set_user_rid(*new_sam_acct, pdb_uid_to_user_rid(pwd->pw_uid));
- -- simo */
+ /* When we get a proper uid -> SID and SID -> uid allocation
+ mechinism, we should call it here.
+
+ We can't just set this to 0 or allow it only to be filled
+ in when added to the backend, becouse the user's SID
+ may already be in security descriptors etc.
+
+ -- abartlet 11-May-02
+ */
+
+ pdb_set_user_rid(sam_account,
+ fallback_pdb_uid_to_user_rid(pwd->pw_uid));
/* call the mapping code here */
if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
@@ -185,24 +193,67 @@ NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
rid=pdb_gid_to_group_rid(pwd->pw_gid);
}
- pdb_set_group_rid(*new_sam_acct, rid);
+ pdb_set_group_rid(sam_account, rid);
+
+ /* check if this is a user account or a machine account */
+ if (pwd->pw_name[strlen(pwd->pw_name)-1] != '$')
+ {
+ pdb_set_profile_path(sam_account,
+ standard_sub_specified((sam_account)->mem_ctx,
+ lp_logon_path(),
+ pwd->pw_name, global_myname,
+ pwd->pw_uid, pwd->pw_gid),
+ False);
+
+ pdb_set_homedir(sam_account,
+ standard_sub_specified((sam_account)->mem_ctx,
+ lp_logon_home(),
+ pwd->pw_name, global_myname,
+ pwd->pw_uid, pwd->pw_gid),
+ False);
+
+ pdb_set_dir_drive(sam_account,
+ standard_sub_specified((sam_account)->mem_ctx,
+ lp_logon_drive(),
+ pwd->pw_name, global_myname,
+ pwd->pw_uid, pwd->pw_gid),
+ False);
+
+ pdb_set_logon_script(sam_account,
+ standard_sub_specified((sam_account)->mem_ctx,
+ lp_logon_script(),
+ pwd->pw_name, global_myname,
+ pwd->pw_uid, pwd->pw_gid),
+ False);
+ }
+ return NT_STATUS_OK;
+}
- pstrcpy(str, lp_logon_path());
- standard_sub_advanced(-1, pwd->pw_name, "", pwd->pw_gid, pwd->pw_name, str);
- pdb_set_profile_path(*new_sam_acct, str, False);
-
- pstrcpy(str, lp_logon_home());
- standard_sub_advanced(-1, pwd->pw_name, "", pwd->pw_gid, pwd->pw_name, str);
- pdb_set_homedir(*new_sam_acct, str, False);
-
- pstrcpy(str, lp_logon_drive());
- standard_sub_advanced(-1, pwd->pw_name, "", pwd->pw_gid, pwd->pw_name, str);
- pdb_set_dir_drive(*new_sam_acct, str, False);
- pstrcpy(str, lp_logon_script());
- standard_sub_advanced(-1, pwd->pw_name, "", pwd->pw_gid, pwd->pw_name, str);
- pdb_set_logon_script(*new_sam_acct, str, False);
-
+/*************************************************************
+ Initialises a struct sam_passwd with sane values.
+ ************************************************************/
+
+NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
+{
+ NTSTATUS nt_status;
+
+ if (!pwd) {
+ new_sam_acct = NULL;
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) {
+ new_sam_acct = NULL;
+ return nt_status;
+ }
+
+ if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*new_sam_acct, pwd))) {
+ pdb_free_sam(new_sam_acct);
+ new_sam_acct = NULL;
+ return nt_status;
+ }
+
return NT_STATUS_OK;
}
@@ -210,18 +261,21 @@ NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
/**
* Free the contets of the SAM_ACCOUNT, but not the structure.
*
- * Also wipes the LM and NT hashes from memory.
+ * Also wipes the LM and NT hashes and plaintext passwrod from
+ * memory.
*
* @param user SAM_ACCOUNT to free members of.
**/
static void pdb_free_sam_contents(SAM_ACCOUNT *user)
{
- /* As we start mallocing more strings this is where
- we should free them. */
+
+ /* Kill off sensitive data. Free()ed by the
+ talloc mechinism */
data_blob_clear_free(&(user->private.lm_pw));
data_blob_clear_free(&(user->private.nt_pw));
+ data_blob_clear_free(&(user->private.plaintext_pw));
}
@@ -519,12 +573,8 @@ BOOL pdb_rid_is_user(uint32 rid)
BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use)
{
uint32 rid;
- BOOL is_user;
SAM_ACCOUNT *sam_account = NULL;
- uid_t uid;
- struct passwd *pass;
GROUP_MAP map;
-
sid_peek_rid(sid, &rid);
*psid_name_use = SID_NAME_UNKNOWN;
@@ -564,6 +614,7 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
return False;
}
+ /* This now does the 'generic' mapping in pdb_unix */
if (pdb_getsampwrid(sam_account, rid)) {
fstrcpy(name, pdb_get_username(sam_account));
*psid_name_use = SID_NAME_USER;
@@ -572,47 +623,36 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
return True;
}
-
+
pdb_free_sam(&sam_account);
if (get_group_map_from_sid(*sid, &map, MAPPING_WITHOUT_PRIV)) {
if (map.gid!=-1) {
DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid));
- fstrcpy(name, map.nt_name);
- *psid_name_use = map.sid_name_use;
- return True;
+ } else {
+ DEBUG(5,("local_lookup_sid: mapped group %s to no unix gid. Returning name.\n", map.nt_name));
}
- }
-
- is_user = pdb_rid_is_user(rid);
- DEBUG(5, ("assuming RID %u is a %s\n", (unsigned)rid, is_user ? "user" : "group"));
+ fstrcpy(name, map.nt_name);
+ *psid_name_use = map.sid_name_use;
+ return True;
+ }
if (pdb_rid_is_user(rid)) {
- uid = fallback_pdb_user_rid_to_uid(rid);
- pass = getpwuid_alloc(uid);
-
- *psid_name_use = SID_NAME_USER;
-
- DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid,
- pass ? "succeeded" : "failed" ));
-
- if(!pass) {
- slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid);
- return True;
- }
-
- fstrcpy(name, pass->pw_name);
-
- DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name,
- (unsigned int)rid ));
-
- passwd_free(&pass);
-
+ uid_t uid;
+
+ DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid));
+
+ uid = fallback_pdb_user_rid_to_uid(rid);
+ slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid);
+
+ return False; /* Indicates that this user was 'not mapped' */
} else {
gid_t gid;
struct group *gr;
+ DEBUG(5, ("assuming RID %u is a group\n", (unsigned)rid));
+
gid = pdb_group_rid_to_gid(rid);
gr = getgrgid(gid);
@@ -623,15 +663,15 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
if(!gr) {
slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid);
- return False;
+ return False; /* Indicates that this group was 'not mapped' */
}
fstrcpy( name, gr->gr_name);
DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name,
(unsigned int)rid ));
+ return True;
}
- return True;
}
/*******************************************************************
@@ -641,11 +681,12 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
{
extern DOM_SID global_sid_World_Domain;
- struct passwd *pass = NULL;
DOM_SID local_sid;
fstring user;
SAM_ACCOUNT *sam_account = NULL;
-
+ struct group *grp;
+ GROUP_MAP map;
+
*psid_name_use = SID_NAME_UNKNOWN;
/*
@@ -691,52 +732,45 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
pdb_free_sam(&sam_account);
- if ((pass = Get_Pwnam(user))) {
- sid_append_rid( &local_sid, fallback_pdb_uid_to_user_rid(pass->pw_uid));
- *psid_name_use = SID_NAME_USER;
+ /*
+ * Maybe it was a group ?
+ */
+ /* check if it's a mapped group */
+ if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) {
+ if (map.gid!=-1) {
+ /* yes it's a mapped group to a valid unix group */
+ sid_copy(&local_sid, &map.sid);
+ *psid_name_use = map.sid_name_use;
+ }
+ else {
+ /* it's a correct name but not mapped so it points to nothing*/
+ return False;
+ }
} else {
- /*
- * Maybe it was a group ?
+ /* it's not a mapped group */
+ grp = getgrnam(user);
+ if(!grp)
+ return False;
+
+ /*
+ *check if it's mapped, if it is reply it doesn't exist
+ *
+ * that's to prevent this case:
+ *
+ * unix group ug is mapped to nt group ng
+ * someone does a lookup on ug
+ * we must not reply as it doesn't "exist" anymore
+ * for NT. For NT only ng exists.
+ * JFM, 30/11/2001
*/
- struct group *grp;
- GROUP_MAP map;
- /* check if it's a mapped group */
- if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) {
- if (map.gid!=-1) {
- /* yes it's a mapped group to a valid unix group */
- sid_copy(&local_sid, &map.sid);
- *psid_name_use = map.sid_name_use;
- }
- else
- /* it's a correct name but not mapped so it points to nothing*/
- return False;
- } else {
- /* it's not a mapped group */
- grp = getgrnam(user);
- if(!grp)
- return False;
-
- /*
- *check if it's mapped, if it is reply it doesn't exist
- *
- * that's to prevent this case:
- *
- * unix group ug is mapped to nt group ng
- * someone does a lookup on ug
- * we must not reply as it doesn't "exist" anymore
- * for NT. For NT only ng exists.
- * JFM, 30/11/2001
- */
-
- if(get_group_map_from_gid(grp->gr_gid, &map, MAPPING_WITHOUT_PRIV)){
- return False;
- }
-
- sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
- *psid_name_use = SID_NAME_ALIAS;
+ if (get_group_map_from_gid(grp->gr_gid, &map, MAPPING_WITHOUT_PRIV)){
+ return False;
}
+
+ sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
+ *psid_name_use = SID_NAME_ALIAS;
}
sid_copy( psid, &local_sid);
@@ -824,15 +858,9 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
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)));
} else {
- if ((pdb_rid_is_user(rid))) {
- *puid = fallback_pdb_user_rid_to_uid(rid);
- DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (non-passdb user).\n", sid_to_string( str, psid),
- (unsigned int)*puid));
- } else {
- DEBUG(5,("local_sid_to_uid: SID %s not mapped becouse RID isn't a user.\n", sid_to_string( str, psid)));
- pdb_free_sam(&sam_user);
- return False;
- }
+ DEBUG(5,("local_sid_to_uid: SID %s not mapped becouse RID was not found in passdb.\n", sid_to_string( str, psid)));
+ pdb_free_sam(&sam_user);
+ return False;
}
pdb_free_sam(&sam_user);
@@ -919,7 +947,7 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
* @return static buffer containing the converted string
**/
-static char *pdb_convert(const UNISTR2 *from)
+const char *pdb_unistr2_convert(const UNISTR2 *from)
{
static pstring convert_buffer;
*convert_buffer = 0;
@@ -950,25 +978,25 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
pdb_set_pass_last_set_time(to, nt_time_to_unix(&from->pass_last_set_time));
if (from->uni_user_name.buffer)
- pdb_set_username(to , pdb_convert(&from->uni_user_name ));
+ pdb_set_username(to , pdb_unistr2_convert(&from->uni_user_name ));
if (from->uni_full_name.buffer)
- pdb_set_fullname(to , pdb_convert(&from->uni_full_name ));
+ pdb_set_fullname(to , pdb_unistr2_convert(&from->uni_full_name ));
if (from->uni_home_dir.buffer)
- pdb_set_homedir(to , pdb_convert(&from->uni_home_dir ), True);
+ pdb_set_homedir(to , pdb_unistr2_convert(&from->uni_home_dir ), True);
if (from->uni_dir_drive.buffer)
- pdb_set_dir_drive(to , pdb_convert(&from->uni_dir_drive ), True);
+ pdb_set_dir_drive(to , pdb_unistr2_convert(&from->uni_dir_drive ), True);
if (from->uni_logon_script.buffer)
- pdb_set_logon_script(to , pdb_convert(&from->uni_logon_script), True);
+ pdb_set_logon_script(to , pdb_unistr2_convert(&from->uni_logon_script), True);
if (from->uni_profile_path.buffer)
- pdb_set_profile_path(to , pdb_convert(&from->uni_profile_path), True);
+ pdb_set_profile_path(to , pdb_unistr2_convert(&from->uni_profile_path), True);
if (from->uni_acct_desc.buffer)
- pdb_set_acct_desc(to , pdb_convert(&from->uni_acct_desc ));
+ pdb_set_acct_desc(to , pdb_unistr2_convert(&from->uni_acct_desc ));
if (from->uni_workstations.buffer)
- pdb_set_workstations(to , pdb_convert(&from->uni_workstations));
+ pdb_set_workstations(to , pdb_unistr2_convert(&from->uni_workstations));
if (from->uni_unknown_str.buffer)
- pdb_set_unknown_str(to , pdb_convert(&from->uni_unknown_str ));
+ pdb_set_unknown_str(to , pdb_unistr2_convert(&from->uni_unknown_str ));
if (from->uni_munged_dial.buffer)
- pdb_set_munged_dial(to , pdb_convert(&from->uni_munged_dial ));
+ pdb_set_munged_dial(to , pdb_unistr2_convert(&from->uni_munged_dial ));
if (from->user_rid)
pdb_set_user_rid(to, from->user_rid);
@@ -1005,25 +1033,25 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
pdb_set_pass_last_set_time(to, nt_time_to_unix(&from->pass_last_set_time));
if (from->uni_user_name.buffer)
- pdb_set_username(to , pdb_convert(&from->uni_user_name ));
+ pdb_set_username(to , pdb_unistr2_convert(&from->uni_user_name ));
if (from->uni_full_name.buffer)
- pdb_set_fullname(to , pdb_convert(&from->uni_full_name ));
+ pdb_set_fullname(to , pdb_unistr2_convert(&from->uni_full_name ));
if (from->uni_home_dir.buffer)
- pdb_set_homedir(to , pdb_convert(&from->uni_home_dir ), True);
+ pdb_set_homedir(to , pdb_unistr2_convert(&from->uni_home_dir ), True);
if (from->uni_dir_drive.buffer)
- pdb_set_dir_drive(to , pdb_convert(&from->uni_dir_drive ), True);
+ pdb_set_dir_drive(to , pdb_unistr2_convert(&from->uni_dir_drive ), True);
if (from->uni_logon_script.buffer)
- pdb_set_logon_script(to , pdb_convert(&from->uni_logon_script), True);
+ pdb_set_logon_script(to , pdb_unistr2_convert(&from->uni_logon_script), True);
if (from->uni_profile_path.buffer)
- pdb_set_profile_path(to , pdb_convert(&from->uni_profile_path), True);
+ pdb_set_profile_path(to , pdb_unistr2_convert(&from->uni_profile_path), True);
if (from->uni_acct_desc.buffer)
- pdb_set_acct_desc(to , pdb_convert(&from->uni_acct_desc ));
+ pdb_set_acct_desc(to , pdb_unistr2_convert(&from->uni_acct_desc ));
if (from->uni_workstations.buffer)
- pdb_set_workstations(to , pdb_convert(&from->uni_workstations));
+ pdb_set_workstations(to , pdb_unistr2_convert(&from->uni_workstations));
if (from->uni_unknown_str.buffer)
- pdb_set_unknown_str(to , pdb_convert(&from->uni_unknown_str ));
+ pdb_set_unknown_str(to , pdb_unistr2_convert(&from->uni_unknown_str ));
if (from->uni_munged_dial.buffer)
- pdb_set_munged_dial(to , pdb_convert(&from->uni_munged_dial ));
+ pdb_set_munged_dial(to , pdb_unistr2_convert(&from->uni_munged_dial ));
if (from->user_rid)
pdb_set_user_rid(to, from->user_rid);
diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c
index cf77efd38f..372b332a45 100644
--- a/source3/passdb/pdb_get_set.c
+++ b/source3/passdb/pdb_get_set.c
@@ -138,6 +138,21 @@ const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass)
return (NULL);
}
+/* Return the plaintext password if known. Most of the time
+ it isn't, so don't assume anything magic about this function.
+
+ Used to pass the plaintext to passdb backends that might
+ want to store more than just the NTLM hashes.
+*/
+const char* pdb_get_plaintext_passwd (const SAM_ACCOUNT *sampass)
+{
+ if (sampass) {
+ return ((char*)sampass->private.plaintext_pw.data);
+ }
+ else
+ return (NULL);
+}
+
uint32 pdb_get_user_rid (const SAM_ACCOUNT *sampass)
{
if (sampass)
@@ -224,6 +239,14 @@ const char* pdb_get_homedir (const SAM_ACCOUNT *sampass)
return (NULL);
}
+const char* pdb_get_unix_homedir (const SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->private.unix_home_dir);
+ else
+ return (NULL);
+}
+
const char* pdb_get_dirdrive (const SAM_ACCOUNT *sampass)
{
if (sampass)
@@ -618,7 +641,7 @@ BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, const char *logon_script, BOOL s
}
if (store) {
- DEBUG(10, ("pdb_set_logon_script: setting logon script sam flag!"));
+ DEBUG(10, ("pdb_set_logon_script: setting logon script sam flag!\n"));
pdb_set_init_flag(sampass, FLAG_SAM_LOGONSCRIPT);
}
@@ -650,7 +673,7 @@ BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, const char *profile_path, BOOL
}
if (store) {
- DEBUG(10, ("pdb_set_profile_path: setting profile path sam flag!"));
+ DEBUG(10, ("pdb_set_profile_path: setting profile path sam flag!\n"));
pdb_set_init_flag(sampass, FLAG_SAM_PROFILE);
}
@@ -682,7 +705,7 @@ BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, const char *dir_drive, BOOL store)
}
if (store) {
- DEBUG(10, ("pdb_set_dir_drive: setting dir drive sam flag!"));
+ DEBUG(10, ("pdb_set_dir_drive: setting dir drive sam flag!\n"));
pdb_set_init_flag(sampass, FLAG_SAM_DRIVE);
}
@@ -722,6 +745,34 @@ BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, const char *home_dir, BOOL store)
}
/*********************************************************************
+ Set the user's unix home directory.
+ ********************************************************************/
+
+BOOL pdb_set_unix_homedir (SAM_ACCOUNT *sampass, const char *unix_home_dir)
+{
+ if (!sampass)
+ return False;
+
+ if (unix_home_dir) {
+ DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", unix_home_dir,
+ (sampass->private.unix_home_dir)?(sampass->private.unix_home_dir):"NULL"));
+
+ sampass->private.unix_home_dir = talloc_strdup(sampass->mem_ctx,
+ unix_home_dir);
+
+ if (!sampass->private.unix_home_dir) {
+ DEBUG(0, ("pdb_set_unix_home_dir: talloc_strdup() failed!\n"));
+ return False;
+ }
+
+ } else {
+ sampass->private.unix_home_dir = PDB_NOT_QUITE_NULL;
+ }
+
+ return True;
+}
+
+/*********************************************************************
Set the user's account description.
********************************************************************/
@@ -840,7 +891,7 @@ BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, const uint8 *pwd)
Set the user's LM hash.
********************************************************************/
-BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 *pwd)
+BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[16])
{
if (!sampass)
return False;
@@ -852,6 +903,23 @@ BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 *pwd)
return True;
}
+/*********************************************************************
+ Set the user's plaintext password only (base procedure, see helper
+ below)
+ ********************************************************************/
+
+BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const uint8 *password, size_t len)
+{
+ if (!sampass)
+ return False;
+
+ data_blob_clear_free(&sampass->private.plaintext_pw);
+
+ sampass->private.plaintext_pw = data_blob(password, len);
+
+ return True;
+}
+
BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn)
{
if (!sampass)
diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c
index a19bf254e7..6488decf94 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -30,6 +30,7 @@ const struct pdb_init_function_entry builtin_pdb_init_functions[] = {
{ "tdbsam_nua", pdb_init_tdbsam_nua },
{ "ldapsam", pdb_init_ldapsam },
{ "ldapsam_nua", pdb_init_ldapsam_nua },
+ { "unixsam", pdb_init_unixsam },
{ "plugin", pdb_init_plugin },
{ NULL, NULL}
};
@@ -42,7 +43,12 @@ static BOOL context_setsampwent(struct pdb_context *context, BOOL update)
}
context->pwent_methods = context->pdb_methods;
-
+
+ if (!context->pwent_methods) {
+ /* No passdbs at all */
+ return True;
+ }
+
while(!(context->pwent_methods->setsampwent(context->pwent_methods, update))){
context->pwent_methods = context->pwent_methods->next;
if(context->pwent_methods == NULL)return False;
@@ -83,7 +89,7 @@ static BOOL context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
if(context->pwent_methods == NULL)return False;
if(!context->pwent_methods->setsampwent){
- DEBUG(0, ("invalid context->pwent_methods->setsampwent\n"));
+ DEBUG(5, ("invalid context->pwent_methods->setsampwent\n"));
return False;
}
@@ -251,7 +257,11 @@ static NTSTATUS make_pdb_methods_name(struct pdb_methods **methods, struct pdb_c
if (!*methods) {
DEBUG(0,("failed to select passdb backed!\n"));
- return nt_status;
+ if (NT_STATUS_IS_OK(nt_status)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ } else {
+ return nt_status;
+ }
}
return NT_STATUS_OK;
}
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index af0cbef4f2..9614483ee1 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -339,7 +339,7 @@ static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state,
search an attribute and return the first value found.
******************************************************************/
static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
- char *attribute, char *value)
+ char *attribute, pstring value)
{
char **values;
@@ -521,12 +521,14 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pw = getpwnam_alloc(username);
if (pw == NULL) {
- DEBUG (2,("init_sam_from_ldap: User [%s] does not have a uid!\n", username));
+ DEBUG (2,("init_sam_from_ldap: User [%s] does not ave a uid!\n", username));
return False;
}
uid = pw->pw_uid;
gid = pw->pw_gid;
+ pdb_set_unix_homedir(sampass, pw->pw_dir);
+
passwd_free(&pw);
pdb_set_uid(sampass, uid);
@@ -603,37 +605,41 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
}
if (!get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive)) {
- pstrcpy(dir_drive, lp_logon_drive());
- standard_sub_advanced(-1, username, "", gid, username, dir_drive);
- DEBUG(5,("homeDrive fell back to %s\n",dir_drive));
- pdb_set_dir_drive(sampass, dir_drive, False);
+ pdb_set_dir_drive(sampass, standard_sub_specified(sampass->mem_ctx,
+ lp_logon_path(),
+ username, domain,
+ uid, gid),
+ False);
} else {
pdb_set_dir_drive(sampass, dir_drive, True);
}
if (!get_single_attribute(ldap_struct, entry, "smbHome", homedir)) {
- pstrcpy(homedir, lp_logon_home());
- standard_sub_advanced(-1, username, "", gid, username, homedir);
- DEBUG(5,("smbHome fell back to %s\n",homedir));
- pdb_set_homedir(sampass, homedir, False);
+ pdb_set_dir_drive(sampass, standard_sub_specified(sampass->mem_ctx,
+ lp_logon_home(),
+ username, domain,
+ uid, gid),
+ False);
} else {
pdb_set_homedir(sampass, homedir, True);
}
if (!get_single_attribute(ldap_struct, entry, "scriptPath", logon_script)) {
- pstrcpy(logon_script, lp_logon_script());
- standard_sub_advanced(-1, username, "", gid, username, logon_script);
- DEBUG(5,("scriptPath fell back to %s\n",logon_script));
- pdb_set_logon_script(sampass, logon_script, False);
+ pdb_set_logon_script(sampass, standard_sub_specified(sampass->mem_ctx,
+ lp_logon_script(),
+ username, domain,
+ uid, gid),
+ False);
} else {
pdb_set_logon_script(sampass, logon_script, True);
}
if (!get_single_attribute(ldap_struct, entry, "profilePath", profile_path)) {
- pstrcpy(profile_path, lp_logon_path());
- standard_sub_advanced(-1, username, "", gid, username, profile_path);
- DEBUG(5,("profilePath fell back to %s\n",profile_path));
- pdb_set_profile_path(sampass, profile_path, False);
+ pdb_set_profile_path(sampass, standard_sub_specified(sampass->mem_ctx,
+ lp_logon_path(),
+ username, domain,
+ uid, gid),
+ False);
} else {
pdb_set_profile_path(sampass, profile_path, True);
}
@@ -740,7 +746,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
} else if (ldap_state->permit_non_unix_accounts) {
rid = ldapsam_get_next_available_nua_rid(ldap_state);
if (rid == 0) {
- DEBUG(0, ("NO user RID specified on account %s, and finding next available NUA RID failed, cannot store!\n", pdb_get_username(sampass)));
+ DEBUG(0, ("NO user RID specified on account %s, and findining next available NUA RID failed, cannot store!\n", pdb_get_username(sampass)));
return False;
}
} else {
@@ -1097,7 +1103,7 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us
if (ldap_count_entries(ldap_struct, result) < 1)
{
DEBUG(4,
- ("We didn't find the user [%s] count=%d\n", sname,
+ ("We don't find this user [%s] count=%d\n", sname,
ldap_count_entries(ldap_struct, result)));
ldap_unbind(ldap_struct);
return False;
@@ -1151,7 +1157,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us
if (ldap_count_entries(ldap_struct, result) < 1)
{
DEBUG(0,
- ("We didn't find the rid [%i] count=%d\n", rid,
+ ("We don't find this rid [%i] count=%d\n", rid,
ldap_count_entries(ldap_struct, result)));
ldap_unbind(ldap_struct);
return False;
@@ -1205,7 +1211,7 @@ static BOOL ldapsam_delete_sam_account(struct pdb_methods *my_methods, const SAM
if (!ldapsam_connect_system(ldap_state, ldap_struct)) {
ldap_unbind (ldap_struct);
- DEBUG(0, ("failed to delete user %s from the LDAP database.\n", sname));
+ DEBUG(0, ("Failed to delete user %s from LDAP.\n", sname));
return False;
}
diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c
index 9f37cadfe8..88e317cea9 100644
--- a/source3/passdb/pdb_smbpasswd.c
+++ b/source3/passdb/pdb_smbpasswd.c
@@ -1218,7 +1218,8 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
/*********************************************************************
Create a SAM_ACCOUNT from a smb_passwd struct
********************************************************************/
-static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw_buf)
+static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state,
+ SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw_buf)
{
struct passwd *pwfile;
@@ -1242,73 +1243,25 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, SAM_AC
} else {
- uint32 grid;
- GROUP_MAP map;
-
- /* Verify in system password file...
- FIXME!!! This is where we should look up an internal
- mapping of allocated uid for machine accounts as well
- --jerry */
pwfile = getpwnam_alloc(pw_buf->smb_name);
if (pwfile == NULL) {
DEBUG(0,("build_sam_account: smbpasswd database is corrupt! username %s with uid %u is not in unix passwd database!\n", pw_buf->smb_name, pw_buf->smb_userid));
return False;
}
- pdb_set_uid (sam_pass, pwfile->pw_uid);
- pdb_set_gid (sam_pass, pwfile->pw_gid);
-
- pdb_set_fullname(sam_pass, pwfile->pw_gecos);
-
- pdb_set_user_rid(sam_pass, fallback_pdb_uid_to_user_rid (pwfile->pw_uid));
-
- if (get_group_map_from_gid(pwfile->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
- sid_peek_rid(&map.sid, &grid);
- } else {
- grid=pdb_gid_to_group_rid(pwfile->pw_gid);
- }
-
- pdb_set_group_rid(sam_pass, grid);
-
- /* check if this is a user account or a machine account */
- if (pw_buf->smb_name[strlen(pw_buf->smb_name)-1] != '$')
- {
- pstring str;
-
- pstrcpy(str, lp_logon_path());
- standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
- pdb_set_profile_path(sam_pass, str, False);
-
- pstrcpy(str, lp_logon_home());
- standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
- pdb_set_homedir(sam_pass, str, False);
-
- pstrcpy(str, lp_logon_drive());
- standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
- pdb_set_dir_drive(sam_pass, str, False);
-
- pstrcpy(str, lp_logon_script());
- standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
- pdb_set_logon_script(sam_pass, str, False);
-
- } else {
- /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
- /*pdb_set_group_rid (sam_pass, DOMAIN_GROUP_RID_USERS); */
+ if (!NT_STATUS_IS_OK(pdb_fill_sam_pw(sam_pass, pwfile))) {
+ return False;
}
passwd_free(&pwfile);
}
- pdb_set_username (sam_pass, pw_buf->smb_name);
pdb_set_nt_passwd (sam_pass, pw_buf->smb_nt_passwd);
pdb_set_lanman_passwd (sam_pass, pw_buf->smb_passwd);
pdb_set_acct_ctrl (sam_pass, pw_buf->acct_ctrl);
pdb_set_pass_last_set_time (sam_pass, pw_buf->pass_last_set_time);
pdb_set_pass_can_change_time (sam_pass, pw_buf->pass_last_set_time, True);
- pdb_set_domain (sam_pass, lp_workgroup());
- pdb_set_dir_drive (sam_pass, lp_logon_drive(), False);
-
#if 0 /* JERRY */
/* the smbpasswd format doesn't have a must change time field, so
we can't get this right. The best we can do is to set this to
diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c
index 3a9bc894bb..46120c3ccc 100644
--- a/source3/passdb/pdb_tdb.c
+++ b/source3/passdb/pdb_tdb.c
@@ -86,12 +86,11 @@ static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state,
uint8 *hours;
static uint8 *lm_pw_ptr, *nt_pw_ptr;
uint32 len = 0;
- uint32 lmpwlen, ntpwlen, hourslen;
+ uint32 lm_pw_len, nt_pw_len, hourslen;
BOOL ret = True;
- BOOL setflag;
pstring sub_buffer;
struct passwd *pw;
- uid_t uid;
+ uid_t uid = -1;
gid_t gid = -1; /* This is what standard sub advanced expects if no gid is known */
if(sampass == NULL || buf == NULL) {
@@ -121,8 +120,8 @@ static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state,
&munged_dial_len, &munged_dial,
&user_rid,
&group_rid,
- &lmpwlen, &lm_pw_ptr,
- &ntpwlen, &nt_pw_ptr,
+ &lm_pw_len, &lm_pw_ptr,
+ &nt_pw_len, &nt_pw_ptr,
&acct_ctrl,
&unknown_3,
&logon_divs,
@@ -152,6 +151,8 @@ static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state,
uid = pw->pw_uid;
gid = pw->pw_gid;
+ pdb_set_unix_homedir(sampass, pw->pw_dir);
+
passwd_free(&pw);
pdb_set_uid(sampass, uid);
@@ -165,66 +166,72 @@ static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state,
pdb_set_pass_must_change_time(sampass, pass_must_change_time, True);
pdb_set_pass_last_set_time(sampass, pass_last_set_time);
- pdb_set_username (sampass, username);
+ pdb_set_username (sampass, username);
pdb_set_domain (sampass, domain);
pdb_set_nt_username (sampass, nt_username);
pdb_set_fullname (sampass, fullname);
- if (homedir) setflag = True;
+ if (homedir) {
+ pdb_set_homedir(sampass, homedir, True);
+ }
else {
- setflag = False;
- pstrcpy(sub_buffer, lp_logon_home());
- /* standard_sub_advanced() assumes pstring is passed!! */
- standard_sub_advanced(-1, username, "", gid, username, sub_buffer);
- homedir = strdup(sub_buffer);
- if(!homedir) { ret = False; goto done; }
- DEBUG(5,("Home directory set back to %s\n", homedir));
+ pdb_set_homedir(sampass,
+ standard_sub_specified(sampass->mem_ctx,
+ lp_logon_home(),
+ username, domain,
+ uid, gid),
+ False);
}
- pdb_set_homedir(sampass, homedir, setflag);
- if (dir_drive) setflag = True;
+ if (dir_drive)
+ pdb_set_dir_drive(sampass, dir_drive, True);
else {
- setflag = False;
- pstrcpy(sub_buffer, lp_logon_drive());
- standard_sub_advanced(-1, username, "", gid, username, sub_buffer);
- dir_drive = strdup(sub_buffer);
- if(!dir_drive) { ret = False; goto done; }
- DEBUG(5,("Drive set back to %s\n", dir_drive));
+ pdb_set_dir_drive(sampass,
+ standard_sub_specified(sampass->mem_ctx,
+ lp_logon_drive(),
+ username, domain,
+ uid, gid),
+ False);
}
- pdb_set_dir_drive(sampass, dir_drive, setflag);
- if (logon_script) setflag = True;
+ if (logon_script)
+ pdb_set_logon_script(sampass, logon_script, True);
else {
- setflag = False;
- pstrcpy(sub_buffer, lp_logon_script());
- standard_sub_advanced(-1, username, "", gid, username, sub_buffer);
- logon_script = strdup(sub_buffer);
- if(!logon_script) { ret = False; goto done; }
- DEBUG(5,("Logon script set back to %s\n", logon_script));
+ pdb_set_logon_script(sampass,
+ standard_sub_specified(sampass->mem_ctx,
+ lp_logon_script(),
+ username, domain,
+ uid, gid),
+ False);
}
- pdb_set_logon_script(sampass, logon_script, setflag);
- if (profile_path) setflag = True;
- else {
- setflag = False;
- pstrcpy(sub_buffer, lp_logon_path());
- standard_sub_advanced(-1, username, "", gid, username, sub_buffer);
- profile_path = strdup(sub_buffer);
- if(!profile_path) { ret = False; goto done; }
- DEBUG(5,("Profile path set back to %s\n", profile_path));
+ if (profile_path) {
+ pdb_set_profile_path(sampass, profile_path, True);
+ } else {
+ pdb_set_profile_path(sampass,
+ standard_sub_specified(sampass->mem_ctx,
+ lp_logon_path(),
+ username, domain,
+ uid, gid),
+ False);
}
- pdb_set_profile_path(sampass, profile_path, setflag);
pdb_set_acct_desc (sampass, acct_desc);
pdb_set_workstations (sampass, workstations);
pdb_set_munged_dial (sampass, munged_dial);
- if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr)) {
- ret = False;
- goto done;
+
+ if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
+ if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr)) {
+ ret = False;
+ goto done;
+ }
}
- if (!pdb_set_nt_passwd(sampass, nt_pw_ptr)) {
- ret = False;
- goto done;
+
+ if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
+ if (!pdb_set_nt_passwd(sampass, nt_pw_ptr)) {
+ ret = False;
+ goto done;
+ }
}
pdb_set_user_rid(sampass, user_rid);
diff --git a/source3/passdb/pdb_unix.c b/source3/passdb/pdb_unix.c
new file mode 100644
index 0000000000..d1f95c445b
--- /dev/null
+++ b/source3/passdb/pdb_unix.c
@@ -0,0 +1,126 @@
+/*
+ * 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 BOOL unixsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname)
+{
+ struct passwd *pass;
+ if (!methods) {
+ DEBUG(0,("invalid methods\n"));
+ return False;
+ }
+ if (!sname) {
+ DEBUG(0,("invalid name specified"));
+ return False;
+ }
+ pass = Get_Pwnam(sname);
+
+ return NT_STATUS_IS_OK(pdb_fill_sam_pw(user, pass));
+}
+
+
+/***************************************************************************
+ Search by rid
+ **************************************************************************/
+
+static BOOL unixsam_getsampwrid (struct pdb_methods *methods,
+ SAM_ACCOUNT *user, uint32 rid)
+{
+ struct passwd *pass;
+ BOOL ret = False;
+ if (!methods) {
+ DEBUG(0,("invalid methods\n"));
+ return False;
+ }
+
+ if (pdb_rid_is_user(rid)) {
+ pass = getpwuid_alloc(fallback_pdb_user_rid_to_uid (rid));
+
+ if (pass) {
+ ret = NT_STATUS_IS_OK(pdb_fill_sam_pw(user, pass));
+ passwd_free(&pass);
+ }
+ }
+ return ret;
+}
+
+/***************************************************************************
+ Delete a SAM_ACCOUNT
+ ****************************************************************************/
+
+static BOOL unixsam_delete_sam_account(struct pdb_methods *methods, const SAM_ACCOUNT *sam_pass)
+{
+ /*
+ * Unsupported as well - we don't need to get involved in
+ * unix passdb's - and hey, we would need to use pam for that anyway
+ */
+ return False;
+}
+
+/***************************************************************************
+ Modifies an existing SAM_ACCOUNT
+ ****************************************************************************/
+
+static BOOL unixsam_update_sam_account (struct pdb_methods *methods, const SAM_ACCOUNT *newpwd)
+{
+ return False;
+}
+
+/***************************************************************************
+ Adds an existing SAM_ACCOUNT
+ ****************************************************************************/
+
+static BOOL unixsam_add_sam_account (struct pdb_methods *methods, const SAM_ACCOUNT *newpwd)
+{
+ DEBUG(0,("pdb_unix should not be listed as the first passdb backend! You can't add users to it.\n"));
+ return False;
+}
+
+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)->setsampwent = NULL;
+ (*pdb_method)->endsampwent = NULL;
+ (*pdb_method)->getsampwent = NULL;
+ (*pdb_method)->getsampwnam = unixsam_getsampwnam;
+ (*pdb_method)->getsampwrid = unixsam_getsampwrid;
+ (*pdb_method)->add_sam_account = unixsam_add_sam_account;
+ (*pdb_method)->update_sam_account = unixsam_update_sam_account;
+ (*pdb_method)->delete_sam_account = unixsam_delete_sam_account;
+
+ /* There's not very much to initialise here */
+ return NT_STATUS_OK;
+}