1998-03-12 00:11:04 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2002-08-17 20:05:44 +04:00
RPC pipe client
Copyright ( C ) Tim Potter 2000 - 2001 ,
Copyright ( C ) Andrew Tridgell 1992 - 1997 , 2000 ,
Copyright ( C ) Rafal Szczesniak 2002.
2005-09-30 21:13:37 +04:00
Copyright ( C ) Jeremy Allison 2005.
2008-02-27 21:38:48 +03:00
Copyright ( C ) Guenther Deschner 2008.
1998-03-12 00:11:04 +03:00
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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1998-03-12 00:11:04 +03:00
( 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
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1998-03-12 00:11:04 +03:00
*/
# include "includes.h"
2008-06-25 13:50:17 +04:00
/* User change password */
NTSTATUS rpccli_samr_chgpasswd_user ( struct rpc_pipe_client * cli ,
TALLOC_CTX * mem_ctx ,
struct policy_handle * user_handle ,
const char * newpassword ,
const char * oldpassword )
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
struct samr_Password hash1 , hash2 , hash3 , hash4 , hash5 , hash6 ;
uchar old_nt_hash [ 16 ] ;
uchar old_lm_hash [ 16 ] ;
uchar new_nt_hash [ 16 ] ;
uchar new_lm_hash [ 16 ] ;
ZERO_STRUCT ( old_nt_hash ) ;
ZERO_STRUCT ( old_lm_hash ) ;
ZERO_STRUCT ( new_nt_hash ) ;
ZERO_STRUCT ( new_lm_hash ) ;
DEBUG ( 10 , ( " rpccli_samr_chgpasswd_user \n " ) ) ;
E_md4hash ( oldpassword , old_nt_hash ) ;
E_md4hash ( newpassword , new_nt_hash ) ;
E_deshash ( oldpassword , old_lm_hash ) ;
E_deshash ( newpassword , new_lm_hash ) ;
E_old_pw_hash ( new_lm_hash , old_lm_hash , hash1 . hash ) ;
E_old_pw_hash ( old_lm_hash , new_lm_hash , hash2 . hash ) ;
E_old_pw_hash ( new_nt_hash , old_nt_hash , hash3 . hash ) ;
E_old_pw_hash ( old_nt_hash , new_nt_hash , hash4 . hash ) ;
E_old_pw_hash ( old_lm_hash , new_nt_hash , hash5 . hash ) ;
E_old_pw_hash ( old_nt_hash , new_lm_hash , hash6 . hash ) ;
result = rpccli_samr_ChangePasswordUser ( cli , mem_ctx ,
user_handle ,
true ,
& hash1 ,
& hash2 ,
true ,
& hash3 ,
& hash4 ,
true ,
& hash5 ,
true ,
& hash6 ) ;
return result ;
}
2004-01-26 11:45:02 +03:00
/* User change password */
2008-06-25 12:35:59 +04:00
NTSTATUS rpccli_samr_chgpasswd_user2 ( struct rpc_pipe_client * cli ,
TALLOC_CTX * mem_ctx ,
const char * username ,
const char * newpassword ,
const char * oldpassword )
2004-01-26 11:45:02 +03:00
{
2007-10-11 00:34:30 +04:00
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2008-02-06 03:50:01 +03:00
struct samr_CryptPassword new_nt_password ;
struct samr_CryptPassword new_lm_password ;
struct samr_Password old_nt_hash_enc ;
struct samr_Password old_lanman_hash_enc ;
2007-10-11 00:34:30 +04:00
2004-01-26 11:45:02 +03:00
uchar old_nt_hash [ 16 ] ;
uchar old_lanman_hash [ 16 ] ;
uchar new_nt_hash [ 16 ] ;
uchar new_lanman_hash [ 16 ] ;
2008-02-06 03:50:01 +03:00
struct lsa_String server , account ;
2007-10-11 00:34:30 +04:00
2008-06-25 12:35:59 +04:00
DEBUG ( 10 , ( " rpccli_samr_chgpasswd_user2 \n " ) ) ;
2004-01-26 11:45:02 +03:00
2008-04-20 01:03:16 +04:00
init_lsa_String ( & server , cli - > srv_name_slash ) ;
2008-02-06 03:50:01 +03:00
init_lsa_String ( & account , username ) ;
2004-01-26 11:45:02 +03:00
/* Calculate the MD4 hash (NT compatible) of the password */
E_md4hash ( oldpassword , old_nt_hash ) ;
E_md4hash ( newpassword , new_nt_hash ) ;
2008-02-06 03:50:01 +03:00
if ( lp_client_lanman_auth ( ) & &
E_deshash ( newpassword , new_lanman_hash ) & &
E_deshash ( oldpassword , old_lanman_hash ) ) {
2004-01-26 11:45:02 +03:00
/* E_deshash returns false for 'long' passwords (> 14
DOS chars ) . This allows us to match Win2k , which
does not store a LM hash for these passwords ( which
would reduce the effective password length to 14 ) */
2008-02-06 03:50:01 +03:00
encode_pw_buffer ( new_lm_password . data , newpassword , STR_UNICODE ) ;
2004-01-26 11:45:02 +03:00
2008-02-06 03:50:01 +03:00
SamOEMhash ( new_lm_password . data , old_nt_hash , 516 ) ;
E_old_pw_hash ( new_nt_hash , old_lanman_hash , old_lanman_hash_enc . hash ) ;
2004-01-26 11:45:02 +03:00
} else {
ZERO_STRUCT ( new_lm_password ) ;
ZERO_STRUCT ( old_lanman_hash_enc ) ;
}
2008-02-06 03:50:01 +03:00
encode_pw_buffer ( new_nt_password . data , newpassword , STR_UNICODE ) ;
2007-10-11 00:34:30 +04:00
2008-02-06 03:50:01 +03:00
SamOEMhash ( new_nt_password . data , old_nt_hash , 516 ) ;
E_old_pw_hash ( new_nt_hash , old_nt_hash , old_nt_hash_enc . hash ) ;
2007-10-11 00:34:30 +04:00
2008-02-06 03:50:01 +03:00
result = rpccli_samr_ChangePasswordUser2 ( cli , mem_ctx ,
& server ,
& account ,
& new_nt_password ,
& old_nt_hash_enc ,
true ,
& new_lm_password ,
& old_lanman_hash_enc ) ;
2007-10-11 00:34:30 +04:00
return result ;
2004-01-26 11:45:02 +03:00
}
2007-10-11 00:34:30 +04:00
/* User change password given blobs */
2006-07-13 13:29:25 +04:00
NTSTATUS rpccli_samr_chng_pswd_auth_crap ( struct rpc_pipe_client * cli ,
2008-02-06 03:50:01 +03:00
TALLOC_CTX * mem_ctx ,
const char * username ,
DATA_BLOB new_nt_password_blob ,
DATA_BLOB old_nt_hash_enc_blob ,
DATA_BLOB new_lm_password_blob ,
DATA_BLOB old_lm_hash_enc_blob )
2006-07-13 13:29:25 +04:00
{
2007-10-11 00:34:30 +04:00
NTSTATUS result = NT_STATUS_UNSUCCESSFUL ;
2008-02-06 03:50:01 +03:00
struct samr_CryptPassword new_nt_password ;
struct samr_CryptPassword new_lm_password ;
struct samr_Password old_nt_hash_enc ;
struct samr_Password old_lm_hash_enc ;
struct lsa_String server , account ;
2006-07-13 13:29:25 +04:00
2007-10-11 00:34:30 +04:00
DEBUG ( 10 , ( " rpccli_samr_chng_pswd_auth_crap \n " ) ) ;
2006-07-13 13:29:25 +04:00
2008-04-20 01:03:16 +04:00
init_lsa_String ( & server , cli - > srv_name_slash ) ;
2008-02-06 03:50:01 +03:00
init_lsa_String ( & account , username ) ;
memcpy ( & new_nt_password . data , new_nt_password_blob . data , 516 ) ;
memcpy ( & new_lm_password . data , new_lm_password_blob . data , 516 ) ;
memcpy ( & old_nt_hash_enc . hash , old_nt_hash_enc_blob . data , 16 ) ;
memcpy ( & old_lm_hash_enc . hash , old_lm_hash_enc_blob . data , 16 ) ;
result = rpccli_samr_ChangePasswordUser2 ( cli , mem_ctx ,
& server ,
& account ,
& new_nt_password ,
& old_nt_hash_enc ,
true ,
& new_lm_password ,
& old_lm_hash_enc ) ;
2007-10-11 00:34:30 +04:00
return result ;
2006-07-13 13:29:25 +04:00
}
2007-10-11 00:34:30 +04:00
2005-11-30 02:23:02 +03:00
/* change password 3 */
2008-06-25 23:49:57 +04:00
NTSTATUS rpccli_samr_chgpasswd_user3 ( struct rpc_pipe_client * cli ,
TALLOC_CTX * mem_ctx ,
const char * username ,
const char * newpassword ,
const char * oldpassword ,
struct samr_DomInfo1 * * dominfo1 ,
struct samr_ChangeReject * * reject )
2005-11-30 02:23:02 +03:00
{
2008-02-05 22:14:54 +03:00
NTSTATUS status ;
struct samr_CryptPassword new_nt_password ;
struct samr_CryptPassword new_lm_password ;
struct samr_Password old_nt_hash_enc ;
struct samr_Password old_lanman_hash_enc ;
2005-11-30 02:23:02 +03:00
uchar old_nt_hash [ 16 ] ;
uchar old_lanman_hash [ 16 ] ;
uchar new_nt_hash [ 16 ] ;
uchar new_lanman_hash [ 16 ] ;
2008-02-05 22:14:54 +03:00
struct lsa_String server , account ;
2005-11-30 02:23:02 +03:00
2008-06-25 23:49:57 +04:00
DEBUG ( 10 , ( " rpccli_samr_chgpasswd_user3 \n " ) ) ;
2005-11-30 02:23:02 +03:00
2008-04-20 01:03:16 +04:00
init_lsa_String ( & server , cli - > srv_name_slash ) ;
2008-02-05 22:14:54 +03:00
init_lsa_String ( & account , username ) ;
2005-11-30 02:23:02 +03:00
/* Calculate the MD4 hash (NT compatible) of the password */
E_md4hash ( oldpassword , old_nt_hash ) ;
E_md4hash ( newpassword , new_nt_hash ) ;
2008-02-05 22:14:54 +03:00
if ( lp_client_lanman_auth ( ) & &
E_deshash ( newpassword , new_lanman_hash ) & &
E_deshash ( oldpassword , old_lanman_hash ) ) {
2005-11-30 02:23:02 +03:00
/* E_deshash returns false for 'long' passwords (> 14
DOS chars ) . This allows us to match Win2k , which
does not store a LM hash for these passwords ( which
would reduce the effective password length to 14 ) */
2008-02-05 22:14:54 +03:00
encode_pw_buffer ( new_lm_password . data , newpassword , STR_UNICODE ) ;
2005-11-30 02:23:02 +03:00
2008-02-05 22:14:54 +03:00
SamOEMhash ( new_lm_password . data , old_nt_hash , 516 ) ;
E_old_pw_hash ( new_nt_hash , old_lanman_hash , old_lanman_hash_enc . hash ) ;
2005-11-30 02:23:02 +03:00
} else {
ZERO_STRUCT ( new_lm_password ) ;
ZERO_STRUCT ( old_lanman_hash_enc ) ;
}
2008-02-05 22:14:54 +03:00
encode_pw_buffer ( new_nt_password . data , newpassword , STR_UNICODE ) ;
SamOEMhash ( new_nt_password . data , old_nt_hash , 516 ) ;
E_old_pw_hash ( new_nt_hash , old_nt_hash , old_nt_hash_enc . hash ) ;
status = rpccli_samr_ChangePasswordUser3 ( cli , mem_ctx ,
& server ,
& account ,
& new_nt_password ,
& old_nt_hash_enc ,
true ,
& new_lm_password ,
& old_lanman_hash_enc ,
NULL ,
dominfo1 ,
reject ) ;
return status ;
2005-11-30 02:23:02 +03:00
}
2003-01-29 23:15:35 +03:00
/* This function returns the bizzare set of (max_entries, max_size) required
for the QueryDisplayInfo RPC to actually work against a domain controller
with large ( 10 k and higher ) numbers of users . These values were
obtained by inspection using ethereal and NT4 running User Manager . */
void get_query_dispinfo_params ( int loop_count , uint32 * max_entries ,
uint32 * max_size )
{
switch ( loop_count ) {
case 0 :
* max_entries = 512 ;
* max_size = 16383 ;
break ;
case 1 :
* max_entries = 1024 ;
* max_size = 32766 ;
break ;
case 2 :
* max_entries = 2048 ;
* max_size = 65532 ;
break ;
case 3 :
* max_entries = 4096 ;
* max_size = 131064 ;
break ;
default : /* loop_count >= 4 */
* max_entries = 4096 ;
* max_size = 131071 ;
break ;
}
2006-09-18 23:18:29 +04:00
}
2008-04-04 03:40:29 +04:00
NTSTATUS rpccli_try_samr_connects ( struct rpc_pipe_client * cli ,
TALLOC_CTX * mem_ctx ,
uint32_t access_mask ,
POLICY_HND * connect_pol )
{
NTSTATUS status ;
union samr_ConnectInfo info_in , info_out ;
struct samr_ConnectInfo1 info1 ;
uint32_t lvl_out = 0 ;
ZERO_STRUCT ( info1 ) ;
info1 . client_version = SAMR_CONNECT_W2K ;
info_in . info1 = info1 ;
status = rpccli_samr_Connect5 ( cli , mem_ctx ,
2008-04-20 01:03:16 +04:00
cli - > srv_name_slash ,
2008-04-04 03:40:29 +04:00
access_mask ,
1 ,
& info_in ,
& lvl_out ,
& info_out ,
connect_pol ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
return status ;
}
status = rpccli_samr_Connect4 ( cli , mem_ctx ,
2008-04-20 01:03:16 +04:00
cli - > srv_name_slash ,
2008-04-04 03:40:29 +04:00
SAMR_CONNECT_W2K ,
access_mask ,
connect_pol ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
return status ;
}
status = rpccli_samr_Connect2 ( cli , mem_ctx ,
2008-04-20 01:03:16 +04:00
cli - > srv_name_slash ,
2008-04-04 03:40:29 +04:00
access_mask ,
connect_pol ) ;
return status ;
}