]> git.samba.org - samba.git/commitdiff
extracted the password change code from smbpasswd and used it in swat
authorAndrew Tridgell <tridge@samba.org>
Thu, 12 Nov 1998 07:06:48 +0000 (07:06 +0000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 12 Nov 1998 07:06:48 +0000 (07:06 +0000)
instead of opening pipes and other horrible stuff.
(This used to be commit 49bf19710345a59a2d17cd449be1a132885ed821)

source3/Makefile.in
source3/include/proto.h
source3/lib/util.c
source3/libsmb/passchange.c [new file with mode: 0644]
source3/passdb/smbpasschange.c [new file with mode: 0644]
source3/smbd/uid.c
source3/utils/smbpasswd.c
source3/web/swat.c

index dcabf917d091d23ed4c02a2aaedbed43f02f9d11..4dde76a60c360f5e3e8616a0f55132535e5c005e 100644 (file)
@@ -103,7 +103,8 @@ PARAM_OBJ = param/loadparm.o param/params.o
 
 LIBSMB_OBJ = libsmb/clientgen.o libsmb/namequery.o libsmb/nmblib.o \
              libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o \
-             libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o
+             libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \
+            libsmb/passchange.o
 
 RPC_SERVER_OBJ = rpc_server/srv_lsa.o \
                  rpc_server/srv_lsa_hnd.o rpc_server/srv_netlog.o \
@@ -132,7 +133,7 @@ LOCKING_OBJ = locking/locking.o locking/locking_shm.o locking/locking_slow.o \
               locking/shmem.o locking/shmem_sysv.o
 
 PASSDB_OBJ = passdb/passdb.o passdb/smbpassfile.o passdb/smbpass.o \
-             passdb/pass_check.o passdb/ldap.o passdb/nispass.o 
+             passdb/pass_check.o passdb/ldap.o passdb/nispass.o passdb/smbpasschange.o
 
 SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
             smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \
index 888e2af33f3d1cc00089544431ba320350b03f33..25804919763be37734bd70229eec3125aaa93ebd 100644 (file)
@@ -507,6 +507,11 @@ void sort_query_replies(char *data, int n, struct in_addr ip);
 
 char *get_nt_error_msg(uint32 nt_code);
 
+/*The following definitions come from  libsmb/passchange.c  */
+
+BOOL remote_password_change(const char *remote_machine, const char *user_name, 
+                           const char *old_passwd, const char *new_passwd);
+
 /*The following definitions come from  libsmb/pwd_cache.c  */
 
 void pwd_init(struct pwd_info *pwd);
@@ -1212,6 +1217,12 @@ BOOL pdb_rid_is_user(uint32 rid);
 
 struct passdb_ops *file_initialize_password_db(void);
 
+/*The following definitions come from  passdb/smbpasschange.c  */
+
+BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user,
+                          BOOL enable_user, BOOL disable_user, BOOL set_no_password,
+                          char *new_passwd);
+
 /*The following definitions come from  passdb/smbpassfile.c  */
 
 BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth);
index 2be1fcaf6fcf3a33dca3e575154753d185bd3285..1710205f3c1bc053aff3985b652dd219c34c0a44 100644 (file)
@@ -3095,3 +3095,56 @@ BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name)
 
        return True;
 }
