summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/Makefile.in2
-rw-r--r--source/include/smb.h9
-rw-r--r--source/lib/substitute.c52
-rw-r--r--source/lib/util_getent.c30
-rw-r--r--source/param/loadparm.c22
-rw-r--r--source/passdb/passdb.c310
-rw-r--r--source/passdb/pdb_get_set.c76
-rw-r--r--source/passdb/pdb_interface.c16
-rw-r--r--source/passdb/pdb_ldap.c50
-rw-r--r--source/passdb/pdb_smbpasswd.c55
-rw-r--r--source/passdb/pdb_tdb.c99
-rw-r--r--source/passdb/pdb_unix.c126
-rw-r--r--source/rpc_parse/parse_samr.c23
-rw-r--r--source/rpc_server/srv_lsa_nt.c4
-rw-r--r--source/script/mkproto.awk10
-rw-r--r--source/smbd/lanman.c29
-rw-r--r--source/smbd/password.c14
-rw-r--r--source/smbd/service.c19
-rw-r--r--source/utils/net_rpc_join.c10
19 files changed, 625 insertions, 331 deletions
diff --git a/source/Makefile.in b/source/Makefile.in
index c78dc28d0be..3a97f78cab1 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -196,7 +196,7 @@ LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
PASSDB_OBJ = passdb/passdb.o passdb/pdb_interface.o passdb/pdb_get_set.o \
passdb/machine_sid.o passdb/pdb_smbpasswd.o \
passdb/pdb_tdb.o passdb/pdb_ldap.o passdb/pdb_plugin.o \
- passdb/pdb_nisplus.o
+ passdb/pdb_nisplus.o passdb/pdb_unix.o
GROUPDB_OBJ = groupdb/mapping.o
diff --git a/source/include/smb.h b/source/include/smb.h
index 0e5a85ad151..ca146ff50a0 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -581,7 +581,7 @@ typedef struct {
#define FLAG_SAM_KICKOFFTIME 0x00000100
#define FLAG_SAM_CANCHANGETIME 0x00000200
#define FLAG_SAM_MUSTCHANGETIME 0x00000400
-
+#define FLAG_SAM_PLAINTEXT_PW 0x00000800
#define IS_SAM_UNIX_USER(x) \
((pdb_get_init_flag(x) & FLAG_SAM_UID) \
@@ -595,7 +595,7 @@ typedef struct sam_passwd
void (*free_fn)(struct sam_passwd **);
- struct pdb_methods *methods;
+ struct pdb_methods *methods;
struct user_data {
/* initiailization flags */
@@ -612,6 +612,7 @@ typedef struct sam_passwd
char * domain; /* Windows Domain name */
char * nt_username; /* Windows username string */
char * full_name; /* user's full name string */
+ char * unix_home_dir; /* UNIX home directory string */
char * home_dir; /* home directory string */
char * dir_drive; /* home directory drive string */
char * logon_script; /* logon script string */
@@ -628,6 +629,7 @@ typedef struct sam_passwd
DATA_BLOB lm_pw; /* .data is Null if no password */
DATA_BLOB nt_pw; /* .data is Null if no password */
+ DATA_BLOB plaintext_pw; /* .data is Null if not available */
uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
uint32 unknown_3; /* 0x00ff ffff */
@@ -639,6 +641,7 @@ typedef struct sam_passwd
uint32 unknown_5; /* 0x0002 0000 */
uint32 unknown_6; /* 0x0000 04ec */
} private;
+
/* Lets see if the remaining code can get the hint that you
are meant to use the pdb_...() functions. */
@@ -1578,6 +1581,8 @@ typedef struct user_struct
userdom_struct user;
char *homedir;
+ char *unix_homedir;
+ char *logon_script;
BOOL guest;
diff --git a/source/lib/substitute.c b/source/lib/substitute.c
index e878ee8cbfd..09921c145d8 100644
--- a/source/lib/substitute.c
+++ b/source/lib/substitute.c
@@ -279,6 +279,58 @@ void standard_sub_advanced(int snum, const char *user, const char *connectpath,
standard_sub_basic(smb_name, str);
}
+const char *standard_sub_specified(TALLOC_CTX *mem_ctx, const char *input_string,
+ const char *username,
+ const char *domain,
+ uid_t uid,
+ gid_t gid)
+{
+ pstring input_pstring;
+ char *p, *s;
+
+ pstrcpy(input_pstring, input_string);
+
+ for (s=input_pstring; (p=strchr_m(s, '%')); s=p) {
+
+ int l = sizeof(pstring) - (int)(p-input_pstring);
+
+ switch (*(p+1)) {
+ case 'U' :
+ string_sub(p,"%U",username,l);
+ break;
+ case 'u' :
+ string_sub(p,"%u",username,l);
+ break;
+ case 'G' :
+ case 'g' :
+ if (gid != -1) {
+ string_sub(p,"%G",gidtoname(gid),l);
+ string_sub(p,"%g",gidtoname(gid),l);
+ } else {
+ string_sub(p,"%G","NO_GROUP",l);
+ string_sub(p,"%g","NO_GROUP",l);
+ }
+ break;
+ case 'D' :
+ string_sub(p,"%D", domain,l);
+ break;
+ case 'N' :
+ string_sub(p,"%N", automount_server(username),l);
+ break;
+ case '\0':
+ p++;
+ break; /* don't run off the end of the string */
+
+ default: p+=2;
+ break;
+ }
+ }
+
+ standard_sub_basic(username, input_pstring);
+
+ return talloc_strdup(mem_ctx, input_pstring);
+}
+
/****************************************************************************
Do some standard substitutions in a string.
****************************************************************************/
diff --git a/source/lib/util_getent.c b/source/lib/util_getent.c
index 02e4b932ded..2e76121aae1 100644
--- a/source/lib/util_getent.c
+++ b/source/lib/util_getent.c
@@ -277,20 +277,24 @@ struct sys_userlist *get_users_in_group(const char *gname)
DOM_SID sid;
enum SID_NAME_USE name_type;
- (void) split_domain_and_name(gname, domain, groupname);
-
- /*
- * If we're doing this via winbindd, don't do the
- * entire group list enumeration as we know this is
- * pointless (and slow).
- */
-
- if (winbind_lookup_name(domain, groupname, &sid, &name_type) && name_type == SID_NAME_DOM_GRP) {
- if ((gptr = (struct group *)getgrnam(gname)) == NULL)
- return NULL;
- return add_members_to_userlist(list_head, gptr);
+ /* No point using winbind if we can't split it in the
+ first place */
+ if (split_domain_and_name(gname, domain, groupname)) {
+
+ /*
+ * If we're doing this via winbindd, don't do the
+ * entire group list enumeration as we know this is
+ * pointless (and slow).
+ */
+
+ if (winbind_lookup_name(domain, groupname, &sid, &name_type)
+ && name_type == SID_NAME_DOM_GRP) {
+ if ((gptr = (struct group *)getgrnam(gname)) == NULL)
+ return NULL;
+ return add_members_to_userlist(list_head, gptr);
+ }
}
-
+
setgrent();
while((gptr = getgrent()) != NULL) {
if (strequal(gname, gptr->gr_name)) {
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 788b25a53d6..79eef6ed5ed 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -138,7 +138,7 @@ typedef struct
char *szAddGroupScript;
char *szDelGroupScript;
char *szAddUserToGroupScript;
- char *szDelUserToGroupScript;
+ char *szDelUserFromGroupScript;
char *szAddMachineScript;
char *szShutdownScript;
char *szAbortShutdownScript;
@@ -893,7 +893,7 @@ static struct parm_struct parm_table[] = {
{"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, 0},
{"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, 0},
{"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, 0},
- {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserToGroupScript, NULL, NULL, 0},
+ {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, 0},
{"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, 0},
{"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, 0},
{"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, 0},
@@ -1187,7 +1187,7 @@ static void init_globals(void)
string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
- string_set(&Globals.szPassdbBackend, "smbpasswd");
+ string_set(&Globals.szPassdbBackend, "smbpasswd unixsam");
/* use the new 'hash2' method by default */
string_set(&Globals.szManglingMethod, "hash2");
@@ -1416,6 +1416,8 @@ static char *lp_string(const char *s)
#define FN_GLOBAL_STRING(fn_name,ptr) \
char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
+#define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
+ const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
#define FN_GLOBAL_LIST(fn_name,ptr) \
char **fn_name(void) {return(*(char ***)(ptr));}
#define FN_GLOBAL_BOOL(fn_name,ptr) \
@@ -1475,10 +1477,10 @@ FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkGroup)
FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
-FN_GLOBAL_STRING(lp_logon_script, &Globals.szLogonScript)
-FN_GLOBAL_STRING(lp_logon_path, &Globals.szLogonPath)
-FN_GLOBAL_STRING(lp_logon_drive, &Globals.szLogonDrive)
-FN_GLOBAL_STRING(lp_logon_home, &Globals.szLogonHome)
+FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
+FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
+FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
+FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
FN_GLOBAL_STRING(lp_wins_server_list, &Globals.szWINSserver)
@@ -1495,7 +1497,7 @@ FN_GLOBAL_STRING(lp_guestaccount, &Globals.szGuestaccount)
FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
-FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserToGroupScript)
+FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
@@ -3873,7 +3875,7 @@ char *lp_printername(int snum)
#define P_LIST_ABS 16 /* P_LIST Allocation Block Size */
-char **lp_list_make(char *string)
+char **lp_list_make(const char *string)
{
char **list, **rlist;
char *str, *s;
@@ -3891,7 +3893,7 @@ char **lp_list_make(char *string)
list = NULL;
str = s;
- while (next_token(&str, tok, LIST_SEP, sizeof(pstring)))
+ while (next_token(&str, tok, LIST_SEP, sizeof(tok)))
{
if (num == lsize) {
lsize += P_LIST_ABS;
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index d34866fa637..edae00389ea 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -30,6 +30,7 @@
*/
extern DOM_SID global_sam_sid;
+extern pstring global_myname;
/************************************************************
Fill the SAM_ACCOUNT with default values.
@@ -150,32 +151,39 @@ NTSTATUS pdb_init_sam(SAM_ACCOUNT **user)
Initialises a struct sam_passwd with sane values.
************************************************************/
-NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
+NTSTATUS pdb_fill_sam_pw(SAM_ACCOUNT *sam_account, const struct passwd *pwd)
{
- pstring str;
GROUP_MAP map;
uint32 rid;
- NTSTATUS nt_status;
if (!pwd) {
- new_sam_acct = NULL;
return NT_STATUS_UNSUCCESSFUL;
}
- if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) {
- new_sam_acct = NULL;
- return nt_status;
- }
+ pdb_fill_default_sam(sam_account);
- pdb_set_username(*new_sam_acct, pwd->pw_name);
- pdb_set_fullname(*new_sam_acct, pwd->pw_gecos);
+ pdb_set_username(sam_account, pwd->pw_name);
+ pdb_set_fullname(sam_account, pwd->pw_gecos);
- pdb_set_uid(*new_sam_acct, pwd->pw_uid);
- pdb_set_gid(*new_sam_acct, pwd->pw_gid);
+ pdb_set_unix_homedir(sam_account, pwd->pw_dir);
+
+ pdb_set_domain (sam_account, lp_workgroup());
+
+ pdb_set_uid(sam_account, pwd->pw_uid);
+ pdb_set_gid(sam_account, pwd->pw_gid);
- /* let the backends set the rid!!
- pdb_set_user_rid(*new_sam_acct, pdb_uid_to_user_rid(pwd->pw_uid));
- -- simo */
+ /* When we get a proper uid -> SID and SID -> uid allocation
+ mechinism, we should call it here.
+
+ We can't just set this to 0 or allow it only to be filled
+ in when added to the backend, becouse the user's SID
+ may already be in security descriptors etc.
+
+ -- abartlet 11-May-02
+ */
+
+ pdb_set_user_rid(sam_account,
+ fallback_pdb_uid_to_user_rid(pwd->pw_uid));
/* call the mapping code here */
if(get_group_map_from_gid(pwd->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
@@ -185,24 +193,67 @@ NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
rid=pdb_gid_to_group_rid(pwd->pw_gid);
}
- pdb_set_group_rid(*new_sam_acct, rid);
+ pdb_set_group_rid(sam_account, rid);
+
+ /* check if this is a user account or a machine account */
+ if (pwd->pw_name[strlen(pwd->pw_name)-1] != '$')
+ {
+ pdb_set_profile_path(sam_account,
+ standard_sub_specified((sam_account)->mem_ctx,
+ lp_logon_path(),
+ pwd->pw_name, global_myname,
+ pwd->pw_uid, pwd->pw_gid),
+ False);
+
+ pdb_set_homedir(sam_account,
+ standard_sub_specified((sam_account)->mem_ctx,
+ lp_logon_home(),
+ pwd->pw_name, global_myname,
+ pwd->pw_uid, pwd->pw_gid),
+ False);
+
+ pdb_set_dir_drive(sam_account,
+ standard_sub_specified((sam_account)->mem_ctx,
+ lp_logon_drive(),
+ pwd->pw_name, global_myname,
+ pwd->pw_uid, pwd->pw_gid),
+ False);
+
+ pdb_set_logon_script(sam_account,
+ standard_sub_specified((sam_account)->mem_ctx,
+ lp_logon_script(),
+ pwd->pw_name, global_myname,
+ pwd->pw_uid, pwd->pw_gid),
+ False);
+ }
+ return NT_STATUS_OK;
+}
- pstrcpy(str, lp_logon_path());
- standard_sub_advanced(-1, pwd->pw_name, "", pwd->pw_gid, pwd->pw_name, str);
- pdb_set_profile_path(*new_sam_acct, str, False);
-
- pstrcpy(str, lp_logon_home());
- standard_sub_advanced(-1, pwd->pw_name, "", pwd->pw_gid, pwd->pw_name, str);
- pdb_set_homedir(*new_sam_acct, str, False);
-
- pstrcpy(str, lp_logon_drive());
- standard_sub_advanced(-1, pwd->pw_name, "", pwd->pw_gid, pwd->pw_name, str);
- pdb_set_dir_drive(*new_sam_acct, str, False);
- pstrcpy(str, lp_logon_script());
- standard_sub_advanced(-1, pwd->pw_name, "", pwd->pw_gid, pwd->pw_name, str);
- pdb_set_logon_script(*new_sam_acct, str, False);
-
+/*************************************************************
+ Initialises a struct sam_passwd with sane values.
+ ************************************************************/
+
+NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
+{
+ NTSTATUS nt_status;
+
+ if (!pwd) {
+ new_sam_acct = NULL;
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(new_sam_acct))) {
+ new_sam_acct = NULL;
+ return nt_status;
+ }
+
+ if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*new_sam_acct, pwd))) {
+ pdb_free_sam(new_sam_acct);
+ new_sam_acct = NULL;
+ return nt_status;
+ }
+
return NT_STATUS_OK;
}
@@ -210,18 +261,21 @@ NTSTATUS pdb_init_sam_pw(SAM_ACCOUNT **new_sam_acct, const struct passwd *pwd)
/**
* Free the contets of the SAM_ACCOUNT, but not the structure.
*
- * Also wipes the LM and NT hashes from memory.
+ * Also wipes the LM and NT hashes and plaintext passwrod from
+ * memory.
*
* @param user SAM_ACCOUNT to free members of.
**/
static void pdb_free_sam_contents(SAM_ACCOUNT *user)
{
- /* As we start mallocing more strings this is where
- we should free them. */
+
+ /* Kill off sensitive data. Free()ed by the
+ talloc mechinism */
data_blob_clear_free(&(user->private.lm_pw));
data_blob_clear_free(&(user->private.nt_pw));
+ data_blob_clear_free(&(user->private.plaintext_pw));
}
@@ -519,12 +573,8 @@ BOOL pdb_rid_is_user(uint32 rid)
BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use)
{
uint32 rid;
- BOOL is_user;
SAM_ACCOUNT *sam_account = NULL;
- uid_t uid;
- struct passwd *pass;
GROUP_MAP map;
-
sid_peek_rid(sid, &rid);
*psid_name_use = SID_NAME_UNKNOWN;
@@ -564,6 +614,7 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
return False;
}
+ /* This now does the 'generic' mapping in pdb_unix */
if (pdb_getsampwrid(sam_account, rid)) {
fstrcpy(name, pdb_get_username(sam_account));
*psid_name_use = SID_NAME_USER;
@@ -572,47 +623,36 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
return True;
}
-
+
pdb_free_sam(&sam_account);
if (get_group_map_from_sid(*sid, &map, MAPPING_WITHOUT_PRIV)) {
if (map.gid!=-1) {
DEBUG(5,("local_lookup_sid: mapped group %s to gid %u\n", map.nt_name, (unsigned int)map.gid));
- fstrcpy(name, map.nt_name);
- *psid_name_use = map.sid_name_use;
- return True;
+ } else {
+ DEBUG(5,("local_lookup_sid: mapped group %s to no unix gid. Returning name.\n", map.nt_name));
}
- }
-
- is_user = pdb_rid_is_user(rid);
- DEBUG(5, ("assuming RID %u is a %s\n", (unsigned)rid, is_user ? "user" : "group"));
+ fstrcpy(name, map.nt_name);
+ *psid_name_use = map.sid_name_use;
+ return True;
+ }
if (pdb_rid_is_user(rid)) {
- uid = fallback_pdb_user_rid_to_uid(rid);
- pass = getpwuid_alloc(uid);
-
- *psid_name_use = SID_NAME_USER;
-
- DEBUG(5,("local_lookup_sid: looking up uid %u %s\n", (unsigned int)uid,
- pass ? "succeeded" : "failed" ));
-
- if(!pass) {
- slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid);
- return True;
- }
-
- fstrcpy(name, pass->pw_name);
-
- DEBUG(5,("local_lookup_sid: found user %s for rid %u\n", name,
- (unsigned int)rid ));
-
- passwd_free(&pass);
-
+ uid_t uid;
+
+ DEBUG(5, ("assuming RID %u is a user\n", (unsigned)rid));
+
+ uid = fallback_pdb_user_rid_to_uid(rid);
+ slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid);
+
+ return False; /* Indicates that this user was 'not mapped' */
} else {
gid_t gid;
struct group *gr;
+ DEBUG(5, ("assuming RID %u is a group\n", (unsigned)rid));
+
gid = pdb_group_rid_to_gid(rid);
gr = getgrgid(gid);
@@ -623,15 +663,15 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
if(!gr) {
slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid);
- return False;
+ return False; /* Indicates that this group was 'not mapped' */
}
fstrcpy( name, gr->gr_name);
DEBUG(5,("local_lookup_sid: found group %s for rid %u\n", name,
(unsigned int)rid ));
+ return True;
}
- return True;
}
/*******************************************************************
@@ -641,11 +681,12 @@ BOOL local_lookup_sid(DOM_SID *sid, char *name, enum SID_NAME_USE *psid_name_use
BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psid_name_use)
{
extern DOM_SID global_sid_World_Domain;
- struct passwd *pass = NULL;
DOM_SID local_sid;
fstring user;
SAM_ACCOUNT *sam_account = NULL;
-
+ struct group *grp;
+ GROUP_MAP map;
+
*psid_name_use = SID_NAME_UNKNOWN;
/*
@@ -691,52 +732,45 @@ BOOL local_lookup_name(const char *c_user, DOM_SID *psid, enum SID_NAME_USE *psi
pdb_free_sam(&sam_account);
- if ((pass = Get_Pwnam(user))) {
- sid_append_rid( &local_sid, fallback_pdb_uid_to_user_rid(pass->pw_uid));
- *psid_name_use = SID_NAME_USER;
+ /*
+ * Maybe it was a group ?
+ */
+ /* check if it's a mapped group */
+ if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) {
+ if (map.gid!=-1) {
+ /* yes it's a mapped group to a valid unix group */
+ sid_copy(&local_sid, &map.sid);
+ *psid_name_use = map.sid_name_use;
+ }
+ else {
+ /* it's a correct name but not mapped so it points to nothing*/
+ return False;
+ }
} else {
- /*
- * Maybe it was a group ?
+ /* it's not a mapped group */
+ grp = getgrnam(user);
+ if(!grp)
+ return False;
+
+ /*
+ *check if it's mapped, if it is reply it doesn't exist
+ *
+ * that's to prevent this case:
+ *
+ * unix group ug is mapped to nt group ng
+ * someone does a lookup on ug
+ * we must not reply as it doesn't "exist" anymore
+ * for NT. For NT only ng exists.
+ * JFM, 30/11/2001
*/
- struct group *grp;
- GROUP_MAP map;
- /* check if it's a mapped group */
- if (get_group_map_from_ntname(user, &map, MAPPING_WITHOUT_PRIV)) {
- if (map.gid!=-1) {
- /* yes it's a mapped group to a valid unix group */
- sid_copy(&local_sid, &map.sid);
- *psid_name_use = map.sid_name_use;
- }
- else
- /* it's a correct name but not mapped so it points to nothing*/
- return False;
- } else {
- /* it's not a mapped group */
- grp = getgrnam(user);
- if(!grp)
- return False;
-
- /*
- *check if it's mapped, if it is reply it doesn't exist
- *
- * that's to prevent this case:
- *
- * unix group ug is mapped to nt group ng
- * someone does a lookup on ug
- * we must not reply as it doesn't "exist" anymore
- * for NT. For NT only ng exists.
- * JFM, 30/11/2001
- */
-
- if(get_group_map_from_gid(grp->gr_gid, &map, MAPPING_WITHOUT_PRIV)){
- return False;
- }
-
- sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
- *psid_name_use = SID_NAME_ALIAS;
+ if (get_group_map_from_gid(grp->gr_gid, &map, MAPPING_WITHOUT_PRIV)){
+ return False;
}
+
+ sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
+ *psid_name_use = SID_NAME_ALIAS;
}
sid_copy( psid, &local_sid);
@@ -824,15 +858,9 @@ BOOL local_sid_to_uid(uid_t *puid, DOM_SID *psid, enum SID_NAME_USE *name_type)
DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (%s).\n", sid_to_string( str, psid),
(unsigned int)*puid, pdb_get_username(sam_user)));
} else {
- if ((pdb_rid_is_user(rid))) {
- *puid = fallback_pdb_user_rid_to_uid(rid);
- DEBUG(10,("local_sid_to_uid: SID %s -> uid (%u) (non-passdb user).\n", sid_to_string( str, psid),
- (unsigned int)*puid));
- } else {
- DEBUG(5,("local_sid_to_uid: SID %s not mapped becouse RID isn't a user.\n", sid_to_string( str, psid)));
- pdb_free_sam(&sam_user);
- return False;
- }
+ DEBUG(5,("local_sid_to_uid: SID %s not mapped becouse RID was not found in passdb.\n", sid_to_string( str, psid)));
+ pdb_free_sam(&sam_user);
+ return False;
}
pdb_free_sam(&sam_user);
@@ -919,7 +947,7 @@ BOOL local_sid_to_gid(gid_t *pgid, DOM_SID *psid, enum SID_NAME_USE *name_type)
* @return static buffer containing the converted string
**/
-static char *pdb_convert(const UNISTR2 *from)
+const char *pdb_unistr2_convert(const UNISTR2 *from)
{
static pstring convert_buffer;
*convert_buffer = 0;
@@ -950,25 +978,25 @@ void copy_id23_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_23 *from)
pdb_set_pass_last_set_time(to, nt_time_to_unix(&from->pass_last_set_time));
if (from->uni_user_name.buffer)
- pdb_set_username(to , pdb_convert(&from->uni_user_name ));
+ pdb_set_username(to , pdb_unistr2_convert(&from->uni_user_name ));
if (from->uni_full_name.buffer)
- pdb_set_fullname(to , pdb_convert(&from->uni_full_name ));
+ pdb_set_fullname(to , pdb_unistr2_convert(&from->uni_full_name ));
if (from->uni_home_dir.buffer)
- pdb_set_homedir(to , pdb_convert(&from->uni_home_dir ), True);
+ pdb_set_homedir(to , pdb_unistr2_convert(&from->uni_home_dir ), True);
if (from->uni_dir_drive.buffer)
- pdb_set_dir_drive(to , pdb_convert(&from->uni_dir_drive ), True);
+ pdb_set_dir_drive(to , pdb_unistr2_convert(&from->uni_dir_drive ), True);
if (from->uni_logon_script.buffer)
- pdb_set_logon_script(to , pdb_convert(&from->uni_logon_script), True);
+ pdb_set_logon_script(to , pdb_unistr2_convert(&from->uni_logon_script), True);
if (from->uni_profile_path.buffer)
- pdb_set_profile_path(to , pdb_convert(&from->uni_profile_path), True);
+ pdb_set_profile_path(to , pdb_unistr2_convert(&from->uni_profile_path), True);
if (from->uni_acct_desc.buffer)
- pdb_set_acct_desc(to , pdb_convert(&from->uni_acct_desc ));
+ pdb_set_acct_desc(to , pdb_unistr2_convert(&from->uni_acct_desc ));
if (from->uni_workstations.buffer)
- pdb_set_workstations(to , pdb_convert(&from->uni_workstations));
+ pdb_set_workstations(to , pdb_unistr2_convert(&from->uni_workstations));
if (from->uni_unknown_str.buffer)
- pdb_set_unknown_str(to , pdb_convert(&from->uni_unknown_str ));
+ pdb_set_unknown_str(to , pdb_unistr2_convert(&from->uni_unknown_str ));
if (from->uni_munged_dial.buffer)
- pdb_set_munged_dial(to , pdb_convert(&from->uni_munged_dial ));
+ pdb_set_munged_dial(to , pdb_unistr2_convert(&from->uni_munged_dial ));
if (from->user_rid)
pdb_set_user_rid(to, from->user_rid);
@@ -1005,25 +1033,25 @@ void copy_id21_to_sam_passwd(SAM_ACCOUNT *to, SAM_USER_INFO_21 *from)
pdb_set_pass_last_set_time(to, nt_time_to_unix(&from->pass_last_set_time));
if (from->uni_user_name.buffer)
- pdb_set_username(to , pdb_convert(&from->uni_user_name ));
+ pdb_set_username(to , pdb_unistr2_convert(&from->uni_user_name ));
if (from->uni_full_name.buffer)
- pdb_set_fullname(to , pdb_convert(&from->uni_full_name ));
+ pdb_set_fullname(to , pdb_unistr2_convert(&from->uni_full_name ));
if (from->uni_home_dir.buffer)
- pdb_set_homedir(to , pdb_convert(&from->uni_home_dir ), True);
+ pdb_set_homedir(to , pdb_unistr2_convert(&from->uni_home_dir ), True);
if (from->uni_dir_drive.buffer)
- pdb_set_dir_drive(to , pdb_convert(&from->uni_dir_drive ), True);
+ pdb_set_dir_drive(to , pdb_unistr2_convert(&from->uni_dir_drive ), True);
if (from->uni_logon_script.buffer)
- pdb_set_logon_script(to , pdb_convert(&from->uni_logon_script), True);
+ pdb_set_logon_script(to , pdb_unistr2_convert(&from->uni_logon_script), True);
if (from->uni_profile_path.buffer)
- pdb_set_profile_path(to , pdb_convert(&from->uni_profile_path), True);
+ pdb_set_profile_path(to , pdb_unistr2_convert(&from->uni_profile_path), True);
if (from->uni_acct_desc.buffer)
- pdb_set_acct_desc(to , pdb_convert(&from->uni_acct_desc ));
+ pdb_set_acct_desc(to , pdb_unistr2_convert(&from->uni_acct_desc ));
if (from->uni_workstations.buffer)
- pdb_set_workstations(to , pdb_convert(&from->uni_workstations));
+ pdb_set_workstations(to , pdb_unistr2_convert(&from->uni_workstations));
if (from->uni_unknown_str.buffer)
- pdb_set_unknown_str(to , pdb_convert(&from->uni_unknown_str ));
+ pdb_set_unknown_str(to , pdb_unistr2_convert(&from->uni_unknown_str ));
if (from->uni_munged_dial.buffer)
- pdb_set_munged_dial(to , pdb_convert(&from->uni_munged_dial ));
+ pdb_set_munged_dial(to , pdb_unistr2_convert(&from->uni_munged_dial ));
if (from->user_rid)
pdb_set_user_rid(to, from->user_rid);
diff --git a/source/passdb/pdb_get_set.c b/source/passdb/pdb_get_set.c
index cf77efd38fe..372b332a451 100644
--- a/source/passdb/pdb_get_set.c
+++ b/source/passdb/pdb_get_set.c
@@ -138,6 +138,21 @@ const uint8* pdb_get_lanman_passwd (const SAM_ACCOUNT *sampass)
return (NULL);
}
+/* Return the plaintext password if known. Most of the time
+ it isn't, so don't assume anything magic about this function.
+
+ Used to pass the plaintext to passdb backends that might
+ want to store more than just the NTLM hashes.
+*/
+const char* pdb_get_plaintext_passwd (const SAM_ACCOUNT *sampass)
+{
+ if (sampass) {
+ return ((char*)sampass->private.plaintext_pw.data);
+ }
+ else
+ return (NULL);
+}
+
uint32 pdb_get_user_rid (const SAM_ACCOUNT *sampass)
{
if (sampass)
@@ -224,6 +239,14 @@ const char* pdb_get_homedir (const SAM_ACCOUNT *sampass)
return (NULL);
}
+const char* pdb_get_unix_homedir (const SAM_ACCOUNT *sampass)
+{
+ if (sampass)
+ return (sampass->private.unix_home_dir);
+ else
+ return (NULL);
+}
+
const char* pdb_get_dirdrive (const SAM_ACCOUNT *sampass)
{
if (sampass)
@@ -618,7 +641,7 @@ BOOL pdb_set_logon_script(SAM_ACCOUNT *sampass, const char *logon_script, BOOL s
}
if (store) {
- DEBUG(10, ("pdb_set_logon_script: setting logon script sam flag!"));
+ DEBUG(10, ("pdb_set_logon_script: setting logon script sam flag!\n"));
pdb_set_init_flag(sampass, FLAG_SAM_LOGONSCRIPT);
}
@@ -650,7 +673,7 @@ BOOL pdb_set_profile_path (SAM_ACCOUNT *sampass, const char *profile_path, BOOL
}
if (store) {
- DEBUG(10, ("pdb_set_profile_path: setting profile path sam flag!"));
+ DEBUG(10, ("pdb_set_profile_path: setting profile path sam flag!\n"));
pdb_set_init_flag(sampass, FLAG_SAM_PROFILE);
}
@@ -682,7 +705,7 @@ BOOL pdb_set_dir_drive (SAM_ACCOUNT *sampass, const char *dir_drive, BOOL store)
}
if (store) {
- DEBUG(10, ("pdb_set_dir_drive: setting dir drive sam flag!"));
+ DEBUG(10, ("pdb_set_dir_drive: setting dir drive sam flag!\n"));
pdb_set_init_flag(sampass, FLAG_SAM_DRIVE);
}
@@ -722,6 +745,34 @@ BOOL pdb_set_homedir (SAM_ACCOUNT *sampass, const char *home_dir, BOOL store)
}
/*********************************************************************
+ Set the user's unix home directory.
+ ********************************************************************/
+
+BOOL pdb_set_unix_homedir (SAM_ACCOUNT *sampass, const char *unix_home_dir)
+{
+ if (!sampass)
+ return False;
+
+ if (unix_home_dir) {
+ DEBUG(10, ("pdb_set_homedir: setting home dir %s, was %s\n", unix_home_dir,
+ (sampass->private.unix_home_dir)?(sampass->private.unix_home_dir):"NULL"));
+
+ sampass->private.unix_home_dir = talloc_strdup(sampass->mem_ctx,
+ unix_home_dir);
+
+ if (!sampass->private.unix_home_dir) {
+ DEBUG(0, ("pdb_set_unix_home_dir: talloc_strdup() failed!\n"));
+ return False;
+ }
+
+ } else {
+ sampass->private.unix_home_dir = PDB_NOT_QUITE_NULL;
+ }
+
+ return True;
+}
+
+/*********************************************************************
Set the user's account description.
********************************************************************/
@@ -840,7 +891,7 @@ BOOL pdb_set_nt_passwd (SAM_ACCOUNT *sampass, const uint8 *pwd)
Set the user's LM hash.
********************************************************************/
-BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 *pwd)
+BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 pwd[16])
{
if (!sampass)
return False;
@@ -852,6 +903,23 @@ BOOL pdb_set_lanman_passwd (SAM_ACCOUNT *sampass, const uint8 *pwd)
return True;
}
+/*********************************************************************
+ Set the user's plaintext password only (base procedure, see helper
+ below)
+ ********************************************************************/
+
+BOOL pdb_set_plaintext_pw_only (SAM_ACCOUNT *sampass, const uint8 *password, size_t len)
+{
+ if (!sampass)
+ return False;
+
+ data_blob_clear_free(&sampass->private.plaintext_pw);
+
+ sampass->private.plaintext_pw = data_blob(password, len);
+
+ return True;
+}
+
BOOL pdb_set_unknown_3 (SAM_ACCOUNT *sampass, uint32 unkn)
{
if (!sampass)
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
index a19bf254e7a..6488decf947 100644
--- a/source/passdb/pdb_interface.c
+++ b/source/passdb/pdb_interface.c
@@ -30,6 +30,7 @@ const struct pdb_init_function_entry builtin_pdb_init_functions[] = {
{ "tdbsam_nua", pdb_init_tdbsam_nua },
{ "ldapsam", pdb_init_ldapsam },
{ "ldapsam_nua", pdb_init_ldapsam_nua },
+ { "unixsam", pdb_init_unixsam },
{ "plugin", pdb_init_plugin },
{ NULL, NULL}
};
@@ -42,7 +43,12 @@ static BOOL context_setsampwent(struct pdb_context *context, BOOL update)
}
context->pwent_methods = context->pdb_methods;
-
+
+ if (!context->pwent_methods) {
+ /* No passdbs at all */
+ return True;
+ }
+
while(!(context->pwent_methods->setsampwent(context->pwent_methods, update))){
context->pwent_methods = context->pwent_methods->next;
if(context->pwent_methods == NULL)return False;
@@ -83,7 +89,7 @@ static BOOL context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *user)
if(context->pwent_methods == NULL)return False;
if(!context->pwent_methods->setsampwent){
- DEBUG(0, ("invalid context->pwent_methods->setsampwent\n"));
+ DEBUG(5, ("invalid context->pwent_methods->setsampwent\n"));
return False;
}
@@ -251,7 +257,11 @@ static NTSTATUS make_pdb_methods_name(struct pdb_methods **methods, struct pdb_c
if (!*methods) {
DEBUG(0,("failed to select passdb backed!\n"));
- return nt_status;
+ if (NT_STATUS_IS_OK(nt_status)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ } else {
+ return nt_status;
+ }
}
return NT_STATUS_OK;
}
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index af0cbef4f2a..9614483ee1e 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -339,7 +339,7 @@ static int ldapsam_search_one_user_by_rid (struct ldapsam_privates *ldap_state,
search an attribute and return the first value found.
******************************************************************/
static BOOL get_single_attribute (LDAP * ldap_struct, LDAPMessage * entry,
- char *attribute, char *value)
+ char *attribute, pstring value)
{
char **values;
@@ -521,12 +521,14 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
pw = getpwnam_alloc(username);
if (pw == NULL) {
- DEBUG (2,("init_sam_from_ldap: User [%s] does not have a uid!\n", username));
+ DEBUG (2,("init_sam_from_ldap: User [%s] does not ave a uid!\n", username));
return False;
}
uid = pw->pw_uid;
gid = pw->pw_gid;
+ pdb_set_unix_homedir(sampass, pw->pw_dir);
+
passwd_free(&pw);
pdb_set_uid(sampass, uid);
@@ -603,37 +605,41 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
}
if (!get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive)) {
- pstrcpy(dir_drive, lp_logon_drive());
- standard_sub_advanced(-1, username, "", gid, username, dir_drive);
- DEBUG(5,("homeDrive fell back to %s\n",dir_drive));
- pdb_set_dir_drive(sampass, dir_drive, False);
+ pdb_set_dir_drive(sampass, standard_sub_specified(sampass->mem_ctx,
+ lp_logon_path(),
+ username, domain,
+ uid, gid),
+ False);
} else {
pdb_set_dir_drive(sampass, dir_drive, True);
}
if (!get_single_attribute(ldap_struct, entry, "smbHome", homedir)) {
- pstrcpy(homedir, lp_logon_home());
- standard_sub_advanced(-1, username, "", gid, username, homedir);
- DEBUG(5,("smbHome fell back to %s\n",homedir));
- pdb_set_homedir(sampass, homedir, False);
+ pdb_set_dir_drive(sampass, standard_sub_specified(sampass->mem_ctx,
+ lp_logon_home(),
+ username, domain,
+ uid, gid),
+ False);
} else {
pdb_set_homedir(sampass, homedir, True);
}
if (!get_single_attribute(ldap_struct, entry, "scriptPath", logon_script)) {
- pstrcpy(logon_script, lp_logon_script());
- standard_sub_advanced(-1, username, "", gid, username, logon_script);
- DEBUG(5,("scriptPath fell back to %s\n",logon_script));
- pdb_set_logon_script(sampass, logon_script, False);
+ pdb_set_logon_script(sampass, standard_sub_specified(sampass->mem_ctx,
+ lp_logon_script(),
+ username, domain,
+ uid, gid),
+ False);
} else {
pdb_set_logon_script(sampass, logon_script, True);
}
if (!get_single_attribute(ldap_struct, entry, "profilePath", profile_path)) {
- pstrcpy(profile_path, lp_logon_path());
- standard_sub_advanced(-1, username, "", gid, username, profile_path);
- DEBUG(5,("profilePath fell back to %s\n",profile_path));
- pdb_set_profile_path(sampass, profile_path, False);
+ pdb_set_profile_path(sampass, standard_sub_specified(sampass->mem_ctx,
+ lp_logon_path(),
+ username, domain,
+ uid, gid),
+ False);
} else {
pdb_set_profile_path(sampass, profile_path, True);
}
@@ -740,7 +746,7 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
} else if (ldap_state->permit_non_unix_accounts) {
rid = ldapsam_get_next_available_nua_rid(ldap_state);
if (rid == 0) {
- DEBUG(0, ("NO user RID specified on account %s, and finding next available NUA RID failed, cannot store!\n", pdb_get_username(sampass)));
+ DEBUG(0, ("NO user RID specified on account %s, and findining next available NUA RID failed, cannot store!\n", pdb_get_username(sampass)));
return False;
}
} else {
@@ -1097,7 +1103,7 @@ static BOOL ldapsam_getsampwnam(struct pdb_methods *my_methods, SAM_ACCOUNT * us
if (ldap_count_entries(ldap_struct, result) < 1)
{
DEBUG(4,
- ("We didn't find the user [%s] count=%d\n", sname,
+ ("We don't find this user [%s] count=%d\n", sname,
ldap_count_entries(ldap_struct, result)));
ldap_unbind(ldap_struct);
return False;
@@ -1151,7 +1157,7 @@ static BOOL ldapsam_getsampwrid(struct pdb_methods *my_methods, SAM_ACCOUNT * us
if (ldap_count_entries(ldap_struct, result) < 1)
{
DEBUG(0,
- ("We didn't find the rid [%i] count=%d\n", rid,
+ ("We don't find this rid [%i] count=%d\n", rid,
ldap_count_entries(ldap_struct, result)));
ldap_unbind(ldap_struct);
return False;
@@ -1205,7 +1211,7 @@ static BOOL ldapsam_delete_sam_account(struct pdb_methods *my_methods, const SAM
if (!ldapsam_connect_system(ldap_state, ldap_struct)) {
ldap_unbind (ldap_struct);
- DEBUG(0, ("failed to delete user %s from the LDAP database.\n", sname));
+ DEBUG(0, ("Failed to delete user %s from LDAP.\n", sname));
return False;
}
diff --git a/source/passdb/pdb_smbpasswd.c b/source/passdb/pdb_smbpasswd.c
index 9f37cadfe89..88e317cea90 100644
--- a/source/passdb/pdb_smbpasswd.c
+++ b/source/passdb/pdb_smbpasswd.c
@@ -1218,7 +1218,8 @@ static BOOL build_smb_pass (struct smb_passwd *smb_pw, const SAM_ACCOUNT *sampas
/*********************************************************************
Create a SAM_ACCOUNT from a smb_passwd struct
********************************************************************/
-static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw_buf)
+static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state,
+ SAM_ACCOUNT *sam_pass, const struct smb_passwd *pw_buf)
{
struct passwd *pwfile;
@@ -1242,73 +1243,25 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state, SAM_AC
} else {
- uint32 grid;
- GROUP_MAP map;
-
- /* Verify in system password file...
- FIXME!!! This is where we should look up an internal
- mapping of allocated uid for machine accounts as well
- --jerry */
pwfile = getpwnam_alloc(pw_buf->smb_name);
if (pwfile == NULL) {
DEBUG(0,("build_sam_account: smbpasswd database is corrupt! username %s with uid %u is not in unix passwd database!\n", pw_buf->smb_name, pw_buf->smb_userid));
return False;
}
- pdb_set_uid (sam_pass, pwfile->pw_uid);
- pdb_set_gid (sam_pass, pwfile->pw_gid);
-
- pdb_set_fullname(sam_pass, pwfile->pw_gecos);
-
- pdb_set_user_rid(sam_pass, fallback_pdb_uid_to_user_rid (pwfile->pw_uid));
-
- if (get_group_map_from_gid(pwfile->pw_gid, &map, MAPPING_WITHOUT_PRIV)) {
- sid_peek_rid(&map.sid, &grid);
- } else {
- grid=pdb_gid_to_group_rid(pwfile->pw_gid);
- }
-
- pdb_set_group_rid(sam_pass, grid);
-
- /* check if this is a user account or a machine account */
- if (pw_buf->smb_name[strlen(pw_buf->smb_name)-1] != '$')
- {
- pstring str;
-
- pstrcpy(str, lp_logon_path());
- standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
- pdb_set_profile_path(sam_pass, str, False);
-
- pstrcpy(str, lp_logon_home());
- standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
- pdb_set_homedir(sam_pass, str, False);
-
- pstrcpy(str, lp_logon_drive());
- standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
- pdb_set_dir_drive(sam_pass, str, False);
-
- pstrcpy(str, lp_logon_script());
- standard_sub_advanced(-1, pwfile->pw_name, "", pwfile->pw_gid, pw_buf->smb_name, str);
- pdb_set_logon_script(sam_pass, str, False);
-
- } else {
- /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
- /*pdb_set_group_rid (sam_pass, DOMAIN_GROUP_RID_USERS); */
+ if (!NT_STATUS_IS_OK(pdb_fill_sam_pw(sam_pass, pwfile))) {
+ return False;
}
passwd_free(&pwfile);
}
- pdb_set_username (sam_pass, pw_buf->smb_name);
pdb_set_nt_passwd (sam_pass, pw_buf->smb_nt_passwd);
pdb_set_lanman_passwd (sam_pass, pw_buf->smb_passwd);
pdb_set_acct_ctrl (sam_pass, pw_buf->acct_ctrl);
pdb_set_pass_last_set_time (sam_pass, pw_buf->pass_last_set_time);
pdb_set_pass_can_change_time (sam_pass, pw_buf->pass_last_set_time, True);
- pdb_set_domain (sam_pass, lp_workgroup());
- pdb_set_dir_drive (sam_pass, lp_logon_drive(), False);
-
#if 0 /* JERRY */
/* the smbpasswd format doesn't have a must change time field, so
we can't get this right. The best we can do is to set this to
diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c
index 3a9bc894bbe..46120c3ccc1 100644
--- a/source/passdb/pdb_tdb.c
+++ b/source/passdb/pdb_tdb.c
@@ -86,12 +86,11 @@ static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state,
uint8 *hours;
static uint8 *lm_pw_ptr, *nt_pw_ptr;
uint32 len = 0;
- uint32 lmpwlen, ntpwlen, hourslen;
+ uint32 lm_pw_len, nt_pw_len, hourslen;
BOOL ret = True;
- BOOL setflag;
pstring sub_buffer;
struct passwd *pw;
- uid_t uid;
+ uid_t uid = -1;
gid_t gid = -1; /* This is what standard sub advanced expects if no gid is known */
if(sampass == NULL || buf == NULL) {
@@ -121,8 +120,8 @@ static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state,
&munged_dial_len, &munged_dial,
&user_rid,
&group_rid,
- &lmpwlen, &lm_pw_ptr,
- &ntpwlen, &nt_pw_ptr,
+ &lm_pw_len, &lm_pw_ptr,
+ &nt_pw_len, &nt_pw_ptr,
&acct_ctrl,
&unknown_3,
&logon_divs,
@@ -152,6 +151,8 @@ static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state,
uid = pw->pw_uid;
gid = pw->pw_gid;
+ pdb_set_unix_homedir(sampass, pw->pw_dir);
+
passwd_free(&pw);
pdb_set_uid(sampass, uid);
@@ -165,66 +166,72 @@ static BOOL init_sam_from_buffer (struct tdbsam_privates *tdb_state,
pdb_set_pass_must_change_time(sampass, pass_must_change_time, True);
pdb_set_pass_last_set_time(sampass, pass_last_set_time);
- pdb_set_username (sampass, username);
+ pdb_set_username (sampass, username);
pdb_set_domain (sampass, domain);
pdb_set_nt_username (sampass, nt_username);
pdb_set_fullname (sampass, fullname);
- if (homedir) setflag = True;
+ if (homedir) {
+ pdb_set_homedir(sampass, homedir, True);
+ }
else {
- setflag = False;
- pstrcpy(sub_buffer, lp_logon_home());
- /* standard_sub_advanced() assumes pstring is passed!! */
- standard_sub_advanced(-1, username, "", gid, username, sub_buffer);
- homedir = strdup(sub_buffer);
- if(!homedir) { ret = False; goto done; }
- DEBUG(5,("Home directory set back to %s\n", homedir));
+ pdb_set_homedir(sampass,
+ standard_sub_specified(sampass->mem_ctx,
+ lp_logon_home(),
+ username, domain,
+ uid, gid),
+ False);
}
- pdb_set_homedir(sampass, homedir, setflag);
- if (dir_drive) setflag = True;
+ if (dir_drive)
+ pdb_set_dir_drive(sampass, dir_drive, True);
else {
- setflag = False;
- pstrcpy(sub_buffer, lp_logon_drive());
- standard_sub_advanced(-1, username, "", gid, username, sub_buffer);
- dir_drive = strdup(sub_buffer);
- if(!dir_drive) { ret = False; goto done; }
- DEBUG(5,("Drive set back to %s\n", dir_drive));
+ pdb_set_dir_drive(sampass,
+ standard_sub_specified(sampass->mem_ctx,
+ lp_logon_drive(),
+ username, domain,
+ uid, gid),
+ False);
}
- pdb_set_dir_drive(sampass, dir_drive, setflag);
- if (logon_script) setflag = True;
+ if (logon_script)
+ pdb_set_logon_script(sampass, logon_script, True);
else {
- setflag = False;
- pstrcpy(sub_buffer, lp_logon_script());
- standard_sub_advanced(-1, username, "", gid, username, sub_buffer);
- logon_script = strdup(sub_buffer);
- if(!logon_script) { ret = False; goto done; }
- DEBUG(5,("Logon script set back to %s\n", logon_script));
+ pdb_set_logon_script(sampass,
+ standard_sub_specified(sampass->mem_ctx,
+ lp_logon_script(),
+ username, domain,
+ uid, gid),
+ False);
}
- pdb_set_logon_script(sampass, logon_script, setflag);
- if (profile_path) setflag = True;
- else {
- setflag = False;
- pstrcpy(sub_buffer, lp_logon_path());
- standard_sub_advanced(-1, username, "", gid, username, sub_buffer);
- profile_path = strdup(sub_buffer);
- if(!profile_path) { ret = False; goto done; }
- DEBUG(5,("Profile path set back to %s\n", profile_path));
+ if (profile_path) {
+ pdb_set_profile_path(sampass, profile_path, True);
+ } else {
+ pdb_set_profile_path(sampass,
+ standard_sub_specified(sampass->mem_ctx,
+ lp_logon_path(),
+ username, domain,
+ uid, gid),
+ False);
}
- pdb_set_profile_path(sampass, profile_path, setflag);
pdb_set_acct_desc (sampass, acct_desc);
pdb_set_workstations (sampass, workstations);
pdb_set_munged_dial (sampass, munged_dial);
- if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr)) {
- ret = False;
- goto done;
+
+ if (lm_pw_ptr && lm_pw_len == LM_HASH_LEN) {
+ if (!pdb_set_lanman_passwd(sampass, lm_pw_ptr)) {
+ ret = False;
+ goto done;
+ }
}
- if (!pdb_set_nt_passwd(sampass, nt_pw_ptr)) {
- ret = False;
- goto done;
+
+ if (nt_pw_ptr && nt_pw_len == NT_HASH_LEN) {
+ if (!pdb_set_nt_passwd(sampass, nt_pw_ptr)) {
+ ret = False;
+ goto done;
+ }
}
pdb_set_user_rid(sampass, user_rid);
diff --git a/source/passdb/pdb_unix.c b/source/passdb/pdb_unix.c
new file mode 100644
index 00000000000..d1f95c445bb
--- /dev/null
+++ b/source/passdb/pdb_unix.c
@@ -0,0 +1,126 @@
+/*
+ * Unix password backend for samba
+ * Copyright (C) Jelmer Vernooij 2002
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+
+/******************************************************************
+ Lookup a name in the SAM database
+ ******************************************************************/
+
+static BOOL unixsam_getsampwnam (struct pdb_methods *methods, SAM_ACCOUNT *user, const char *sname)
+{
+ struct passwd *pass;
+ if (!methods) {
+ DEBUG(0,("invalid methods\n"));
+ return False;
+ }
+ if (!sname) {
+ DEBUG(0,("invalid name specified"));
+ return False;
+ }
+ pass = Get_Pwnam(sname);
+
+ return NT_STATUS_IS_OK(pdb_fill_sam_pw(user, pass));
+}
+
+
+/***************************************************************************
+ Search by rid
+ **************************************************************************/
+
+static BOOL unixsam_getsampwrid (struct pdb_methods *methods,
+ SAM_ACCOUNT *user, uint32 rid)
+{
+ struct passwd *pass;
+ BOOL ret = False;
+ if (!methods) {
+ DEBUG(0,("invalid methods\n"));
+ return False;
+ }
+
+ if (pdb_rid_is_user(rid)) {
+ pass = getpwuid_alloc(fallback_pdb_user_rid_to_uid (rid));
+
+ if (pass) {
+ ret = NT_STATUS_IS_OK(pdb_fill_sam_pw(user, pass));
+ passwd_free(&pass);
+ }
+ }
+ return ret;
+}
+
+/***************************************************************************
+ Delete a SAM_ACCOUNT
+ ****************************************************************************/
+
+static BOOL unixsam_delete_sam_account(struct pdb_methods *methods, const SAM_ACCOUNT *sam_pass)
+{
+ /*
+ * Unsupported as well - we don't need to get involved in
+ * unix passdb's - and hey, we would need to use pam for that anyway
+ */
+ return False;
+}
+
+/***************************************************************************
+ Modifies an existing SAM_ACCOUNT
+ ****************************************************************************/
+
+static BOOL unixsam_update_sam_account (struct pdb_methods *methods, const SAM_ACCOUNT *newpwd)
+{
+ return False;
+}
+
+/***************************************************************************
+ Adds an existing SAM_ACCOUNT
+ ****************************************************************************/
+
+static BOOL unixsam_add_sam_account (struct pdb_methods *methods, const SAM_ACCOUNT *newpwd)
+{
+ DEBUG(0,("pdb_unix should not be listed as the first passdb backend! You can't add users to it.\n"));
+ return False;
+}
+
+NTSTATUS pdb_init_unixsam(PDB_CONTEXT *pdb_context, PDB_METHODS **pdb_method, const char *location)
+{
+ NTSTATUS nt_status;
+
+ if (!pdb_context) {
+ DEBUG(0, ("invalid pdb_context specified\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (!NT_STATUS_IS_OK(nt_status = make_pdb_methods(pdb_context->mem_ctx, pdb_method))) {
+ return nt_status;
+ }
+
+ (*pdb_method)->name = "unixsam";
+
+ (*pdb_method)->setsampwent = NULL;
+ (*pdb_method)->endsampwent = NULL;
+ (*pdb_method)->getsampwent = NULL;
+ (*pdb_method)->getsampwnam = unixsam_getsampwnam;
+ (*pdb_method)->getsampwrid = unixsam_getsampwrid;
+ (*pdb_method)->add_sam_account = unixsam_add_sam_account;
+ (*pdb_method)->update_sam_account = unixsam_update_sam_account;
+ (*pdb_method)->delete_sam_account = unixsam_delete_sam_account;
+
+ /* There's not very much to initialise here */
+ return NT_STATUS_OK;
+}
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index b8a558665f3..66312db52eb 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -1462,13 +1462,30 @@ NTSTATUS init_sam_dispinfo_1(TALLOC_CTX *ctx, SAM_DISPINFO_1 *sam, uint32 num_en
ZERO_STRUCTP(sam->str);
for (i = 0; i < num_entries ; i++) {
+ const char *username;
+ const char *fullname;
+ const char *acct_desc;
+
DEBUG(11, ("init_sam_dispinfo_1: entry: %d\n",i));
pwd=disp_user_info[i+start_idx].sam;
- len_sam_name = strlen(pdb_get_username(pwd));
- len_sam_full = strlen(pdb_get_fullname(pwd));
- len_sam_desc = strlen(pdb_get_acct_desc(pwd));
+ username = pdb_get_username(pwd);
+ fullname = pdb_get_fullname(pwd);
+ acct_desc = pdb_get_acct_desc(pwd);
+
+ if (!username)
+ username = "";
+
+ if (!fullname)
+ fullname = "";
+
+ if (!acct_desc)
+ acct_desc = "";
+
+ len_sam_name = strlen(username);
+ len_sam_full = strlen(fullname);
+ len_sam_desc = strlen(acct_desc);
init_sam_entry1(&sam->sam[i], start_idx + i + 1,
len_sam_name, len_sam_full, len_sam_desc,
diff --git a/source/rpc_server/srv_lsa_nt.c b/source/rpc_server/srv_lsa_nt.c
index c4adc26360b..a5e3f5003c5 100644
--- a/source/rpc_server/srv_lsa_nt.c
+++ b/source/rpc_server/srv_lsa_nt.c
@@ -259,6 +259,8 @@ static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME
if (!status) {
sid_name_use = SID_NAME_UNKNOWN;
+ } else {
+ (*mapped_count)++;
}
/* Store domain sid in ref array */
@@ -272,8 +274,6 @@ static void init_lsa_trans_names(TALLOC_CTX *ctx, DOM_R_REF *ref, LSA_TRANS_NAME
DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to "
"referenced list.\n", dom_name, name ));
- (*mapped_count)++;
-
init_lsa_trans_name(&trn->name[total], &trn->uni_name[total],
sid_name_use, name, dom_idx);
total++;
diff --git a/source/script/mkproto.awk b/source/script/mkproto.awk
index 9b0aa360bcc..c701ed41cda 100644
--- a/source/script/mkproto.awk
+++ b/source/script/mkproto.awk
@@ -72,6 +72,11 @@ END {
printf "char *%s(int );\n", a[2]
}
+/^FN_LOCAL_CONST_STRING/ {
+ split($0,a,"[,()]")
+ printf "const char *%s(int );\n", a[2]
+}
+
/^FN_LOCAL_INT/ {
split($0,a,"[,()]")
printf "int %s(int );\n", a[2]
@@ -97,6 +102,11 @@ END {
printf "char *%s(void);\n", a[2]
}
+/^FN_GLOBAL_CONST_STRING/ {
+ split($0,a,"[,()]")
+ printf "const char *%s(void);\n", a[2]
+}
+
/^FN_GLOBAL_INT/ {
split($0,a,"[,()]")
printf "int %s(void);\n", a[2]
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
index f8875c5c0f2..5585097c912 100644
--- a/source/smbd/lanman.c
+++ b/source/smbd/lanman.c
@@ -1933,7 +1933,7 @@ static BOOL api_RNetUserEnum(connection_struct *conn,uint16 vuid, char *param,ch
while ( pdb_getsampwent(pwd) ) {
const char *name=pdb_get_username(pwd);
- if( *(name+strlen(name)-1)!='$' ) {
+ if ((name) && (*(name+strlen(name)-1)!='$')) {
count_total++;
if(count_total>=resume_context) {
if( ((PTR_DIFF(p,*rdata)+21)<=*rdata_len)&&(strlen(name)<=21) ) {
@@ -2793,8 +2793,7 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
SIVAL(p,usri11_auth_flags,AF_OP_PRINT); /* auth flags */
SIVALS(p,usri11_password_age,-1); /* password age */
SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */
- pstrcpy(p2, lp_logon_home());
- standard_sub_conn(conn, p2);
+ pstrcpy(p2, vuser && vuser->homedir ? vuser->homedir : "");
p2 = skip_string(p2,1);
SIVAL(p,usri11_parms,PTR_DIFF(p2,p)); /* parms */
pstrcpy(p2,"");
@@ -2830,15 +2829,13 @@ static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param
SSVAL(p,42,
conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
- pstrcpy(p2,lp_logon_home());
- standard_sub_conn(conn, p2);
+ pstrcpy(p2, vuser && vuser->homedir ? vuser->homedir : "");
p2 = skip_string(p2,1);
SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* comment */
*p2++ = 0;
SSVAL(p,52,0); /* flags */
SIVAL(p,54,PTR_DIFF(p2,*rdata)); /* script_path */
- pstrcpy(p2,lp_logon_script());
- standard_sub_conn( conn, p2 );
+ pstrcpy(p2,vuser && vuser->logon_script ? vuser->logon_script : "");
p2 = skip_string(p2,1);
if (uLevel == 2)
{
@@ -2888,6 +2885,12 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
int uLevel;
struct pack_desc desc;
char* name;
+ /* With share level security vuid will always be zero.
+ Don't depend on vuser being non-null !!. JRA */
+ user_struct *vuser = get_valid_user_struct(vuid);
+ if(vuser != NULL)
+ DEBUG(3,(" Username of UID %d is %s\n", (int)vuser->uid,
+ vuser->user.unix_name));
uLevel = SVAL(p,0);
name = p + 2;
@@ -2931,15 +2934,7 @@ static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param
}
PACKS(&desc,"z",global_myworkgroup);/* domain */
-/* JHT - By calling lp_logon_script() and standard_sub() we have */
-/* made sure all macros are fully substituted and available */
- {
- pstring logon_script;
- pstrcpy(logon_script,lp_logon_script());
- standard_sub_conn( conn, logon_script );
- PACKS(&desc,"z", logon_script); /* script path */
- }
-/* End of JHT mods */
+ PACKS(&desc,"z", vuser && vuser->logon_script ? vuser->logon_script :""); /* script path */
PACKI(&desc,"D",0x00000000); /* reserved */
}
@@ -3458,7 +3453,7 @@ static int gather_sessioninfo(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, vo
{
struct sessions_info *sinfo = state;
struct session_info *curinfo = NULL;
- struct sessionid *sessid = (struct sessionid *) dbuf.dptr;
+ const struct sessionid *sessid = (const struct sessionid *) dbuf.dptr;
sinfo->count += 1;
sinfo->session_list = REALLOC(sinfo->session_list, sinfo->count * sizeof(struct session_info));
diff --git a/source/smbd/password.c b/source/smbd/password.c
index 629157f22d8..a8fd2b47f16 100644
--- a/source/smbd/password.c
+++ b/source/smbd/password.c
@@ -259,9 +259,19 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name)
{
/* Keep the homedir handy */
const char *homedir = pdb_get_homedir(server_info->sam_account);
+ const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account);
+ const char *logon_script = pdb_get_logon_script(server_info->sam_account);
if (homedir) {
vuser->homedir = smb_xstrdup(homedir);
}
+
+ if (unix_homedir) {
+ vuser->unix_homedir = smb_xstrdup(unix_homedir);
+ }
+
+ if (logon_script) {
+ vuser->logon_script = smb_xstrdup(logon_script);
+ }
}
memcpy(vuser->session_key, server_info->session_key, sizeof(vuser->session_key));
@@ -301,9 +311,9 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name)
}
/* Register a home dir service for this user */
- if ((!vuser->guest) && vuser->homedir && *(vuser->homedir)
+ if ((!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)
&& (lp_servicenumber(vuser->user.unix_name) < 0)) {
- add_home_service(vuser->user.unix_name, vuser->homedir);
+ add_home_service(vuser->user.unix_name, vuser->unix_homedir);
}
return vuser->vuid;
diff --git a/source/smbd/service.c b/source/smbd/service.c
index 467bab4a0ac..32ceb631543 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -81,9 +81,6 @@ BOOL set_current_service(connection_struct *conn,BOOL do_chdir)
int add_home_service(const char *service, const char *homedir)
{
int iHomeService;
- int iService;
- fstring new_service;
- fstring domain;
if (!service || !homedir)
return -1;
@@ -98,11 +95,19 @@ int add_home_service(const char *service, const char *homedir)
* include any macros.
*/
- split_domain_and_name(service, domain, new_service);
- lp_add_home(new_service, iHomeService, homedir);
- iService = lp_servicenumber(new_service);
+ {
+ const char *p = strchr(service,*lp_winbind_separator());
+
+ /* We only want the 'user' part of the string */
+ if (p) {
+ service = p + 1;
+ }
+ }
+
+ lp_add_home(service, iHomeService, homedir);
+
+ return lp_servicenumber(service);
- return iService;
}
diff --git a/source/utils/net_rpc_join.c b/source/utils/net_rpc_join.c
index c4558ea10b8..cc1a203ca13 100644
--- a/source/utils/net_rpc_join.c
+++ b/source/utils/net_rpc_join.c
@@ -53,7 +53,6 @@ int net_rpc_join_newstyle(int argc, const char **argv)
/* libsmb variables */
struct cli_state *cli;
- fstring acct_name;
TALLOC_CTX *mem_ctx;
uint32 acb_info;
@@ -81,7 +80,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
fstring domain;
uint32 num_rids, *name_types, *user_rids;
uint32 flags = 0x3e8;
- char *names;
+ const char *acct_name;
/* Connect to remote machine */
@@ -132,8 +131,7 @@ int net_rpc_join_newstyle(int argc, const char **argv)
"could not open domain");
/* Create domain user */
- fstrcpy(acct_name, global_myname);
- fstrcat(acct_name, "$");
+ acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname);
strlower(acct_name);
acb_info = ((lp_server_role() == ROLE_DOMAIN_BDC) || lp_server_role() == ROLE_DOMAIN_PDC) ? ACB_SVRTRUST : ACB_WSTRUST;
@@ -162,11 +160,9 @@ int net_rpc_join_newstyle(int argc, const char **argv)
if (NT_STATUS_IS_OK(result))
cli_samr_close(cli, mem_ctx, &user_pol);
- names = (char *)&acct_name[0];
-
CHECK_RPC_ERR_DEBUG(cli_samr_lookup_names(cli, mem_ctx,
&domain_pol, flags,
- 1, &names, &num_rids,
+ 1, &acct_name, &num_rids,
&user_rids, &name_types),
("error looking up rid for user %s: %s\n",
acct_name, nt_errstr(result)));