summaryrefslogtreecommitdiff
path: root/source3/libsmb
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
commit7abbf368f908cacdb2978e33069e49755e54faa8 (patch)
treeb723cf86b9d578b80691dc76e8bdd8d77e16e285 /source3/libsmb
parentda050244c305c1e03e2f3fb2ac02f6bc93ad47ca (diff)
downloadsamba-7abbf368f908cacdb2978e33069e49755e54faa8.tar.gz
samba-7abbf368f908cacdb2978e33069e49755e54faa8.tar.bz2
samba-7abbf368f908cacdb2978e33069e49755e54faa8.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. (This used to be commit 20770b6f1c25288e90d3e0d215afa7f0809ce124)
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/clientgen.c100
-rw-r--r--source3/libsmb/smbdes.c10
2 files changed, 107 insertions, 3 deletions
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 4585c8a544..dcebf70455 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/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/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c
index 8f95a5a297..e5d8f4a1e0 100644
--- a/source3/libsmb/smbdes.c
+++ b/source3/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;