+
+/****************************************************************************
+  become the specified uid - permanently !
+****************************************************************************/
+BOOL become_user_permanently(uid_t uid, gid_t gid)
+{
+       /* now completely lose our privilages. This is a fairly paranoid
+          way of doing it, but it does work on all systems that I know of */
+
+#ifdef HAVE_SETRESUID
+       /*
+        * Firstly ensure all our uids are set to root.
+        */
+       setresgid(0,0,0);
+       setresuid(0,0,0);
+
+       /*
+        * Now ensure we change all our gids.
+        */
+       setresgid(gid,gid,gid);
+       
+       /*
+        * Now ensure all the uids are the user.
+        */
+       setresuid(uid,uid,uid);
+#else
+       /*
+        * Firstly ensure all our uids are set to root.
+        */
+       setuid(0);
+       seteuid(0);
+       
+       /*
+        * Now ensure we change all our gids.
+        */
+       setgid(gid);
+       setegid(gid);
+       
+       /*
+        * Now ensure all the uids are the user.
+        */
+       setuid(uid);
+       seteuid(uid);
+#endif
+       
+       if (getuid() != uid || geteuid() != uid ||
+           getgid() != gid || getegid() != gid) {
+               /* We failed to lose our privilages. */
+               return False;
+       }
+       
+       return(True);
+}
diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c
new file mode 100644 (file)
index 0000000..7d89cbd
--- /dev/null
@@ -0,0 +1,100 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   SMB client password change routine
+   Copyright (C) Andrew Tridgell 1994-1998
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+
+extern pstring global_myname;
+extern pstring scope;
+
+/*************************************************************
+change a password on a remote machine using IPC calls
+*************************************************************/
+BOOL remote_password_change(const char *remote_machine, const char *user_name, 
+                           const char *old_passwd, const char *new_passwd)
+{
+       struct nmb_name calling, called;
+       struct cli_state cli;
+       struct in_addr ip;
+
+       if(!resolve_name( remote_machine, &ip, 0x20)) {
+               fprintf(stderr, "unable to find an IP address for machine %s.\n",
+                       remote_machine );
+               return False;
+       }
+       ZERO_STRUCT(cli);
+       if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) {
+               fprintf(stderr, "unable to connect to SMB server on machine %s. Error was : %s.\n",
+                       remote_machine, cli_errstr(&cli) );
+               return False;
+       }
+  
+       make_nmb_name(&calling, global_myname , 0x0 , scope);
+       make_nmb_name(&called , remote_machine, 0x20, scope);
+       
+       if (!cli_session_request(&cli, &calling, &called)) {
+               fprintf(stderr, "machine %s rejected the session setup. Error was : %s.\n",
+                       remote_machine, cli_errstr(&cli) );
+               cli_shutdown(&cli);
+               return False;
+       }
+  
+       cli.protocol = PROTOCOL_NT1;
+
+       if (!cli_negprot(&cli)) {
+               fprintf(stderr, "machine %s rejected the negotiate protocol. Error was : %s.\n",        
+                       remote_machine, cli_errstr(&cli) );
+               cli_shutdown(&cli);
+               return False;
+       }
+  
+       /*
+        * We should connect as the anonymous user here, in case
+        * the server has "must change password" checked...
+        * Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix.
+        */
+
+       if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
+               fprintf(stderr, "machine %s rejected the session setup. Error was : %s.\n",        
+                       remote_machine, cli_errstr(&cli) );
+               cli_shutdown(&cli);
+               return False;
+       }               
+
+       if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
+               fprintf(stderr, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n",
+                       remote_machine, cli_errstr(&cli) );
+               cli_shutdown(&cli);
+               return False;
+       }
+
+       if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
+               fprintf(stderr, "machine %s rejected the password change: Error was : %s.\n",
+                       remote_machine, cli_errstr(&cli) );
+               cli_shutdown(&cli);
+               return False;
+       }
+       
+       cli_shutdown(&cli);
+       return True;
+}
diff --git a/source3/passdb/smbpasschange.c b/source3/passdb/smbpasschange.c
new file mode 100644 (file)
index 0000000..4e28133
--- /dev/null
@@ -0,0 +1,162 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 1.9.
+   change a password in a local smbpasswd file
+   Copyright (C) Andrew Tridgell 1998
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+
+/*************************************************************
+add a new user to the local smbpasswd file
+*************************************************************/
+static BOOL add_new_user(char *user_name, uid_t uid, BOOL trust_account, 
+                        BOOL disable_user, BOOL set_no_password,
+                        uchar *new_p16, uchar *new_nt_p16)
+{
+       struct smb_passwd new_smb_pwent;
+
+       /* Create a new smb passwd entry and set it to the given password. */
+       new_smb_pwent.smb_userid = uid;
+       new_smb_pwent.smb_name = user_name; 
+       new_smb_pwent.smb_passwd = NULL;
+       new_smb_pwent.smb_nt_passwd = NULL;
+       new_smb_pwent.acct_ctrl = (trust_account ? ACB_WSTRUST : ACB_NORMAL);
+       
+       if(disable_user) {
+               new_smb_pwent.acct_ctrl |= ACB_DISABLED;
+       } else if (set_no_password) {
+               new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ;
+       } else {
+               new_smb_pwent.smb_passwd = new_p16;
+               new_smb_pwent.smb_nt_passwd = new_nt_p16;
+       }
+       
+       return add_smbpwd_entry(&new_smb_pwent);
+}
+
+
+/*************************************************************
+change a password entry in the local smbpasswd file
+*************************************************************/
+BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user,
+                          BOOL enable_user, BOOL disable_user, BOOL set_no_password,
+                          char *new_passwd)
+{
+       struct passwd  *pwd;
+       void *vp;
+       struct smb_passwd *smb_pwent;
+       uchar           new_p16[16];
+       uchar           new_nt_p16[16];
+
+       pwd = getpwnam(user_name);
+       
+       /*
+        * Check for a machine account.
+        */
+       
+       if(trust_account && !pwd) {
+               fprintf(stderr, "User %s does not exist in system password file (usually /etc/passwd). Cannot add machine account without a valid system user.\n",
+                       user_name);
+               return False;
+       }
+
+       /* Calculate the MD4 hash (NT compatible) of the new password. */
+       nt_lm_owf_gen(new_passwd, new_nt_p16, new_p16);
+
+       /*
+        * Open the smbpaswd file.
+        */
+       vp = startsmbpwent(True);
+       if (!vp && errno == ENOENT) {
+               FILE *fp;
+               fprintf(stderr,"smbpasswd file did not exist - attempting to create it.\n");
+               fp = fopen(lp_smb_passwd_file(), "w");
+               if (fp) {
+                       fprintf(fp, "# Samba SMB password file\n");
+                       fclose(fp);
+                       vp = startsmbpwent(True);
+               }
+       }
+
+       if (!vp) {
+               perror(lp_smb_passwd_file());
+               return False;
+       }
+  
+       /* Get the smb passwd entry for this user */
+       smb_pwent = getsmbpwnam(user_name);
+       if (smb_pwent == NULL) {
+               if(add_user == False) {
+                       fprintf(stderr, "Failed to find entry for user %s.\n",
+                               pwd->pw_name);
+                       endsmbpwent(vp);
+                       return False;
+               }
+
+               if (add_new_user(user_name, pwd->pw_uid, trust_account, disable_user,
+                                set_no_password, new_p16, new_nt_p16)) {
+                       printf("Added user %s.\n", user_name);
+                       endsmbpwent(vp);
+                       return True;
+               } else {
+                       fprintf(stderr, "Failed to add entry for user %s.\n", user_name);
+                       endsmbpwent(vp);
+                       return False;
+               }
+       } else {
+               /* the entry already existed */
+               add_user = False;
+       }
+
+       /*
+        * We are root - just write the new password
+        * and the valid last change time.
+        */
+
+       if(disable_user) {
+               smb_pwent->acct_ctrl |= ACB_DISABLED;
+       } else if (enable_user) {
+               if(smb_pwent->smb_passwd == NULL) {
+                       smb_pwent->smb_passwd = new_p16;
+                       smb_pwent->smb_nt_passwd = new_nt_p16;
+               }
+               smb_pwent->acct_ctrl &= ~ACB_DISABLED;
+       } else if (set_no_password) {
+               smb_pwent->acct_ctrl |= ACB_PWNOTREQ;
+               /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
+               smb_pwent->smb_passwd = NULL;
+               smb_pwent->smb_nt_passwd = NULL;
+       } else {
+               smb_pwent->acct_ctrl &= ~ACB_PWNOTREQ;
+               smb_pwent->smb_passwd = new_p16;
+               smb_pwent->smb_nt_passwd = new_nt_p16;
+       }
+       
+       if(mod_smbpwd_entry(smb_pwent,True) == False) {
+               fprintf(stderr, "Failed to modify entry for user %s.\n",
+                       pwd->pw_name);
+               endsmbpwent(vp);
+               return False;
+       }
+
+       endsmbpwent(vp);
+
+       return True;
+}
+
index 7cd8c8673cbad1a0d2a63d83dc4e0fea303741dc..7c951b461ad6a889c1bda64b2bef1babc3d54079 100644 (file)
@@ -421,3 +421,5 @@ void unbecome_root(BOOL restore_dir)
 
        become_root_depth = 0;
 }
