summaryrefslogtreecommitdiff
path: root/source3/passdb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/passdb')
-rw-r--r--source3/passdb/machine_sid.c53
-rw-r--r--source3/passdb/passdb.c513
-rw-r--r--source3/passdb/passgrp.c3
-rw-r--r--source3/passdb/pdb_get_set.c168
-rw-r--r--source3/passdb/pdb_interface.c335
-rw-r--r--source3/passdb/pdb_ldap.c279
-rw-r--r--source3/passdb/pdb_nisplus.c22
-rw-r--r--source3/passdb/pdb_plugin.c21
-rw-r--r--source3/passdb/pdb_smbpasswd.c272
-rw-r--r--source3/passdb/pdb_tdb.c226
-rw-r--r--source3/passdb/secrets.c192
11 files changed, 1226 insertions, 858 deletions
diff --git a/source3/passdb/machine_sid.c b/source3/passdb/machine_sid.c
index 6436a2cd05..e1f7dec2a9 100644
--- a/source3/passdb/machine_sid.c
+++ b/source3/passdb/machine_sid.c
@@ -4,6 +4,7 @@
Copyright (C) Jeremy Allison 1996-2002
Copyright (C) Andrew Tridgell 2002
Copyright (C) Gerald (Jerry) Carter 2000
+ Copyright (C) Stefan (metze) Metzmacher 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
@@ -22,6 +23,13 @@
#include "includes.h"
+/* NOTE! the global_sam_sid is the SID of our local SAM. This is only
+ equal to the domain SID when we are a DC, otherwise its our
+ workstation SID */
+static DOM_SID *global_sam_sid=NULL;
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_PASSDB
/****************************************************************************
Read a SID from a file. This is for compatibility with the old MACHINE.SID
@@ -68,13 +76,17 @@ static void generate_random_sid(DOM_SID *sid)
Generate the global machine sid.
****************************************************************************/
-BOOL pdb_generate_sam_sid(void)
+static BOOL pdb_generate_sam_sid(void)
{
char *fname = NULL;
extern pstring global_myname;
extern fstring global_myworkgroup;
BOOL is_dc = False;
+ if(global_sam_sid==NULL)
+ if(!(global_sam_sid=(DOM_SID *)malloc(sizeof(DOM_SID))))
+ return False;
+
generate_wellknown_sids();
switch (lp_server_role()) {
@@ -87,7 +99,7 @@ BOOL pdb_generate_sam_sid(void)
break;
}
- if (secrets_fetch_domain_sid(global_myname, &global_sam_sid)) {
+ if (secrets_fetch_domain_sid(global_myname, global_sam_sid)) {
DOM_SID domain_sid;
/* We got our sid. If not a pdc/bdc, we're done. */
@@ -98,19 +110,19 @@ BOOL pdb_generate_sam_sid(void)
/* No domain sid and we're a pdc/bdc. Store it */
- if (!secrets_store_domain_sid(global_myworkgroup, &global_sam_sid)) {
+ if (!secrets_store_domain_sid(global_myworkgroup, global_sam_sid)) {
DEBUG(0,("pdb_generate_sam_sid: Can't store domain SID as a pdc/bdc.\n"));
return False;
}
return True;
}
- if (!sid_equal(&domain_sid, &global_sam_sid)) {
+ if (!sid_equal(&domain_sid, global_sam_sid)) {
/* Domain name sid doesn't match global sam sid. Re-store global sam sid as domain sid. */
DEBUG(0,("pdb_generate_sam_sid: Mismatched SIDs as a pdc/bdc.\n"));
- if (!secrets_store_domain_sid(global_myworkgroup, &global_sam_sid)) {
+ if (!secrets_store_domain_sid(global_myworkgroup, global_sam_sid)) {
DEBUG(0,("pdb_generate_sam_sid: Can't re-store domain SID as a pdc/bdc.\n"));
return False;
}
@@ -124,24 +136,23 @@ BOOL pdb_generate_sam_sid(void)
/* check for an old MACHINE.SID file for backwards compatibility */
asprintf(&fname, "%s/MACHINE.SID", lp_private_dir());
- if (read_sid_from_file(fname, &global_sam_sid)) {
+ if (read_sid_from_file(fname, global_sam_sid)) {
/* remember it for future reference and unlink the old MACHINE.SID */
- if (!secrets_store_domain_sid(global_myname, &global_sam_sid)) {
+ if (!secrets_store_domain_sid(global_myname, global_sam_sid)) {
DEBUG(0,("pdb_generate_sam_sid: Failed to store SID from file.\n"));
SAFE_FREE(fname);
return False;
}
unlink(fname);
if (is_dc) {
- if (!secrets_store_domain_sid(global_myworkgroup, &global_sam_sid)) {
+ if (!secrets_store_domain_sid(global_myworkgroup, global_sam_sid)) {
DEBUG(0,("pdb_generate_sam_sid: Failed to store domain SID from file.\n"));
SAFE_FREE(fname);
return False;
}
}
- /* Stored the old sid from MACHINE.SID successfully.
- Patch from Stefan "metze" Metzmacher <metze@metzemix.de>*/
+ /* Stored the old sid from MACHINE.SID successfully.*/
SAFE_FREE(fname);
return True;
}
@@ -150,14 +161,14 @@ BOOL pdb_generate_sam_sid(void)
/* we don't have the SID in secrets.tdb, we will need to
generate one and save it */
- generate_random_sid(&global_sam_sid);
+ generate_random_sid(global_sam_sid);
- if (!secrets_store_domain_sid(global_myname, &global_sam_sid)) {
+ if (!secrets_store_domain_sid(global_myname, global_sam_sid)) {
DEBUG(0,("pdb_generate_sam_sid: Failed to store generated machine SID.\n"));
return False;
}
if (is_dc) {
- if (!secrets_store_domain_sid(global_myworkgroup, &global_sam_sid)) {
+ if (!secrets_store_domain_sid(global_myworkgroup, global_sam_sid)) {
DEBUG(0,("pdb_generate_sam_sid: Failed to store generated domain SID.\n"));
return False;
}
@@ -165,3 +176,19 @@ BOOL pdb_generate_sam_sid(void)
return True;
}
+
+/* return our global_sam_sid */
+DOM_SID *get_global_sam_sid(void)
+{
+ if (global_sam_sid != NULL)
+ return global_sam_sid;
+
+ /* memory for global_sam_sid is allocated in
+ pdb_generate_sam_sid() as needed */
+
+ if (!pdb_generate_sam_sid())
+ global_sam_sid=NULL;
+
+ return global_sam_sid;
+}
+
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index 17aefe1159..4e3d558e98 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -23,13 +23,16 @@
#include "includes.h"
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_PASSDB
+
/*
* This is set on startup - it defines the SID for this
* machine, and therefore the SAM database for which it is
* responsible.
*/
-extern DOM_SID global_sam_sid;
+extern pstring global_myname;
/************************************************************
Fill the SAM_ACCOUNT with default values.
@@ -90,7 +93,7 @@ static void destroy_pdb_talloc(SAM_ACCOUNT **user)
NTSTATUS pdb_init_sam_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **user)
{
if (*user != NULL) {
- DEBUG(0,("pdb_init_sam: SAM_ACCOUNT was non NULL\n"));
+ DEBUG(0,("pdb_init_sam_talloc: SAM_ACCOUNT was non NULL\n"));
#if 0
smb_panic("non-NULL pointer passed to pdb_init_sam\n");
#endif
@@ -105,7 +108,7 @@ NTSTATUS pdb_init_sam_talloc(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **user)
*user=(SAM_ACCOUNT *)talloc(mem_ctx, sizeof(SAM_ACCOUNT));
if (*user==NULL) {
- DEBUG(0,("pdb_init_sam: error while allocating memory\n"));
+ DEBUG(0,("pdb_init_sam_talloc: error while allocating memory\n"));
return NT_STATUS_NO_MEMORY;
}
@@ -150,59 +153,115 @@ 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(sam_account, pwd->pw_name);
+ pdb_set_fullname(sam_account, pwd->pw_gecos);
- pdb_set_username(*new_sam_acct, pwd->pw_name);
- pdb_set_fullname(*new_sam_acct, pwd->pw_gecos);
+ pdb_set_unix_homedir(sam_account, pwd->pw_dir);
- pdb_set_uid(*new_sam_acct, pwd->pw_uid);
- pdb_set_gid(*new_sam_acct, pwd->pw_gid);
+ 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
+ */
+
+ if (!pdb_set_user_sid_from_rid(sam_account,
+ fallback_pdb_uid_to_user_rid(pwd->pw_uid))) {
+ DEBUG(0,("Can't set User SID from RID!\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
/* call the mapping code here */
if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
- sid_peek_rid(&map.sid, &rid);
+ if (!pdb_set_group_sid(sam_account,&map.sid)){
+ DEBUG(0,("Can't set Group SID!\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
}
else {
- rid=pdb_gid_to_group_rid(pwd->pw_gid);
+ if (!pdb_set_group_sid_from_rid(sam_account,pdb_gid_to_group_rid(pwd->pw_gid))) {
+ 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] != '$')
+ {
+ pdb_set_profile_path(sam_account,
+ talloc_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,
+ talloc_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,
+ talloc_sub_specified((sam_account)->mem_ctx,
+ lp_logon_drive(),
+ pwd->pw_name, global_myname,
+ pwd->pw_uid, pwd->pw_gid),
+ False);
- pdb_set_group_rid(*new_sam_acct, rid);
+ pdb_set_logon_script(sam_account,
+ talloc_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 +269,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));
}
@@ -399,46 +461,14 @@ BOOL pdb_gethexpwd(const char *p, unsigned char *pwd)
return (True);
}
-#if 0 /* seem it is not used by anyone */
-/*******************************************************************
- Group and User RID username mapping function
- ********************************************************************/
-
-BOOL pdb_name_to_rid(const char *user_name, uint32 *u_rid, uint32 *g_rid)
-{
- GROUP_MAP map;
- struct passwd *pw = Get_Pwnam(user_name);
-
- if (u_rid == NULL || g_rid == NULL || user_name == NULL)
- return False;
-
- if (!pw) {
- DEBUG(1,("Username %s is invalid on this system\n", user_name));
- return False;
- }
-
- /* turn the unix UID into a Domain RID. this is what the posix
- sub-system does (adds 1000 to the uid) */
- *u_rid = fallback_pdb_uid_to_user_rid(pw->pw_uid);
-
- /* absolutely no idea what to do about the unix GID to Domain RID mapping */
- /* map it ! */
- if (get_group_map_from_gid(pw->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
- sid_peek_rid(&map.sid, g_rid);
- } else
- *g_rid = pdb_gid_to_group_rid(pw->pw_gid);
-
- return True;
-}
-#endif /* seem it is not used by anyone */
-
/*******************************************************************
Converts NT user RID to a UNIX uid.
********************************************************************/
-static uid_t fallback_pdb_user_rid_to_uid(uint32 user_rid)
+uid_t fallback_pdb_user_rid_to_uid(uint32 user_rid)
{
- return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER);
+ int rid_offset = lp_algorithmic_rid_base();
+ return (uid_t)(((user_rid & (~USER_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
}
@@ -446,9 +476,10 @@ static uid_t fallback_pdb_user_rid_to_uid(uint32 user_rid)
converts UNIX uid to an NT User RID.
********************************************************************/
-static uint32 fallback_pdb_uid_to_user_rid(uid_t uid)
+uint32 fallback_pdb_uid_to_user_rid(uid_t uid)
{
- return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE);
+ int rid_offset = lp_algorithmic_rid_base();
+ return (((((uint32)uid)*RID_MULTIPLIER) + rid_offset) | USER_RID_TYPE);
}
/*******************************************************************
@@ -457,7 +488,8 @@ static uint32 fallback_pdb_uid_to_user_rid(uid_t uid)
gid_t pdb_group_rid_to_gid(uint32 group_rid)
{
- return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- 1000)/RID_MULTIPLIER);
+ int rid_offset = lp_algorithmic_rid_base();
+ return (gid_t)(((group_rid & (~GROUP_RID_TYPE))- rid_offset)/RID_MULTIPLIER);
}
/*******************************************************************
@@ -470,7 +502,8 @@ gid_t pdb_group_rid_to_gid(uint32 group_rid)
uint32 pdb_gid_to_group_rid(gid_t gid)
{
- return (((((uint32)gid)*RID_MULTIPLIER) + 1000) | GROUP_RID_TYPE);
+ int rid_offset = lp_algorithmic_rid_base();
+ return (((((uint32)gid)*RID_MULTIPLIER) + rid_offset) | GROUP_RID_TYPE);
}
/*******************************************************************
@@ -479,7 +512,10 @@ uint32 pdb_gid_to_group_rid(gid_t gid)
static BOOL pdb_rid_is_well_known(uint32 rid)
{
- return (rid < 1000);
+ /* Not using rid_offset here, becouse this is the actual
+ NT fixed value (1000) */
+
+ return (rid < BASE_RID);
}
/*******************************************************************
@@ -512,14 +548,14 @@ 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);
+ if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid)){
+ DEBUG(0,("local_sid_to_gid: sid_peek_check_rid return False! SID: %s\n",
+ sid_string_static(&map.sid)));
+ return False;
+ }
*psid_name_use = SID_NAME_UNKNOWN;
DEBUG(5,("local_lookup_sid: looking up RID %u.\n", (unsigned int)rid));
@@ -557,7 +593,8 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
return False;
}
- if (pdb_getsampwrid(sam_account, rid)) {
+ /* This now does the 'generic' mapping in pdb_unix */
+ if (pdb_getsampwsid(sam_account, sid)) {
fstrcpy(name, pdb_get_username(sam_account));
*psid_name_use = SID_NAME_USER;
@@ -565,47 +602,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);
@@ -616,15 +642,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;
}
/*******************************************************************
@@ -634,11 +660,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;
/*
@@ -648,7 +675,7 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
fstrcpy(user, c_user);
- sid_copy(&local_sid, &global_sam_sid);
+ sid_copy(&local_sid, get_global_sam_sid());
/*
* Special case for MACHINE\Everyone. Map to the world_sid.
@@ -674,62 +701,54 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
}
if (pdb_getsampwnam(sam_account, user)) {
- sid_append_rid( &local_sid, pdb_get_user_rid(sam_account));
+ sid_copy(psid, pdb_get_user_sid(sam_account));
*psid_name_use = SID_NAME_USER;
- sid_copy( psid, &local_sid);
pdb_free_sam(&sam_account);
return True;
}
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);
@@ -743,12 +762,11 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
{
- extern DOM_SID global_sam_sid;
struct passwd *pass;
SAM_ACCOUNT *sam_user = NULL;
fstring str; /* sid string buffer */
- sid_copy(psid, &global_sam_sid);
+ sid_copy(psid, get_global_sam_sid());
if((pass = getpwuid_alloc(uid))) {
@@ -758,7 +776,7 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
}
if (pdb_getsampwnam(sam_user, pass->pw_name)) {
- sid_append_rid(psid, pdb_get_user_rid(sam_user));
+ sid_copy(psid, pdb_get_user_sid(sam_user));
} else {
sid_append_rid(psid, fallback_pdb_uid_to_user_rid(uid));
}
@@ -786,8 +804,6 @@ DOM_SID *local_uid_to_sid(DOM_SID *psid, uid_t uid)
BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
{
- extern DOM_SID global_sam_sid;
-
DOM_SID dom_sid;
uint32 rid;
fstring str;
@@ -802,13 +818,13 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
* We can only convert to a uid if this is our local
* Domain SID (ie. we are the controling authority).
*/
- if (!sid_equal(&global_sam_sid, &dom_sid))
+ if (!sid_equal(get_global_sam_sid(), &dom_sid))
return False;
if (NT_STATUS_IS_ERR(pdb_init_sam(&sam_user)))
return False;
- if (pdb_getsampwrid(sam_user, rid)) {
+ if (pdb_getsampwsid(sam_user, psid)) {
*puid = pdb_get_uid(sam_user);
if (*puid == -1) {
pdb_free_sam(&sam_user);
@@ -817,14 +833,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 {
- 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);
@@ -839,14 +850,13 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
{
- extern DOM_SID global_sam_sid;
GROUP_MAP map;
- sid_copy(psid, &global_sam_sid);
+ sid_copy(psid, get_global_sam_sid());
if (get_group_map_from_gid(gid, &map, MAPPING_WITHOUT_PRIV)) {
sid_copy(psid, &map.sid);
- }
+ }
else {
sid_append_rid(psid, pdb_gid_to_group_rid(gid));
}
@@ -860,11 +870,9 @@ DOM_SID *local_gid_to_sid(DOM_SID *psid, gid_t gid)
BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
{
- extern DOM_SID global_sam_sid;
DOM_SID dom_sid;
uint32 rid;
fstring str;
- struct group *grp;
GROUP_MAP map;
*name_type = SID_NAME_UNKNOWN;
@@ -879,7 +887,7 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
* Or in the Builtin SID too. JFM, 11/30/2001
*/
- if (!sid_equal(&global_sam_sid, &dom_sid))
+ if (!sid_equal(get_global_sam_sid(), &dom_sid))
return False;
if (get_group_map_from_sid(*psid, &map, MAPPING_WITHOUT_PRIV)) {
@@ -888,27 +896,26 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
if (map.gid==-1)
return False;
- sid_peek_rid(&map.sid, &rid);
+ if (!sid_peek_check_rid(get_global_sam_sid(), &map.sid, &rid)){
+ DEBUG(0,("local_sid_to_gid: sid_peek_check_rid return False! SID: %s\n",
+ sid_string_static(&map.sid)));
+ 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 {
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));
}
- /*
- * Ensure this gid really does exist.
- */
-
- if(!(grp = getgrgid(*pgid)))
- return False;
-
- DEBUG(10,("local_sid_to_gid: SID %s -> gid (%u) (%s).\n", sid_to_string( str, psid),
- (unsigned int)*pgid, grp->gr_name ));
-
return True;
}
@@ -917,7 +924,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;
@@ -930,122 +937,6 @@ static char *pdb_convert(const UNISTR2 *from)
}
/*************************************************************
- Copies a SAM_USER_INFO_23 to a SAM_ACCOUNT
- **************************************************************/
-
-void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
-{
-
- if (from == NULL || to == NULL)
- return;
-
- pdb_set_logon_time(to,nt_time_to_unix(&from->logon_time), True);
- pdb_set_logoff_time(to,nt_time_to_unix(&from->logoff_time), True);
- pdb_set_kickoff_time(to, nt_time_to_unix(&from->kickoff_time), True);
- pdb_set_pass_can_change_time(to, nt_time_to_unix(&from->pass_can_change_time), True);
- pdb_set_pass_must_change_time(to, nt_time_to_unix(&from->pass_must_change_time), True);
-
- 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 ));
- if (from->uni_full_name.buffer)
- pdb_set_fullname(to , pdb_convert(&from->uni_full_name ));
- if (from->uni_home_dir.buffer)
- pdb_set_homedir(to , pdb_convert(&from->uni_home_dir ), True);
- if (from->uni_dir_drive.buffer)
- pdb_set_dir_drive(to , pdb_convert(&from->uni_dir_drive ), True);
- if (from->uni_logon_script.buffer)
- pdb_set_logon_script(to , pdb_convert(&from->uni_logon_script), True);
- if (from->uni_profile_path.buffer)
- pdb_set_profile_path(to , pdb_convert(&from->uni_profile_path), True);
- if (from->uni_acct_desc.buffer)
- pdb_set_acct_desc(to , pdb_convert(&from->uni_acct_desc ));
- if (from->uni_workstations.buffer)
- pdb_set_workstations(to , pdb_convert(&from->uni_workstations));
- if (from->uni_unknown_str.buffer)
- pdb_set_unknown_str(to , pdb_convert(&from->uni_unknown_str ));
- if (from->uni_munged_dial.buffer)
- pdb_set_munged_dial(to , pdb_convert(&from->uni_munged_dial ));
-
- if (from->user_rid)
- pdb_set_user_rid(to, from->user_rid);
- if (from->group_rid)
- pdb_set_group_rid(to, from->group_rid);
-
- pdb_set_acct_ctrl(to, from->acb_info);
- pdb_set_unknown_3(to, from->unknown_3);
-
- pdb_set_logon_divs(to, from->logon_divs);
- pdb_set_hours_len(to, from->logon_hrs.len);
- pdb_set_hours(to, from->logon_hrs.hours);
-
- pdb_set_unknown_5(to, from->unknown_5);
- pdb_set_unknown_6(to, from->unknown_6);
-}
-
-
-/*************************************************************
- Copies a sam passwd.
- **************************************************************/
-
-void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
-{
- if (from == NULL || to == NULL)
- return;
-
- pdb_set_logon_time(to,nt_time_to_unix(&from->logon_time), True);
- pdb_set_logoff_time(to,nt_time_to_unix(&from->logoff_time), True);
- pdb_set_kickoff_time(to, nt_time_to_unix(&from->kickoff_time), True);
- pdb_set_pass_can_change_time(to, nt_time_to_unix(&from->pass_can_change_time), True);
- pdb_set_pass_must_change_time(to, nt_time_to_unix(&from->pass_must_change_time), True);
-
- 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 ));
- if (from->uni_full_name.buffer)
- pdb_set_fullname(to , pdb_convert(&from->uni_full_name ));
- if (from->uni_home_dir.buffer)
- pdb_set_homedir(to , pdb_convert(&from->uni_home_dir ), True);
- if (from->uni_dir_drive.buffer)
- pdb_set_dir_drive(to , pdb_convert(&from->uni_dir_drive ), True);
- if (from->uni_logon_script.buffer)
- pdb_set_logon_script(to , pdb_convert(&from->uni_logon_script), True);
- if (from->uni_profile_path.buffer)
- pdb_set_profile_path(to , pdb_convert(&from->uni_profile_path), True);
- if (from->uni_acct_desc.buffer)
- pdb_set_acct_desc(to , pdb_convert(&from->uni_acct_desc ));
- if (from->uni_workstations.buffer)
- pdb_set_workstations(to , pdb_convert(&from->uni_workstations));
- if (from->uni_unknown_str.buffer)
- pdb_set_unknown_str(to , pdb_convert(&from->uni_unknown_str ));
- if (from->uni_munged_dial.buffer)
- pdb_set_munged_dial(to , pdb_convert(&from->uni_munged_dial ));
-
- if (from->user_rid)
- pdb_set_user_rid(to, from->user_rid);
- if (from->group_rid)
- pdb_set_group_rid(to, from->group_rid);
-
- /* FIXME!! Do we need to copy the passwords here as well?
- I don't know. Need to figure this out --jerry */
-
- /* Passwords dealt with in caller --abartlet */
-
- pdb_set_acct_ctrl(to, from->acb_info);
- pdb_set_unknown_3(to, from->unknown_3);
-
- pdb_set_logon_divs(to, from->logon_divs);
- pdb_set_hours_len(to, from->logon_hrs.len);
- pdb_set_hours(to, from->logon_hrs.hours);
-
- pdb_set_unknown_5(to, from->unknown_5);
- pdb_set_unknown_6(to, from->unknown_6);
-}
-
-
-/*************************************************************
Change a password entry in the local smbpasswd file.
FIXME!! The function needs to be abstracted into the
diff --git a/source3/passdb/passgrp.c b/source3/passdb/passgrp.c
index d7ed965648..f73591793f 100644
--- a/source3/passdb/passgrp.c
+++ b/source3/passdb/passgrp.c
@@ -21,6 +21,9 @@
#include "includes.h"
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_PASSDB
+
/*
* NOTE. All these functions are abstracted into a structure
* that points to the correct function for the selected database. JRA.
diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c
index cf77efd38f..dff4b40f4d 100644
--- a/source3/passdb/pdb_get_set.c
+++ b/source3/passdb/pdb_get_set.c
@@ -5,6 +5,7 @@
Copyright (C) Luke Kenneth Casson Leighton 1996-1998
Copyright (C) Gerald (Jerry) Carter 2000-2001
Copyright (C) Andrew Bartlett 2001-2002
+ Copyright (C) Stefan (metze) Metzmacher 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
@@ -23,6 +24,9 @@
#include "includes.h"
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_PASSDB
+
/**
* @todo Redefine this to NULL, but this changes the API becouse
* much of samba assumes that the pdb_get...() funtions
@@ -138,22 +142,36 @@ const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass)
return (NULL);
}
-uint32 pdb_get_user_rid (const SAM_ACCOUNT *sampass)
+/* 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 (sampass->private.user_rid);
+ if (sampass) {
+ return ((char*)sampass->private.plaintext_pw.data);
+ }
else
- return (-1);
+ return (NULL);
}
-
-uint32 pdb_get_group_rid (const SAM_ACCOUNT *sampass)
+const DOM_SID *pdb_get_user_sid(const SAM_ACCOUNT *sampass)
{
- if (sampass)
- return (sampass->private.group_rid);
+ if (sampass)
+ return &sampass->private.user_sid;
else
- return (-1);
+ return (NULL);
}
+const DOM_SID *pdb_get_group_sid(const SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return &sampass->private.group_sid;
+ else
+ return (NULL);
+}
+
/**
* Get flags showing what is initalised in the SAM_ACCOUNT
* @param sampass the SAM_ACCOUNT in question
@@ -224,6 +242,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)
@@ -461,27 +487,72 @@ BOOL pdb_set_gid (SAM_ACCOUNT *sampass, const gid_t gid)
}
-BOOL pdb_set_user_rid (SAM_ACCOUNT *sampass, uint32 rid)
+BOOL pdb_set_user_sid (SAM_ACCOUNT *sampass, DOM_SID *u_sid)
{
- if (!sampass)
+ if (!sampass || !u_sid)
return False;
+
+ sid_copy(&sampass->private.user_sid, u_sid);
- DEBUG(10, ("pdb_set_rid: setting user rid %d, was %d\n",
- rid, sampass->private.user_rid));
-
- sampass->private.user_rid = rid;
+ DEBUG(10, ("pdb_set_user_sid: setting user sid %s\n",
+ sid_string_static(&sampass->private.user_sid)));
+
return True;
}
-BOOL pdb_set_group_rid (SAM_ACCOUNT *sampass, uint32 grid)
+BOOL pdb_set_user_sid_from_string (SAM_ACCOUNT *sampass, fstring u_sid)
{
- if (!sampass)
+ DOM_SID new_sid;
+ if (!sampass || !u_sid)
return False;
- DEBUG(10, ("pdb_set_group_rid: setting group rid %d, was %d\n",
- grid, sampass->private.group_rid));
-
- sampass->private.group_rid = grid;
+ DEBUG(10, ("pdb_set_user_sid_from_string: setting user sid %s\n",
+ u_sid));
+
+ if (!string_to_sid(&new_sid, u_sid)) {
+ DEBUG(1, ("pdb_set_user_sid_from_string: %s isn't a valid SID!\n", u_sid));
+ return False;
+ }
+
+ if (!pdb_set_user_sid(sampass, &new_sid)) {
+ DEBUG(1, ("pdb_set_user_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", u_sid));
+ return False;
+ }
+
+ return True;
+}
+
+BOOL pdb_set_group_sid (SAM_ACCOUNT *sampass, DOM_SID *g_sid)
+{
+ if (!sampass || !g_sid)
+ return False;
+
+ sid_copy(&sampass->private.group_sid, g_sid);
+
+ DEBUG(10, ("pdb_set_group_sid: setting group sid %s\n",
+ sid_string_static(&sampass->private.group_sid)));
+
+ return True;
+}
+
+BOOL pdb_set_group_sid_from_string (SAM_ACCOUNT *sampass, fstring g_sid)
+{
+ DOM_SID new_sid;
+ if (!sampass || !g_sid)
+ return False;
+
+ DEBUG(10, ("pdb_set_group_sid_from_string: setting group sid %s\n",
+ g_sid));
+
+ if (!string_to_sid(&new_sid, g_sid)) {
+ DEBUG(1, ("pdb_set_group_sid_from_string: %s isn't a valid SID!\n", g_sid));
+ return False;
+ }
+
+ if (!pdb_set_group_sid(sampass, &new_sid)) {
+ DEBUG(1, ("pdb_set_group_sid_from_string: could not set sid %s on SAM_ACCOUNT!\n", g_sid));
+ return False;
+ }
return True;
}
@@ -618,7 +689,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 +721,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 +753,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);
}
@@ -714,7 +785,7 @@ BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, const char *home_dir, BOOL store)
}
if (store) {
- DEBUG(10, ("pdb_set_homedir: setting home dir sam flag!"));
+ DEBUG(10, ("pdb_set_homedir: setting home dir sam flag!\n"));
pdb_set_init_flag(sampass, FLAG_SAM_SMBHOME);
}
@@ -722,6 +793,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_unix_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 +939,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 +951,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 435b627da6..3b0f54b2b3 100644
--- a/source3/passdb/pdb_interface.c
+++ b/source3/passdb/pdb_interface.c
@@ -1,18 +1,19 @@
/*
Unix SMB/CIFS implementation.
Password and authentication handling
- Copyright (C) Andrew Bartlett 2002
-
+ Copyright (C) Andrew Bartlett 2002
+ 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.
@@ -20,6 +21,9 @@
#include "includes.h"
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_PASSDB
+
/** List of various built-in passdb modules */
const struct pdb_init_function_entry builtin_pdb_init_functions[] = {
@@ -29,102 +33,199 @@ 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 },
-#if 0
- { "nisplus", pdb_init_nisplus },
- { "unix", pdb_init_unix },
-#endif
+ { "unixsam", pdb_init_unixsam },
{ "plugin", pdb_init_plugin },
{ NULL, NULL}
};
static BOOL context_setsampwent(struct pdb_context *context, BOOL update)
{
- if ((!context) || (!context->pdb_selected)) {
+ if ((!context) || (!context->pdb_methods) || (!context->pdb_methods->setsampwent)) {
DEBUG(0, ("invalid pdb_context specified!\n"));
return False;
}
-
- return context->pdb_selected->setsampwent(context, 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;
+ }
+ return True;
}
static void context_endsampwent(struct pdb_context *context)
{
- if ((!context) || (!context->pdb_selected)) {
+ if ((!context)){
DEBUG(0, ("invalid pdb_context specified!\n"));
return;
}
-
- context->pdb_selected->endsampwent(context);
+
+ if (context->pwent_methods && context->pwent_methods->endsampwent)
+ context->pwent_methods->endsampwent(context->pwent_methods);
+
+ /* So we won't get strange data when calling getsampwent now */
+ context->pwent_methods = NULL;
}
static BOOL context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
{
- if ((!context) || (!context->pdb_selected)) {
+ if ((!context) || (!context->pwent_methods)) {
DEBUG(0, ("invalid pdb_context specified!\n"));
return False;
}
+ /* Loop until we find something useful */
+ while ((!context->pwent_methods->getsampwent) ||
+ context->pwent_methods->getsampwent(context->pwent_methods, user) == False){
+
+ if (context->pwent_methods->endsampwent)
+ context->pwent_methods->endsampwent(context->pwent_methods);
+
+ context->pwent_methods = context->pwent_methods->next;
+
+ /* All methods are checked now. There are no more entries */
+ if (context->pwent_methods == NULL)
+ return False;
- return context->pdb_selected->getsampwent(context, user);
+ if (!context->pwent_methods->setsampwent){
+ DEBUG(5, ("next backend does not implment setsampwent\n"));
+ return False;
+ }
+
+ context->pwent_methods->setsampwent(context->pwent_methods, False);
+ }
+ user->methods = context->pwent_methods;
+ return True;
}
static BOOL context_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username)
{
- if ((!context) || (!context->pdb_selected)) {
+ struct pdb_methods *curmethods;
+ if ((!context)) {
DEBUG(0, ("invalid pdb_context specified!\n"));
return False;
}
-
- return context->pdb_selected->getsampwnam(context, sam_acct, username);
+ curmethods = context->pdb_methods;
+ while (curmethods){
+ if (curmethods->getsampwnam && curmethods->getsampwnam(curmethods, sam_acct, username) == True){
+ sam_acct->methods = curmethods;
+ return True;
+ }
+ curmethods = curmethods->next;
+ }
+
+ return False;
}
-static BOOL context_getsampwrid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, uint32 rid)
+static BOOL context_getsampwsid(struct pdb_context *context, SAM_ACCOUNT *sam_acct, DOM_SID *sid)
{
- if ((!context) || (!context->pdb_selected)) {
+ struct pdb_methods *curmethods;
+ if ((!context)) {
DEBUG(0, ("invalid pdb_context specified!\n"));
return False;
}
- return context->pdb_selected->getsampwrid(context, sam_acct, rid);
+ curmethods = context->pdb_methods;
+
+ while (curmethods){
+ if (curmethods->getsampwsid && curmethods->getsampwsid(curmethods, sam_acct, sid) == True){
+ sam_acct->methods = curmethods;
+ return True;
+ }
+ curmethods = curmethods->next;
+ }
+
+ return False;
}
static BOOL context_add_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
{
- if ((!context) || (!context->pdb_selected)) {
+ if ((!context) || (!context->pdb_methods) || (!context->pdb_methods->add_sam_account)) {
DEBUG(0, ("invalid pdb_context specified!\n"));
return False;
}
-
+
/** @todo This is where a 're-read on add' should be done */
-
- return context->pdb_selected->add_sam_account(context, sam_acct);
+ /* We now add a new account to the first database listed.
+ * Should we? */
+
+ return context->pdb_methods->add_sam_account(context->pdb_methods, sam_acct);
}
static BOOL context_update_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
{
- if ((!context) || (!context->pdb_selected)) {
+ if (!context) {
DEBUG(0, ("invalid pdb_context specified!\n"));
return False;
}
-
+
+ if (!sam_acct || !sam_acct->methods){
+ DEBUG(0, ("invalid sam_acct specified\n"));
+ return False;
+ }
+
+ if (!sam_acct->methods->update_sam_account){
+ DEBUG(0, ("invalid sam_acct->methods\n"));
+ return False;
+ }
+
/** @todo This is where a 're-read on update' should be done */
-
- return context->pdb_selected->update_sam_account(context, sam_acct);
+
+ return sam_acct->methods->update_sam_account(sam_acct->methods, sam_acct);
}
static BOOL context_delete_sam_account(struct pdb_context *context, SAM_ACCOUNT *sam_acct)
{
- if ((!context) || (!context->pdb_selected)) {
+ struct pdb_methods *pdb_selected;
+ if (!context) {
DEBUG(0, ("invalid pdb_context specified!\n"));
return False;
}
+
+ if (!sam_acct->methods){
+ pdb_selected = context->pdb_methods;
+ /* There's no passdb backend specified for this account.
+ * Try to delete it in every passdb available
+ * Needed to delete accounts in smbpasswd that are not
+ * in /etc/passwd.
+ */
+ while (pdb_selected){
+ if (pdb_selected->delete_sam_account && pdb_selected->delete_sam_account(pdb_selected, sam_acct)){
+ return True;
+ }
+ pdb_selected = pdb_selected->next;
+ }
+ return False;
+ }
+
+ if (!sam_acct->methods->delete_sam_account){
+ DEBUG(0,("invalid sam_acct->methods->delete_sam_account\n"));
+ return False;
+ }
- return context->pdb_selected->delete_sam_account(context, sam_acct);
+ return sam_acct->methods->delete_sam_account(sam_acct->methods, sam_acct);
}
+/******************************************************************
+ Free and cleanup a pdb context, any associated data and anything
+ that the attached modules might have associated.
+ *******************************************************************/
+
static void free_pdb_context(struct pdb_context **context)
{
- if (((*context)->pdb_selected) && ((*context)->pdb_selected->free_private_data)) {
- (*context)->pdb_selected->free_private_data((*context)->pdb_selected->private_data);
+ struct pdb_methods *pdb_selected = (*context)->pdb_methods;
+
+ while (pdb_selected){
+ if (pdb_selected->free_private_data) {
+ pdb_selected->free_private_data(&(pdb_selected->private_data));
+ }
+ pdb_selected = pdb_selected->next;
}
talloc_destroy((*context)->mem_ctx);
@@ -132,13 +233,57 @@ static void free_pdb_context(struct pdb_context **context)
}
/******************************************************************
- Make a pdb_context from scratch.
-*******************************************************************/
+ Make a pdb_methods from scratch
+ *******************************************************************/
+
+static NTSTATUS make_pdb_methods_name(struct pdb_methods **methods, struct pdb_context *context, const char *selected)
+{
+ char *module_name = smb_xstrdup(selected);
+ char *module_location = NULL, *p;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ int i;
+
+ p = strchr(module_name, ':');
+
+ if (p) {
+ *p = 0;
+ module_location = p+1;
+ trim_string(module_location, " ", " ");
+ }
+
+ trim_string(module_name, " ", " ");
+
+ DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n", selected, module_name));
+ for (i = 0; builtin_pdb_init_functions[i].name; i++)
+ {
+ if (strequal(builtin_pdb_init_functions[i].name, module_name))
+ {
+ DEBUG(5,("Found pdb backend %s (at pos %d)\n", module_name, i));
+ nt_status = builtin_pdb_init_functions[i].init(context, methods, module_location);
+ if (NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(5,("pdb backend %s has a valid init\n", selected));
+ } else {
+ DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", selected, nt_errstr(nt_status)));
+ }
+ SAFE_FREE(module_name);
+ return nt_status;
+ break; /* unreached */
+ }
+ }
+
+ /* No such backend found */
+ SAFE_FREE(module_name);
+ return NT_STATUS_INVALID_PARAMETER;
+}
+
+/******************************************************************
+ Make a pdb_context from scratch.
+ *******************************************************************/
static NTSTATUS make_pdb_context(struct pdb_context **context)
{
TALLOC_CTX *mem_ctx;
-
+
mem_ctx = talloc_init_named("pdb_context internal allocation context");
if (!mem_ctx) {
@@ -160,82 +305,60 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
(*context)->pdb_endsampwent = context_endsampwent;
(*context)->pdb_getsampwent = context_getsampwent;
(*context)->pdb_getsampwnam = context_getsampwnam;
- (*context)->pdb_getsampwrid = context_getsampwrid;
+ (*context)->pdb_getsampwsid = context_getsampwsid;
(*context)->pdb_add_sam_account = context_add_sam_account;
(*context)->pdb_update_sam_account = context_update_sam_account;
(*context)->pdb_delete_sam_account = context_delete_sam_account;
(*context)->free_fn = free_pdb_context;
-
+
return NT_STATUS_OK;
}
/******************************************************************
- Make a pdb_context, given a text string.
-*******************************************************************/
+ Make a pdb_context, given an array of strings
+ *******************************************************************/
-NTSTATUS make_pdb_context_name(struct pdb_context **context, const char *selected)
+NTSTATUS make_pdb_context_list(struct pdb_context **context, char **selected)
{
- /* HINT: Don't store 'selected' becouse its often an lp_ string and
- will 'go away' */
+ int i = 0;
+ struct pdb_methods *curmethods, *tmpmethods;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
- int i;
- char *module_name = smb_xstrdup(selected);
- char *module_location = NULL;
- char *p;
- p = strchr(module_name, ':');
-
- if (p) {
- *p = 0;
-
- module_location = p+1;
-
- trim_string(module_location, " ", " ");
+ if (!NT_STATUS_IS_OK(nt_status = make_pdb_context(context))) {
+ return nt_status;
}
- trim_string(module_name, " ", " ");
-
- if (!NT_STATUS_IS_OK(nt_status = make_pdb_context(context)))
- goto done;
-
- DEBUG(5,("Attempting to find an passdb backend to match %s (%s)\n",
- selected, module_name));
-
- for (i = 0; builtin_pdb_init_functions[i].name; i++) {
- if (strequal(builtin_pdb_init_functions[i].name,
- module_name)) {
-
- DEBUG(5,("Found pdb backend %s (at pos %d)\n",
- module_name, i));
-
- if (NT_STATUS_IS_OK(nt_status = builtin_pdb_init_functions[i].init(*context, &(*context)->pdb_selected, module_location))) {
- DEBUG(5,("pdb backend %s has a valid init\n", selected));
- } else {
- DEBUG(0,("pdb backend %s did not correctly init (error was %s)\n", selected, nt_errstr(nt_status)));
- (*context)->pdb_selected = NULL;
- }
- break;
+ while (selected[i]){
+ /* Try to initialise pdb */
+ DEBUG(5,("Trying to load: %s\n", selected[i]));
+ if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods_name(&curmethods, *context, selected[i]))) {
+ DEBUG(1, ("Loading %s failed!\n", selected[i]));
+ free_pdb_context(context);
+ return nt_status;
}
- }
-
- if (!(*context)->pdb_selected) {
- DEBUG(0,("failed to select passdb backed!\n"));
- talloc_destroy((*context)->mem_ctx);
- *context = NULL;
- goto done;
+ curmethods->parent = *context;
+ DLIST_ADD_END((*context)->pdb_methods, curmethods, tmpmethods);
+ i++;
}
- nt_status = NT_STATUS_OK;
+ return NT_STATUS_OK;
+}
- done:
- SAFE_FREE(module_name);
+/******************************************************************
+ Make a pdb_context, given a text string.
+ *******************************************************************/
- return nt_status;
+NTSTATUS make_pdb_context_string(struct pdb_context **context, const char *selected)
+{
+ NTSTATUS ret;
+ char **newsel = str_list_make(selected);
+ ret = make_pdb_context_list(context, newsel);
+ str_list_free(&newsel);
+ return ret;
}
-
/******************************************************************
Return an already initialised pdb_context, to facilitate backward
compatibility (see functions below).
@@ -244,20 +367,20 @@ NTSTATUS make_pdb_context_name(struct pdb_context **context, const char *selecte
static struct pdb_context *pdb_get_static_context(BOOL reload)
{
static struct pdb_context *pdb_context = NULL;
-
+
if ((pdb_context) && (reload)) {
pdb_context->free_fn(&pdb_context);
- if (!NT_STATUS_IS_OK(make_pdb_context_name(&pdb_context, lp_passdb_backend()))) {
+ if (!NT_STATUS_IS_OK(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) {
return NULL;
}
}
-
+
if (!pdb_context) {
- if (!NT_STATUS_IS_OK(make_pdb_context_name(&pdb_context, lp_passdb_backend()))) {
+ if (!NT_STATUS_IS_OK(make_pdb_context_list(&pdb_context, lp_passdb_backend()))) {
return NULL;
}
}
-
+
return pdb_context;
}
@@ -311,7 +434,7 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT *sam_acct, const char *username)
return pdb_context->pdb_getsampwnam(pdb_context, sam_acct, username);
}
-BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct, uint32 rid)
+BOOL pdb_getsampwsid(SAM_ACCOUNT *sam_acct, DOM_SID *sid)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -319,7 +442,7 @@ BOOL pdb_getsampwrid(SAM_ACCOUNT *sam_acct, uint32 rid)
return False;
}
- return pdb_context->pdb_getsampwrid(pdb_context, sam_acct, rid);
+ return pdb_context->pdb_getsampwsid(pdb_context, sam_acct, sid);
}
BOOL pdb_add_sam_account(SAM_ACCOUNT *sam_acct)
@@ -347,21 +470,21 @@ BOOL pdb_update_sam_account(SAM_ACCOUNT *sam_acct)
BOOL pdb_delete_sam_account(SAM_ACCOUNT *sam_acct)
{
struct pdb_context *pdb_context = pdb_get_static_context(False);
-
+
if (!pdb_context) {
return False;
}
-
+
return pdb_context->pdb_delete_sam_account(pdb_context, sam_acct);
}
#endif /* !defined(WITH_NISPLUS_SAM) */
/***************************************************************
- Initialize the static context (at smbd startup etc).
+ Initialize the static context (at smbd startup etc).
- If uninitialised, context will auto-init on first use.
-***************************************************************/
+ If uninitialised, context will auto-init on first use.
+ ***************************************************************/
BOOL initialize_password_db(BOOL reload)
{
@@ -381,11 +504,3 @@ NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods)
return NT_STATUS_OK;
}
-
-
-
-
-
-
-
-
diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c
index 02bb43b7ff..24eb7b9dc1 100644
--- a/source3/passdb/pdb_ldap.c
+++ b/source3/passdb/pdb_ldap.c
@@ -24,7 +24,10 @@
#include "includes.h"
-#ifdef WITH_LDAP_SAM
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_PASSDB
+
+#ifdef HAVE_LDAP
/* TODO:
* persistent connections: if using NSS LDAP, many connections are made
* however, using only one within Samba would be nice
@@ -72,55 +75,77 @@ struct ldapsam_privates {
static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state);
/*******************************************************************
- Converts NT user RID to a UNIX uid.
- ********************************************************************/
-
-static uid_t pdb_user_rid_to_uid(uint32 user_rid)
-{
- return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER);
-}
-
-/*******************************************************************
- converts UNIX uid to an NT User RID.
- ********************************************************************/
-
-static uint32 pdb_uid_to_user_rid(uid_t uid)
-{
- return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE);
-}
-
-/*******************************************************************
find the ldap password
******************************************************************/
-static BOOL fetch_ldapsam_pw(char *dn, char* pw, int len)
+static BOOL fetch_ldapsam_pw(char **dn, char** pw)
{
- fstring key;
- char *p;
- void *data = NULL;
+ char *key = NULL;
size_t size;
- pstrcpy(key, dn);
- for (p=key; *p; p++)
- if (*p == ',') *p = '/';
+ *dn = smb_xstrdup(lp_ldap_admin_dn());
- data=secrets_fetch(key, &size);
- if (!size) {
- DEBUG(0,("fetch_ldap_pw: no ldap secret retrieved!\n"));
- return False;
+ if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, *dn) < 0) {
+ SAFE_FREE(*dn);
+ DEBUG(0, ("fetch_ldapsam_pw: asprintf failed!\n"));
}
- if (size > len-1)
- {
- DEBUG(0,("fetch_ldap_pw: ldap secret is too long (%d > %d)!\n", size, len-1));
- return False;
- }
+ *pw=secrets_fetch(key, &size);
+ if (!size) {
+ /* Upgrade 2.2 style entry */
+ char *p;
+ char* old_style_key = strdup(*dn);
+ char *data;
+ fstring old_style_pw;
+
+ if (!old_style_key) {
+ DEBUG(0, ("fetch_ldapsam_pw: strdup failed!\n"));
+ return False;
+ }
- memcpy(pw, data, size);
- pw[size] = '\0';
+ for (p=old_style_key; *p; p++)
+ if (*p == ',') *p = '/';
+
+ data=secrets_fetch(old_style_key, &size);
+ if (!size && size < sizeof(old_style_pw)) {
+ DEBUG(0,("fetch_ldap_pw: neither ldap secret retrieved!\n"));
+ SAFE_FREE(old_style_key);
+ SAFE_FREE(*dn);
+ return False;
+ }
+
+ strncpy(old_style_pw, data, size);
+ old_style_pw[size] = 0;
+
+ SAFE_FREE(data);
+
+ if (!secrets_store_ldap_pw(*dn, old_style_pw)) {
+ DEBUG(0,("fetch_ldap_pw: ldap secret could not be upgraded!\n"));
+ SAFE_FREE(old_style_key);
+ SAFE_FREE(*dn);
+ return False;
+ }
+ if (!secrets_delete(old_style_key)) {
+ DEBUG(0,("fetch_ldap_pw: old ldap secret could not be deleted!\n"));
+ }
+
+ SAFE_FREE(old_style_key);
+
+ *pw = smb_xstrdup(old_style_pw);
+ }
return True;
}
+static const char *attr[] = {"uid", "pwdLastSet", "logonTime",
+ "logoffTime", "kickoffTime", "cn",
+ "pwdCanChange", "pwdMustChange",
+ "displayName", "homeDrive",
+ "smbHome", "scriptPath",
+ "profilePath", "description",
+ "userWorkstations", "rid",
+ "primaryGroupID", "lmPassword",
+ "ntPassword", "acctFlags",
+ "domain", "description", NULL };
/*******************************************************************
open a connection to the ldap server.
@@ -225,20 +250,57 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP *
return True;
}
+
+/*******************************************************************
+ Add a rebind function for authenticated referrals
+******************************************************************/
+
+static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
+ int *method, int freeit )
+{
+ int rc;
+ char *ldap_dn;
+ char *ldap_secret;
+
+ /** @TODO Should we be doing something to check what servers we rebind to?
+ Could we get a referral to a machine that we don't want to give our
+ username and password to? */
+
+ if (freeit != 0)
+ {
+
+ if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
+ {
+ DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
+ return LDAP_OPERATIONS_ERROR; /* No idea what to return */
+ }
+
+ DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
+ ldap_dn));
+
+ rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
+
+ SAFE_FREE(ldap_dn);
+ SAFE_FREE(ldap_secret);
+
+ return rc;
+ }
+ return 0;
+}
+
/*******************************************************************
connect to the ldap server under system privilege.
******************************************************************/
static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * ldap_struct)
{
int rc;
- static BOOL got_pw = False;
- static pstring ldap_secret;
+ char *ldap_dn;
+ char *ldap_secret;
- /* get the password if we don't have it already */
- if (!got_pw && !(got_pw=fetch_ldapsam_pw(lp_ldap_admin_dn(), ldap_secret, sizeof(pstring))))
+ /* get the password */
+ if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
{
- DEBUG(0, ("ldap_connect_system: Failed to retrieve password for %s from secrets.tdb\n",
- lp_ldap_admin_dn()));
+ DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
return False;
}
@@ -246,10 +308,16 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l
(OpenLDAP) doesnt' seem to support it */
DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n",
- lp_ldap_admin_dn()));
-
- if ((rc = ldap_simple_bind_s(ldap_struct, lp_ldap_admin_dn(),
- ldap_secret)) != LDAP_SUCCESS)
+ ldap_dn));
+
+ ldap_set_rebind_proc(ldap_struct, (LDAP_REBIND_PROC *)(&rebindproc));
+
+ rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
+
+ SAFE_FREE(ldap_dn);
+ SAFE_FREE(ldap_secret);
+
+ if (rc != LDAP_SUCCESS)
{
DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc)));
return False;
@@ -269,7 +337,7 @@ static int ldapsam_search_one_user (struct ldapsam_privates *ldap_state, LDAP *
DEBUG(2, ("ldapsam_search_one_user: searching for:[%s]\n", filter));
- rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, NULL, 0, result);
+ rc = ldap_search_s(ldap_struct, lp_ldap_suffix (), scope, filter, attr, 0, result);
if (rc != LDAP_SUCCESS) {
DEBUG(0,("ldapsam_search_one_user: Problem during the LDAP search: %s\n",
@@ -347,7 +415,7 @@ static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state,
if (rc != LDAP_SUCCESS)
rc = ldapsam_search_one_user_by_uid(ldap_state, ldap_struct,
- pdb_user_rid_to_uid(rid),
+ fallback_pdb_user_rid_to_uid(rid),
result);
return rc;
@@ -357,7 +425,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,10 +589,14 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
get_single_attribute(ldap_struct, entry, "rid", temp);
user_rid = (uint32)atol(temp);
+
+ pdb_set_user_sid_from_rid(sampass, user_rid);
+
if (!get_single_attribute(ldap_struct, entry, "primaryGroupID", temp)) {
group_rid = 0;
} else {
group_rid = (uint32)atol(temp);
+ pdb_set_group_sid_from_rid(sampass, group_rid);
}
if ((ldap_state->permit_non_unix_accounts)
@@ -539,12 +611,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 ave a uid!\n", username));
+ DEBUG (2,("init_sam_from_ldap: User [%s] does not exist via system getpwnam!\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);
@@ -554,10 +628,10 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
GROUP_MAP map;
/* call the mapping code here */
if(get_group_map_from_gid(gid, &map, MAPPING_WITHOUT_PRIV)) {
- sid_peek_rid(&map.sid, &group_rid);
+ pdb_set_group_sid(sampass, &map.sid);
}
else {
- group_rid=pdb_gid_to_group_rid(gid);
+ pdb_set_group_sid_from_rid(sampass, pdb_gid_to_group_rid(gid));
}
}
}
@@ -621,37 +695,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, talloc_sub_specified(sampass->mem_ctx,
+ lp_logon_drive(),
+ 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_homedir(sampass, talloc_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, talloc_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, talloc_sub_specified(sampass->mem_ctx,
+ lp_logon_path(),
+ username, domain,
+ uid, gid),
+ False);
} else {
pdb_set_profile_path(sampass, profile_path, True);
}
@@ -706,9 +784,6 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pdb_set_hours_len(sampass, hours_len);
pdb_set_logon_divs(sampass, logon_divs);
- pdb_set_user_rid(sampass, user_rid);
- pdb_set_group_rid(sampass, group_rid);
-
pdb_set_username(sampass, username);
pdb_set_domain(sampass, domain);
@@ -754,7 +829,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
if ( pdb_get_user_rid(sampass) ) {
rid = pdb_get_user_rid(sampass);
} else if (IS_SAM_SET(sampass, FLAG_SAM_UID)) {
- rid = pdb_uid_to_user_rid(pdb_get_uid(sampass));
+ rid = fallback_pdb_uid_to_user_rid(pdb_get_uid(sampass));
} else if (ldap_state->permit_non_unix_accounts) {
rid = ldapsam_get_next_available_nua_rid(ldap_state);
if (rid == 0) {
@@ -932,7 +1007,7 @@ static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap
DEBUG(2, ("ldapsam_get_next_available_nua_rid: searching for:[%s]\n", final_filter));
rc = ldap_search_s(ldap_struct, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, final_filter, NULL, 0,
+ LDAP_SCOPE_SUBTREE, final_filter, attr, 0,
&result);
if (rc != LDAP_SUCCESS)
@@ -973,6 +1048,10 @@ static uint32 search_top_nua_rid(struct ldapsam_privates *ldap_state, LDAP *ldap
}
ldap_msgfree(result);
+
+ if (top_rid < ldap_state->low_nua_rid)
+ top_rid = ldap_state->low_nua_rid;
+
return top_rid;
}
@@ -1006,9 +1085,9 @@ static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_s
/**********************************************************************
Connect to LDAP server for password enumeration
*********************************************************************/
-static BOOL ldapsam_setsampwent(struct pdb_context *context, BOOL update)
+static BOOL ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
int rc;
pstring filter;
@@ -1026,7 +1105,7 @@ static BOOL ldapsam_setsampwent(struct pdb_context *context, BOOL update)
all_string_sub(filter, "%u", "*", sizeof(pstring));
rc = ldap_search_s(ldap_state->ldap_struct, lp_ldap_suffix(),
- LDAP_SCOPE_SUBTREE, filter, NULL, 0,
+ LDAP_SCOPE_SUBTREE, filter, attr, 0,
&ldap_state->result);
if (rc != LDAP_SUCCESS)
@@ -1054,9 +1133,9 @@ static BOOL ldapsam_setsampwent(struct pdb_context *context, BOOL update)
/**********************************************************************
End enumeration of the LDAP password list
*********************************************************************/
-static void ldapsam_endsampwent(struct pdb_context *context)
+static void ldapsam_endsampwent(struct pdb_methods *my_methods)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
if (ldap_state->ldap_struct && ldap_state->result)
{
ldap_msgfree(ldap_state->result);
@@ -1069,9 +1148,9 @@ static void ldapsam_endsampwent(struct pdb_context *context)
/**********************************************************************
Get the next entry in the LDAP password database
*********************************************************************/
-static BOOL ldapsam_getsampwent(struct pdb_context *context, SAM_ACCOUNT * user)
+static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * user)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
BOOL ret = False;
while (!ret) {
@@ -1093,9 +1172,9 @@ static BOOL ldapsam_getsampwent(struct pdb_context *context, SAM_ACCOUNT * user)
/**********************************************************************
Get SAM_ACCOUNT entry from LDAP by username
*********************************************************************/
-static BOOL ldapsam_getsampwnam(struct pdb_context *context, SAM_ACCOUNT * user, const char *sname)
+static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * user, const char *sname)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
LDAP *ldap_struct;
LDAPMessage *result;
LDAPMessage *entry;
@@ -1144,9 +1223,9 @@ static BOOL ldapsam_getsampwnam(struct pdb_context *context, SAM_ACCOUNT * user,
/**********************************************************************
Get SAM_ACCOUNT entry from LDAP by rid
*********************************************************************/
-static BOOL ldapsam_getsampwrid(struct pdb_context *context, SAM_ACCOUNT * user, uint32 rid)
+static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, uint32 rid)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
LDAP *ldap_struct;
LDAPMessage *result;
LDAPMessage *entry;
@@ -1196,12 +1275,20 @@ static BOOL ldapsam_getsampwrid(struct pdb_context *context, SAM_ACCOUNT * user,
}
}
+static BOOL ldapsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
+{
+ uint32 rid;
+ if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
+ return False;
+ return ldapsam_getsampwrid(my_methods, user, rid);
+}
+
/**********************************************************************
Delete entry from LDAP for username
*********************************************************************/
-static BOOL ldapsam_delete_sam_account(struct pdb_context *context, const SAM_ACCOUNT * sam_acct)
+static BOOL ldapsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * sam_acct)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
const char *sname;
int rc;
char *dn;
@@ -1259,9 +1346,9 @@ static BOOL ldapsam_delete_sam_account(struct pdb_context *context, const SAM_AC
/**********************************************************************
Update SAM_ACCOUNT
*********************************************************************/
-static BOOL ldapsam_update_sam_account(struct pdb_context *context, const SAM_ACCOUNT * newpwd)
+static BOOL ldapsam_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
int rc;
char *dn;
LDAP *ldap_struct;
@@ -1326,9 +1413,9 @@ static BOOL ldapsam_update_sam_account(struct pdb_context *context, const SAM_AC
/**********************************************************************
Add SAM_ACCOUNT to LDAP
*********************************************************************/
-static BOOL ldapsam_add_sam_account(struct pdb_context *context, const SAM_ACCOUNT * newpwd)
+static BOOL ldapsam_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT * newpwd)
{
- struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)context->pdb_selected->private_data;
+ struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
int rc;
pstring filter;
LDAP *ldap_struct = NULL;
@@ -1463,7 +1550,7 @@ NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, co
(*pdb_method)->endsampwent = ldapsam_endsampwent;
(*pdb_method)->getsampwent = ldapsam_getsampwent;
(*pdb_method)->getsampwnam = ldapsam_getsampwnam;
- (*pdb_method)->getsampwrid = ldapsam_getsampwrid;
+ (*pdb_method)->getsampwsid = ldapsam_getsampwsid;
(*pdb_method)->add_sam_account = ldapsam_add_sam_account;
(*pdb_method)->update_sam_account = ldapsam_update_sam_account;
(*pdb_method)->delete_sam_account = ldapsam_delete_sam_account;
@@ -1511,9 +1598,9 @@ NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method
return NT_STATUS_UNSUCCESSFUL;
}
- ldap_state->low_nua_rid=pdb_uid_to_user_rid(low_nua_uid);
+ ldap_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid);
- ldap_state->high_nua_rid=pdb_uid_to_user_rid(high_nua_uid);
+ ldap_state->high_nua_rid=fallback_pdb_uid_to_user_rid(high_nua_uid);
return NT_STATUS_OK;
}
@@ -1523,13 +1610,13 @@ NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method
NTSTATUS pdb_init_ldapsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
{
- DEBUG(0, ("ldapsam not compiled in!\n"));
+ DEBUG(0, ("ldap not detected at configure time, ldapsam not availalble!\n"));
return NT_STATUS_UNSUCCESSFUL;
}
NTSTATUS pdb_init_ldapsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
{
- DEBUG(0, ("ldapsam_nua not compiled in!\n"));
+ DEBUG(0, ("ldap not dectected at configure time, ldapsam_nua not available!\n"));
return NT_STATUS_UNSUCCESSFUL;
}
diff --git a/source3/passdb/pdb_nisplus.c b/source3/passdb/pdb_nisplus.c
index 145e1d4f0c..9c5b2e1171 100644
--- a/source3/passdb/pdb_nisplus.c
+++ b/source3/passdb/pdb_nisplus.c
@@ -56,7 +56,7 @@ struct nisp_enum_info
};
static struct nisp_enum_info global_nisp_ent;
-static VOLATILE sig_atomic_t gotalarm;
+static SIG_ATOMIC_T gotalarm;
/***************************************************************
@@ -339,8 +339,8 @@ static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, const nis_object *obj
pdb_set_uid(pw_buf, atoi(ENTRY_VAL(obj, NPF_UID)));
pdb_set_gid(pw_buf, atoi(ENTRY_VAL(obj, NPF_SMB_GRPID)));
- pdb_set_user_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_USER_RID)));
- pdb_set_group_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_GROUP_RID)));
+ pdb_set_user_sid_from_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_USER_RID)));
+ pdb_set_group_sid_from_rid(pw_buf, atoi(ENTRY_VAL(obj, NPF_GROUP_RID)));
/* values, must exist for user */
if( !(pdb_get_acct_ctrl(pw_buf) & ACB_WSTRUST) ) {
@@ -381,7 +381,7 @@ static BOOL make_sam_from_nisp_object(SAM_ACCOUNT *pw_buf, const nis_object *obj
else
{
/* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
- pdb_set_group_rid (pw_buf, DOMAIN_GROUP_RID_USERS);
+ pdb_set_group_sid_from_rid (pw_buf, DOMAIN_GROUP_RID_USERS);
}
/* Check the lanman password column. */
@@ -538,7 +538,8 @@ static BOOL init_nisp_from_sam(nis_object *obj, const SAM_ACCOUNT *sampass,
if (rid==0) {
if (get_group_map_from_gid(pdb_get_gid(sampass), &map, MAPPING_WITHOUT_PRIV)) {
- sid_peek_rid(&map.sid, &rid);
+ 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));
}
@@ -1030,7 +1031,16 @@ BOOL pdb_getsampwnam(SAM_ACCOUNT * user, const char *sname)
/*************************************************************************
Routine to search the nisplus passwd file for an entry matching the username
*************************************************************************/
-BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
+
+BOOL pdb_getsampwsid(SAM_ACCOUNT * user, DOM_SID *sid)
+{
+ uint32 rid;
+ if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
+ return False;
+ return pdb_getsampwrid(user, rid);
+}
+
+static BOOL pdb_getsampwrid(SAM_ACCOUNT * user, uint32 rid)
{
nis_result *result;
char *nisname;
diff --git a/source3/passdb/pdb_plugin.c b/source3/passdb/pdb_plugin.c
index 1de61abd5f..1a246631fe 100644
--- a/source3/passdb/pdb_plugin.c
+++ b/source3/passdb/pdb_plugin.c
@@ -21,11 +21,15 @@
#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"));
@@ -48,8 +52,23 @@ NTSTATUS pdb_init_plugin(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con
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){
+ 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;
}
diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c
index 89a4217c3b..8c7ba364b8 100644
--- a/source3/passdb/pdb_smbpasswd.c
+++ b/source3/passdb/pdb_smbpasswd.c
@@ -23,6 +23,8 @@
#include "includes.h"
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_PASSDB
/*
smb_passwd is analogous to sam_passwd used everywhere
@@ -69,24 +71,6 @@ struct smbpasswd_privates
enum pwf_access_type { PWF_READ, PWF_UPDATE, PWF_CREATE };
-/*******************************************************************
- Converts NT user RID to a UNIX uid.
- ********************************************************************/
-
-static uid_t pdb_user_rid_to_uid(uint32 user_rid)
-{
- return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER);
-}
-
-/*******************************************************************
- converts UNIX uid to an NT User RID.
- ********************************************************************/
-
-static uint32 pdb_uid_to_user_rid(uid_t uid)
-{
- return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE);
-}
-
/***************************************************************
Lock an fd. Abandon after waitsecs seconds.
****************************************************************/
@@ -117,6 +101,10 @@ static BOOL pw_file_unlock(int fd, int *plock_depth)
{
BOOL ret=True;
+ if (fd == 0 || *plock_depth == 0) {
+ return True;
+ }
+
if(*plock_depth == 1)
ret = do_file_lock(fd, 5, F_UNLCK);
@@ -198,7 +186,7 @@ static FILE *startsmbfilepwent(const char *pfile, enum pwf_access_type type, int
DEBUG(10, ("startsmbfilepwent_internal: opening file %s\n", pfile));
if((fp = sys_fopen(pfile, open_mode)) == NULL) {
- DEBUG(2, ("startsmbfilepwent_internal: unable to open file %s. Error was %s\n", pfile, strerror(errno) ));
+ DEBUG(0, ("startsmbfilepwent_internal: unable to open file %s. Error was %s\n", pfile, strerror(errno) ));
return NULL;
}
@@ -280,10 +268,13 @@ Error was %s\n.", pfile, strerror(errno) ));
****************************************************************/
static void endsmbfilepwent(FILE *fp, int *lock_depth)
{
+ if (!fp) {
+ return;
+ }
- pw_file_unlock(fileno(fp), lock_depth);
- fclose(fp);
- DEBUG(7, ("endsmbfilepwent_internal: closed password file.\n"));
+ pw_file_unlock(fileno(fp), lock_depth);
+ fclose(fp);
+ DEBUG(7, ("endsmbfilepwent_internal: closed password file.\n"));
}
/*************************************************************************
@@ -375,6 +366,8 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
* As 256 is shorter than a pstring we don't need to check
* length here - if this ever changes....
*/
+ SMB_ASSERT(sizeof(pstring) > sizeof(linebuf));
+
strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
user_name[PTR_DIFF(p, linebuf)] = '\0';
@@ -414,15 +407,6 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
/* Skip the ':' */
p++;
- if (*p == '*' || *p == 'X') {
- /* Password deliberately invalid - end here. */
- DEBUG(10, ("getsmbfilepwent: entry invalidated for user %s\n", user_name));
- pw_buf->smb_nt_passwd = NULL;
- pw_buf->smb_passwd = NULL;
- pw_buf->acct_ctrl |= ACB_DISABLED;
- return pw_buf;
- }
-
if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
DEBUG(0, ("getsmbfilepwent: malformed password entry (passwd too short)\n"));
continue;
@@ -437,11 +421,16 @@ static struct smb_passwd *getsmbfilepwent(struct smbpasswd_privates *smbpasswd_s
pw_buf->smb_passwd = NULL;
pw_buf->acct_ctrl |= ACB_PWNOTREQ;
} else {
- if (!pdb_gethexpwd((char *)p, smbpwd)) {
- DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n"));
- continue;
- }
- pw_buf->smb_passwd = smbpwd;
+ if (*p == '*' || *p == 'X') {
+ /* NULL LM password */
+ pw_buf->smb_passwd = NULL;
+ DEBUG(10, ("getsmbfilepwent: LM password for user %s invalidated\n", user_name));
+ } else if (pdb_gethexpwd((char *)p, smbpwd)) {
+ pw_buf->smb_passwd = smbpwd;
+ } else {
+ pw_buf->smb_passwd = NULL;
+ DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n"));
+ }
}
/*
@@ -524,7 +513,6 @@ static char *format_new_smbpasswd_entry(const struct smb_passwd *newpwd)
int new_entry_length;
char *new_entry;
char *p;
- int i;
new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2;
@@ -534,38 +522,16 @@ static char *format_new_smbpasswd_entry(const struct smb_passwd *newpwd)
}
slprintf(new_entry, new_entry_length - 1, "%s:%u:", newpwd->smb_name, (unsigned)newpwd->smb_userid);
- p = &new_entry[strlen(new_entry)];
- if(newpwd->smb_passwd != NULL) {
- for( i = 0; i < 16; i++) {
- slprintf((char *)&p[i*2], new_entry_length - (p - new_entry) - 1, "%02X", newpwd->smb_passwd[i]);
- }
- } else {
- i=0;
- if(newpwd->acct_ctrl & ACB_PWNOTREQ)
- safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
- else
- safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
- }
+ p = new_entry+strlen(new_entry);
- p += 32;
+ pdb_sethexpwd(p, newpwd->smb_passwd, newpwd->acct_ctrl);
- *p++ = ':';
+ p+=strlen(p); *p = ':'; p++;
- if(newpwd->smb_nt_passwd != NULL) {
- for( i = 0; i < 16; i++) {
- slprintf((char *)&p[i*2], new_entry_length - 1 - (p - new_entry), "%02X", newpwd->smb_nt_passwd[i]);
- }
- } else {
- if(newpwd->acct_ctrl & ACB_PWNOTREQ)
- safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
- else
- safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
- }
+ pdb_sethexpwd(p, newpwd->smb_nt_passwd, newpwd->acct_ctrl);
- p += 32;
-
- *p++ = ':';
+ p+=strlen(p); *p = ':'; p++;
/* Add the account encoding and the last change time. */
slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n",
@@ -712,7 +678,7 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, const struct smb_passwd* pwd)
{
/* Static buffers we will return. */
- char * user_name = smbpasswd_state->user_name;
+ pstring user_name;
char linebuf[256];
char readbuf[1024];
@@ -830,6 +796,9 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
* As 256 is shorter than a pstring we don't need to check
* length here - if this ever changes....
*/
+
+ SMB_ASSERT(sizeof(user_name) > sizeof(linebuf));
+
strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
user_name[PTR_DIFF(p, linebuf)] = '\0';
if (strequal(user_name, pwd->smb_name)) {
@@ -841,6 +810,9 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
if (!found_entry) {
pw_file_unlock(lockfd, &(smbpasswd_state->pw_file_lock_depth));
fclose(fp);
+
+ DEBUG(2, ("Cannot update entry for user %s, as they don't exist in the smbpasswd file!\n",
+ pwd->smb_name));
return False;
}
@@ -967,30 +939,12 @@ static BOOL mod_smbfilepwd_entry(struct smbpasswd_privates *smbpasswd_state, con
/* Entry is correctly formed. */
/* Create the 32 byte representation of the new p16 */
- if(pwd->smb_passwd != NULL) {
- for (i = 0; i < 16; i++) {
- slprintf(&ascii_p16[i*2], sizeof(fstring) - 1, "%02X", (uchar) pwd->smb_passwd[i]);
- }
- } else {
- if(pwd->acct_ctrl & ACB_PWNOTREQ)
- fstrcpy(ascii_p16, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
- else
- fstrcpy(ascii_p16, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
- }
+ pdb_sethexpwd(ascii_p16, pwd->smb_passwd, pwd->acct_ctrl);
/* Add on the NT md4 hash */
ascii_p16[32] = ':';
wr_len = 66;
- if (pwd->smb_nt_passwd != NULL) {
- for (i = 0; i < 16; i++) {
- slprintf(&ascii_p16[(i*2)+33], sizeof(fstring) - 1, "%02X", (uchar) pwd->smb_nt_passwd[i]);
- }
- } else {
- if(pwd->acct_ctrl & ACB_PWNOTREQ)
- fstrcpy(&ascii_p16[33], "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
- else
- fstrcpy(&ascii_p16[33], "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
- }
+ pdb_sethexpwd(ascii_p16+33, pwd->smb_nt_passwd, pwd->acct_ctrl);
ascii_p16[65] = ':';
ascii_p16[66] = '\0'; /* null-terminate the string so that strlen works */
@@ -1184,18 +1138,18 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
if (sampass == NULL)
return False;
- ZERO_STRUCTP(smb_pw);
+ ZERO_STRUCTP(smb_pw);
if (!IS_SAM_UNIX_USER(sampass)) {
smb_pw->smb_userid_set = False;
- DEBUG(5,("build_sam_pass: storing user without a UNIX uid or gid. \n"));
+ 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);
/* If the user specified a RID, make sure its able to be both stored and retreived */
- if (rid && uid != pdb_user_rid_to_uid(rid)) {
+ if (rid && 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;
}
@@ -1236,7 +1190,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;
@@ -1249,84 +1204,37 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, SAM_AC
&& (pw_buf->smb_userid >= smbpasswd_state->low_nua_userid)
&& (pw_buf->smb_userid <= smbpasswd_state->high_nua_userid)) {
- pdb_set_user_rid(sam_pass, pdb_uid_to_user_rid (pw_buf->smb_userid));
+ pdb_set_user_sid_from_rid(sam_pass, fallback_pdb_uid_to_user_rid (pw_buf->smb_userid));
/* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here.
This was down the bottom for machines, but it looks pretty good as
a general default for non-unix users. --abartlet 2002-01-08
*/
- pdb_set_group_rid (sam_pass, DOMAIN_GROUP_RID_USERS);
-
+ pdb_set_group_sid_from_rid (sam_pass, DOMAIN_GROUP_RID_USERS);
+ pdb_set_username (sam_pass, pw_buf->smb_name);
+ pdb_set_domain (sam_pass, lp_workgroup());
} 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 not in unix passwd database!\n", pw_buf->smb_name));
+ 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, 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
@@ -1340,9 +1248,9 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, SAM_AC
/*****************************************************************
Functions to be implemented by the new passdb API
****************************************************************/
-static BOOL smbpasswd_setsampwent (struct pdb_context *context, BOOL update)
+static BOOL smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update)
{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
smbpasswd_state->pw_file = startsmbfilepwent(smbpasswd_state->smbpasswd_file,
update ? PWF_UPDATE : PWF_READ,
@@ -1370,17 +1278,17 @@ static BOOL smbpasswd_setsampwent (struct pdb_context *context, BOOL update)
return (smbpasswd_state->pw_file != NULL);
}
-static void smbpasswd_endsampwent (struct pdb_context *context)
+static void smbpasswd_endsampwent (struct pdb_methods *my_methods)
{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
endsmbfilepwent(smbpasswd_state->pw_file, &(smbpasswd_state->pw_file_lock_depth));
}
/*****************************************************************
****************************************************************/
-static BOOL smbpasswd_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
+static BOOL smbpasswd_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd *pw_buf=NULL;
BOOL done = False;
DEBUG(5,("pdb_getsampwent\n"));
@@ -1419,32 +1327,14 @@ static BOOL smbpasswd_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user
call getpwnam() for unix account information until we have found
the correct entry
***************************************************************/
-static BOOL smbpasswd_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_acct, const char *username)
+static BOOL smbpasswd_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_acct, const char *username)
{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd *smb_pw;
void *fp = NULL;
- char *domain = NULL;
- char *user = NULL;
- fstring name;
DEBUG(10, ("getsampwnam (smbpasswd): search by name: %s\n", username));
-
- /* break the username from the domain if we have
- been given a string in the form 'DOMAIN\user' */
- fstrcpy (name, username);
- if ((user=strchr_m(name, '\\')) != NULL) {
- domain = name;
- *user = '\0';
- user++;
- }
-
- /* if a domain was specified and it wasn't ours
- then there is no chance of matching */
- if ( domain && !StrCaseCmp(domain, lp_workgroup()) )
- return False;
-
/* startsmbfilepwent() is used here as we don't want to lookup
the UNIX account in the local system password file until
we have a match. */
@@ -1455,11 +1345,6 @@ static BOOL smbpasswd_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_
return False;
}
- /* if we have a domain name, then we should map it to a UNIX
- username first */
- if ( domain )
- map_username(user);
-
while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL)&& (!strequal(smb_pw->smb_name, username)) )
/* do nothing....another loop */ ;
@@ -1488,10 +1373,9 @@ static BOOL smbpasswd_getsampwnam(struct pdb_context *context, SAM_ACCOUNT *sam_
return True;
}
-
-static BOOL smbpasswd_getsampwrid(struct pdb_context *context, SAM_ACCOUNT *sam_acct,uint32 rid)
+static BOOL smbpasswd_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_acct,uint32 rid)
{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd *smb_pw;
void *fp = NULL;
@@ -1505,7 +1389,7 @@ static BOOL smbpasswd_getsampwrid(struct pdb_context *context, SAM_ACCOUNT *sam_
return False;
}
- while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL) && (pdb_uid_to_user_rid(smb_pw->smb_userid) != rid) )
+ while ( ((smb_pw=getsmbfilepwent(smbpasswd_state, fp)) != NULL) && (fallback_pdb_uid_to_user_rid(smb_pw->smb_userid) != rid) )
/* do nothing */ ;
endsmbfilepwent(fp, &(smbpasswd_state->pw_file_lock_depth));
@@ -1533,9 +1417,17 @@ static BOOL smbpasswd_getsampwrid(struct pdb_context *context, SAM_ACCOUNT *sam_
return True;
}
-static BOOL smbpasswd_add_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sampass)
+static BOOL smbpasswd_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+ uint32 rid;
+ if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
+ return False;
+ return smbpasswd_getsampwrid(my_methods, user, rid);
+}
+
+static BOOL smbpasswd_add_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
+{
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd smb_pw;
/* convert the SAM_ACCOUNT */
@@ -1551,25 +1443,29 @@ static BOOL smbpasswd_add_sam_account(struct pdb_context *context, const SAM_ACC
return True;
}
-static BOOL smbpasswd_update_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sampass)
+static BOOL smbpasswd_update_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
struct smb_passwd smb_pw;
/* convert the SAM_ACCOUNT */
- if (!build_smb_pass(&smb_pw, sampass))
+ if (!build_smb_pass(&smb_pw, sampass)) {
+ DEBUG(0, ("smbpasswd_update_sam_account: build_smb_pass failed!\n"));
return False;
+ }
/* update the entry */
- if(!mod_smbfilepwd_entry(smbpasswd_state, &smb_pw))
+ if(!mod_smbfilepwd_entry(smbpasswd_state, &smb_pw)) {
+ DEBUG(0, ("smbpasswd_update_sam_account: mod_smbfilepwd_entry failed!\n"));
return False;
-
+ }
+
return True;
}
-static BOOL smbpasswd_delete_sam_account (struct pdb_context *context, const SAM_ACCOUNT *sampass)
+static BOOL smbpasswd_delete_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *sampass)
{
- struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)context->pdb_selected->private_data;
+ struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
const char *username = pdb_get_username(sampass);
@@ -1602,7 +1498,7 @@ NTSTATUS pdb_init_smbpasswd(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method,
(*pdb_method)->endsampwent = smbpasswd_endsampwent;
(*pdb_method)->getsampwent = smbpasswd_getsampwent;
(*pdb_method)->getsampwnam = smbpasswd_getsampwnam;
- (*pdb_method)->getsampwrid = smbpasswd_getsampwrid;
+ (*pdb_method)->getsampwsid = smbpasswd_getsampwsid;
(*pdb_method)->add_sam_account = smbpasswd_add_sam_account;
(*pdb_method)->update_sam_account = smbpasswd_update_sam_account;
(*pdb_method)->delete_sam_account = smbpasswd_delete_sam_account;
diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c
index a8edac917e..6279318969 100644
--- a/source3/passdb/pdb_tdb.c
+++ b/source3/passdb/pdb_tdb.c
@@ -2,7 +2,7 @@
* Unix SMB/CIFS implementation.
* SMB parameters and setup
* Copyright (C) Andrew Tridgell 1992-1998
- * Copyright (C) Simo Sorce 2000
+ * Copyright (C) Simo Sorce 2000-2002
* Copyright (C) Gerald Carter 2000
* Copyright (C) Jeremy Allison 2001
* Copyright (C) Andrew Bartlett 2002
@@ -24,6 +24,19 @@
#include "includes.h"
+#if 0 /* when made a module use this */
+
+static int tdbsam_debug_level = DBGC_ALL;
+#undef DBGC_CLASS
+#define DBGC_CLASS tdbsam_debug_level
+
+#else
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_PASSDB
+
+#endif
+
#ifdef WITH_TDB_SAM
#define PDB_VERSION "20010830"
@@ -41,8 +54,10 @@ struct tdbsam_privates {
BOOL permit_non_unix_accounts;
-/* uint32 low_nua_rid;
- uint32 high_nua_rid; */
+ BOOL algorithmic_rids;
+
+ uint32 low_nua_rid;
+ uint32 high_nua_rid;
};
/**********************************************************************
@@ -84,12 +99,10 @@ 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) {
@@ -119,8 +132,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,
@@ -150,6 +163,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);
@@ -163,70 +178,76 @@ 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;
- 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));
+ if (homedir) {
+ pdb_set_homedir(sampass, homedir, True);
}
- pdb_set_homedir(sampass, homedir, setflag);
-
- if (dir_drive) setflag = 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_homedir(sampass,
+ talloc_sub_specified(sampass->mem_ctx,
+ lp_logon_home(),
+ username, domain,
+ uid, gid),
+ False);
}
- pdb_set_dir_drive(sampass, dir_drive, setflag);
- if (logon_script) setflag = True;
+ if (dir_drive)
+ pdb_set_dir_drive(sampass, dir_drive, 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_dir_drive(sampass,
+ talloc_sub_specified(sampass->mem_ctx,
+ lp_logon_drive(),
+ username, domain,
+ uid, gid),
+ False);
}
- pdb_set_logon_script(sampass, logon_script, setflag);
- if (profile_path) setflag = True;
+ if (logon_script)
+ pdb_set_logon_script(sampass, logon_script, 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));
+ pdb_set_logon_script(sampass,
+ talloc_sub_specified(sampass->mem_ctx,
+ lp_logon_script(),
+ username, domain,
+ uid, gid),
+ False);
+ }
+
+ if (profile_path) {
+ pdb_set_profile_path(sampass, profile_path, True);
+ } else {
+ pdb_set_profile_path(sampass,
+ talloc_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);
- pdb_set_group_rid(sampass, group_rid);
+ pdb_set_user_sid_from_rid(sampass, user_rid);
+ pdb_set_group_sid_from_rid(sampass, group_rid);
pdb_set_unknown_3(sampass, unknown_3);
pdb_set_hours_len(sampass, hours_len);
pdb_set_unknown_5(sampass, unknown_5);
@@ -462,9 +483,9 @@ static uint32 init_buffer_from_sam (struct tdbsam_privates *tdb_state,
Open the TDB passwd database for SAM account enumeration.
****************************************************************/
-static BOOL tdbsam_setsampwent(struct pdb_context *context, BOOL update)
+static BOOL tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
/* Open tdb passwd */
if (!(tdb_state->passwd_tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, update?(O_RDWR|O_CREAT):O_RDONLY, 0600)))
@@ -490,9 +511,9 @@ static void close_tdb(struct tdbsam_privates *tdb_state)
End enumeration of the TDB passwd list.
****************************************************************/
-static void tdbsam_endsampwent(struct pdb_context *context)
+static void tdbsam_endsampwent(struct pdb_methods *my_methods)
{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
close_tdb(tdb_state);
DEBUG(7, ("endtdbpwent: closed sam database.\n"));
@@ -502,9 +523,9 @@ static void tdbsam_endsampwent(struct pdb_context *context)
Get one SAM_ACCOUNT from the TDB (next in line)
*****************************************************************/
-static BOOL tdbsam_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
+static BOOL tdbsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT *user)
{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
TDB_DATA data;
char *prefix = USERPREFIX;
int prefixlen = strlen (prefix);
@@ -550,9 +571,9 @@ static BOOL tdbsam_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
Lookup a name in the SAM TDB
******************************************************************/
-static BOOL tdbsam_getsampwnam (struct pdb_context *context, SAM_ACCOUNT *user, const char *sname)
+static BOOL tdbsam_getsampwnam (struct pdb_methods *my_methods, SAM_ACCOUNT *user, const char *sname)
{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
TDB_CONTEXT *pwd_tdb;
TDB_DATA data, key;
fstring keystr;
@@ -606,9 +627,9 @@ static BOOL tdbsam_getsampwnam (struct pdb_context *context, SAM_ACCOUNT *user,
Search by rid
**************************************************************************/
-static BOOL tdbsam_getsampwrid (struct pdb_context *context, SAM_ACCOUNT *user, uint32 rid)
+static BOOL tdbsam_getsampwrid (struct pdb_methods *my_methods, SAM_ACCOUNT *user, uint32 rid)
{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
TDB_CONTEXT *pwd_tdb;
TDB_DATA data, key;
fstring keystr;
@@ -644,16 +665,24 @@ static BOOL tdbsam_getsampwrid (struct pdb_context *context, SAM_ACCOUNT *user,
tdb_close (pwd_tdb);
- return tdbsam_getsampwnam (context, user, name);
+ return tdbsam_getsampwnam (my_methods, user, name);
+}
+
+static BOOL tdbsam_getsampwsid(struct pdb_methods *my_methods, SAM_ACCOUNT * user, DOM_SID *sid)
+{
+ uint32 rid;
+ if (!sid_peek_check_rid(get_global_sam_sid(), sid, &rid))
+ return False;
+ return tdbsam_getsampwrid(my_methods, user, rid);
}
/***************************************************************************
Delete a SAM_ACCOUNT
****************************************************************************/
-static BOOL tdbsam_delete_sam_account(struct pdb_context *context, const SAM_ACCOUNT *sam_pass)
+static BOOL tdbsam_delete_sam_account(struct pdb_methods *my_methods, SAM_ACCOUNT *sam_pass)
{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
TDB_CONTEXT *pwd_tdb;
TDB_DATA key;
fstring keystr;
@@ -707,9 +736,9 @@ static BOOL tdbsam_delete_sam_account(struct pdb_context *context, const SAM_ACC
Update the TDB SAM
****************************************************************************/
-static BOOL tdb_update_sam(struct pdb_context *context, const SAM_ACCOUNT* newpwd, int flag)
+static BOOL tdb_update_sam(struct pdb_methods *my_methods, SAM_ACCOUNT* newpwd, int flag)
{
- struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)context->pdb_selected->private_data;
+ struct tdbsam_privates *tdb_state = (struct tdbsam_privates *)my_methods->private_data;
TDB_CONTEXT *pwd_tdb = NULL;
TDB_DATA key, data;
uint8 *buf = NULL;
@@ -717,7 +746,7 @@ static BOOL tdb_update_sam(struct pdb_context *context, const SAM_ACCOUNT* newpw
fstring name;
BOOL ret = True;
uint32 user_rid;
- int32 tdb_ret;
+ BOOL tdb_ret;
/* invalidate the existing TDB iterator if it is open */
if (tdb_state->passwd_tdb) {
@@ -736,13 +765,32 @@ static BOOL tdb_update_sam(struct pdb_context *context, const SAM_ACCOUNT* newpw
/* 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) {
- user_rid = BASE_RID;
- tdb_ret = tdb_change_int32_atomic(pwd_tdb, "RID_COUNTER", &user_rid, RID_MULTIPLIER);
- if (tdb_ret == -1) {
- ret = False;
- goto done;
+ 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);
+ } 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_set_user_rid(newpwd, user_rid);
} else {
DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a RID\n",pdb_get_username(newpwd)));
ret = False;
@@ -758,7 +806,7 @@ static BOOL tdb_update_sam(struct pdb_context *context, const SAM_ACCOUNT* newpw
goto done;
} else {
/* This seems like a good default choice for non-unix users */
- pdb_set_group_rid(newpwd, DOMAIN_GROUP_RID_USERS);
+ pdb_set_group_sid_from_rid(newpwd, DOMAIN_GROUP_RID_USERS);
}
} else {
DEBUG (0,("tdb_update_sam: Failing to store a SAM_ACCOUNT for [%s] without a primary group RID\n",pdb_get_username(newpwd)));
@@ -823,18 +871,18 @@ done:
Modifies an existing SAM_ACCOUNT
****************************************************************************/
-static BOOL tdbsam_update_sam_account (struct pdb_context *context, const SAM_ACCOUNT *newpwd)
+static BOOL tdbsam_update_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd)
{
- return (tdb_update_sam(context, newpwd, TDB_MODIFY));
+ return (tdb_update_sam(my_methods, newpwd, TDB_MODIFY));
}
/***************************************************************************
Adds an existing SAM_ACCOUNT
****************************************************************************/
-static BOOL tdbsam_add_sam_account (struct pdb_context *context, const SAM_ACCOUNT *newpwd)
+static BOOL tdbsam_add_sam_account (struct pdb_methods *my_methods, SAM_ACCOUNT *newpwd)
{
- return (tdb_update_sam(context, newpwd, TDB_INSERT));
+ return (tdb_update_sam(my_methods, newpwd, TDB_INSERT));
}
static void free_private_data(void **vp)
@@ -852,6 +900,14 @@ NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con
NTSTATUS nt_status;
struct tdbsam_privates *tdb_state;
+#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;
}
@@ -862,7 +918,7 @@ NTSTATUS pdb_init_tdbsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, con
(*pdb_method)->endsampwent = tdbsam_endsampwent;
(*pdb_method)->getsampwent = tdbsam_getsampwent;
(*pdb_method)->getsampwnam = tdbsam_getsampwnam;
- (*pdb_method)->getsampwrid = tdbsam_getsampwrid;
+ (*pdb_method)->getsampwsid = tdbsam_getsampwsid;
(*pdb_method)->add_sam_account = tdbsam_add_sam_account;
(*pdb_method)->update_sam_account = tdbsam_update_sam_account;
(*pdb_method)->delete_sam_account = tdbsam_delete_sam_account;
@@ -884,6 +940,8 @@ 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;
@@ -904,7 +962,7 @@ NTSTATUS pdb_init_tdbsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method,
(*pdb_method)->name = "tdbsam_nua";
tdb_state = (*pdb_method)->private_data;
-
+
tdb_state->permit_non_unix_accounts = True;
if (!lp_non_unix_account_range(&low_nua_uid, &high_nua_uid)) {
@@ -912,10 +970,10 @@ NTSTATUS pdb_init_tdbsam_nua(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method,
return NT_STATUS_UNSUCCESSFUL;
}
-/* tdb_state->low_nua_rid=fallback_pdb_uid_to_user_rid(low_nua_uid);
+ 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;
}
diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c
index b3507a1392..3ecaf52e58 100644
--- a/source3/passdb/secrets.c
+++ b/source3/passdb/secrets.c
@@ -1,6 +1,8 @@
/*
Unix SMB/CIFS implementation.
Copyright (C) Andrew Tridgell 1992-2001
+ Copyright (C) Andrew Bartlett 2002
+ Copyright (C) Rafal Szczesniak 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
@@ -22,6 +24,9 @@
#include "includes.h"
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_PASSDB
+
static TDB_CONTEXT *tdb;
/* open up the secrets database */
@@ -47,7 +52,7 @@ BOOL secrets_init(void)
/* read a entry from the secrets database - the caller must free the result
if size is non-null then the size of the entry is put in there
*/
-void *secrets_fetch(char *key, size_t *size)
+void *secrets_fetch(const char *key, size_t *size)
{
TDB_DATA kbuf, dbuf;
secrets_init();
@@ -63,7 +68,7 @@ void *secrets_fetch(char *key, size_t *size)
/* store a secrets entry
*/
-BOOL secrets_store(char *key, void *data, size_t size)
+BOOL secrets_store(const char *key, void *data, size_t size)
{
TDB_DATA kbuf, dbuf;
secrets_init();
@@ -79,7 +84,7 @@ BOOL secrets_store(char *key, void *data, size_t size)
/* delete a secets database entry
*/
-BOOL secrets_delete(char *key)
+BOOL secrets_delete(const char *key)
{
TDB_DATA kbuf;
secrets_init();
@@ -124,10 +129,14 @@ BOOL secrets_fetch_domain_sid(char *domain, DOM_SID *sid)
}
-/************************************************************************
-form a key for fetching the machine trust account password
-************************************************************************/
-char *trust_keystr(char *domain)
+/**
+ * Form a key for fetching the machine trust account password
+ *
+ * @param domain domain name
+ *
+ * @return stored password's key
+ **/
+const char *trust_keystr(const char *domain)
{
static fstring keystr;
@@ -141,11 +150,11 @@ char *trust_keystr(char *domain)
/**
* Form a key for fetching a trusted domain password
*
- * @param domain domain name
+ * @param domain trusted domain name
*
* @return stored password's key
**/
-char *trustdom_keystr(char *domain)
+char *trustdom_keystr(const char *domain)
{
static char* keystr;
@@ -194,21 +203,23 @@ BOOL secrets_fetch_trust_account_password(char *domain, uint8 ret_pwd[16],
Routine to get account password to trusted domain
************************************************************************/
BOOL secrets_fetch_trusted_domain_password(char *domain, char** pwd,
- DOM_SID *sid, time_t *pass_last_set_time)
+ DOM_SID *sid, time_t *pass_last_set_time)
{
struct trusted_dom_pass *pass;
size_t size;
+ /* fetching trusted domain password structure */
if (!(pass = secrets_fetch(trustdom_keystr(domain), &size))) {
DEBUG(5, ("secrets_fetch failed!\n"));
return False;
}
-
+
if (size != sizeof(*pass)) {
DEBUG(0, ("secrets were of incorrect size!\n"));
return False;
}
-
+
+ /* the trust's password */
if (pwd) {
*pwd = strdup(pass->pass);
if (!*pwd) {
@@ -216,9 +227,12 @@ BOOL secrets_fetch_trusted_domain_password(char *domain, char** pwd,
}
}
+ /* last change time */
if (pass_last_set_time) *pass_last_set_time = pass->mod_time;
+ /* domain sid */
memcpy(&sid, &(pass->domain_sid), sizeof(sid));
+
SAFE_FREE(pass);
return True;
@@ -247,19 +261,30 @@ BOOL secrets_store_trust_account_password(char *domain, uint8 new_pwd[16])
* @return true if succeeded
**/
-BOOL secrets_store_trusted_domain_password(char* domain, char* pwd,
+BOOL secrets_store_trusted_domain_password(char* domain, smb_ucs2_t *uni_dom_name,
+ size_t uni_name_len, char* pwd,
DOM_SID sid)
{
struct trusted_dom_pass pass;
ZERO_STRUCT(pass);
+ /* unicode domain name and its length */
+ if (!uni_dom_name)
+ return False;
+
+ strncpy_w(pass.uni_name, uni_dom_name, sizeof(pass.uni_name) - 1);
+ pass.uni_name_len = uni_name_len;
+
+ /* last change time */
pass.mod_time = time(NULL);
+ /* password of the trust */
pass.pass_len = strlen(pwd);
fstrcpy(pass.pass, pwd);
+ /* domain sid */
memcpy(&(pass.domain_sid), &sid, sizeof(sid));
-
+
return secrets_store(trustdom_keystr(domain), (void *)&pass, sizeof(pass));
}
@@ -300,7 +325,7 @@ char *secrets_fetch_machine_password(void)
Routine to delete the machine trust account password file for a domain.
************************************************************************/
-BOOL trust_password_delete(char *domain)
+BOOL trust_password_delete(const char *domain)
{
return secrets_delete(trust_keystr(domain));
}
@@ -308,7 +333,7 @@ BOOL trust_password_delete(char *domain)
/************************************************************************
Routine to delete the password for trusted domain
************************************************************************/
-BOOL trusted_domain_password_delete(char *domain)
+BOOL trusted_domain_password_delete(const char *domain)
{
return secrets_delete(trustdom_keystr(domain));
}
@@ -345,15 +370,136 @@ void reset_globals_after_fork(void)
generate_random_buffer( &dummy, 1, True);
}
-BOOL secrets_store_ldap_pw(char* dn, char* pw)
+BOOL secrets_store_ldap_pw(const char* dn, char* pw)
{
- fstring key;
- char *p;
+ char *key = NULL;
+ BOOL ret;
- pstrcpy(key, dn);
- for (p=key; *p; p++)
- if (*p == ',') *p = '/';
+ if (asprintf(&key, "%s/%s", SECRETS_LDAP_BIND_PW, dn) < 0) {
+ DEBUG(0, ("secrets_store_ldap_pw: asprintf failed!\n"));
+ return False;
+ }
+
+ ret = secrets_store(key, pw, strlen(pw)+1);
+
+ SAFE_FREE(key);
+ return ret;
+}
+
+
+/**
+ * The linked list is allocated on the supplied talloc context, caller gets to destory
+ * when done.
+ *
+ * @param ctx Allocation context
+ * @param enum_ctx Starting index, eg. we can start fetching at third
+ * or sixth trusted domain entry. Zero is the first index.
+ * Value it is set to is the enum context for the next enumeration.
+ * @param num_domains Number of domain entries to fetch at one call
+ * @param domains Pointer to array of trusted domain structs to be filled up
+ *
+ * @return nt status code of rpc response
+ **/
+
+NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num_domains, int *num_domains, TRUSTDOM ***domains)
+{
+ TDB_LIST_NODE *keys, *k;
+ TRUSTDOM *dom = NULL;
+ char *pattern;
+ int start_idx;
+ uint32 idx = 0;
+ size_t size;
+ struct trusted_dom_pass *pass;
+ NTSTATUS status;
+
+ secrets_init();
+
+ *num_domains = 0;
+ start_idx = *enum_ctx;
+
+ /* generate searching pattern */
+ if (!(pattern = talloc_asprintf(ctx, "%s/*", SECRETS_DOMTRUST_ACCT_PASS))) {
+ DEBUG(0, ("secrets_get_trusted_domains: talloc_asprintf() failed!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ DEBUG(5, ("secrets_get_trusted_domains: looking for %d domains, starting at index %d\n",
+ max_num_domains, *enum_ctx));
+
+ *domains = talloc_zero(ctx, sizeof(**domains)*max_num_domains);
+
+ /* fetching trusted domains' data and collecting them in a list */
+ keys = tdb_search_keys(tdb, pattern);
+
+ /*
+ * if there's no keys returned ie. no trusted domain,
+ * return "no more entries" code
+ */
+ status = NT_STATUS_NO_MORE_ENTRIES;
+
+ /* searching for keys in sectrets db -- way to go ... */
+ for (k = keys; k; k = k->next) {
+ char *secrets_key;
+
+ /* important: ensure null-termination of the key string */
+ secrets_key = strndup(k->node_key.dptr, k->node_key.dsize);
+ if (!secrets_key) {
+ DEBUG(0, ("strndup failed!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ pass = secrets_fetch(secrets_key, &size);
+
+ if (size != sizeof(*pass)) {
+ DEBUG(2, ("Secrets record %s is invalid!\n", secrets_key));
+ SAFE_FREE(pass);
+ continue;
+ }
+
+ SAFE_FREE(secrets_key);
+
+ if (idx >= start_idx && idx < start_idx + max_num_domains) {
+ dom = talloc_zero(ctx, sizeof(*dom));
+ if (!dom) {
+ /* free returned tdb record */
+ SAFE_FREE(pass);
+
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* copy domain sid */
+ SMB_ASSERT(sizeof(dom->sid) == sizeof(pass->domain_sid));
+ memcpy(&(dom->sid), &(pass->domain_sid), sizeof(dom->sid));
+
+ /* copy unicode domain name */
+ dom->name = talloc_strdup_w(ctx, pass->uni_name);
+
+ (*domains)[idx - start_idx] = dom;
+
+ *enum_ctx = idx + 1;
+ (*num_domains)++;
+
+ /* set proper status code to return */
+ if (k->next) {
+ /* there are yet some entries to enumerate */
+ status = STATUS_MORE_ENTRIES;
+ } else {
+ /* this is the last entry in the whole enumeration */
+ status = NT_STATUS_OK;
+ }
+ }
+
+ idx++;
+
+ /* free returned tdb record */
+ SAFE_FREE(pass);
+ }
- return secrets_store(key, pw, strlen(pw));
+ DEBUG(5, ("secrets_get_trusted_domains: got %d domains\n", *num_domains));
+
+ /* free the results of searching the keys */
+ tdb_search_list_free(keys);
+
+ return status;
}