1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

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 commit is contained in:
Andrew Bartlett 0001-01-01 00:00:00 +00:00
parent 8f607810eb
commit e7634f81c5
13 changed files with 115 additions and 54 deletions

View File

@ -86,7 +86,7 @@ static BOOL check_user_equiv(const char *user, const char *remote, const char *e
static char *mydomain = NULL; static char *mydomain = NULL;
if (!mydomain) if (!mydomain)
yp_get_default_domain(&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; host_ok = True;
} }
#else #else
@ -135,7 +135,7 @@ static BOOL check_hosts_equiv(char *user) /* should be const... */
{ {
char *fname = NULL; char *fname = NULL;
pstring rhostsfile; pstring rhostsfile;
struct passwd *pass = Get_Pwnam(user,False); struct passwd *pass = Get_Pwnam(user);
if (!pass) if (!pass)
return(False); return(False);

View File

@ -89,7 +89,7 @@ NTSTATUS check_unix_security(const auth_usersupplied_info *user_info, auth_serve
become_root(); become_root();
pass = Get_Pwnam(user_info->unix_username.str, False); pass = Get_Pwnam(user_info->unix_username.str);
nt_status = pass_check(pass, nt_status = pass_check(pass,
pass ? pass->pw_name : user_info->unix_username.str, pass ? pass->pw_name : user_info->unix_username.str,

View File

@ -186,7 +186,7 @@ void standard_sub_basic(char *str)
string_sub(p,"%U",tmp_str,l); string_sub(p,"%U",tmp_str,l);
break; break;
case 'G' : 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); string_sub(p,"%G",gidtoname(pass->pw_gid),l);
} else { } else {
p += 2; p += 2;

View File

@ -22,18 +22,18 @@
#include "includes.h" #include "includes.h"
/* internal functions */ /* internal functions */
static struct passwd *uname_string_combinations(char *s, 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) (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. Get a users home directory.
****************************************************************************/ ****************************************************************************/
char *get_user_home_dir(char *user) char *get_user_home_dir(const char *user)
{ {
static struct passwd *pass; static struct passwd *pass;
pass = Get_Pwnam(user, False); pass = Get_Pwnam(user);
if (!pass) return(NULL); if (!pass) return(NULL);
return(pass->pw_dir); return(pass->pw_dir);
@ -158,7 +158,7 @@ BOOL map_username(char *user)
Get_Pwnam wrapper Get_Pwnam wrapper
****************************************************************************/ ****************************************************************************/
static struct passwd *_Get_Pwnam(char *s) static struct passwd *_Get_Pwnam(const char *s)
{ {
struct passwd *ret; struct passwd *ret;
@ -183,19 +183,17 @@ static struct passwd *_Get_Pwnam(char *s)
* - in all lower case if this differs from transmitted * - in all lower case if this differs from transmitted
* - in all upper case if this differs from transmitted * - in all upper case if this differs from transmitted
* - using lp_usernamelevel() for permutations. * - 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; struct passwd *ret = NULL;
if (!user2 || !(*user2))
return(NULL);
if (!user || !(*user)) if (!user || !(*user))
return(NULL); return(NULL);
fstrcpy(user2, user);
/* Try in all lower case first as this is the most /* Try in all lower case first as this is the most
common case on UNIX systems */ common case on UNIX systems */
strlower(user2); strlower(user2);
@ -228,10 +226,44 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change)
done: done:
DEBUG(5,("Get_Pwnam %s find a valid username!\n",ret ? "did":"didn't")); DEBUG(5,("Get_Pwnam %s find a valid username!\n",ret ? "did":"didn't"));
/* If caller wants the modified username, ensure they get it */ return ret;
if(allow_change) }
fstrcpy(user,user2);
/****************************************************************************
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 */
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 */ /* We can safely assume ret is NULL if none of the above succeed */
return(ret); return(ret);
} }
@ -240,7 +272,7 @@ done:
Check if a user is in a netgroup user list. 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 #ifdef HAVE_NETGROUP
static char *mydomain = NULL; static char *mydomain = NULL;
@ -333,11 +365,11 @@ failed with error %s\n", strerror(errno) ));
Check if a user is in a UNIX group. 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; struct group *gptr;
char **member; 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)); 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; char *sep;
extern pstring global_myname; 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 (pw) return pw;
/* if it is a domain qualified name and it isn't in our password /* 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); p = strchr_m(user,*sep);
if (p && if (p &&
strncasecmp(global_myname, user, strlen(global_myname))==0) { 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; return NULL;
} }

View File

@ -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) if (pwfile == NULL)
{ {
DEBUG(0,("getsmbfilegrpent: smbpasswd database is corrupt!\n")); DEBUG(0,("getsmbfilegrpent: smbpasswd database is corrupt!\n"));

View File

@ -864,7 +864,7 @@ static NTSTATUS get_group_alias_entries(TALLOC_CTX *ctx, DOMAIN_GRP **d_grp, DOM
} }
/* Don't return user private groups... */ /* 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 )); DEBUG(10,("get_group_alias_entries: not returing %s, clashes with user.\n", smap.nt_name ));
continue; 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. * 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, 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)) q_u->nt_newpass.pass, q_u->nt_oldhash.hash))

View File

@ -86,7 +86,7 @@ static BOOL check_user_equiv(const char *user, const char *remote, const char *e
static char *mydomain = NULL; static char *mydomain = NULL;
if (!mydomain) if (!mydomain)
yp_get_default_domain(&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; host_ok = True;
} }
#else #else
@ -135,7 +135,7 @@ static BOOL check_hosts_equiv(char *user) /* should be const... */
{ {
char *fname = NULL; char *fname = NULL;
pstring rhostsfile; pstring rhostsfile;
struct passwd *pass = Get_Pwnam(user,False); struct passwd *pass = Get_Pwnam(user);
if (!pass) if (!pass)
return(False); return(False);

View File

@ -89,7 +89,7 @@ NTSTATUS check_unix_security(const auth_usersupplied_info *user_info, auth_serve
become_root(); become_root();
pass = Get_Pwnam(user_info->unix_username.str, False); pass = Get_Pwnam(user_info->unix_username.str);
nt_status = pass_check(pass, nt_status = pass_check(pass,
pass ? pass->pw_name : user_info->unix_username.str, pass ? pass->pw_name : user_info->unix_username.str,

View File

@ -118,20 +118,18 @@ static int findpty(char **slave)
return (-1); return (-1);
} }
static int dochild(int master, char *slavedev, char *name, static int dochild(int master, const char *slavedev, const struct passwd *pass,
char *passwordprogram, BOOL as_root) const char *passwordprogram, BOOL as_root)
{ {
int slave; int slave;
struct termios stermios; struct termios stermios;
struct passwd *pass = Get_Pwnam(name, True);
gid_t gid; gid_t gid;
uid_t uid; uid_t uid;
if (pass == NULL) if (pass == NULL)
{ {
DEBUG(0, DEBUG(0,
("dochild: user name %s doesn't exist in the UNIX password database.\n", ("dochild: user doesn't exist in the UNIX password database.\n"));
name));
return False; return False;
} }
@ -318,7 +316,7 @@ static int talktochild(int master, char *seq)
return (count > 0); 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 *chatsequence, BOOL as_root)
{ {
char *slavedev; char *slavedev;
@ -327,12 +325,19 @@ static BOOL chat_with_program(char *passwordprogram, char *name,
int wstat; int wstat;
BOOL chstat = False; 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 */ /* allocate a pseudo-terminal device */
if ((master = findpty(&slavedev)) < 0) if ((master = findpty(&slavedev)) < 0)
{ {
DEBUG(3, DEBUG(3,
("Cannot Allocate pty for password change: %s\n", ("Cannot Allocate pty for password change: %s\n",
name)); pass->pw_name));
return (False); return (False);
} }
@ -347,7 +352,7 @@ static BOOL chat_with_program(char *passwordprogram, char *name,
{ {
DEBUG(3, DEBUG(3,
("Cannot fork() child for password change: %s\n", ("Cannot fork() child for password change: %s\n",
name)); pass->pw_name));
close(master); close(master);
CatchChild(); CatchChild();
return (False); return (False);
@ -360,7 +365,7 @@ static BOOL chat_with_program(char *passwordprogram, char *name,
{ {
DEBUG(3, DEBUG(3,
("Child failed to change password: %s\n", ("Child failed to change password: %s\n",
name)); pass->pw_name));
kill(pid, SIGKILL); /* be sure to end this process */ kill(pid, SIGKILL); /* be sure to end this process */
} }
@ -426,10 +431,10 @@ static BOOL chat_with_program(char *passwordprogram, char *name,
become_root(); become_root();
DEBUG(3, 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())); (int)getuid(), (int)getgid()));
chstat = chstat =
dochild(master, slavedev, name, passwordprogram, dochild(master, slavedev, pass, passwordprogram,
as_root); as_root);
if (as_root) if (as_root)
@ -448,19 +453,20 @@ static BOOL chat_with_program(char *passwordprogram, char *name,
if (chstat) if (chstat)
DEBUG(3, DEBUG(3,
("Password change %ssuccessful for user %s\n", ("Password change %ssuccessful for user %s\n",
(chstat ? "" : "un"), name)); (chstat ? "" : "un"), pass->pw_name));
return (chstat); 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 passwordprogram;
pstring chatsequence; pstring chatsequence;
size_t i; size_t i;
size_t len; size_t len;
strlower(name); struct passwd *pass;
DEBUG(3, ("Password change for user: %s\n", name)); DEBUG(3, ("Password change for user: %s\n", name));
#if DEBUG_PASSWORD #if DEBUG_PASSWORD
@ -505,6 +511,8 @@ BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root)
return False; return False;
} }
} }
pass = Get_Pwnam(name);
#ifdef WITH_PAM #ifdef WITH_PAM
if (lp_pam_password_change()) { if (lp_pam_password_change()) {
@ -513,8 +521,12 @@ BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root)
if (as_root) if (as_root)
become_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) if (as_root)
unbecome_root(); unbecome_root();
@ -522,6 +534,16 @@ BOOL chgpasswd(char *name, char *oldpass, char *newpass, BOOL as_root)
} }
#endif #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(passwordprogram, lp_passwd_program());
pstrcpy(chatsequence, lp_passwd_chat()); 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, "%o", oldpass, sizeof(pstring));
all_string_sub(chatsequence, "%n", newpass, sizeof(pstring)); all_string_sub(chatsequence, "%n", newpass, sizeof(pstring));
return (chat_with_program return (chat_with_program
(passwordprogram, name, chatsequence, as_root)); (passwordprogram, pass, chatsequence, as_root));
} }
#else /* ALLOW_CHANGE_PASSWORD */ #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)); DEBUG(0, ("Password changing not compiled in (user=%s)\n", name));
return (False); return (False);

View File

@ -1954,7 +1954,7 @@ static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param
/* /*
* Do any UNIX username case mangling. * 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 * 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. * 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)) if (pass_oem_change(user, (uchar*) data, (uchar *)&data[516], NULL, NULL))
{ {

View File

@ -276,7 +276,7 @@ void add_session_user(char *user)
fstring suser; fstring suser;
StrnCpy(suser,user,sizeof(suser)-1); 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)) 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)) { if (!ok && GUEST_OK(snum)) {
fstring guestname; fstring guestname;
StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1); StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1);
if (Get_Pwnam(guestname,True)) { if (Get_Pwnam(guestname)) {
fstrcpy(user,guestname); fstrcpy(user,guestname);
ok = True; ok = True;
DEBUG(3,("authorise_login: ACCEPTED: guest account and guest ok (%s)\n", DEBUG(3,("authorise_login: ACCEPTED: guest account and guest ok (%s)\n",

View File

@ -450,7 +450,7 @@ connection_struct *make_connection(char *service,char *password,
/* Allow %S to be used by force user. */ /* Allow %S to be used by force user. */
pstring_sub(fuser,"%S",service); pstring_sub(fuser,"%S",service);
pass2 = (struct passwd *)Get_Pwnam(fuser,True); pass2 = (struct passwd *)Get_Pwnam_Modify(fuser);
if (pass2) { if (pass2) {
conn->uid = pass2->pw_uid; conn->uid = pass2->pw_uid;
conn->gid = pass2->pw_gid; conn->gid = pass2->pw_gid;

View File

@ -36,7 +36,7 @@ BOOL change_to_guest(void)
static fstring guest_name; static fstring guest_name;
if (!pass) { if (!pass) {
pass = Get_Pwnam(lp_guestaccount(-1),True); pass = Get_Pwnam(lp_guestaccount(-1));
if (!pass) if (!pass)
return(False); return(False);
guest_uid = pass->pw_uid; guest_uid = pass->pw_uid;