#include <netinet/tcp.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
+#include <termios.h>
#if __FreeBSD__ >= 3
#include <dirent.h>
#else
/*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);
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);
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);
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) {
* 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());
* "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()) );
BOOL bTimeServer;
BOOL bBindInterfacesOnly;
BOOL bNetWkstaUserLogon;
+ BOOL bUnixPasswdSync;
} global;
static global Globals;
{"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},
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:
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)
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 */
}
/* 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) {
}
-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;
/* 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));
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);
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);
*/
if (password_ok(user,pass1,strlen(pass1),NULL) &&
- chgpasswd(user,pass1,pass2))
+ chgpasswd(user,pass1,pass2,False))
{
SSVAL(*rparam,0,NERR_Success);
}
* 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);