+
+
index da7caacb117743f719d87fc0ec365bb0985cc8eb..2303bc56df168fdbf9e6c14549ea0ca0a7830f16 100644 (file)
 
 #include "includes.h"
 
-extern pstring scope;
 extern pstring myhostname;
 extern pstring global_myname;
-extern fstring global_myworkgroup;
 extern int DEBUGLEVEL;
 
 
@@ -213,222 +211,6 @@ static char *prompt_for_new_password(BOOL stdin_get)
 }
 
 
-
-
-/*************************************************************
-change a password on a remote machine using IPC calls
-*************************************************************/
-static BOOL remote_password_change(const char *remote_machine, const char *user_name, 
-                                  const char *old_passwd, const char *new_passwd)
-{
-       struct nmb_name calling, called;
-       struct cli_state cli;
-       struct in_addr ip;
-
-       if(!resolve_name( remote_machine, &ip, 0x20)) {
-               fprintf(stderr, "unable to find an IP address for machine %s.\n",
-                       remote_machine );
-               return False;
-       }
-       ZERO_STRUCT(cli);
-       if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) {
-               fprintf(stderr, "unable to connect to SMB server on machine %s. Error was : %s.\n",
-                       remote_machine, cli_errstr(&cli) );
-               return False;
-       }
-  
-       make_nmb_name(&calling, global_myname , 0x0 , scope);
-       make_nmb_name(&called , remote_machine, 0x20, scope);
-       
-       if (!cli_session_request(&cli, &calling, &called)) {
-               fprintf(stderr, "machine %s rejected the session setup. Error was : %s.\n",
-                       remote_machine, cli_errstr(&cli) );
-               cli_shutdown(&cli);
-               return False;
-       }
-  
-       cli.protocol = PROTOCOL_NT1;
-
-       if (!cli_negprot(&cli)) {
-               fprintf(stderr, "machine %s rejected the negotiate protocol. Error was : %s.\n",        
-                       remote_machine, cli_errstr(&cli) );
-               cli_shutdown(&cli);
-               return False;
-       }
-  
-       /*
-        * We should connect as the anonymous user here, in case
-        * the server has "must change password" checked...
-        * Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix.
-        */
-
-       if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
-               fprintf(stderr, "machine %s rejected the session setup. Error was : %s.\n",        
-                       remote_machine, cli_errstr(&cli) );
-               cli_shutdown(&cli);
-               return False;
-       }               
-
-       if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
-               fprintf(stderr, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n",
-                       remote_machine, cli_errstr(&cli) );
-               cli_shutdown(&cli);
-               return False;
-       }
-
-       if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
-               fprintf(stderr, "machine %s rejected the password change: Error was : %s.\n",
-                       remote_machine, cli_errstr(&cli) );
-               cli_shutdown(&cli);
-               return False;
-       }
-       
-       cli_shutdown(&cli);
-       return True;
-}
-
-
-/*************************************************************
-add a new user to the local smbpasswd file
-*************************************************************/
-static BOOL add_new_user(char *user_name, uid_t uid, BOOL trust_account, 
-                        BOOL disable_user, BOOL set_no_password,
-                        uchar *new_p16, uchar *new_nt_p16)
-{
-       struct smb_passwd new_smb_pwent;
-
-       /* Create a new smb passwd entry and set it to the given password. */
-       new_smb_pwent.smb_userid = uid;
-       new_smb_pwent.smb_name = user_name; 
-       new_smb_pwent.smb_passwd = NULL;
-       new_smb_pwent.smb_nt_passwd = NULL;
-       new_smb_pwent.acct_ctrl = (trust_account ? ACB_WSTRUST : ACB_NORMAL);
-       
-       if(disable_user) {
-               new_smb_pwent.acct_ctrl |= ACB_DISABLED;
-       } else if (set_no_password) {
-               new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ;
-       } else {
-               new_smb_pwent.smb_passwd = new_p16;
-               new_smb_pwent.smb_nt_passwd = new_nt_p16;
-       }
-       
-       return add_smbpwd_entry(&new_smb_pwent);
-}
-
-
-/*************************************************************
-change a password entry in the local smbpasswd file
-*************************************************************/
-static BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user,
-                                BOOL enable_user, BOOL disable_user, BOOL set_no_password,
-                                char *new_passwd)
-{
-       struct passwd  *pwd;
-       void *vp;
-       struct smb_passwd *smb_pwent;
-       uchar           new_p16[16];
-       uchar           new_nt_p16[16];
-
-       pwd = getpwnam(user_name);
-       
-       /*
-        * Check for a machine account.
-        */
-       
-       if(trust_account && !pwd) {
-               fprintf(stderr, "User %s does not exist in system password file (usually /etc/passwd). Cannot add machine account without a valid system user.\n",
-                       user_name);
-               return False;
-       }
-
-       /* Calculate the MD4 hash (NT compatible) of the new password. */
-       nt_lm_owf_gen(new_passwd, new_nt_p16, new_p16);
-
-       /*
-        * Open the smbpaswd file.
-        */
-       vp = startsmbpwent(True);
-       if (!vp && errno == ENOENT) {
-               FILE *fp;
-               fprintf(stderr,"smbpasswd file did not exist - attempting to create it.\n");
-               fp = fopen(lp_smb_passwd_file(), "w");
-               if (fp) {
-                       fprintf(fp, "# Samba SMB password file\n");
-                       fclose(fp);
-                       vp = startsmbpwent(True);
-               }
-       }
-
-       if (!vp) {
-               perror(lp_smb_passwd_file());
-               return False;
-       }
-  
-       /* Get the smb passwd entry for this user */
-       smb_pwent = getsmbpwnam(user_name);
-       if (smb_pwent == NULL) {
-               if(add_user == False) {
-                       fprintf(stderr, "Failed to find entry for user %s.\n",
-                               pwd->pw_name);
-                       endsmbpwent(vp);
-                       return False;
-               }
-
-               if (add_new_user(user_name, pwd->pw_uid, trust_account, disable_user,
-                                set_no_password, new_p16, new_nt_p16)) {
-                       printf("Added user %s.\n", user_name);
-                       endsmbpwent(vp);
-                       return True;
-               } else {
-                       fprintf(stderr, "Failed to add entry for user %s.\n", user_name);
-                       endsmbpwent(vp);
-                       return False;
-               }
-       } else {
-               /* the entry already existed */
-               add_user = False;
-       }
-
-       /*
-        * We are root - just write the new password
-        * and the valid last change time.
-        */
-
-       if(disable_user) {
-               smb_pwent->acct_ctrl |= ACB_DISABLED;
-       } else if (enable_user) {
-               if(smb_pwent->smb_passwd == NULL) {
-                       smb_pwent->smb_passwd = new_p16;
-                       smb_pwent->smb_nt_passwd = new_nt_p16;
-               }
-               smb_pwent->acct_ctrl &= ~ACB_DISABLED;
-       } else if (set_no_password) {
-               smb_pwent->acct_ctrl |= ACB_PWNOTREQ;
-               /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
-               smb_pwent->smb_passwd = NULL;
-               smb_pwent->smb_nt_passwd = NULL;
-       } else {
-               smb_pwent->acct_ctrl &= ~ACB_PWNOTREQ;
-               smb_pwent->smb_passwd = new_p16;
-               smb_pwent->smb_nt_passwd = new_nt_p16;
-       }
-       
-       if(mod_smbpwd_entry(smb_pwent,True) == False) {
-               fprintf(stderr, "Failed to modify entry for user %s.\n",
-                       pwd->pw_name);
-               endsmbpwent(vp);
-               return False;
-       }
-
-       endsmbpwent(vp);
-
-       return True;
-}
-
-
 /*************************************************************
 change a password either locally or remotely
 *************************************************************/
