summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>1998-11-12 07:06:48 +0000
committerAndrew Tridgell <tridge@samba.org>1998-11-12 07:06:48 +0000
commit29e36b713468d7e7de301c483fc340ef42b4a9fb (patch)
treefd97dcedea842356595ce290c2fb1f95d8448285 /source3
parent4f368d8b924b76007809e967ac1f37f6a1ebdd68 (diff)
downloadsamba-29e36b713468d7e7de301c483fc340ef42b4a9fb.tar.gz
samba-29e36b713468d7e7de301c483fc340ef42b4a9fb.tar.bz2
samba-29e36b713468d7e7de301c483fc340ef42b4a9fb.zip
extracted the password change code from smbpasswd and used it in swat
instead of opening pipes and other horrible stuff. (This used to be commit 49bf19710345a59a2d17cd449be1a132885ed821)
Diffstat (limited to 'source3')
-rw-r--r--source3/Makefile.in5
-rw-r--r--source3/include/proto.h11
-rw-r--r--source3/lib/util.c53
-rw-r--r--source3/libsmb/passchange.c100
-rw-r--r--source3/passdb/smbpasschange.c162
-rw-r--r--source3/smbd/uid.c2
-rw-r--r--source3/utils/smbpasswd.c218
-rw-r--r--source3/web/swat.c353
8 files changed, 385 insertions, 519 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index dcabf917d0..4dde76a60c 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -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 \
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 888e2af33f..2580491976 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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);
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 2be1fcaf6f..1710205f3c 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -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
index 0000000000..7d89cbd3d7
--- /dev/null
+++ b/source3/libsmb/passchange.c
@@ -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
index 0000000000..4e2813316e
--- /dev/null
+++ b/source3/passdb/smbpasschange.c
@@ -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;
+}
+
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 7cd8c8673c..7c951b461a 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -421,3 +421,5 @@ void unbecome_root(BOOL restore_dir)
become_root_depth = 0;
}
+
+
diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c
index da7caacb11..2303bc56df 100644
--- a/source3/utils/smbpasswd.c
+++ b/source3/utils/smbpasswd.c
@@ -19,10 +19,8 @@
#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
*************************************************************/
diff --git a/source3/web/swat.c b/source3/web/swat.c
index 1ab90a3a3d..67582bc116 100644
--- a/source3/web/swat.c
+++ b/source3/web/swat.c
@@ -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();
}