diff options
-rw-r--r-- | source3/include/includes.h | 1 | ||||
-rw-r--r-- | source3/include/proto.h | 7 | ||||
-rw-r--r-- | source3/libsmb/namequery.c | 8 | ||||
-rw-r--r-- | source3/param/loadparm.c | 4 | ||||
-rw-r--r-- | source3/smbd/chgpasswd.c | 74 | ||||
-rw-r--r-- | source3/smbd/ipc.c | 5 |
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); |