index 1ab90a3a3ddf6e8125a31f7c9e016efa6daa15d7..67582bc1167f5b0a612ef3569c1721947d317371 100644 (file)
@@ -33,20 +33,18 @@ static pstring servicesf = CONFIGFILE;
 /*
  * Password Management Globals
  */
-char user[] = "username";
-char old_pswd[] = "old_passwd";
-char new_pswd[] = "new_passwd";
-char new2_pswd[] = "new2_passwd";
-char chg_passwd_flag[] = "chg_passwd_flag";
-char add_user_flag[] = "add_user_flag";
-char disable_user_flag[] = "disable_user_flag";
-char enable_user_flag[] = "enable_user_flag";
+#define USER "username"
+#define OLD_PSWD "old_passwd"
+#define NEW_PSWD "new_passwd"
+#define NEW2_PSWD "new2_passwd"
+#define CHG_PASSWD_FLAG "chg_passwd_flag"
+#define ADD_USER_FLAG "add_user_flag"
+#define DISABLE_USER_FLAG "disable_user_flag"
+#define ENABLE_USER_FLAG "enable_user_flag"
 
 /* we need these because we link to locking*.o */
  void become_root(BOOL save_dir) {}
  void unbecome_root(BOOL restore_dir) {}
-/* We need this because we link to password.o */
-BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd, BOOL override) {return False;}
 
 /****************************************************************************
 ****************************************************************************/
