summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>1998-03-19 20:06:47 +0000
committerJeremy Allison <jra@samba.org>1998-03-19 20:06:47 +0000
commit20770b6f1c25288e90d3e0d215afa7f0809ce124 (patch)
treeff60815a291db1bf9e95ff4cba0c3c2ffa2f8b70 /source
parente02e3bcbbd4333113dde7bef47763fb229148007 (diff)
downloadsamba-20770b6f1c25288e90d3e0d215afa7f0809ce124.tar.gz
samba-20770b6f1c25288e90d3e0d215afa7f0809ce124.tar.xz
samba-20770b6f1c25288e90d3e0d215afa7f0809ce124.zip
Adding the same changes to HEAD as were added to BRANCH_1_9_18.
Changed smbpasswd to be client-server for a normal user, rather than accessing the private/smbpasswd file directly (it still accesses this file directly when run as root, so root can add users/change a users password without knowing the old password). A shakeout of this change is that smbpasswd can now be used to change a users password on a remote NT machine (yep - you heard that one right - we can now change a NT password from UNIX !!!!!). Jeremy.
Diffstat (limited to 'source')
-rw-r--r--source/client/client.c25
-rw-r--r--source/client/smbmount.c25
-rw-r--r--source/include/proto.h5
-rw-r--r--source/libsmb/clientgen.c100
-rw-r--r--source/libsmb/smbdes.c10
-rw-r--r--source/passdb/smbpass.c6
-rw-r--r--source/smbd/chgpasswd.c29
-rw-r--r--source/utils/smbpasswd.c379
8 files changed, 382 insertions, 197 deletions
diff --git a/source/client/client.c b/source/client/client.c
index 679114fa2bb..3ce635fbeb2 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -3845,31 +3845,6 @@ static void usage(char *pname)
return(ret);
}
-#ifdef NTDOMAIN
-
- if (nt_domain_logon)
- {
- int ret = 0;
- sprintf(service,"\\\\%s\\IPC$",query_host);
- strupper(service);
- connect_as_ipc = True;
-
- DEBUG(5,("NT Domain Logon. Service: %s\n", service));
-
- if (cli_open_sockets(port))
- {
- if (!cli_send_login(NULL,NULL,True,True,NULL)) return(1);
-
- do_nt_login(desthost, myhostname, Client, cnum);
-
- cli_send_logout();
- close_sockets();
- }
-
- return(ret);
- }
-#endif
-
if (cli_open_sockets(port))
{
if (!process(base_directory))
diff --git a/source/client/smbmount.c b/source/client/smbmount.c
index fdafaec9faf..bab74308592 100644
--- a/source/client/smbmount.c
+++ b/source/client/smbmount.c
@@ -883,31 +883,6 @@ static void usage(char *pname)
get_myname((*myname)?NULL:myname,NULL);
strupper(myname);
-#ifdef NTDOMAIN
-
- if (nt_domain_logon)
- {
- int ret = 0;
- sprintf(service,"\\\\%s\\IPC$",query_host);
- strupper(service);
- connect_as_ipc = True;
-
- DEBUG(5,("NT Domain Logon. Service: %s\n", service));
-
- if (cli_open_sockets(port))
- {
- if (!cli_send_login(NULL,NULL,True,True,NULL)) return(1);
-
- do_nt_login(desthost, myhostname, Client, cnum);
-
- cli_send_logout();
- close_sockets();
- }
-
- return(ret);
- }
-#endif
-
if (cli_open_sockets(port))
{
if (!process(base_directory))
diff --git a/source/include/proto.h b/source/include/proto.h
index e980bcacc9a..209004e90ad 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -82,6 +82,8 @@ BOOL cli_qpathinfo2(struct cli_state *cli, char *fname,
time_t *w_time, uint32 *size);
BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size);
+BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_password,
+ char *old_password);
BOOL cli_negprot(struct cli_state *cli);
BOOL cli_session_request(struct cli_state *cli, char *host, int name_type,
char *myname);
@@ -1666,9 +1668,10 @@ struct shmem_ops *sysv_shm_open(int ronly);
void E_P16(unsigned char *p14,unsigned char *p16);
void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out);
+void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out);
void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key);
void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key);
-void SamOEMhash( unsigned char *data, unsigned char *key);
+void SamOEMhash( unsigned char *data, unsigned char *key, int val);
/*The following definitions come from smbencrypt.c */
diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c
index 4585c8a5441..dcebf704554 100644
--- a/source/libsmb/clientgen.c
+++ b/source/libsmb/clientgen.c
@@ -426,7 +426,7 @@ BOOL cli_session_setup(struct cli_state *cli,
return False;
}
- if ((cli->sec_mode & 2) && *pass && passlen != 24) {
+ if ((cli->sec_mode & 2) && passlen != 24) {
passlen = 24;
SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword);
} else {
@@ -1207,6 +1207,104 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
return True;
}
+/****************************************************************************
+Send a SamOEMChangePassword command
+****************************************************************************/
+
+BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_password,
+ char *old_password)
+{
+ char param[16+sizeof(fstring)];
+ char data[532];
+ char *p = param;
+ fstring upper_case_old_pw;
+ fstring upper_case_new_pw;
+ unsigned char old_pw_hash[16];
+ unsigned char new_pw_hash[16];
+ int data_len;
+ int param_len = 0;
+ int new_pw_len = strlen(new_password);
+ char *rparam = NULL;
+ char *rdata = NULL;
+ int rprcnt, rdrcnt;
+
+ cli->error = -1;
+
+ if(strlen(user) >= sizeof(fstring)-1) {
+ DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user));
+ return False;
+ }
+
+ if(new_pw_len > 512) {
+ DEBUG(0,("cli_oem_change_password: new password for user %s is too long.\n", user));
+ return False;
+ }
+
+ SSVAL(p,0,214); /* SamOEMChangePassword command. */
+ p += 2;
+ strcpy(p, "zsT");
+ p = skip_string(p,1);
+ strcpy(p, "B516B16");
+ p = skip_string(p,1);
+ fstrcpy(p,user);
+ p = skip_string(p,1);
+ SSVAL(p,0,532);
+ p += 2;
+
+ param_len = PTR_DIFF(p,param);
+
+ /*
+ * Now setup the data area.
+ */
+ memset(data, '\0', sizeof(data));
+ fstrcpy( &data[512 - new_pw_len], new_password);
+ SIVAL(data, 512, new_pw_len);
+
+ /*
+ * Get the Lanman hash of the old password, we
+ * use this as the key to SamOEMHash().
+ */
+ memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw));
+ fstrcpy(upper_case_old_pw, old_password);
+ strupper(upper_case_old_pw);
+ E_P16((uchar *)upper_case_old_pw, old_pw_hash);
+
+ SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True);
+
+ /*
+ * Now place the old password hash in the data.
+ */
+ memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw));
+ fstrcpy(upper_case_new_pw, new_password);
+ strupper(upper_case_new_pw);
+
+ E_P16((uchar *)upper_case_new_pw, new_pw_hash);
+
+ E_old_pw_hash( new_pw_hash, old_pw_hash, &data[516]);
+
+ data_len = 532;
+
+ if(cli_send_trans(cli,SMBtrans,PIPE_LANMAN,0,0,
+ data,param,NULL,
+ data_len , param_len,0,
+ 0,2,0) == False) {
+ DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n",
+ user ));
+ return False;
+ }
+
+ if(cli_receive_trans(cli,SMBtrans, &rdrcnt, &rprcnt, &rdata, &rparam)) {
+ if(rparam)
+ cli->error = SVAL(rparam,0);
+ }
+
+ if (rparam)
+ free(rparam);
+ if (rdata)
+ free(rdata);
+
+ return (cli->error == 0);
+}
/****************************************************************************
send a negprot command
diff --git a/source/libsmb/smbdes.c b/source/libsmb/smbdes.c
index 8f95a5a297b..e5d8f4a1e0b 100644
--- a/source/libsmb/smbdes.c
+++ b/source/libsmb/smbdes.c
@@ -323,6 +323,12 @@ void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
smbhash(out+8, in+8, p14+7, 0);
}
+void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out)
+{
+ smbhash(out, in, p14, 1);
+ smbhash(out+8, in+8, p14+7, 1);
+}
+
void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key)
{
unsigned char buf[8];
@@ -341,7 +347,7 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key)
smbhash(out, buf, key2, 1);
}
-void SamOEMhash( unsigned char *data, unsigned char *key)
+void SamOEMhash( unsigned char *data, unsigned char *key, int val)
{
unsigned char s_box[256];
unsigned char index_i = 0;
@@ -365,7 +371,7 @@ void SamOEMhash( unsigned char *data, unsigned char *key)
s_box[j] = tc;
}
- for( ind = 0; ind < 516; ind++)
+ for( ind = 0; ind < (val ? 516 : 16); ind++)
{
unsigned char tc;
unsigned char t;
diff --git a/source/passdb/smbpass.c b/source/passdb/smbpass.c
index b51f6753065..a1913c4959e 100644
--- a/source/passdb/smbpass.c
+++ b/source/passdb/smbpass.c
@@ -768,12 +768,6 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd)
return False;
}
- if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
- fclose(fp);
- pw_file_unlock(lockfd);
- return False;
- }
-
/* Now check if the NT compatible password is
available. */
p += 33; /* Move to the first character of the line after
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
index 57d81ad756d..779845d37ae 100644
--- a/source/smbd/chgpasswd.c
+++ b/source/smbd/chgpasswd.c
@@ -408,6 +408,7 @@ BOOL check_lanman_password(char *user, unsigned char *pass1,
{
unsigned char unenc_new_pw[16];
unsigned char unenc_old_pw[16];
+ unsigned char null_pw[16];
struct smb_passwd *smbpw;
*psmbpw = NULL;
@@ -428,8 +429,13 @@ BOOL check_lanman_password(char *user, unsigned char *pass1,
return False;
}
- if(smbpw->smb_passwd == NULL)
+ if((smbpw->smb_passwd == NULL) && (smbpw->acct_ctrl & ACB_PWNOTREQ))
{
+ unsigned char no_pw[14];
+ memset(no_pw, '\0', 14);
+ E_P16((uchar *)no_pw, (uchar *)null_pw);
+ smbpw->smb_passwd = null_pw;
+ } else if (smbpw->smb_passwd == NULL) {
DEBUG(0,("check_lanman_password: no lanman password !\n"));
return False;
}
@@ -460,6 +466,7 @@ BOOL check_lanman_password(char *user, unsigned char *pass1,
BOOL change_lanman_password(struct smb_passwd *smbpw, unsigned char *pass1, unsigned char *pass2)
{
unsigned char unenc_new_pw[16];
+ unsigned char null_pw[16];
BOOL ret;
if(smbpw == NULL)
@@ -474,8 +481,13 @@ BOOL change_lanman_password(struct smb_passwd *smbpw, unsigned char *pass1, unsi
return False;
}
- if(smbpw->smb_passwd == NULL)
+ if((smbpw->smb_passwd == NULL) && (smbpw->acct_ctrl & ACB_PWNOTREQ))
{
+ unsigned char no_pw[14];
+ memset(no_pw, '\0', 14);
+ E_P16((uchar *)no_pw, (uchar *)null_pw);
+ smbpw->smb_passwd = null_pw;
+ } else if (smbpw->smb_passwd == NULL) {
DEBUG(0,("change_lanman_password: no lanman password !\n"));
return False;
}
@@ -507,6 +519,7 @@ BOOL check_oem_password(char *user, unsigned char *data,
fstring upper_case_new_passwd;
unsigned char new_p16[16];
unsigned char unenc_old_pw[16];
+ unsigned char null_pw[16];
become_root(0);
*psmbpw = smbpw = get_smbpwd_entry(user, 0);
@@ -524,8 +537,13 @@ BOOL check_oem_password(char *user, unsigned char *data,
return False;
}
- if(smbpw->smb_passwd == NULL)
+ if((smbpw->smb_passwd == NULL) && (smbpw->acct_ctrl & ACB_PWNOTREQ))
{
+ unsigned char no_pw[14];
+ memset(no_pw, '\0', 14);
+ E_P16((uchar *)no_pw, (uchar *)null_pw);
+ smbpw->smb_passwd = null_pw;
+ } else if (smbpw->smb_passwd == NULL) {
DEBUG(0,("check_oem_password: no lanman password !\n"));
return False;
}
@@ -533,7 +551,7 @@ BOOL check_oem_password(char *user, unsigned char *data,
/*
* Call the hash function to get the new password.
*/
- SamOEMhash( (unsigned char *)data, (unsigned char *)smbpw->smb_passwd);
+ SamOEMhash( (unsigned char *)data, (unsigned char *)smbpw->smb_passwd, True);
/*
* The length of the new password is in the last 4 bytes of
@@ -541,7 +559,7 @@ BOOL check_oem_password(char *user, unsigned char *data,
*/
new_pw_len = IVAL(data,512);
if(new_pw_len < 0 || new_pw_len > new_passwd_size - 1) {
- DEBUG(0,("check_oem_password: incorrect password length.\n"));
+ DEBUG(0,("check_oem_password: incorrect password length (%d).\n", new_pw_len));
return False;
}
@@ -587,6 +605,7 @@ BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd)
unsigned char new_nt_p16[16];
unsigned char new_p16[16];
+ memset(upper_case_new_passwd, '\0', sizeof(upper_case_new_passwd));
fstrcpy(upper_case_new_passwd, new_passwd);
strupper(upper_case_new_passwd);
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c
index 7ab8d8a0dbf..5b5f86c5e1c 100644
--- a/source/utils/smbpasswd.c
+++ b/source/utils/smbpasswd.c
@@ -19,11 +19,23 @@
#include "includes.h"
-/* Static buffers we will return. */
-static struct smb_passwd pw_buf;
-static pstring user_name;
-static unsigned char smbpwd[16];
-static unsigned char smbntpwd[16];
+/*
+ * Password changing error codes.
+ */
+
+struct
+{
+ int err;
+ char *message;
+} pw_change_errmap[] =
+{
+ {5, "User has insufficient privilege" },
+ {86, "The specified password is invalid" },
+ {2226, "Operation only permitted on a Primary Domain Controller" },
+ {2243, "The password cannot be changed" },
+ {2246, "The password is too short" },
+ {0, NULL}
+};
static int gethexpwd(char *p, char *pwd)
{
@@ -52,6 +64,12 @@ static struct smb_passwd *
_my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd,
BOOL *got_valid_nt_entry, long *pwd_seekpos)
{
+ /* Static buffers we will return. */
+ static struct smb_passwd pw_buf;
+ static pstring user_name;
+ static unsigned char smbpwd[16];
+ static unsigned char smbntpwd[16];
+
char linebuf[256];
unsigned char c;
unsigned char *p;
@@ -198,14 +216,21 @@ _my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd,
/*
* Print command usage on stderr and die.
*/
-static void usage(char *name)
+static void usage(char *name, BOOL is_root)
{
- fprintf(stderr, "Usage is : %s [-add] [username] [password]\n", name);
+ if(is_root)
+ fprintf(stderr, "Usage is : %s [-a] [username] [password]\n\
+%s: [-r machine] [username] [password]\n%s: [-h]", name, name, name);
+ else
+ fprintf(stderr, "Usage is : %s [-h] [-r machine] [password]\n", name);
exit(1);
}
- int main(int argc, char **argv)
+int main(int argc, char **argv)
{
+ extern char *optarg;
+ extern int optind;
+ char *prog_name;
int real_uid;
struct passwd *pwd;
fstring old_passwd;
@@ -218,9 +243,7 @@ static void usage(char *name)
struct smb_passwd *smb_pwent;
FILE *fp;
BOOL valid_old_pwd = False;
- BOOL got_valid_nt_entry = False;
- BOOL add_user = False;
- int add_pass = 0;
+ BOOL got_valid_nt_entry = False;
long seekpos;
int pwfd;
char ascii_p16[66];
@@ -229,103 +252,141 @@ static void usage(char *name)
int lockfd = -1;
char *pfile = SMB_PASSWD_FILE;
char readbuf[16 * 1024];
-
+ BOOL is_root = False;
+ pstring user_name;
+ char *remote_machine = NULL;
+ BOOL add_user = False;
+ BOOL got_new_pass = False;
+ pstring servicesf = CONFIGFILE;
+
+ new_passwd[0] = '\0';
+ user_name[0] = '\0';
+
+ memset(old_passwd, '\0', sizeof(old_passwd));
+ memset(new_passwd, '\0', sizeof(old_passwd));
+
+ prog_name = argv[0];
+
TimeInit();
- setup_logging(argv[0],True);
+ setup_logging(prog_name,True);
charset_initialise();
-
-#ifndef DEBUG_PASSWORD
- /* Check the effective uid */
- if (geteuid() != 0) {
- fprintf(stderr, "%s: Must be setuid root.\n", argv[0]);
- exit(1);
+
+ if (!lp_load(servicesf,True,False,False)) {
+ fprintf(stderr, "%s: Can't load %s - run testparm to debug it\n", prog_name, servicesf);
}
-#endif
-
+
+ codepage_initialise(lp_client_code_page());
+
/* Get the real uid */
real_uid = getuid();
- /* Deal with usage problems */
- if (real_uid == 0)
- {
- /* As root we can change anothers password and add a user. */
- if (argc > 4 )
- usage(argv[0]);
- }
- else if (argc == 2 || argc > 3)
- {
- fprintf(stderr, "%s: Only root can set anothers password.\n", argv[0]);
- usage(argv[0]);
+ /* Check the effective uid */
+ if ((geteuid() == 0) && (real_uid != 0)) {
+ fprintf(stderr, "%s: Must *NOT* be setuid root.\n", prog_name);
+ exit(1);
}
-
- if (real_uid == 0 && (argc > 1))
- {
- /* We are root - check if we should add the user */
- if ((argv[1][0] == '-') && (argv[1][1] == 'a'))
+
+ is_root = (real_uid == 0);
+
+ while ((c = getopt(argc, argv, "ahr:")) != EOF) {
+ switch(c) {
+ case 'a':
add_user = True;
+ break;
+ case 'r':
+ remote_machine = optarg;
+ break;
+ case 'h':
+ default:
+ usage(prog_name, is_root);
+ }
+ }
- if(add_user && (argc <= 2 || argc > 4))
- usage(argv[0]);
+ argc -= optind;
+ argv += optind;
- /* root can specify password on command-line */
- if (argc == (add_user ? 4 : 3))
- {
- /* -a argument (add_user): new password is 3rd argument. */
- /* no -a argument (add_user): new password is 2nd argument */
+ /*
+ * Ensure add_user and remote machine are
+ * not both set.
+ */
+ if(add_user && (remote_machine != NULL))
+ usage(prog_name, True);
+
+ if( is_root ) {
+
+ /*
+ * Deal with root - can add a user, but only locally.
+ */
+
+ switch(argc) {
+ case 0:
+ break;
+ case 1:
+ /* If we are root we can change another's password. */
+ pstrcpy(user_name, argv[0]);
+ break;
+ case 2:
+ pstrcpy(user_name, argv[0]);
+ fstrcpy(new_passwd, argv[1]);
+ got_new_pass = True;
+ break;
+ default:
+ usage(prog_name, True);
+ }
- add_pass = add_user ? 3 : 2;
+ if(*user_name)
+ pwd = getpwnam(user_name);
+ else {
+ if((pwd = getpwuid(real_uid)) != NULL)
+ pstrcpy( user_name, pwd->pw_name);
}
- /* If we are root we can change another's password. */
- strncpy(user_name, add_user ? argv[2] : argv[1], sizeof(user_name) - 1);
- user_name[sizeof(user_name) - 1] = '\0';
+ } else {
- pwd = getpwnam(user_name);
- }
- else
- {
- /* non-root can specify old pass / new pass on command-line */
- if (argc == 3)
- {
- /* non-root specifies new password as 2nd argument */
- add_pass = 2;
+ if(add_user) {
+ fprintf(stderr, "%s: Only root can set anothers password.\n", prog_name);
+ usage(prog_name, False);
}
- pwd = getpwuid(real_uid);
- }
-
- if (pwd == 0) {
- fprintf(stderr, "%s: Unable to get UNIX password entry for user.\n", argv[0]);
- exit(1);
- }
+ if(argc > 1)
+ usage(prog_name, False);
- /* If we are root we don't ask for the old password. */
- old_passwd[0] = '\0';
- if (real_uid != 0)
- {
- if (add_pass)
- {
- /* old password, as non-root, is 1st argument */
- strncpy(old_passwd, argv[1], sizeof(fstring));
+ if(argc == 1) {
+ fstrcpy(new_passwd, argv[0]);
+ got_new_pass = True;
}
- else
- {
- p = getpass("Old SMB password:");
- strncpy(old_passwd, p, sizeof(fstring));
- }
- old_passwd[sizeof(fstring)-1] = '\0';
+
+ if((pwd = getpwuid(real_uid)) != NULL)
+ pstrcpy( user_name, pwd->pw_name);
+
+ /*
+ * A non-root user is always setting a password
+ * via a remote machine (even if that machine is
+ * localhost).
+ */
+
+ if(remote_machine == NULL)
+ remote_machine = "127.0.0.1";
+ }
+
+ if (*user_name == '\0') {
+ fprintf(stderr, "%s: Unable to get a user name for password change.\n", prog_name);
+ exit(1);
}
- if (add_pass)
- {
- /* new password is specified on the command line */
- strncpy(new_passwd, argv[add_user ? 3 : 2], sizeof(new_passwd) - 1);
- new_passwd[sizeof(new_passwd) - 1] = '\0';
+ /*
+ * If we are root we don't ask for the old password (unless it's on a
+ * remote machine.
+ */
+
+ if (remote_machine != NULL) {
+ p = getpass("Old SMB password:");
+ fstrcpy(old_passwd, p);
}
- else
- {
+
+ if (!got_new_pass) {
new_passwd[0] = '\0';
p = getpass("New SMB password:");
@@ -337,17 +398,96 @@ static void usage(char *name)
if (strncmp(p, new_passwd, sizeof(fstring)-1))
{
- fprintf(stderr, "%s: Mismatch - password unchanged.\n", argv[0]);
+ fprintf(stderr, "%s: Mismatch - password unchanged.\n", prog_name);
exit(1);
}
}
- if (new_passwd[0] == '\0')
- {
+ if (new_passwd[0] == '\0') {
printf("Password not set\n");
exit(0);
}
+
+ /*
+ * Now do things differently depending on if we're changing the
+ * password on a remote machine. Remember - a normal user is
+ * always using this code, looping back to the local smbd.
+ */
+
+ if(remote_machine != NULL) {
+ struct cli_state cli;
+ struct in_addr ip;
+ fstring myname;
+
+ if(get_myname(myname,NULL) == False) {
+ fprintf(stderr, "%s: unable to get my hostname.\n", prog_name );
+ exit(1);
+ }
+
+ if(!resolve_name( remote_machine, &ip)) {
+ fprintf(stderr, "%s: unable to find an IP address for machine %s.\n",
+ prog_name, remote_machine );
+ exit(1);
+ }
+
+ if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) {
+ fprintf(stderr, "%s: unable to connect to SMB server on machine %s.\n",
+ prog_name, remote_machine );
+ exit(1);
+ }
+
+ if (!cli_session_request(&cli, remote_machine, 0x20, myname)) {
+ fprintf(stderr, "%s: machine %s rejected the session setup.\n",
+ prog_name, remote_machine );
+ cli_shutdown(&cli);
+ exit(1);
+ }
+
+ cli.protocol = PROTOCOL_NT1;
+
+ if (!cli_negprot(&cli)) {
+ fprintf(stderr, "%s: machine %s rejected the negotiate protocol.\n",
+ prog_name, remote_machine );
+ cli_shutdown(&cli);
+ exit(1);
+ }
+ if (!cli_session_setup(&cli, user_name, old_passwd, strlen(old_passwd),
+ "", 0, "")) {
+ fprintf(stderr, "%s: machine %s rejected the session setup.\n",
+ prog_name, remote_machine );
+ cli_shutdown(&cli);
+ exit(1);
+ }
+
+ if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
+ fprintf(stderr, "%s: machine %s rejected the tconX on the IPC$ share.\n",
+ prog_name, remote_machine );
+ cli_shutdown(&cli);
+ exit(1);
+ }
+
+ if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) {
+ fstring error_message;
+
+ sprintf(error_message, " with code %d", cli.error);
+
+ for(i = 0; pw_change_errmap[i].message != NULL; i++) {
+ if (pw_change_errmap[i].err == cli.error) {
+ fstrcpy( error_message, pw_change_errmap[i].message);
+ break;
+ }
+ }
+ fprintf(stderr, "%s: machine %s rejected the password change: %s.\n",
+ prog_name, remote_machine, error_message );
+ cli_shutdown(&cli);
+ exit(1);
+ }
+
+ cli_shutdown(&cli);
+ exit(0);
+ }
+
/* Calculate the MD4 hash (NT compatible) of the old and new passwords */
memset(old_nt_p16, '\0', 16);
E_md4hash((uchar *)old_passwd, old_nt_p16);
@@ -387,9 +527,9 @@ static void usage(char *name)
if (!fp) {
err = errno;
fprintf(stderr, "%s: Failed to open password file %s.\n",
- argv[0], pfile);
+ prog_name, pfile);
errno = err;
- perror(argv[0]);
+ perror(prog_name);
exit(err);
}
@@ -403,19 +543,19 @@ static void usage(char *name)
if ((lockfd = pw_file_lock(fileno(fp), F_WRLCK, 5)) < 0) {
err = errno;
fprintf(stderr, "%s: Failed to lock password file %s.\n",
- argv[0], pfile);
+ prog_name, pfile);
fclose(fp);
errno = err;
- perror(argv[0]);
+ perror(prog_name);
exit(err);
}
/* Get the smb passwd entry for this user */
- smb_pwent = _my_get_smbpwnam(fp, pwd->pw_name, &valid_old_pwd,
+ smb_pwent = _my_get_smbpwnam(fp, user_name, &valid_old_pwd,
&got_valid_nt_entry, &seekpos);
if (smb_pwent == NULL) {
if(add_user == False) {
fprintf(stderr, "%s: Failed to find entry for user %s in file %s.\n",
- argv[0], pwd->pw_name, pfile);
+ prog_name, pwd->pw_name, pfile);
fclose(fp);
pw_file_unlock(lockfd);
exit(1);
@@ -435,7 +575,7 @@ static void usage(char *name)
if((offpos = lseek(fd, 0, SEEK_END)) == -1) {
fprintf(stderr, "%s: Failed to add entry for user %s to file %s. \
-Error was %s\n", argv[0], pwd->pw_name, pfile, strerror(errno));
+Error was %s\n", prog_name, pwd->pw_name, pfile, strerror(errno));
fclose(fp);
pw_file_unlock(lockfd);
exit(1);
@@ -447,7 +587,7 @@ Error was %s\n", argv[0], pwd->pw_name, pfile, strerror(errno));
strlen(pwd->pw_shell) + 1;
if((new_entry = (char *)malloc( new_entry_length )) == 0) {
fprintf(stderr, "%s: Failed to add entry for user %s to file %s. \
-Error was %s\n", argv[0], pwd->pw_name, pfile, strerror(errno));
+Error was %s\n", prog_name, pwd->pw_name, pfile, strerror(errno));
fclose(fp);
pw_file_unlock(lockfd);
exit(1);
@@ -467,12 +607,12 @@ Error was %s\n", argv[0], pwd->pw_name, pfile, strerror(errno));
pwd->pw_dir, pwd->pw_shell);
if(write(fd, new_entry, strlen(new_entry)) != strlen(new_entry)) {
fprintf(stderr, "%s: Failed to add entry for user %s to file %s. \
-Error was %s\n", argv[0], pwd->pw_name, pfile, strerror(errno));
+Error was %s\n", prog_name, pwd->pw_name, pfile, strerror(errno));
/* Remove the entry we just wrote. */
if(ftruncate(fd, offpos) == -1) {
fprintf(stderr, "%s: ERROR failed to ftruncate file %s. \
Error was %s. Password file may be corrupt ! Please examine by hand !\n",
- argv[0], pwd->pw_name, strerror(errno));
+ prog_name, pwd->pw_name, strerror(errno));
}
fclose(fp);
pw_file_unlock(lockfd);
@@ -488,35 +628,10 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
add_user = False;
}
- /* If we are root or the password is 'NO PASSWORD' then
- we don't need to check the old password. */
- if (real_uid != 0) {
- if (valid_old_pwd == False) {
- fprintf(stderr, "%s: User %s has no old SMB password.\n", argv[0], pwd->pw_name);
- }
- /* Check the old Lanman password - NULL means 'NO PASSWORD' */
- if (smb_pwent->smb_passwd != NULL) {
- if (memcmp(old_p16, smb_pwent->smb_passwd, 16)) {
- fprintf(stderr, "%s: Couldn't change password.\n", argv[0]);
- fclose(fp);
- pw_file_unlock(lockfd);
- exit(1);
- }
- }
- /* Check the NT password if it exists */
- if (smb_pwent->smb_nt_passwd != NULL) {
- if (memcmp(old_nt_p16, smb_pwent->smb_nt_passwd, 16)) {
- fprintf(stderr, "%s: Couldn't change password.\n", argv[0]);
- fclose(fp);
- pw_file_unlock(lockfd);
- exit(1);
- }
- }
- }
/*
- * If we get here either we were root or the old password checked out
- * ok.
+ * We are root - just write the new password.
*/
+
/* Create the 32 byte representation of the new p16 */
for (i = 0; i < 16; i++) {
sprintf(&ascii_p16[i * 2], "%02X", (uchar) new_p16[i]);
@@ -537,10 +652,10 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
if (ret != seekpos - 1) {
err = errno;
fprintf(stderr, "%s: seek fail on file %s.\n",
- argv[0], pfile);
+ prog_name, pfile);
fclose(fp);
errno = err;
- perror(argv[0]);
+ perror(prog_name);
pw_file_unlock(lockfd);
exit(1);
}
@@ -548,16 +663,16 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
if (read(pwfd, &c, 1) != 1) {
err = errno;
fprintf(stderr, "%s: read fail on file %s.\n",
- argv[0], pfile);
+ prog_name, pfile);
fclose(fp);
errno = err;
- perror(argv[0]);
+ perror(prog_name);
pw_file_unlock(lockfd);
exit(1);
}
if (c != ':') {
fprintf(stderr, "%s: sanity check on passwd file %s failed.\n",
- argv[0], pfile);
+ prog_name, pfile);
fclose(fp);
pw_file_unlock(lockfd);
exit(1);
@@ -566,10 +681,10 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
if (write(pwfd, ascii_p16, writelen) != writelen) {
err = errno;
fprintf(stderr, "%s: write fail in file %s.\n",
- argv[0], pfile);
+ prog_name, pfile);
fclose(fp);
errno = err;
- perror(argv[0]);
+ perror(prog_name);
pw_file_unlock(lockfd);
exit(err);
}