diff options
author | Jeremy Allison <jra@samba.org> | 1998-03-19 20:06:47 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 1998-03-19 20:06:47 +0000 |
commit | 7abbf368f908cacdb2978e33069e49755e54faa8 (patch) | |
tree | b723cf86b9d578b80691dc76e8bdd8d77e16e285 /source3/libsmb | |
parent | da050244c305c1e03e2f3fb2ac02f6bc93ad47ca (diff) | |
download | samba-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.c | 100 | ||||
-rw-r--r-- | source3/libsmb/smbdes.c | 10 |
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; |