@@ -87,8 +85,8 @@ char *p = newstring;
 
 static char *make_parm_name(char *label)
 {
-static char parmname[1024];
-char *p = parmname;
+       static char parmname[1024];
+       char *p = parmname;
 
        while (*label) {
                if (*label == ' ') *p++ = '_';
@@ -576,257 +574,24 @@ static void shares_page(void)
        printf("</FORM>\n");
 }
 
-/****************************************************************************
-****************************************************************************/
-static void sig_pipe ( int signo)
+/*************************************************************
+change a password either locally or remotely
+*************************************************************/
+static BOOL change_password(const char *remote_machine, char *user_name, 
+                           char *old_passwd, char *new_passwd, 
+                           BOOL add_user, BOOL enable_user, BOOL disable_user)
 {
-       printf("<p> SIGPIPE caught\n");
-}
-
-/****************************************************************************
-  create 2 pipes and use them to feed the smbpasswd program 
-****************************************************************************/
-static BOOL talk_to_smbpasswd(char *old, char *new)
-{
-       int     i, n, fd1[2], fd2[2];
-       pid_t   pid;
-       BOOL    rslt;
-       char    line[MAX_STRINGLEN + 2]; /* one for newline, one for null */
-
-       if (signal(SIGPIPE, sig_pipe) == SIG_ERR) {
-               printf("<p> signal error");
+       if (remote_machine != NULL) {
+               return remote_password_change(remote_machine, user_name, old_passwd, new_passwd);
        }
 
-       if ((pipe(fd1) < 0) || (pipe(fd2) < 0)) {
-               printf("<p> pipe error");
+       if(!initialize_password_db()) {
+               printf("Can't setup password database vectors.\n");
+               return False;
        }
-
-       if ((pid = fork()) < 0) {
-               printf("<p> fork error");
-       }
-
-       /*
-        * Create this relationship with the pipes between the parent and 
-        * the child as detailed below.
-        *
-        * parent -> fd1[1] -- fd1[0] -> child 
-        * parent <- fd2[0] -- fd2[1] <- child 
-        *
-        * fd1[0] is turned into child's stdin
-        * fd2[1] is turned into child's stdout
-        * fd2[1] is also turned into child's stderr
-        *
-        */
-       else if (pid > 0) {                     /* parent */
-
-               int     to_child    = fd1[1];
-               int     from_child  = fd2[0];
-               int     wstat;
-
-               close(fd1[0]); /* parent doesn't need input  side of pipe fd1 */
-               close(fd2[1]); /* parent doesn't need output side of pipe fd2 */
-
-               /*
-                * smbpasswd doesn't require any input to disable or enable a user 
-                */
-               if (!cgi_variable(disable_user_flag) && !cgi_variable(enable_user_flag)) {
-                       /*
-                        * smbpasswd requires a regular old user to send their old password 
-                        */
-                       if (am_root() == False) {
-                               n = (strlen(old) <= (MAX_STRINGLEN)) ? strlen(old) : (MAX_STRINGLEN);
-                               strncpy( line, old, n);
-                               line[n] = '\n'; n++; /* add carriage return */
-                               line[n] =    0;      /* add null terminator, for debug */
-                               if (write( to_child, line, n) != n) {
-                                       printf("<p> error on write to child");
-                               }
-                       }
-
-                       /*
-                        * smbpasswd requires that the new password be sent to it twice
-                        */
-                       for( i=0; i<2; i++) {
-                               n = (strlen(new) <= (MAX_STRINGLEN)) ? strlen(new) : (MAX_STRINGLEN);
-                               strncpy( line, new, n);
-                               line[n] = '\n'; n++; /* add carriage return */
-                               line[n] =    0;      /* add null terminator, for debug */
-                               if (write( to_child, line, n) != n) {
-                                       printf("<p> error on write to child");
-                                       break;
-                               }
-                       }
-               }
-
-               /*
-                * Wait for smbpasswd to finish
-                */
-               if (sys_waitpid(pid, &wstat, 0) < 0) {
-                       printf("<p> problem waiting");
-               }
-
-               /* 
-                * Read the answer from the add program
-                */
-               memset( line, '\0', sizeof(line));
-               if ((n = read( from_child, line, MAX_STRINGLEN)) < 0) {
-                       printf("<p> error on read from child");
-               }
-
-               /*
-                * Write the response from smbpasswd to user, if all is well
-                * line[] should be just a null terminated line. We could 
-                * check for the null line and not print anything, but we 
-                * really should be checking the exit code if we want to be 
-                * sure.
-                */
-               line[n] = 0;    /* null terminate */
-               printf("<p> %s\n",line);
-       
-               close(to_child); 
-               close(from_child); 
        
-               if (line[0] == '\0') {
-                       rslt = True;   /* All ok */
-               } else {
-                       rslt = False;  /* Something didn't work */
-               }
-               
-       } else {                                /* child  */
-
-               int     from_parent  = fd1[0];
-               int     to_parent    = fd2[1];
-
-               close(fd1[1]); /* child  doesn't need output side of pipe fd1 */
-               close(fd2[0]); /* child  doesn't need input  side of pipe fd2 */
-
-               /*
-                * Turn the from_parent pipe into the childs stdin 
-                */
-               if (from_parent != STDIN_FILENO) {
-                       if (dup2( from_parent, STDIN_FILENO) != STDIN_FILENO) {
-                               printf("<p> dup2 error of stdin");
-                       }
-                       close( from_parent);
-               }
-
-               /*
-                * Turn the to_parent pipe into the childs stdout
-                */
-               if (to_parent != STDOUT_FILENO) {
-                       if (dup2( to_parent, STDOUT_FILENO) != STDOUT_FILENO) {
-                               printf("<p> dup2 error of stdout");
-                       }
-                       close( to_parent);
-               }
-               /*
-                * Make the childs stderr the to_parent pipe also
-                */
-               if (dup2( STDOUT_FILENO, STDERR_FILENO) != STDERR_FILENO) {
-                       printf("<p> dup2 error of stdout");
-               }
-
-               
-               /* Root can do more */
-               if (am_root() == True) {
-                       if (cgi_variable(add_user_flag)) {
-                               /* 
-                                * Add a user 
-                                */
-                               if (execl(SMB_PASSWD_PROGRAM, "smbpasswd", "-s", "-a", cgi_variable(user), (char *) 0) < 0) {
-                                       printf("<p> execl error of smbpasswd");
-                               }
-                       } else if (cgi_variable(disable_user_flag)) {
-                               /* 
-                                * Disable a user 
-                                */
-                               if (execl(SMB_PASSWD_PROGRAM, "smbpasswd", "-s", "-d", cgi_variable(user), (char *) 0) < 0) {
-                                       printf("<p> execl error of smbpasswd");
-                               }
-                       } else if (cgi_variable(enable_user_flag)) {
-                               /* 
-                                * Enable a user 
-                                */
-                               if (execl(SMB_PASSWD_PROGRAM, "smbpasswd", "-s", "-e", cgi_variable(user), (char *) 0) < 0) {
-                                       printf("<p> execl error of smbpasswd");
-                               }
-                       } else {
-                               /* 
-                                * Change a users password 
-                                */
-                               if (execl(SMB_PASSWD_PROGRAM, "smbpasswd", "-s", cgi_variable(user), (char *) 0) < 0) {
-                                       printf("<p> execl error of smbpasswd");
-                               }
-                       }
-               } else {
-                       /* 
-                        * Ordinary users can change any users passwd if they know the old passwd
-                        */
-                       if (execl(SMB_PASSWD_PROGRAM, "smbpasswd", "-s", (char *) 0) < 0) {
-                               printf("<p> execl error of smbpasswd");
-                       }
-               }
-       }
-       return(rslt);  
-}
-
-/****************************************************************************
-  become the specified uid - permanently !
-****************************************************************************/
-
-BOOL become_user_permanently(uid_t uid, gid_t gid)
-{
-
-    if (geteuid() != 0) {
-        return(True);
-    }
-
-    /* now completely lose our privilages. This is a fairly paranoid
-    way of doing it, but it does work on all systems that I know of */
-
-#ifdef HAVE_SETRESUID
-       /*
-        * Firstly ensure all our uids are set to root.
-        */
-    setresgid(0,0,0);
-    setresuid(0,0,0);
-
-       /*
-        * Now ensure we change all our gids.
-        */
-    setresgid(gid,gid,gid);
-
-       /*
-        * Now ensure all the uids are the user.
-        */
-    setresuid(uid,uid,uid);
-#else
-       /*
-        * Firstly ensure all our uids are set to root.
-        */
-    setuid(0);
-    seteuid(0);
-
-       /*
-        * Now ensure we change all our gids.
-        */
-    setgid(gid);
-    setegid(gid);
-
-       /*
-        * Now ensure all the uids are the user.
-        */
-    setuid(uid);
-    seteuid(uid);
-#endif
-
-    if (getuid() != uid || geteuid() != uid ||
-        getgid() != gid || getegid() != gid) {
-        /* We failed to lose our privilages. */
-        return False;
-    }
-
-       return(True);
+       return local_password_change(user_name, False, add_user, enable_user, 
+                                    disable_user, False, new_passwd);
 }
 
 /****************************************************************************
@@ -834,11 +599,10 @@ BOOL become_user_permanently(uid_t uid, gid_t gid)
 ****************************************************************************/
 static void chg_passwd(void)
 {
-       struct passwd *pass = NULL;
        BOOL rslt;
 
        /* Make sure users name has been specified */
-       if (strlen(cgi_variable(user)) == 0) {
+       if (strlen(cgi_variable(USER)) == 0) {
                printf("<p> Must specify \"User Name\" \n");
                return;
        }
@@ -847,50 +611,40 @@ static void chg_passwd(void)
         * smbpasswd doesn't require anything but the users name to disable or enable the user,
         * so if that's what we're doing, skip the rest of the checks
         */
-       if (!cgi_variable(disable_user_flag) && !cgi_variable(enable_user_flag)) {
+       if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG)) {
 
                /* If current user is not root, make sure old password has been specified */
-               if ((am_root() == False) &&  (strlen( cgi_variable(old_pswd)) <= 0)) {
+               if ((am_root() == False) &&  (strlen( cgi_variable(OLD_PSWD)) <= 0)) {
                        printf("<p> Must specify \"Old Password\" \n");
                        return;
                }
 
                /* Make sure new passwords have been specified */
-               if ((strlen( cgi_variable(new_pswd )) <= 0) ||
-                   (strlen( cgi_variable(new2_pswd)) <= 0)) {
+               if ((strlen( cgi_variable(NEW_PSWD)) <= 0) ||
+                   (strlen( cgi_variable(NEW2_PSWD)) <= 0)) {
                        printf("<p> Must specify \"New, and Re-typed Passwords\" \n");
                        return;
                }
 
                /* Make sure new passwords was typed correctly twice */
-               if (strcmp(cgi_variable(new_pswd), cgi_variable(new2_pswd)) != 0) {
+               if (strcmp(cgi_variable(NEW_PSWD), cgi_variable(NEW2_PSWD)) != 0) {
                        printf("<p> Re-typed password didn't match new password\n");
                        return;
                }
        }
 
-#ifdef SWAT_DEBUG
-       if (pass) printf("<p> User uid %d  gid %d \n", pass->pw_uid, pass->pw_gid);
-       printf("<p> Processes uid %d, euid %d, gid %d, egid %d \n",getuid(),geteuid(),getgid(),getegid());
-       printf("<p> User Name %s     \n", cgi_variable(user));
-       printf("<p> Old passwd %s    \n", cgi_variable(old_pswd) ? cgi_variable(old_pswd):"");
-       printf("<p> New passwd %s    \n", cgi_variable(new_pswd));
-       printf("<p> Re-typed New passwd %s    \n", cgi_variable(new2_pswd));
-       printf("<p> flags '%s', '%s', '%s'   \n", 
-               (cgi_variable( chg_passwd_flag) ? cgi_variable( chg_passwd_flag) : ""),
-               (cgi_variable( add_user_flag) ? cgi_variable( add_user_flag) : ""),
-               (cgi_variable( disable_user_flag) ? cgi_variable( disable_user_flag) : ""));
-               (cgi_variable( enable_user_flag) ? cgi_variable( enable_user_flag) : ""));
-#endif /* SWAT_DEBUG */
-
-
-       rslt = talk_to_smbpasswd( cgi_variable(old_pswd), cgi_variable(new_pswd));
-       if (am_root() == False) {
-               if (rslt == True) {
-                       printf("<p> The passwd for '%s' has been changed. \n",cgi_variable(user));
-               } else {
-                       printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(user));
-               }
+       rslt = change_password(am_root() ? NULL : "127.0.0.1",
+                              cgi_variable(USER),
+                              cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
+                              cgi_variable(ADD_USER_FLAG)? True : False,
+                              cgi_variable(ENABLE_USER_FLAG)? True : False,
+                              cgi_variable(DISABLE_USER_FLAG)? True : False);
+
+
+       if (rslt == True) {
+               printf("<p> The passwd for '%s' has been changed. \n", cgi_variable(USER));
+       } else {
+               printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(USER));
        }
        
        return;
@@ -913,29 +667,30 @@ static void passwd_page(void)
         * After the first time through here be nice. If the user
         * changed the User box text to another users name, remember it.
         */
-       if ( cgi_variable(user) && 
-           (strcmp(cgi_variable(user), get_user_name()))) {
+       if (cgi_variable(USER) && 
+           (strcmp(cgi_variable(USER), get_user_name()))) {
                /* User is changing another accounts passwd */
-               new_name = cgi_variable(user);
+               new_name = cgi_variable(USER);
        } else {
                /* User is changing there own passwd */
                new_name = get_user_name();
        }
 
-       printf("<p> User Name        : <input type=text size=30 name=%s value=%s> \n", user, new_name);
+       printf("<p> User Name        : <input type=text size=30 name=%s value=%s> \n", 
+              USER, new_name);
        if (am_root() == False) {
-               printf("<p> Old Password: <input type=password size=30 name=%s>\n",old_pswd);
+               printf("<p> Old Password: <input type=password size=30 name=%s>\n",OLD_PSWD);
        }
-       printf("<p> New Password: <input type=password size=30 name=%s>\n",new_pswd);
-       printf("<p> Re-type New Password: <input type=password size=30 name=%s>\n",new2_pswd);
+       printf("<p> New Password: <input type=password size=30 name=%s>\n",NEW_PSWD);
+       printf("<p> Re-type New Password: <input type=password size=30 name=%s>\n",NEW2_PSWD);
 
        printf("</select></td></tr><p>");
        printf("<tr><td>");
-       printf("<input type=submit name=%s value=\"Change Password\">", chg_passwd_flag);
+       printf("<input type=submit name=%s value=\"Change Password\">", CHG_PASSWD_FLAG);
        if (am_root() == True) {
-               printf("<input type=submit name=%s value=\"Add New User\">", add_user_flag);
-               printf("<input type=submit name=%s value=\"Disable User\">", disable_user_flag);
-               printf("<input type=submit name=%s value=\"Enable User\">", enable_user_flag);
+               printf("<input type=submit name=%s value=\"Add New User\">", ADD_USER_FLAG);
+               printf("<input type=submit name=%s value=\"Disable User\">", DISABLE_USER_FLAG);
+               printf("<input type=submit name=%s value=\"Enable User\">", ENABLE_USER_FLAG);
        }
        printf("</td>\n");
 
@@ -943,7 +698,7 @@ static void passwd_page(void)
         * If we don't have user information then there's nothing to do. It's probably
         * the first time through this code.
         */
-       if (cgi_variable(user)) {
+       if (cgi_variable(USER)) {
                chg_passwd();           
        }