summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/includes.h1
-rw-r--r--source3/include/proto.h7
-rw-r--r--source3/libsmb/namequery.c8
-rw-r--r--source3/param/loadparm.c4
-rw-r--r--source3/smbd/chgpasswd.c74
-rw-r--r--source3/smbd/ipc.c5
6 files changed, 73 insertions, 26 deletions
diff --git a/source3/include/includes.h b/source3/include/includes.h
index c9a515af9a..e6dee108a5 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -516,6 +516,7 @@ char *mktemp(char *); /* No standard include */
#include <netinet/tcp.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
+#include <termios.h>
#if __FreeBSD__ >= 3
#include <dirent.h>
#else
diff --git a/source3/include/proto.h b/source3/include/proto.h
index a643996d3c..993cf46486 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -32,9 +32,9 @@ void add_char_string(char *s);
/*The following definitions come from chgpasswd.c */
-BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence);
-BOOL chgpasswd(char *name,char *oldpass,char *newpass);
-BOOL chgpasswd(char *name,char *oldpass,char *newpass);
+BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence, BOOL as_root);
+BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root);
+BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root);
BOOL check_lanman_password(char *user, unsigned char *pass1,
unsigned char *pass2, struct smb_passwd **psmbpw);
BOOL change_lanman_password(struct smb_passwd *smbpw, unsigned char *pass1, unsigned char *pass2);
@@ -924,6 +924,7 @@ BOOL lp_nis_home_map(void);
BOOL lp_time_server(void);
BOOL lp_bind_interfaces_only(void);
BOOL lp_net_wksta_user_logon(void);
+BOOL lp_unix_password_sync(void);
int lp_os_level(void);
int lp_max_ttl(void);
int lp_max_wins_ttl(void);
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 7b8a01b28f..faa2a09007 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -460,7 +460,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip)
struct hostent *hp;
- DEBUG(3,("resolve_name: Attempting host lookup for name %s\n"));
+ DEBUG(3,("resolve_name: Attempting host lookup for name %s\n", name));
if (((hp = Get_Hostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
putip((char *)return_ip,(char *)hp->h_addr);
@@ -477,7 +477,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip)
pstring lmhost_name;
int name_type;
- DEBUG(3,("resolve_name: Attempting lmhosts lookup for name %s\n"));
+ DEBUG(3,("resolve_name: Attempting lmhosts lookup for name %s\n", name));
fp = startlmhosts( LMHOSTSFILE );
if(fp) {
@@ -502,7 +502,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip)
* would then block).
*/
- DEBUG(3,("resolve_name: Attempting wins lookup for name %s\n"));
+ DEBUG(3,("resolve_name: Attempting wins lookup for name %s<0x20>\n", name));
if(*lp_wins_server()) {
struct in_addr wins_ip = *interpret_addr2(lp_wins_server());
@@ -536,7 +536,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip)
* "bcast" means do a broadcast lookup on all the local interfaces.
*/
- DEBUG(3,("resolve_name: Attempting broadcast lookup for name %s\n"));
+ DEBUG(3,("resolve_name: Attempting broadcast lookup for name %s<0x20>\n", name));
sock = open_socket_in( SOCK_DGRAM, 0, 3,
interpret_addr(lp_socket_address()) );
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index da7958b6a0..70f06065a3 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -191,6 +191,7 @@ typedef struct
BOOL bTimeServer;
BOOL bBindInterfacesOnly;
BOOL bNetWkstaUserLogon;
+ BOOL bUnixPasswdSync;
} global;
static global Globals;
@@ -445,6 +446,7 @@ static struct parm_struct parm_table[] =
{"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0},
{"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0},
{"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0},
+ {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0},
{"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL},
{"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL},
{"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL},
@@ -743,6 +745,7 @@ static void init_globals(void)
Globals.bTimeServer = False;
Globals.bBindInterfacesOnly = False;
Globals.bNetWkstaUserLogon = True;
+ Globals.bUnixPasswdSync = False;
/* these parameters are set to defaults that are more appropriate
for the increasing samba install base:
@@ -965,6 +968,7 @@ FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
FN_GLOBAL_BOOL(lp_bind_interfaces_only,&Globals.bBindInterfacesOnly)
FN_GLOBAL_BOOL(lp_net_wksta_user_logon,&Globals.bNetWkstaUserLogon)
+FN_GLOBAL_BOOL(lp_unix_password_sync,&Globals.bUnixPasswdSync)
FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
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);