summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2001-10-29 07:28:32 +0000
committerAndrew Bartlett <abartlet@samba.org>2001-10-29 07:28:32 +0000
commit2038649e51f48a489aeec49947e1b791f0b3df43 (patch)
treeb3df7e09c5d563306f9a1b359a4b2579829b1a01
parent0db1899256517507fb5a441bd75725e3fcecc2e8 (diff)
downloadsamba-2038649e51f48a489aeec49947e1b791f0b3df43.tar.gz
samba-2038649e51f48a489aeec49947e1b791f0b3df43.tar.bz2
samba-2038649e51f48a489aeec49947e1b791f0b3df43.zip
This commit is number 3 of 4.
In particular this commit focuses on: Changing the Get_Pwnam code so that it can work in a const-enforced environment. While these changes have been mildly tested, and are pretty small, any assistance in this is appreciated. ---- These changes allow for 'const' in the Samba tree. There are a number of good reasons to do this: - I want to allow the SAM_ACCOUNT structure to move from wasteful pstrings and fstrings to allocated strings. We can't do that if people are modifying these outputs, as they may well make assumptions about getting pstrings and fstrings - I want --with-pam_smbpass to compile with a slightly sane volume of warnings, currently its pretty bad, even in 2.2 where is compiles at all. - Tridge assures me that he no longer opposes 'const religion' based on the ability to #define const the problem away. - Changed Get_Pwnam(x,y) into two variants (so that the const parameter can work correctly): - Get_Pwnam(const x) and Get_Pwnam_Modify(x). - Reworked smbd/chgpasswd.c to work with these mods, passing around a 'struct passwd' rather than the modified username (This used to be commit e7634f81c5116ff4addfb7e495f54b6bb78e8f77)
-rw-r--r--source3/auth/auth_rhosts.c4
-rw-r--r--source3/auth/auth_unix.c2
-rw-r--r--source3/lib/substitute.c2
-rw-r--r--source3/lib/username.c77
-rw-r--r--source3/passdb/smbpassgroup.c2
-rw-r--r--source3/rpc_server/srv_samr_nt.c4
-rw-r--r--source3/smbd/auth_rhosts.c4
-rw-r--r--source3/smbd/auth_unix.c2
-rw-r--r--source3/smbd/chgpasswd.c58
-rw-r--r--source3/smbd/lanman.c4
-rw-r--r--source3/smbd/password.c4
-rw-r--r--source3/smbd/service.c2
-rw-r--r--source3/smbd/uid.c2
13 files changed, 114 insertions, 53 deletions
diff --git a/source3/auth/auth_rhosts.c b/source3/auth/auth_rhosts.c
index d6ca01936f..9f5f1e10e5 100644
--- a/source3/auth/auth_rhosts.c
+++ b/source3/auth/auth_rhosts.c
@@ -86,7 +86,7 @@ static BOOL check_user_equiv(const char *user, const char *remote, const char *e
static char *mydomain = NULL;
if (!mydomain)
yp_get_default_domain(&mydomain);
- if (mydomain && innetgr(file_host,(char *)remote,(char *)user,mydomain))
+ if (mydomain && innetgr(file_host,remote,user,mydomain))
host_ok = True;
}
#else
@@ -135,7 +135,7 @@ static BOOL check_hosts_equiv(char *user) /* should be const... */
{
char *fname = NULL;
pstring rhostsfile;
- struct passwd *pass = Get_Pwnam(user,False);
+ struct passwd *pass = Get_Pwnam(user);
if (!pass)
return(False);
diff --git a/source3/auth/auth_unix.c b/source3/auth/auth_unix.c
index 2f9034e3e5..29a2a6eafb 100644
--- a/source3/auth/auth_unix.c
+++ b/source3/auth/auth_unix.c
@@ -89,7 +89,7 @@ NTSTATUS check_unix_security(const auth_usersupplied_info *user_info, auth_serve
become_root();
- pass = Get_Pwnam(user_info->unix_username.str, False);
+ pass = Get_Pwnam(user_info->unix_username.str);
nt_status = pass_check(pass,
pass ? pass->pw_name : user_info->unix_username.str,
diff --git a/source3/lib/substitute.c b/source3/lib/substitute.c
index 5336eb947f..60ff62cb06 100644
--- a/source3/lib/substitute.c
+++ b/source3/lib/substitute.c
@@ -186,7 +186,7 @@ void standard_sub_basic(char *str)
string_sub(p,"%U",tmp_str,l);
break;
case 'G' :
- if ((pass = Get_Pwnam(current_user_info.smb_name, False))!=NULL) {
+ if ((pass = Get_Pwnam(current_user_info.smb_name))!=NULL) {
string_sub(p,"%G",gidtoname(pass->pw_gid),l);
} else {
p += 2;
diff --git a/source3/lib/username.c b/source3/lib/username.c
index 24195b196b..074e6c8992 100644
--- a/source3/lib/username.c
+++ b/source3/lib/username.c
@@ -22,18 +22,18 @@
#include "includes.h"
/* internal functions */
-static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (char *), int N);
-static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (char *), int N);
+static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (const char *), int N);
+static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (const char *), int N);
/****************************************************************************
Get a users home directory.
****************************************************************************/
-char *get_user_home_dir(char *user)
+char *get_user_home_dir(const char *user)
{
static struct passwd *pass;
- pass = Get_Pwnam(user, False);
+ pass = Get_Pwnam(user);
if (!pass) return(NULL);
return(pass->pw_dir);
@@ -158,7 +158,7 @@ BOOL map_username(char *user)
Get_Pwnam wrapper
****************************************************************************/
-static struct passwd *_Get_Pwnam(char *s)
+static struct passwd *_Get_Pwnam(const char *s)
{
struct passwd *ret;
@@ -183,18 +183,16 @@ static struct passwd *_Get_Pwnam(char *s)
* - in all lower case if this differs from transmitted
* - in all upper case if this differs from transmitted
* - using lp_usernamelevel() for permutations.
- * NOTE: This can potentially modify 'user' depending on value of
- * allow_change!
*/
-struct passwd *Get_Pwnam(char *user,BOOL allow_change)
+struct passwd *Get_Pwnam_internals(const char *user, char *user2)
{
- fstring user2;
struct passwd *ret = NULL;
- if (!user || !(*user))
+ if (!user2 || !(*user2))
return(NULL);
- fstrcpy(user2, user);
+ if (!user || !(*user))
+ return(NULL);
/* Try in all lower case first as this is the most
common case on UNIX systems */
@@ -228,19 +226,53 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change)
done:
DEBUG(5,("Get_Pwnam %s find a valid username!\n",ret ? "did":"didn't"));
+ return ret;
+}
+
+/****************************************************************************
+ Get_Pwnam wrapper for modification.
+ NOTE: This can potentially modify 'user'!
+****************************************************************************/
+
+struct passwd *Get_Pwnam_Modify(char *user)
+{
+ fstring user2;
+ struct passwd *ret;
+
+ fstrcpy(user2, user);
+
+ ret = Get_Pwnam_internals(user, user2);
+
/* If caller wants the modified username, ensure they get it */
- if(allow_change)
- fstrcpy(user,user2);
+ fstrcpy(user,user2);
/* We can safely assume ret is NULL if none of the above succeed */
return(ret);
}
/****************************************************************************
+ Get_Pwnam wrapper without modification.
+ NOTE: This with NOT modify 'user'!
+****************************************************************************/
+
+struct passwd *Get_Pwnam(const char *user)
+{
+ fstring user2;
+ struct passwd *ret;
+
+ fstrcpy(user2, user);
+
+ ret = Get_Pwnam_internals(user, user2);
+
+ /* We can safely assume ret is NULL if none of the above succeed */
+ return(ret);
+}
+
+/****************************************************************************
Check if a user is in a netgroup user list.
****************************************************************************/
-static BOOL user_in_netgroup_list(char *user,char *ngname)
+static BOOL user_in_netgroup_list(const char *user, const char *ngname)
{
#ifdef HAVE_NETGROUP
static char *mydomain = NULL;
@@ -333,11 +365,11 @@ failed with error %s\n", strerror(errno) ));
Check if a user is in a UNIX group.
****************************************************************************/
-static BOOL user_in_unix_group_list(char *user,char *gname)
+static BOOL user_in_unix_group_list(const char *user,const char *gname)
{
struct group *gptr;
char **member;
- struct passwd *pass = Get_Pwnam(user,False);
+ struct passwd *pass = Get_Pwnam(user);
DEBUG(10,("user_in_unix_group_list: checking user %s in group %s\n", user, gname));
@@ -532,7 +564,11 @@ struct passwd *smb_getpwnam(char *user, BOOL allow_change)
char *sep;
extern pstring global_myname;
- pw = Get_Pwnam(user, allow_change);
+ if (allow_change) {
+ pw = Get_Pwnam_Modify(user);
+ } else {
+ pw = Get_Pwnam(user);
+ }
if (pw) return pw;
/* if it is a domain qualified name and it isn't in our password
@@ -543,8 +579,11 @@ struct passwd *smb_getpwnam(char *user, BOOL allow_change)
p = strchr_m(user,*sep);
if (p &&
strncasecmp(global_myname, user, strlen(global_myname))==0) {
- return Get_Pwnam(p+1, allow_change);
+ if (allow_change) {
+ pw = Get_Pwnam_Modify(p+1);
+ } else {
+ pw = Get_Pwnam(p+1);
+ }
}
-
return NULL;
}
diff --git a/source3/passdb/smbpassgroup.c b/source3/passdb/smbpassgroup.c
index b332c9da7f..808abde661 100644
--- a/source3/passdb/smbpassgroup.c
+++ b/source3/passdb/smbpassgroup.c
@@ -157,7 +157,7 @@ static struct smb_passwd *getsmbfilegrpent(void *vp,
}
}
- pwfile = Get_Pwnam(pw_buf.smb_name, False);
+ pwfile = Get_Pwnam(pw_buf.smb_name);
if (pwfile == NULL)
{
DEBUG(0,("getsmbfilegrpent: smbpasswd database is corrupt!\n"));
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 7e48d74359..6d57069149 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -864,7 +864,7 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM
}
/* Don't return user private groups... */
- if (Get_Pwnam(smap.nt_name, False) != 0) {
+ if (Get_Pwnam(smap.nt_name) != 0) {
DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
continue;
}
@@ -1362,7 +1362,7 @@ NTSTATUS _samr_chgpasswd_user(pipes_struct *p, SAMR_Q_CHGPASSWD_USER *q_u, SAMR_
/*
* Do any UNIX username case mangling.
*/
- (void)Get_Pwnam( user_name, True);
+ (void)Get_Pwnam_Modify( user_name);
if (!pass_oem_change(user_name, q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
diff --git a/source3/smbd/auth_rhosts.c b/source3/smbd/auth_rhosts.c
index d6ca01936f..9f5f1e10e5 100644
--- a/source3/smbd/auth_rhosts.c
+++ b/source3/smbd/auth_rhosts.c
@@ -86,7 +86,7 @@ static BOOL check_user_equiv(const char *user, const char *remote, const char *e
static char *mydomain = NULL;
if (!mydomain)
yp_get_default_domain(&mydomain);
- if (mydomain && innetgr(file_host,(char *)remote,(char *)user,mydomain))
+ if (mydomain && innetgr(file_host,remote,user,mydomain))
host_ok = True;
}
#else
@@ -135,7 +135,7 @@ static BOOL check_hosts_equiv(char *user) /* should be const... */
{
char *fname = NULL;
pstring rhostsfile;
- struct passwd *pass = Get_Pwnam(user,False);
+ struct passwd *pass = Get_Pwnam(user);
if (!pass)
return(False);
diff --git a/source3/smbd/auth_unix.c b/source3/smbd/auth_unix.c
index 2f9034e3e5..29a2a6eafb 100644
--- a/source3/smbd/auth_unix.c
+++ b/source3/smbd/auth_unix.c
@@ -89,7 +89,7 @@ NTSTATUS check_unix_security(const auth_usersupplied_info *user_info, auth_serve
become_root();
- pass = Get_Pwnam(user_info->unix_username.str, False);
+ pass = Get_Pwnam(user_info->unix_username.str);
nt_status = pass_check(pass,
pass ? pass->pw_name : user_info->unix_username.str,
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index 49f87a4ca1..132a20cf05 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -118,20 +118,18 @@ static int findpty(char **slave)
return (-1);
}
-static int dochild(int master, char *slavedev, char *name,
- char *passwordprogram, BOOL as_root)
+static int dochild(int master, const char *slavedev, const struct passwd *pass,
+ const char *passwordprogram, BOOL as_root)
{
int slave;
struct termios stermios;
- struct passwd *pass = Get_Pwnam(name, True);
gid_t gid;
uid_t uid;
if (pass == NULL)
{
DEBUG(0,
- ("dochild: user name %s doesn't exist in the UNIX password database.\n",
- name));
+ ("dochild: user doesn't exist in the UNIX password database.\n"));
return False;
}
@@ -318,7 +316,7 @@ static int talktochild(int master, char *seq)
return (count > 0);
}
-static BOOL chat_with_program(char *passwordprogram, char *name,
+static BOOL chat_with_program(char *passwordprogram, struct passwd *pass,
char *chatsequence, BOOL as_root)
{
char *slavedev;
@@ -327,12 +325,19 @@ static BOOL chat_with_program(char *passwordprogram, char *name,
int wstat;
BOOL chstat = False;
+ if (pass == NULL)
+ {
+ DEBUG(0,
+ ("chat_with_program: user doesn't exist in the UNIX password database.\n"));
+ return False;
+ }
+
/* allocate a pseudo-terminal device */
if ((master = findpty(&slavedev)) < 0)
{
DEBUG(3,
("Cannot Allocate pty for password change: %s\n",
- name));
+ pass->pw_name));
return (False);
}
@@ -347,7 +352,7 @@ static BOOL chat_with_program(char *passwordprogram, char *name,
{
DEBUG(3,
("Cannot fork() child for password change: %s\n",
- name));
+ pass->pw_name));
close(master);
CatchChild();
return (False);
@@ -360,7 +365,7 @@ static BOOL chat_with_program(char *passwordprogram, char *name,
{
DEBUG(3,
("Child failed to change password: %s\n",
- name));
+ pass->pw_name));
kill(pid, SIGKILL); /* be sure to end this process */
}
@@ -426,10 +431,10 @@ static BOOL chat_with_program(char *passwordprogram, char *name,
become_root();
DEBUG(3,
- ("Dochild for user %s (uid=%d,gid=%d)\n", name,
+ ("Dochild for user %s (uid=%d,gid=%d)\n", pass->pw_name,
(int)getuid(), (int)getgid()));
chstat =
- dochild(master, slavedev, name, passwordprogram,
+ dochild(master, slavedev, pass, passwordprogram,
as_root);
if (as_root)
@@ -448,19 +453,20 @@ static BOOL chat_with_program(char *passwordprogram, char *name,
if (chstat)
DEBUG(3,
("Password change %ssuccessful for user %s\n",
- (chstat ? "" : "un"), name));
+ (chstat ? "" : "un"), pass->pw_name));
return (chstat);
}
-BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root)
+BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL as_root)
{
pstring passwordprogram;
pstring chatsequence;
size_t i;
size_t len;
- strlower(name);
+ struct passwd *pass;
+
DEBUG(3, ("Password change for user: %s\n", name));
#if DEBUG_PASSWORD
@@ -505,6 +511,8 @@ BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root)
return False;
}
}
+
+ pass = Get_Pwnam(name);
#ifdef WITH_PAM
if (lp_pam_password_change()) {
@@ -513,8 +521,12 @@ BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root)
if (as_root)
become_root();
- ret = smb_pam_passchange(name, oldpass, newpass);
-
+ if (pass) {
+ ret = smb_pam_passchange(pass->pw_name, oldpass, newpass);
+ } else {
+ ret = smb_pam_passchange(name, oldpass, newpass);
+ }
+
if (as_root)
unbecome_root();
@@ -522,6 +534,16 @@ BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root)
}
#endif
+ /* A non-PAM password change just doen't make sense without a valid local user */
+
+ if (pass == NULL)
+ {
+ DEBUG(0,
+ ("chgpasswd: user %s doesn't exist in the UNIX password database.\n",
+ name));
+ return False;
+ }
+
pstrcpy(passwordprogram, lp_passwd_program());
pstrcpy(chatsequence, lp_passwd_chat());
@@ -553,12 +575,12 @@ the string %%u, and the given string %s does not.\n", passwordprogram ));
all_string_sub(chatsequence, "%o", oldpass, sizeof(pstring));
all_string_sub(chatsequence, "%n", newpass, sizeof(pstring));
return (chat_with_program
- (passwordprogram, name, chatsequence, as_root));
+ (passwordprogram, pass, chatsequence, as_root));
}
#else /* ALLOW_CHANGE_PASSWORD */
-BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root)
+BOOL chgpasswd(const char *name, const char *oldpass, const char *newpass, BOOL as_root)
{
DEBUG(0, ("Password changing not compiled in (user=%s)\n", name));
return (False);
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index 3150253dab..7ade1e6d47 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -1954,7 +1954,7 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
/*
* Do any UNIX username case mangling.
*/
- passwd = Get_Pwnam( user, True);
+ passwd = Get_Pwnam_Modify( user );
/*
* Attempt to verify the old password against smbpasswd entries
@@ -2082,7 +2082,7 @@ static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *
/*
* Do any UNIX username case mangling.
*/
- (void)Get_Pwnam( user, True);
+ (void)Get_Pwnam_Modify( user );
if (pass_oem_change(user, (uchar*) data, (uchar *)&data[516], NULL, NULL))
{
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index b1739d9bb6..e8f40f1fa3 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -276,7 +276,7 @@ void add_session_user(char *user)
fstring suser;
StrnCpy(suser,user,sizeof(suser)-1);
- if (!Get_Pwnam(suser,True)) return;
+ if (!Get_Pwnam_Modify(suser)) return;
if (suser && *suser && !in_list(suser,session_users,False))
{
@@ -551,7 +551,7 @@ and given password ok (%s)\n", user));
if (!ok && GUEST_OK(snum)) {
fstring guestname;
StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1);
- if (Get_Pwnam(guestname,True)) {
+ if (Get_Pwnam(guestname)) {
fstrcpy(user,guestname);
ok = True;
DEBUG(3,("authorise_login: ACCEPTED: guest account and guest ok (%s)\n",
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index a871192ad5..37f4610b9d 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -450,7 +450,7 @@ connection_struct *make_connection(char *service,char *password,
/* Allow %S to be used by force user. */
pstring_sub(fuser,"%S",service);
- pass2 = (struct passwd *)Get_Pwnam(fuser,True);
+ pass2 = (struct passwd *)Get_Pwnam_Modify(fuser);
if (pass2) {
conn->uid = pass2->pw_uid;
conn->gid = pass2->pw_gid;
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 2151068de5..ae287cca76 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -36,7 +36,7 @@ BOOL change_to_guest(void)
static fstring guest_name;
if (!pass) {
- pass = Get_Pwnam(lp_guestaccount(-1),True);
+ pass = Get_Pwnam(lp_guestaccount(-1));
if (!pass)
return(False);
guest_uid = pass->pw_uid;