summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/chgpasswd.c74
-rw-r--r--source3/smbd/ipc.c5
2 files changed, 60 insertions, 19 deletions
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index 779845d37a..ae1fd1a675 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -98,14 +98,22 @@ static int findpty(char **slave)
return (-1);
}
-static int dochild(int master,char *slavedev, char *name, char *passwordprogram)
+static int dochild(int master,char *slavedev, char *name, char *passwordprogram, BOOL as_root)
{
int slave;
struct termios stermios;
struct passwd *pass = Get_Pwnam(name,True);
- int gid = pass->pw_gid;
- int uid = pass->pw_uid;
+ int gid;
+ int uid;
+ if(pass == NULL) {
+ DEBUG(0,("dochild: user name %s doesn't exist in the UNIX password database.\n",
+ name));
+ return False;
+ }
+
+ gid = pass->pw_gid;
+ uid = pass->pw_uid;
#ifdef USE_SETRES
setresuid(0,0,0);
#else /* USE_SETRES */
@@ -169,19 +177,21 @@ static int dochild(int master,char *slavedev, char *name, char *passwordprogram)
}
/* make us completely into the right uid */
+ if(!as_root) {
#ifdef USE_SETRES
- setresgid(0,0,0);
- setresuid(0,0,0);
- setresgid(gid,gid,gid);
- setresuid(uid,uid,uid);
+ setresgid(0,0,0);
+ setresuid(0,0,0);
+ setresgid(gid,gid,gid);
+ setresuid(uid,uid,uid);
#else
- setuid(0);
- seteuid(0);
- setgid(gid);
- setegid(gid);
- setuid(uid);
- seteuid(uid);
+ setuid(0);
+ seteuid(0);
+ setgid(gid);
+ setegid(gid);
+ setuid(uid);
+ seteuid(uid);
#endif
+ }
/* execl() password-change application */
if (execl("/bin/sh","sh","-c",passwordprogram,NULL) < 0) {
@@ -279,7 +289,7 @@ static int talktochild(int master, char *chatsequence)
}
-BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence)
+BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence, BOOL as_root)
{
char *slavedev;
int master;
@@ -328,18 +338,25 @@ BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence)
/* make sure it doesn't freeze */
alarm(20);
+ if(as_root)
+ become_root(False);
DEBUG(3,("Dochild for user %s (uid=%d,gid=%d)\n",name,getuid(),getgid()));
- chstat = dochild(master, slavedev, name, passwordprogram);
+ chstat = dochild(master, slavedev, name, passwordprogram, as_root);
+
+ if(as_root)
+ unbecome_root(False);
}
DEBUG(3,("Password change %ssuccessful for user %s\n", (chstat?"":"un"), name));
return (chstat);
}
-BOOL chgpasswd(char *name,char *oldpass,char *newpass)
+BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root)
{
pstring passwordprogram;
pstring chatsequence;
+ int i;
+ int len;
strlower(name);
DEBUG(3,("Password change for user: %s\n",name));
@@ -381,6 +398,27 @@ BOOL chgpasswd(char *name,char *oldpass,char *newpass)
return(False);
}
+ /*
+ * Check the old and new passwords don't contain any control
+ * characters.
+ */
+
+ len = strlen(oldpass);
+ for(i = 0; i < len; i++) {
+ if(iscntrl(oldpass[i])) {
+ DEBUG(0,("chat_with_program: oldpass contains control characters (disallowed).\n"));
+ return False;
+ }
+ }
+
+ len = strlen(newpass);
+ for(i = 0; i < len; i++) {
+ if(iscntrl(newpass[i])) {
+ DEBUG(0,("chat_with_program: newpass contains control characters (disallowed).\n"));
+ return False;
+ }
+ }
+
string_sub(passwordprogram,"%u",name);
string_sub(passwordprogram,"%o",oldpass);
string_sub(passwordprogram,"%n",newpass);
@@ -388,11 +426,11 @@ BOOL chgpasswd(char *name,char *oldpass,char *newpass)
string_sub(chatsequence,"%u",name);
string_sub(chatsequence,"%o",oldpass);
string_sub(chatsequence,"%n",newpass);
- return(chat_with_program(passwordprogram,name,chatsequence));
+ return(chat_with_program(passwordprogram,name,chatsequence, as_root));
}
#else
-BOOL chgpasswd(char *name,char *oldpass,char *newpass)
+BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root)
{
DEBUG(0,("Password changing not compiled in (user=%s)\n",name));
return(False);
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 4798188454..f38a76d74a 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -1634,7 +1634,7 @@ static BOOL api_SetUserPassword(int cnum,uint16 vuid, char *param,char *data,
*/
if (password_ok(user,pass1,strlen(pass1),NULL) &&
- chgpasswd(user,pass1,pass2))
+ chgpasswd(user,pass1,pass2,False))
{
SSVAL(*rparam,0,NERR_Success);
}
@@ -1714,6 +1714,9 @@ static BOOL api_SamOEMChangePassword(int cnum,uint16 vuid, char *param,char *dat
* as the plaintext of the old users password is not
* available. JRA.
*/
+
+ if(lp_unix_password_sync())
+ chgpasswd(user,"", new_passwd, True);
if(change_oem_password( smbpw, new_passwd)) {
SSVAL(*rparam,0,NERR_Success);