diff options
Diffstat (limited to 'source3')
44 files changed, 150 insertions, 2514 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index bd09be988d..9c6b2df8ff 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -374,7 +374,7 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \ lib/bitmap.o lib/dprintf.o $(UTIL_REG_OBJ) \ lib/wins_srv.o \ lib/util_str.o lib/clobber.o lib/util_sid.o lib/util_uuid.o \ - lib/util_unistr.o lib/util_file.o \ + lib/util_unistr.o ../lib/util/charset/util_unistr.c lib/util_file.o \ lib/util.o lib/util_sock.o lib/sock_exec.o lib/util_sec.o \ lib/substitute.o lib/dbwrap_util.o \ lib/ms_fnmatch.o lib/select.o lib/errmap_unix.o \ @@ -445,15 +445,16 @@ DOSERR_OBJ = ../libcli/util/doserr.o ERRORMAP_OBJ = libsmb/errormap.o DCE_RPC_ERR_OBJ = ../librpc/rpc/dcerpc_error.o -LIBSMB_ERR_OBJ0 = $(NTERR_OBJ) $(DOSERR_OBJ) $(ERRORMAP_OBJ) $(DCE_RPC_ERR_OBJ) \ - libsmb/smbdes.o libsmb/smbencrypt.o libsmb/ntlmssp_parse.o +LIBSMB_ERR_OBJ0 = $(NTERR_OBJ) $(DOSERR_OBJ) $(ERRORMAP_OBJ) $(DCE_RPC_ERR_OBJ) -LIBSMB_ERR_OBJ = $(LIBSMB_ERR_OBJ0) \ +LIBSMB_ERR_OBJ1 = ../libcli/auth/smbdes.o ../libcli/auth/smbencrypt.o ../libcli/auth/msrpc_parse.o + +LIBSMB_ERR_OBJ = $(LIBSMB_ERR_OBJ0) $(LIBSMB_ERR_OBJ1) \ $(RPC_PARSE_OBJ1) \ $(SECRETS_OBJ) LIBSMB_OBJ0 = \ - libsmb/ntlm_check.o \ + ../libcli/auth/ntlm_check.o \ libsmb/ntlmssp.o \ libsmb/ntlmssp_sign.o @@ -481,7 +482,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \ libsmb/clitrans.o libsmb/clisecdesc.o libsmb/clidgram.o \ libsmb/clistr.o libsmb/cliquota.o libsmb/clifsinfo.o libsmb/clidfs.o \ - libsmb/credentials.o \ + libsmb/credentials.o ../libcli/auth/credentials.o \ libsmb/clioplock.o libsmb/clirap2.o \ libsmb/smb_seal.o libsmb/async_smb.o \ $(LIBSAMBA_OBJ) \ @@ -1145,7 +1146,7 @@ LDB_LDAP_OBJ=@LDBLDAP@ LDB_OBJ = ${LDB_COMMON_OBJ} ${LDB_TDB_OBJ} ${LDB_LDAP_OBJ} ${LDB_MODULES_OBJ} LDB_CMDLINE_OBJ = $(PARAM_OBJ) \ - $(POPT_LIB_OBJ) $(LIB_OBJ) $(LIB_DUMMY_OBJ) $(LIBSMB_ERR_OBJ0) \ + $(POPT_LIB_OBJ) $(LIB_OBJ) $(LIB_DUMMY_OBJ) $(LIBSMB_ERR_OBJ0) $(LIBSMB_ERR_OBJ1) \ $(RPC_PARSE_OBJ1) $(SECRETS_OBJ) \ $(LDB_OBJ) lib/ldb/tools/cmdline.o diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index f11dbe60ee..6aca443fe7 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH diff --git a/source3/auth/auth_netlogond.c b/source3/auth/auth_netlogond.c index c39dd8c752..d595e27a60 100644 --- a/source3/auth/auth_netlogond.c +++ b/source3/auth/auth_netlogond.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index f5d61e9a9b..dc15509922 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index cf6588ad82..c55fb70ef2 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH @@ -330,10 +331,10 @@ bool make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, #endif if (lm_interactive_pwd) - SamOEMhash(lm_pwd, key, sizeof(lm_pwd)); + arcfour_crypt(lm_pwd, key, sizeof(lm_pwd)); if (nt_interactive_pwd) - SamOEMhash(nt_pwd, key, sizeof(nt_pwd)); + arcfour_crypt(nt_pwd, key, sizeof(nt_pwd)); #ifdef DEBUG_PASSWORD DEBUG(100,("decrypt of lm owf password:")); diff --git a/source3/include/proto.h b/source3/include/proto.h index b8ba8c03ad..64b1d7c43c 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1782,6 +1782,23 @@ bool create_local_private_krb5_conf_for_domain(const char *realm, const char *sitename, struct sockaddr_storage *pss); + +/* The following definitions come from libsmb/credentials.c */ + +char *credstr(const unsigned char *cred); +void creds_server_init(uint32 neg_flags, + struct dcinfo *dc, + struct netr_Credential *clnt_chal, + struct netr_Credential *srv_chal, + const unsigned char mach_pw[16], + struct netr_Credential *init_chal_out); +bool netlogon_creds_server_check(const struct dcinfo *dc, + const struct netr_Credential *rcv_cli_chal_in); +bool netlogon_creds_server_step(struct dcinfo *dc, + const struct netr_Authenticator *received_cred, + struct netr_Authenticator *cred_out); +void cred_hash3(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw); + /* The following definitions come from libads/kerberos_keytab.c */ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc); @@ -2933,31 +2950,6 @@ void delete_negative_conn_cache(const char *domain, const char *server); void flush_negative_conn_cache( void ); void flush_negative_conn_cache_for_domain(const char *domain); -/* The following definitions come from libsmb/credentials.c */ - -char *credstr(const unsigned char *cred); -void creds_server_init(uint32 neg_flags, - struct dcinfo *dc, - struct netr_Credential *clnt_chal, - struct netr_Credential *srv_chal, - const unsigned char mach_pw[16], - struct netr_Credential *init_chal_out); -bool netlogon_creds_server_check(const struct dcinfo *dc, - const struct netr_Credential *rcv_cli_chal_in); -bool netlogon_creds_server_step(struct dcinfo *dc, - const struct netr_Authenticator *received_cred, - struct netr_Authenticator *cred_out); -void creds_client_init(uint32 neg_flags, - struct dcinfo *dc, - struct netr_Credential *clnt_chal, - struct netr_Credential *srv_chal, - const unsigned char mach_pw[16], - struct netr_Credential *init_chal_out); -bool netlogon_creds_client_check(const struct dcinfo *dc, - const struct netr_Credential *rcv_srv_chal_in); -void netlogon_creds_client_step(struct dcinfo *dc, - struct netr_Authenticator *next_cred_out); - /* The following definitions come from ../librpc/rpc/dcerpc_error.c */ const char *dcerpc_errstr(TALLOC_CTX *mem_ctx, uint32_t fault_code); @@ -3109,21 +3101,6 @@ const char *get_nt_error_c_code(NTSTATUS nt_code); NTSTATUS nt_status_string_to_code(const char *nt_status_str); NTSTATUS nt_status_squash(NTSTATUS nt_status); -/* The following definitions come from libsmb/ntlm_check.c */ - -NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, - const DATA_BLOB *challenge, - const DATA_BLOB *lm_response, - const DATA_BLOB *nt_response, - const DATA_BLOB *lm_interactive_pwd, - const DATA_BLOB *nt_interactive_pwd, - const char *username, - const char *client_username, - const char *client_domain, - const uint8 *lm_pw, const uint8 *nt_pw, - DATA_BLOB *user_sess_key, - DATA_BLOB *lm_sess_key); - /* The following definitions come from libsmb/ntlmssp.c */ void debug_ntlmssp_flags(uint32 neg_flags); @@ -3145,13 +3122,6 @@ DATA_BLOB ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *mem_ctx) NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state); NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state); -/* The following definitions come from libsmb/ntlmssp_parse.c */ - -bool msrpc_gen(DATA_BLOB *blob, - const char *format, ...); -bool msrpc_parse(const DATA_BLOB *blob, - const char *format, ...); - /* The following definitions come from libsmb/ntlmssp_sign.c */ NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, @@ -3235,84 +3205,6 @@ void srv_set_signing(struct smbd_server_connection *conn, const DATA_BLOB user_session_key, const DATA_BLOB response); -/* The following definitions come from libsmb/smbdes.c */ - -void des_crypt56(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw); -void E_P16(const unsigned char *p14,unsigned char *p16); -void E_P24(const unsigned char *p21, const unsigned char *c8, unsigned char *p24); -void D_P16(const unsigned char *p14, const unsigned char *in, unsigned char *out); -void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char *out); -void des_crypt128(unsigned char out[8], const unsigned char in[8], const unsigned char key[16]); -void des_crypt64(unsigned char out[8], const unsigned char in[8], const unsigned char key[8]); -void des_crypt112(unsigned char out[8], const unsigned char in[8], const unsigned char key[14], int forw); -void cred_hash3(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw); -void des_crypt112_16(unsigned char out[16], unsigned char in[16], const unsigned char key[14], int forw); -void SamOEMhash( unsigned char *data, const unsigned char key[16], size_t len); -void SamOEMhashBlob( unsigned char *data, size_t len, DATA_BLOB *key); -void sam_pwd_hash(unsigned int rid, const uchar *in, uchar *out, int forw); - -/* The following definitions come from libsmb/smbencrypt.c */ - -void SMBencrypt_hash(const uchar lm_hash[16], const uchar *c8, uchar p24[24]); -bool SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]); -void E_md4hash(const char *passwd, uchar p16[16]); -void E_md5hash(const uchar salt[16], const uchar nthash[16], uchar hash_out[16]); -bool E_deshash(const char *passwd, uchar p16[16]); -void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]); -bool ntv2_owf_gen(const uchar owf[16], - const char *user_in, const char *domain_in, - bool upper_case_domain, /* Transform the domain into UPPER case */ - uchar kr_buf[16]); -void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24]); -void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p24[24]); -void SMBNTencrypt_hash(const uchar nt_hash[16], uchar *c8, uchar *p24); -void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24); -void SMBOWFencrypt_ntv2(const uchar kr[16], - const DATA_BLOB *srv_chal, - const DATA_BLOB *cli_chal, - uchar resp_buf[16]); -void SMBsesskeygen_ntv2(const uchar kr[16], - const uchar * nt_resp, uint8 sess_key[16]); -void SMBsesskeygen_ntv1(const uchar kr[16], - const uchar * nt_resp, uint8 sess_key[16]); -void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16], - const uchar lm_resp[24], /* only uses 8 */ - uint8 sess_key[16]); -DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, - const char *domain); -bool SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uchar nt_hash[16], - const DATA_BLOB *server_chal, - const DATA_BLOB *names_blob, - DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *user_session_key) ; -bool SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, - const DATA_BLOB *server_chal, - const DATA_BLOB *names_blob, - DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *user_session_key) ; -bool encode_pw_buffer(uint8 buffer[516], const char *password, int string_flags); -bool decode_pw_buffer(TALLOC_CTX *ctx, - uint8 in_buffer[516], - char **pp_new_pwrd, - uint32 *new_pw_len, - int string_flags); -void encode_or_decode_arc4_passwd_buffer(unsigned char pw_buf[532], const DATA_BLOB *psession_key); -void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key, int forward); -char *decrypt_trustdom_secret(uint8_t nt_hash[16], DATA_BLOB *data_in); -void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, - const char *pwd, - DATA_BLOB *session_key, - struct wkssvc_PasswordBuffer **pwd_buf); -WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, - struct wkssvc_PasswordBuffer *pwd_buf, - DATA_BLOB *session_key, - char **pwd); -DATA_BLOB decrypt_drsuapi_blob(TALLOC_CTX *mem_ctx, - const DATA_BLOB *session_key, - bool rcrypt, - uint32_t rid, - const DATA_BLOB *buffer); - /* The following definitions come from libsmb/smberr.c */ const char *smb_dos_err_name(uint8 e_class, uint16 num); diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h index ca58040757..8780169c75 100644 --- a/source3/include/rpc_dce.h +++ b/source3/include/rpc_dce.h @@ -88,51 +88,6 @@ enum RPC_PKT_TYPE { #define RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN 0x20 #define RPC_AUTH_SCHANNEL_SIGN_ONLY_CHK_LEN 0x18 -/* The 7 here seems to be required to get Win2k not to downgrade us - to NT4. Actually, anything other than 1ff would seem to do... */ -#define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff -/* - (NETLOGON_NEG_ACCOUNT_LOCKOUT | - NETLOGON_NEG_PERSISTENT_SAMREPL | - NETLOGON_NEG_ARCFOUR | - NETLOGON_NEG_PROMOTION_COUNT | - NETLOGON_NEG_CHANGELOG_BDC | - NETLOGON_NEG_FULL_SYNC_REPL | - NETLOGON_NEG_MULTIPLE_SIDS | - NETLOGON_NEG_REDO | - NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL | - NETLOGON_NEG_DNS_DOMAIN_TRUSTS | - NETLOGON_NEG_PASSWORD_SET2 | - NETLOGON_NEG_GETDOMAININFO) -*/ -#define NETLOGON_NEG_DOMAIN_TRUST_ACCOUNT 0x2010b000 - -/* these are the flags that ADS clients use */ -#define NETLOGON_NEG_AUTH2_ADS_FLAGS 0x600fffff -/* - (NETLOGON_NEG_ACCOUNT_LOCKOUT | - NETLOGON_NEG_PERSISTENT_SAMREPL | - NETLOGON_NEG_ARCFOUR | - NETLOGON_NEG_PROMOTION_COUNT | - NETLOGON_NEG_CHANGELOG_BDC | - NETLOGON_NEG_FULL_SYNC_REPL | - NETLOGON_NEG_MULTIPLE_SIDS | - NETLOGON_NEG_REDO | - NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL | - NETLOGON_NEG_SEND_PASSWORD_INFO_PDC | - NETLOGON_NEG_GENERIC_PASSTHROUGH | - NETLOGON_NEG_CONCURRENT_RPC | - NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL | - NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL | - NETLOGON_NEG_128BIT | - NETLOGON_NEG_TRANSITIVE_TRUSTS | - NETLOGON_NEG_DNS_DOMAIN_TRUSTS | - NETLOGON_NEG_PASSWORD_SET2 | - NETLOGON_NEG_GETDOMAININFO | - NETLOGON_NEG_CROSS_FOREST_TRUSTS | - NETLOGON_NEG_AUTHENTICATED_RPC_LSASS | - NETLOGON_NEG_SCHANNEL) -*/ enum schannel_direction { SENDER_IS_INITIATOR, diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c index 0c00b8518a..b4dbe3afde 100644 --- a/source3/libnet/libnet_samsync.c +++ b/source3/libnet/libnet_samsync.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libnet/libnet.h" +#include "../lib/crypto/crypto.h" /** * Decrypt and extract the user's passwords. @@ -72,7 +73,7 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, enum ndr_err_code ndr_err; data.data = user->user_private_info.SensitiveData; data.length = user->user_private_info.DataLength; - SamOEMhashBlob(data.data, data.length, session_key); + arcfour_crypt_blob(data.data, data.length, session_key); user->user_private_info.SensitiveData = data.data; user->user_private_info.DataLength = data.length; @@ -127,13 +128,13 @@ static NTSTATUS fix_secret(TALLOC_CTX *mem_ctx, { struct netr_DELTA_SECRET *secret = delta->delta_union.secret; - SamOEMhashBlob(secret->current_cipher.cipher_data, - secret->current_cipher.maxlen, - session_key); - - SamOEMhashBlob(secret->old_cipher.cipher_data, - secret->old_cipher.maxlen, - session_key); + arcfour_crypt_blob(secret->current_cipher.cipher_data, + secret->current_cipher.maxlen, + session_key); + + arcfour_crypt_blob(secret->old_cipher.cipher_data, + secret->old_cipher.maxlen, + session_key); return NT_STATUS_OK; } diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 3f95e77aee..cc8c9ba67f 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -468,7 +468,7 @@ bool cli_oem_change_password(struct cli_state *cli, const char *user, const char DEBUG(100,("make_oem_passwd_hash\n")); dump_data(100, data, 516); #endif - SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); + arcfour_crypt( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); /* * Now place the old password hash in the data. diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 9ba460f869..0d7bde0c09 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -19,6 +19,8 @@ */ #include "includes.h" +#include "../lib/crypto/crypto.h" +#include "libcli/auth/libcli_auth.h" /**************************************************************************** Represent a credential as a string. @@ -278,84 +280,12 @@ bool netlogon_creds_server_step(struct dcinfo *dc, return true; } -/**************************************************************************** - Create a client credential struct. -****************************************************************************/ - -void creds_client_init(uint32 neg_flags, - struct dcinfo *dc, - struct netr_Credential *clnt_chal, - struct netr_Credential *srv_chal, - const unsigned char mach_pw[16], - struct netr_Credential *init_chal_out) -{ - dc->sequence = time(NULL); - - DEBUG(10,("creds_client_init: neg_flags : %x\n", (unsigned int)neg_flags)); - DEBUG(10,("creds_client_init: client chal : %s\n", credstr(clnt_chal->data) )); - DEBUG(10,("creds_client_init: server chal : %s\n", credstr(srv_chal->data) )); - dump_data_pw("creds_client_init: machine pass", (const unsigned char *)mach_pw, 16); - - /* Generate the session key and the next client and server creds. */ - if (neg_flags & NETLOGON_NEG_128BIT) { - creds_init_128(dc, - clnt_chal, - srv_chal, - mach_pw); - } else { - creds_init_64(dc, - clnt_chal, - srv_chal, - mach_pw); - } - - dump_data_pw("creds_client_init: session key", dc->sess_key, 16); - - DEBUG(10,("creds_client_init: clnt : %s\n", credstr(dc->clnt_chal.data) )); - DEBUG(10,("creds_client_init: server : %s\n", credstr(dc->srv_chal.data) )); - DEBUG(10,("creds_client_init: seed : %s\n", credstr(dc->seed_chal.data) )); - - memcpy(init_chal_out->data, dc->clnt_chal.data, 8); -} - -/**************************************************************************** - Check a credential returned by the server. -****************************************************************************/ - -bool netlogon_creds_client_check(const struct dcinfo *dc, - const struct netr_Credential *rcv_srv_chal_in) -{ - if (memcmp(dc->srv_chal.data, rcv_srv_chal_in->data, - sizeof(dc->srv_chal.data))) { - - DEBUG(0,("netlogon_creds_client_check: credentials check failed.\n")); - DEBUGADD(5,("netlogon_creds_client_check: challenge : %s\n", - credstr(rcv_srv_chal_in->data))); - DEBUGADD(5,("calculated: %s\n", credstr(dc->srv_chal.data))); - return false; - } - - DEBUG(10,("netlogon_creds_client_check: credentials check OK.\n")); - - return true; -} - - -/**************************************************************************** - Step the client credentials to the next element in the chain, updating the - current client and server credentials and the seed - produce the next authenticator in the sequence ready to send to - the server -****************************************************************************/ - -void netlogon_creds_client_step(struct dcinfo *dc, - struct netr_Authenticator *next_cred_out) +void cred_hash3(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) { - dc->sequence += 2; - creds_step(dc); - creds_reseed(dc); + unsigned char key2[8]; - memcpy(&next_cred_out->cred.data, &dc->clnt_chal.data, - sizeof(next_cred_out->cred.data)); - next_cred_out->timestamp = dc->sequence; + memset(key2,'\0',8); + des_crypt56(out, in, key, forw); + key2[0] = key[7]; + des_crypt56(out + 8, in + 8, key2, forw); } diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c deleted file mode 100644 index 9380a83ea0..0000000000 --- a/source3/libsmb/ntlm_check.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Password and authentication handling - Copyright (C) Andrew Tridgell 1992-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Andrew Bartlett 2001-2003 - Copyright (C) Gerald Carter 2003 - - 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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - -/**************************************************************************** - Core of smb password checking routine. -****************************************************************************/ - -static bool smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, - const uchar *part_passwd, - const DATA_BLOB *sec_blob, - DATA_BLOB *user_sess_key) -{ - /* Finish the encryption of part_passwd. */ - uchar p24[24]; - - if (part_passwd == NULL) { - DEBUG(10,("No password set - DISALLOWING access\n")); - /* No password set - always false ! */ - return false; - } - - if (sec_blob->length != 8) { - DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%lu)\n", - (unsigned long)sec_blob->length)); - return false; - } - - if (nt_response->length != 24) { - DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%lu)\n", - (unsigned long)nt_response->length)); - return false; - } - - SMBOWFencrypt(part_passwd, sec_blob->data, p24); - if (user_sess_key != NULL) { - *user_sess_key = data_blob(NULL, 16); - SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key->data); - } - - -#if DEBUG_PASSWORD - DEBUG(100,("Part password (P16) was |\n")); - dump_data(100, part_passwd, 16); - DEBUGADD(100,("Password from client was |\n")); - dump_data(100, nt_response->data, nt_response->length); - DEBUGADD(100,("Given challenge was |\n")); - dump_data(100, sec_blob->data, sec_blob->length); - DEBUGADD(100,("Value from encryption was |\n")); - dump_data(100, p24, 24); -#endif - return (memcmp(p24, nt_response->data, 24) == 0); -} - -/**************************************************************************** - Core of smb password checking routine. (NTLMv2, LMv2) - Note: The same code works with both NTLMv2 and LMv2. -****************************************************************************/ - -static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx, - const DATA_BLOB *ntv2_response, - const uint8_t *part_passwd, - const DATA_BLOB *sec_blob, - const char *user, const char *domain, - bool upper_case_domain, /* should the domain be transformed into upper case? */ - DATA_BLOB *user_sess_key) -{ - /* Finish the encryption of part_passwd. */ - uint8_t kr[16]; - uint8_t value_from_encryption[16]; - uint8_t client_response[16]; - DATA_BLOB client_key_data; - bool res; - - if (part_passwd == NULL) { - DEBUG(10,("No password set - DISALLOWING access\n")); - /* No password set - always false */ - return false; - } - - if (sec_blob->length != 8) { - DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect challenge size (%lu)\n", - (unsigned long)sec_blob->length)); - return false; - } - - if (ntv2_response->length < 24) { - /* We MUST have more than 16 bytes, or the stuff below will go - crazy. No known implementation sends less than the 24 bytes - for LMv2, let alone NTLMv2. */ - DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", - (unsigned long)ntv2_response->length)); - return false; - } - - client_key_data = data_blob_talloc(mem_ctx, ntv2_response->data+16, ntv2_response->length-16); - /* - todo: should we be checking this for anything? We can't for LMv2, - but for NTLMv2 it is meant to contain the current time etc. - */ - - memcpy(client_response, ntv2_response->data, sizeof(client_response)); - - if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) { - return false; - } - - SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); - if (user_sess_key != NULL) { - *user_sess_key = data_blob(NULL, 16); - SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data); - } - -#if DEBUG_PASSWORD - DEBUG(100,("Part password (P16) was |\n")); - dump_data(100, part_passwd, 16); - DEBUGADD(100,("Password from client was |\n")); - dump_data(100, ntv2_response->data, ntv2_response->length); - DEBUGADD(100,("Variable data from client was |\n")); - dump_data(100, client_key_data.data, client_key_data.length); - DEBUGADD(100,("Given challenge was |\n")); - dump_data(100, sec_blob->data, sec_blob->length); - DEBUGADD(100,("Value from encryption was |\n")); - dump_data(100, value_from_encryption, 16); -#endif - data_blob_clear_free(&client_key_data); - res = (memcmp(value_from_encryption, client_response, 16) == 0); - if ((!res) && (user_sess_key != NULL)) - data_blob_clear_free(user_sess_key); - return res; -} - -/** - * Check a challenge-response password against the value of the NT or - * LM password hash. - * - * @param mem_ctx talloc context - * @param challenge 8-byte challenge. If all zero, forces plaintext comparison - * @param nt_response 'unicode' NT response to the challenge, or unicode password - * @param lm_response ASCII or LANMAN response to the challenge, or password in DOS code page - * @param username internal Samba username, for log messages - * @param client_username username the client used - * @param client_domain domain name the client used (may be mapped) - * @param nt_pw MD4 unicode password from our passdb or similar - * @param lm_pw LANMAN ASCII password from our passdb or similar - * @param user_sess_key User session key - * @param lm_sess_key LM session key (first 8 bytes of the LM hash) - */ - -NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, - const DATA_BLOB *challenge, - const DATA_BLOB *lm_response, - const DATA_BLOB *nt_response, - const DATA_BLOB *lm_interactive_pwd, - const DATA_BLOB *nt_interactive_pwd, - const char *username, - const char *client_username, - const char *client_domain, - const uint8_t *lm_pw, const uint8_t *nt_pw, - DATA_BLOB *user_sess_key, - DATA_BLOB *lm_sess_key) -{ - unsigned char zeros[8]; - - ZERO_STRUCT(zeros); - - if (nt_pw == NULL) { - DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n", - username)); - } - - if (nt_interactive_pwd && nt_interactive_pwd->length && nt_pw) { - if (nt_interactive_pwd->length != 16) { - DEBUG(3,("ntlm_password_check: Interactive logon: Invalid NT password length (%d) supplied for user %s\n", (int)nt_interactive_pwd->length, - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - if (memcmp(nt_interactive_pwd->data, nt_pw, 16) == 0) { - if (user_sess_key) { - *user_sess_key = data_blob(NULL, 16); - SMBsesskeygen_ntv1(nt_pw, NULL, user_sess_key->data); - } - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: Interactive logon: NT password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - } else if (lm_interactive_pwd && lm_interactive_pwd->length && lm_pw) { - if (lm_interactive_pwd->length != 16) { - DEBUG(3,("ntlm_password_check: Interactive logon: Invalid LANMAN password length (%d) supplied for user %s\n", (int)lm_interactive_pwd->length, - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - if (!lp_lanman_auth()) { - DEBUG(3,("ntlm_password_check: Interactive logon: only LANMAN password supplied for user %s, and LM passwords are disabled!\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - if (memcmp(lm_interactive_pwd->data, lm_pw, 16) == 0) { - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: Interactive logon: LANMAN password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - } - - /* Check for cleartext netlogon. Used by Exchange 5.5. */ - if (challenge->length == sizeof(zeros) && - (memcmp(challenge->data, zeros, challenge->length) == 0 )) { - - DEBUG(4,("ntlm_password_check: checking plaintext passwords for user %s\n", - username)); - if (nt_pw && nt_response->length) { - unsigned char pwhash[16]; - mdfour(pwhash, nt_response->data, nt_response->length); - if (memcmp(pwhash, nt_pw, sizeof(pwhash)) == 0) { - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: NT (Unicode) plaintext password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - } else if (!lp_lanman_auth()) { - DEBUG(3,("ntlm_password_check: (plaintext password check) LANMAN passwords NOT PERMITTED for user %s\n", - username)); - - } else if (lm_pw && lm_response->length) { - uchar dospwd[14]; - uchar p16[16]; - ZERO_STRUCT(dospwd); - - memcpy(dospwd, lm_response->data, MIN(lm_response->length, sizeof(dospwd))); - /* Only the fisrt 14 chars are considered, password need not be null terminated. */ - - /* we *might* need to upper-case the string here */ - E_P16((const unsigned char *)dospwd, p16); - - if (memcmp(p16, lm_pw, sizeof(p16)) == 0) { - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: LANMAN (ASCII) plaintext password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - } else { - DEBUG(3, ("Plaintext authentication for user %s attempted, but neither NT nor LM passwords available\n", username)); - return NT_STATUS_WRONG_PASSWORD; - } - } - - if (nt_response->length != 0 && nt_response->length < 24) { - DEBUG(2,("ntlm_password_check: invalid NT password length (%lu) for user %s\n", - (unsigned long)nt_response->length, username)); - } - - if (nt_response->length >= 24 && nt_pw) { - if (nt_response->length > 24) { - /* We have the NT MD4 hash challenge available - see if we can - use it - */ - DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with domain [%s]\n", client_domain)); - if (smb_pwd_check_ntlmv2(mem_ctx, - nt_response, - nt_pw, challenge, - client_username, - client_domain, - False, - user_sess_key)) { - return NT_STATUS_OK; - } - - DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with uppercased version of domain [%s]\n", client_domain)); - if (smb_pwd_check_ntlmv2(mem_ctx, - nt_response, - nt_pw, challenge, - client_username, - client_domain, - true, - user_sess_key)) { - return NT_STATUS_OK; - } - - DEBUG(4,("ntlm_password_check: Checking NTLMv2 password without a domain\n")); - if (smb_pwd_check_ntlmv2(mem_ctx, - nt_response, - nt_pw, challenge, - client_username, - "", - False, - user_sess_key)) { - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: NTLMv2 password check failed\n")); - return NT_STATUS_WRONG_PASSWORD; - } - } - - if (lp_ntlm_auth()) { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - DEBUG(4,("ntlm_password_check: Checking NT MD4 password\n")); - if (smb_pwd_check_ntlmv1(nt_response, - nt_pw, challenge, - user_sess_key)) { - /* The LM session key for this response is not very secure, - so use it only if we otherwise allow LM authentication */ - - if (lp_lanman_auth() && lm_pw) { - uint8_t first_8_lm_hash[16]; - memcpy(first_8_lm_hash, lm_pw, 8); - memset(first_8_lm_hash + 8, '\0', 8); - if (lm_sess_key) { - *lm_sess_key = data_blob(first_8_lm_hash, 16); - } - } - return NT_STATUS_OK; - } else { - DEBUG(3,("ntlm_password_check: NT MD4 password check failed for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - } else { - DEBUG(2,("ntlm_password_check: NTLMv1 passwords NOT PERMITTED for user %s\n", - username)); - /* no return, becouse we might pick up LMv2 in the LM field */ - } - } - - if (lm_response->length == 0) { - DEBUG(3,("ntlm_password_check: NEITHER LanMan nor NT password supplied for user %s\n", - username)); - return NT_STATUS_WRONG_PASSWORD; - } - - if (lm_response->length < 24) { - DEBUG(2,("ntlm_password_check: invalid LanMan password length (%lu) for user %s\n", - (unsigned long)nt_response->length, username)); - return NT_STATUS_WRONG_PASSWORD; - } - - if (!lp_lanman_auth()) { - DEBUG(3,("ntlm_password_check: Lanman passwords NOT PERMITTED for user %s\n", - username)); - } else if (!lm_pw) { - DEBUG(3,("ntlm_password_check: NO LanMan password set for user %s (and no NT password supplied)\n", - username)); - } else { - DEBUG(4,("ntlm_password_check: Checking LM password\n")); - if (smb_pwd_check_ntlmv1(lm_response, - lm_pw, challenge, - NULL)) { - uint8_t first_8_lm_hash[16]; - memcpy(first_8_lm_hash, lm_pw, 8); - memset(first_8_lm_hash + 8, '\0', 8); - if (user_sess_key) { - *user_sess_key = data_blob(first_8_lm_hash, 16); - } - - if (lm_sess_key) { - *lm_sess_key = data_blob(first_8_lm_hash, 16); - } - return NT_STATUS_OK; - } - } - - if (!nt_pw) { - DEBUG(4,("ntlm_password_check: LM password check failed for user, no NT password %s\n",username)); - return NT_STATUS_WRONG_PASSWORD; - } - - /* This is for 'LMv2' authentication. almost NTLMv2 but limited to 24 bytes. - - related to Win9X, legacy NAS pass-though authentication - */ - DEBUG(4,("ntlm_password_check: Checking LMv2 password with domain %s\n", client_domain)); - if (smb_pwd_check_ntlmv2(mem_ctx, - lm_response, - nt_pw, challenge, - client_username, - client_domain, - false, - NULL)) { - return NT_STATUS_OK; - } - - DEBUG(4,("ntlm_password_check: Checking LMv2 password with upper-cased version of domain %s\n", client_domain)); - if (smb_pwd_check_ntlmv2(mem_ctx, - lm_response, - nt_pw, challenge, - client_username, - client_domain, - true, - NULL)) { - return NT_STATUS_OK; - } - - DEBUG(4,("ntlm_password_check: Checking LMv2 password without a domain\n")); - if (smb_pwd_check_ntlmv2(mem_ctx, - lm_response, - nt_pw, challenge, - client_username, - "", - false, - NULL)) { - return NT_STATUS_OK; - } - - /* Apparently NT accepts NT responses in the LM field - - I think this is related to Win9X pass-though authentication - */ - DEBUG(4,("ntlm_password_check: Checking NT MD4 password in LM field\n")); - if (lp_ntlm_auth()) { - if (smb_pwd_check_ntlmv1(lm_response, - nt_pw, challenge, - NULL)) { - /* The session key for this response is still very odd. - It not very secure, so use it only if we otherwise - allow LM authentication */ - - if (lp_lanman_auth() && lm_pw) { - uint8_t first_8_lm_hash[16]; - memcpy(first_8_lm_hash, lm_pw, 8); - memset(first_8_lm_hash + 8, '\0', 8); - if (user_sess_key) { - *user_sess_key = data_blob(first_8_lm_hash, 16); - } - - if (lm_sess_key) { - *lm_sess_key = data_blob(first_8_lm_hash, 16); - } - } - return NT_STATUS_OK; - } - DEBUG(3,("ntlm_password_check: LM password, NT MD4 password in LM field and LMv2 failed for user %s\n",username)); - } else { - DEBUG(3,("ntlm_password_check: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",username)); - } - return NT_STATUS_WRONG_PASSWORD; -} - diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 0764f97d85..f9976902d8 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, DATA_BLOB reply, DATA_BLOB *next_request); @@ -873,9 +874,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->session_key = session_key; } else { dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); - SamOEMhash(encrypted_session_key.data, - session_key.data, - encrypted_session_key.length); + arcfour_crypt_blob(encrypted_session_key.data, + encrypted_session_key.length, + &session_key); ntlmssp_state->session_key = data_blob_talloc( ntlmssp_state, encrypted_session_key.data, encrypted_session_key.length); @@ -1079,7 +1080,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, /* not doing NLTM2 without a password */ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } else if (ntlmssp_state->use_ntlmv2) { - if (!struct_blob.length) { /* be lazy, match win2k - we can't do NTLMv2 without it */ DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n")); @@ -1089,11 +1089,13 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, /* TODO: if the remote server is standalone, then we should replace 'domain' with the server name as supplied above */ - if (!SMBNTLMv2encrypt_hash(ntlmssp_state->user, - ntlmssp_state->domain, - ntlmssp_state->nt_hash, &challenge_blob, - &struct_blob, - &lm_response, &nt_response, &session_key)) { + if (!SMBNTLMv2encrypt_hash(ntlmssp_state, + ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->nt_hash, &challenge_blob, + &struct_blob, + &lm_response, &nt_response, NULL, + &session_key)) { data_blob_free(&challenge_blob); data_blob_free(&struct_blob); return NT_STATUS_NO_MEMORY; @@ -1122,12 +1124,12 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, nt_response = data_blob_talloc(ntlmssp_state, NULL, 24); SMBNTencrypt_hash(ntlmssp_state->nt_hash, - session_nonce_hash, - nt_response.data); + session_nonce_hash, + nt_response.data); session_key = data_blob_talloc(ntlmssp_state, NULL, 16); - SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, NULL, user_session_key); + SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, user_session_key); hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); } else { @@ -1150,7 +1152,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, session_key.data); dump_data_pw("LM session key\n", session_key.data, session_key.length); } else { - SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, NULL, session_key.data); + SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, session_key.data); dump_data_pw("NT session key:\n", session_key.data, session_key.length); } } @@ -1166,7 +1168,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, /* Encrypt the new session key with the old one */ encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); - SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length); + arcfour_crypt_blob(encrypted_session_key.data, encrypted_session_key.length, &session_key); dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); /* Mark the new session key as the 'real' session key */ diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c deleted file mode 100644 index 98c50596be..0000000000 --- a/source3/libsmb/ntlmssp_parse.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple kerberos5/SPNEGO routines - Copyright (C) Andrew Tridgell 2001 - Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 - Copyright (C) Andrew Bartlett 2002-2003 - - 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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" - -/* - this is a tiny msrpc packet generator. I am only using this to - avoid tying this code to a particular varient of our rpc code. This - generator is not general enough for all our rpc needs, its just - enough for the spnego/ntlmssp code - - format specifiers are: - - U = unicode string (input is unix string) - a = address (input is char *unix_string) - (1 byte type, 1 byte length, unicode/ASCII string, all inline) - A = ASCII string (input is unix string) - B = data blob (pointer + length) - b = data blob in header (pointer + length) - D - d = word (4 bytes) - C = constant ascii string - */ -bool msrpc_gen(DATA_BLOB *blob, - const char *format, ...) -{ - int i, n; - va_list ap; - char *s; - uint8 *b; - int head_size=0, data_size=0; - int head_ofs, data_ofs; - - /* first scan the format to work out the header and body size */ - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - s = va_arg(ap, char *); - head_size += 8; - data_size += str_charnum(s) * 2; - break; - case 'A': - s = va_arg(ap, char *); - head_size += 8; - data_size += str_ascii_charnum(s); - break; - case 'a': - n = va_arg(ap, int); - s = va_arg(ap, char *); - data_size += (str_charnum(s) * 2) + 4; - break; - case 'B': - b = va_arg(ap, uint8 *); - head_size += 8; - data_size += va_arg(ap, int); - break; - case 'b': - b = va_arg(ap, uint8 *); - head_size += va_arg(ap, int); - break; - case 'd': - n = va_arg(ap, int); - head_size += 4; - break; - case 'C': - s = va_arg(ap, char *); - head_size += str_charnum(s) + 1; - break; - } - } - va_end(ap); - - /* allocate the space, then scan the format - * again to fill in the values */ - - *blob = data_blob(NULL, head_size + data_size); - - head_ofs = 0; - data_ofs = head_size; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - s = va_arg(ap, char *); - n = str_charnum(s); - SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; - SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string_check(blob->data+data_ofs, - s, n*2, STR_UNICODE|STR_NOALIGN); - data_ofs += n*2; - break; - case 'A': - s = va_arg(ap, char *); - n = str_ascii_charnum(s); - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string_check(blob->data+data_ofs, - s, n, STR_ASCII|STR_NOALIGN); - data_ofs += n; - break; - case 'a': - n = va_arg(ap, int); - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - s = va_arg(ap, char *); - n = str_charnum(s); - SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; - if (0 < n) { - push_string_check(blob->data+data_ofs, s, n*2, - STR_UNICODE|STR_NOALIGN); - } - data_ofs += n*2; - break; - - case 'B': - b = va_arg(ap, uint8 *); - n = va_arg(ap, int); - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - if (n && b) /* don't follow null pointers... */ - memcpy(blob->data+data_ofs, b, n); - data_ofs += n; - break; - case 'd': - n = va_arg(ap, int); - SIVAL(blob->data, head_ofs, n); head_ofs += 4; - break; - case 'b': - b = va_arg(ap, uint8 *); - n = va_arg(ap, int); - memcpy(blob->data + head_ofs, b, n); - head_ofs += n; - break; - case 'C': - s = va_arg(ap, char *); - n = str_charnum(s) + 1; - head_ofs += push_string_check(blob->data+head_ofs, s, n, - STR_ASCII|STR_TERMINATE); - break; - } - } - va_end(ap); - - return true; -} - - -/* a helpful macro to avoid running over the end of our blob */ -#define NEED_DATA(amount) \ -if ((head_ofs + amount) > blob->length) { \ - va_end(ap); \ - return False; \ -} - -/* - this is a tiny msrpc packet parser. This the the partner of msrpc_gen - - format specifiers are: - - U = unicode string (output is unix string) - A = ascii string - B = data blob - b = data blob in header - d = word (4 bytes) - C = constant ascii string - */ - -bool msrpc_parse(const DATA_BLOB *blob, - const char *format, ...) -{ - int i; - va_list ap; - char **ps, *s; - DATA_BLOB *b; - size_t head_ofs = 0; - uint16 len1, len2; - uint32 ptr; - uint32 *v; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - ps = va_arg(ap, char **); - if (len1 == 0 && len2 == 0) { - *ps = smb_xstrdup(""); - } else { - /* make sure its in the right format - * be strict */ - if ((len1 != len2) || (ptr + len1 < ptr) || - (ptr + len1 < len1) || - (ptr + len1 > blob->length)) { - va_end(ap); - return false; - } - if (len1 & 1) { - /* if odd length and unicode */ - va_end(ap); - return false; - } - if (blob->data + ptr < - (uint8 *)(unsigned long)ptr || - blob->data + ptr < blob->data) { - va_end(ap); - return false; - } - - if (0 < len1) { - char *p = NULL; - pull_string_talloc(talloc_tos(), - NULL, - 0, - &p, - blob->data + ptr, - len1, - STR_UNICODE|STR_NOALIGN); - if (p) { - (*ps) = smb_xstrdup(p); - TALLOC_FREE(p); - } else { - (*ps) = smb_xstrdup(""); - } - } else { - (*ps) = smb_xstrdup(""); - } - } - break; - case 'A': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - ps = va_arg(ap, char **); - /* make sure its in the right format - be strict */ - if (len1 == 0 && len2 == 0) { - *ps = smb_xstrdup(""); - } else { - if ((len1 != len2) || (ptr + len1 < ptr) || - (ptr + len1 < len1) || - (ptr + len1 > blob->length)) { - va_end(ap); - return false; - } - - if (blob->data + ptr < - (uint8 *)(unsigned long)ptr || - blob->data + ptr < blob->data) { - va_end(ap); - return false; - } - - if (0 < len1) { - char *p = NULL; - pull_string_talloc(talloc_tos(), - NULL, - 0, - &p, - blob->data + ptr, - len1, - STR_ASCII|STR_NOALIGN); - if (p) { - (*ps) = smb_xstrdup(p); - TALLOC_FREE(p); - } else { - (*ps) = smb_xstrdup(""); - } - } else { - (*ps) = smb_xstrdup(""); - } - } - break; - case 'B': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - b = (DATA_BLOB *)va_arg(ap, void *); - if (len1 == 0 && len2 == 0) { - *b = data_blob_null; - } else { - /* make sure its in the right format - * be strict */ - if ((len1 != len2) || (ptr + len1 < ptr) || - (ptr + len1 < len1) || - (ptr + len1 > blob->length)) { - va_end(ap); - return false; - } - - if (blob->data + ptr < - (uint8 *)(unsigned long)ptr || - blob->data + ptr < blob->data) { - va_end(ap); - return false; - } - - *b = data_blob(blob->data + ptr, len1); - } - break; - case 'b': - b = (DATA_BLOB *)va_arg(ap, void *); - len1 = va_arg(ap, unsigned); - /* make sure its in the right format - be strict */ - NEED_DATA(len1); - if (blob->data + head_ofs < (uint8 *)head_ofs || - blob->data + head_ofs < blob->data) { - va_end(ap); - return false; - } - - *b = data_blob(blob->data + head_ofs, len1); - head_ofs += len1; - break; - case 'd': - v = va_arg(ap, uint32 *); - NEED_DATA(4); - *v = IVAL(blob->data, head_ofs); head_ofs += 4; - break; - case 'C': - s = va_arg(ap, char *); - - if (blob->data + head_ofs < (uint8 *)head_ofs || - blob->data + head_ofs < blob->data) { - va_end(ap); - return false; - } - - { - char *p = NULL; - size_t ret = pull_string_talloc(talloc_tos(), - NULL, - 0, - &p, - blob->data+head_ofs, - blob->length - head_ofs, - STR_ASCII|STR_TERMINATE); - if (ret == (size_t)-1 || p == NULL) { - va_end(ap); - return false; - } - head_ofs += ret; - if (strcmp(s, p) != 0) { - TALLOC_FREE(p); - va_end(ap); - return false; - } - TALLOC_FREE(p); - } - break; - } - } - va_end(ap); - - return True; -} diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c deleted file mode 100644 index 8087d66799..0000000000 --- a/source3/libsmb/smbdes.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - a partial implementation of DES designed for use in the - SMB authentication protocol - - 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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" - -/* NOTES: - - This code makes no attempt to be fast! In fact, it is a very - slow implementation - - This code is NOT a complete DES implementation. It implements only - the minimum necessary for SMB authentication, as used by all SMB - products (including every copy of Microsoft Windows95 ever sold) - - In particular, it can only do a unchained forward DES pass. This - means it is not possible to use this code for encryption/decryption - of data, instead it is only useful as a "hash" algorithm. - - There is no entry point into this code that allows normal DES operation. - - I believe this means that this code does not come under ITAR - regulations but this is NOT a legal opinion. If you are concerned - about the applicability of ITAR regulations to this code then you - should confirm it for yourself (and maybe let me know if you come - up with a different answer to the one above) -*/ - - -#define uchar unsigned char - -static const uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, - 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4}; - -static const uchar perm2[48] = {14, 17, 11, 24, 1, 5, - 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, - 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, - 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, - 46, 42, 50, 36, 29, 32}; - -static const uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7}; - -static const uchar perm4[48] = { 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1}; - -static const uchar perm5[32] = { 16, 7, 20, 21, - 29, 12, 28, 17, - 1, 15, 23, 26, - 5, 18, 31, 10, - 2, 8, 24, 14, - 32, 27, 3, 9, - 19, 13, 30, 6, - 22, 11, 4, 25}; - - -static const uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, - 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, - 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, - 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, - 33, 1, 41, 9, 49, 17, 57, 25}; - - -static const uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; - -static const uchar sbox[8][4][16] = { - {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, - {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, - {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, - {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, - - {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, - {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, - {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, - {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, - - {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, - {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, - {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, - {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, - - {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, - {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, - {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, - {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, - - {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, - {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, - {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, - {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, - - {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, - {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, - {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, - {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, - - {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, - {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, - {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, - {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, - - {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, - {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, - {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, - {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; - -static void permute(char *out, const char *in, const uchar *p, int n) -{ - int i; - for (i=0;i<n;i++) - out[i] = in[p[i]-1]; -} - -static void lshift(char *d, int count, int n) -{ - char out[64]; - int i; - for (i=0;i<n;i++) - out[i] = d[(i+count)%n]; - for (i=0;i<n;i++) - d[i] = out[i]; -} - -static void concat(char *out, char *in1, char *in2, int l1, int l2) -{ - while (l1--) - *out++ = *in1++; - while (l2--) - *out++ = *in2++; -} - -static void x_or(char *out, char *in1, char *in2, int n) -{ - int i; - for (i=0;i<n;i++) - out[i] = in1[i] ^ in2[i]; -} - -static void dohash(char *out, char *in, char *key, int forw) -{ - int i, j, k; - char pk1[56]; - char c[28]; - char d[28]; - char cd[56]; - char ki[16][48]; - char pd1[64]; - char l[32], r[32]; - char rl[64]; - - permute(pk1, key, perm1, 56); - - for (i=0;i<28;i++) - c[i] = pk1[i]; - for (i=0;i<28;i++) - d[i] = pk1[i+28]; - - for (i=0;i<16;i++) { - lshift(c, sc[i], 28); - lshift(d, sc[i], 28); - - concat(cd, c, d, 28, 28); - permute(ki[i], cd, perm2, 48); - } - - permute(pd1, in, perm3, 64); - - for (j=0;j<32;j++) { - l[j] = pd1[j]; - r[j] = pd1[j+32]; - } - - for (i=0;i<16;i++) { - char er[48]; - char erk[48]; - char b[8][6]; - char cb[32]; - char pcb[32]; - char r2[32]; - - permute(er, r, perm4, 48); - - x_or(erk, er, ki[forw ? i : 15 - i], 48); - - for (j=0;j<8;j++) - for (k=0;k<6;k++) - b[j][k] = erk[j*6 + k]; - - for (j=0;j<8;j++) { - int m, n; - m = (b[j][0]<<1) | b[j][5]; - - n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4]; - - for (k=0;k<4;k++) - b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0; - } - - for (j=0;j<8;j++) - for (k=0;k<4;k++) - cb[j*4+k] = b[j][k]; - permute(pcb, cb, perm5, 32); - - x_or(r2, l, pcb, 32); - - for (j=0;j<32;j++) - l[j] = r[j]; - - for (j=0;j<32;j++) - r[j] = r2[j]; - } - - concat(rl, r, l, 32, 32); - - permute(out, rl, perm6, 64); -} - -/* Convert a 7 byte string to an 8 byte key. */ -static void str_to_key(const unsigned char str[7], unsigned char key[8]) -{ - int i; - - key[0] = str[0]>>1; - key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); - key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); - key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); - key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); - key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); - key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); - key[7] = str[6]&0x7F; - for (i=0;i<8;i++) { - key[i] = (key[i]<<1); - } -} - - -void des_crypt56(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) -{ - int i; - char outb[64]; - char inb[64]; - char keyb[64]; - unsigned char key2[8]; - - str_to_key(key, key2); - - for (i=0;i<64;i++) { - inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0; - keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0; - outb[i] = 0; - } - - dohash(outb, inb, keyb, forw); - - for (i=0;i<8;i++) { - out[i] = 0; - } - - for (i=0;i<64;i++) { - if (outb[i]) - out[i/8] |= (1<<(7-(i%8))); - } -} - -void E_P16(const unsigned char *p14,unsigned char *p16) -{ - unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; - des_crypt56(p16, sp8, p14, 1); - des_crypt56(p16+8, sp8, p14+7, 1); -} - -void E_P24(const unsigned char *p21, const unsigned char *c8, unsigned char *p24) -{ - des_crypt56(p24, c8, p21, 1); - des_crypt56(p24+8, c8, p21+7, 1); - des_crypt56(p24+16, c8, p21+14, 1); -} - -void D_P16(const unsigned char *p14, const unsigned char *in, unsigned char *out) -{ - des_crypt56(out, in, p14, 0); - des_crypt56(out+8, in+8, p14+7, 0); -} - -void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char *out) -{ - des_crypt56(out, in, p14, 1); - des_crypt56(out+8, in+8, p14+7, 1); -} - -/* forward des encryption with a 128 bit key */ -void des_crypt128(unsigned char out[8], const unsigned char in[8], const unsigned char key[16]) -{ - unsigned char buf[8]; - - des_crypt56(buf, in, key, 1); - des_crypt56(out, buf, key+9, 1); -} - -/* forward des encryption with a 64 bit key */ -void des_crypt64(unsigned char out[8], const unsigned char in[8], const unsigned char key[8]) -{ - unsigned char buf[8]; - unsigned char key2[8]; - - memset(key2,'\0',8); - des_crypt56(buf, in, key, 1); - key2[0] = key[7]; - des_crypt56(out, buf, key2, 1); -} - -/* des encryption with a 112 bit (14 byte) key */ -/* Note that if the forw is 1, and key is actually 8 bytes of key, followed by 6 bytes of zeros, - this is identical to des_crypt64(). JRA. */ - -void des_crypt112(unsigned char out[8], const unsigned char in[8], const unsigned char key[14], int forw) -{ - unsigned char buf[8]; - des_crypt56(buf, in, key, forw); - des_crypt56(out, buf, key+7, forw); -} - -void cred_hash3(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) -{ - unsigned char key2[8]; - - memset(key2,'\0',8); - des_crypt56(out, in, key, forw); - key2[0] = key[7]; - des_crypt56(out + 8, in + 8, key2, forw); -} - -/* des encryption of a 16 byte lump of data with a 112 bit key */ -/* Note that if the key is actually 8 bytes of key, followed by 6 bytes of zeros, - this is identical to cred_hash3(). JRA. */ - -void des_crypt112_16(unsigned char out[16], unsigned char in[16], const unsigned char key[14], int forw) -{ - des_crypt56(out, in, key, forw); - des_crypt56(out + 8, in + 8, key+7, forw); -} - -/***************************************************************** - arc4 crypt/decrypt with a 16 byte key. -*****************************************************************/ - -void SamOEMhash( unsigned char *data, const unsigned char key[16], size_t len) -{ - struct arcfour_state arc4_state; - const DATA_BLOB keyblob = data_blob_const(key, 16); - - arcfour_init(&arc4_state, &keyblob); - arcfour_crypt_sbox(&arc4_state, data, len); -} - -void SamOEMhashBlob( unsigned char *data, size_t len, DATA_BLOB *key) -{ - struct arcfour_state arc4_state; - - arcfour_init(&arc4_state, key); - arcfour_crypt_sbox(&arc4_state, data, len); -} - -/* Decode a sam password hash into a password. The password hash is the - same method used to store passwords in the NT registry. The DES key - used is based on the RID of the user. */ - -void sam_pwd_hash(unsigned int rid, const uchar *in, uchar *out, int forw) -{ - uchar s[14]; - - s[0] = s[4] = s[8] = s[12] = (uchar)(rid & 0xFF); - s[1] = s[5] = s[9] = s[13] = (uchar)((rid >> 8) & 0xFF); - s[2] = s[6] = s[10] = (uchar)((rid >> 16) & 0xFF); - s[3] = s[7] = s[11] = (uchar)((rid >> 24) & 0xFF); - - des_crypt56(out, in, s, forw); - des_crypt56(out+8, in+8, s+7, forw); -} diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c deleted file mode 100644 index 27702b9f42..0000000000 --- a/source3/libsmb/smbencrypt.c +++ /dev/null @@ -1,898 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB parameters and setup - Copyright (C) Andrew Tridgell 1992-1998 - Modified by Jeremy Allison 1995. - Copyright (C) Jeremy Allison 1995-2000. - Copyright (C) Luke Kennethc Casson Leighton 1996-2000. - Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003 - - 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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "../lib/util/byteorder.h" - -void SMBencrypt_hash(const uchar lm_hash[16], const uchar *c8, uchar p24[24]) -{ - uchar p21[21]; - - memset(p21,'\0',21); - memcpy(p21, lm_hash, 16); - - SMBOWFencrypt(p21, c8, p24); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("SMBencrypt_hash: lm#, challenge, response\n")); - dump_data(100, p21, 16); - dump_data(100, c8, 8); - dump_data(100, p24, 24); -#endif -} - -/* - This implements the X/Open SMB password encryption - It takes a password ('unix' string), a 8 byte "crypt key" - and puts 24 bytes of encrypted password into p24 - - Returns False if password must have been truncated to create LM hash -*/ - -bool SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) -{ - bool ret; - uchar lm_hash[16]; - - ret = E_deshash(passwd, lm_hash); - SMBencrypt_hash(lm_hash, c8, p24); - return ret; -} - -/** - * Creates the MD4 Hash of the users password in NT UNICODE. - * @param passwd password in 'unix' charset. - * @param p16 return password hashed with md4, caller allocated 16 byte buffer - */ - -void E_md4hash(const char *passwd, uchar p16[16]) -{ - int len; - smb_ucs2_t wpwd[129]; - - /* Password must be converted to NT unicode - null terminated. */ - push_ucs2(NULL, wpwd, (const char *)passwd, 256, STR_UNICODE|STR_NOALIGN|STR_TERMINATE); - /* Calculate length in bytes */ - len = strlen_w(wpwd) * sizeof(int16); - - mdfour(p16, (unsigned char *)wpwd, len); - ZERO_STRUCT(wpwd); -} - -/** - * Creates the MD5 Hash of a combination of 16 byte salt and 16 byte NT hash. - * @param 16 byte salt. - * @param 16 byte NT hash. - * @param 16 byte return hashed with md5, caller allocated 16 byte buffer - */ - -void E_md5hash(const uchar salt[16], const uchar nthash[16], uchar hash_out[16]) -{ - struct MD5Context tctx; - uchar array[32]; - - memset(hash_out, '\0', 16); - memcpy(array, salt, 16); - memcpy(&array[16], nthash, 16); - MD5Init(&tctx); - MD5Update(&tctx, array, 32); - MD5Final(hash_out, &tctx); -} - -/** - * Creates the DES forward-only Hash of the users password in DOS ASCII charset - * @param passwd password in 'unix' charset. - * @param p16 return password hashed with DES, caller allocated 16 byte buffer - * @return False if password was > 14 characters, and therefore may be incorrect, otherwise True - * @note p16 is filled in regardless - */ - -bool E_deshash(const char *passwd, uchar p16[16]) -{ - bool ret = True; - fstring dospwd; - ZERO_STRUCT(dospwd); - - /* Password must be converted to DOS charset - null terminated, uppercase. */ - push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); - - /* Only the fisrt 14 chars are considered, password need not be null terminated. */ - E_P16((const unsigned char *)dospwd, p16); - - if (strlen(dospwd) > 14) { - ret = False; - } - - ZERO_STRUCT(dospwd); - - return ret; -} - -/** - * Creates the MD4 and DES (LM) Hash of the users password. - * MD4 is of the NT Unicode, DES is of the DOS UPPERCASE password. - * @param passwd password in 'unix' charset. - * @param nt_p16 return password hashed with md4, caller allocated 16 byte buffer - * @param p16 return password hashed with des, caller allocated 16 byte buffer - */ - -/* Does both the NT and LM owfs of a user's password */ -void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) -{ - /* Calculate the MD4 hash (NT compatible) of the password */ - memset(nt_p16, '\0', 16); - E_md4hash(pwd, nt_p16); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); - dump_data(120, (uint8 *)pwd, strlen(pwd)); - dump_data(100, nt_p16, 16); -#endif - - E_deshash(pwd, (uchar *)p16); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); - dump_data(120, (uint8 *)pwd, strlen(pwd)); - dump_data(100, p16, 16); -#endif -} - -/* Does both the NTLMv2 owfs of a user's password */ -bool ntv2_owf_gen(const uchar owf[16], - const char *user_in, const char *domain_in, - bool upper_case_domain, /* Transform the domain into UPPER case */ - uchar kr_buf[16]) -{ - smb_ucs2_t *user; - smb_ucs2_t *domain; - - size_t user_byte_len; - size_t domain_byte_len; - - HMACMD5Context ctx; - - if (!push_ucs2_talloc(NULL, &user, user_in, &user_byte_len)) { - DEBUG(0, ("push_uss2_talloc() for user failed: %s\n", - strerror(errno))); - return False; - } - - if (!push_ucs2_talloc(NULL, &domain, domain_in, &domain_byte_len)) { - DEBUG(0, ("push_uss2_talloc() for domain failed: %s\n", - strerror(errno))); - TALLOC_FREE(user); - return False; - } - - strupper_w(user); - - if (upper_case_domain) - strupper_w(domain); - - SMB_ASSERT(user_byte_len >= 2); - SMB_ASSERT(domain_byte_len >= 2); - - /* We don't want null termination */ - user_byte_len = user_byte_len - 2; - domain_byte_len = domain_byte_len - 2; - - hmac_md5_init_limK_to_64(owf, 16, &ctx); - hmac_md5_update((const unsigned char *)user, user_byte_len, &ctx); - hmac_md5_update((const unsigned char *)domain, domain_byte_len, &ctx); - hmac_md5_final(kr_buf, &ctx); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); - dump_data(100, (uint8 *)user, user_byte_len); - dump_data(100, (uint8 *)domain, domain_byte_len); - dump_data(100, (uint8 *)owf, 16); - dump_data(100, (uint8 *)kr_buf, 16); -#endif - - TALLOC_FREE(user); - TALLOC_FREE(domain); - return True; -} - -/* Does the des encryption from the NT or LM MD4 hash. */ -void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24]) -{ - uchar p21[21]; - - ZERO_STRUCT(p21); - - memcpy(p21, passwd, 16); - E_P24(p21, c8, p24); -} - -/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ -void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p24[24]) -{ - uchar p21[21]; - - memset(p21,'\0',21); - memcpy(p21, passwd, 8); - memset(p21 + 8, 0xbd, 8); - - E_P24(p21, ntlmchalresp, p24); -#ifdef DEBUG_PASSWORD - DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n")); - dump_data(100, p21, 21); - dump_data(100, ntlmchalresp, 8); - dump_data(100, p24, 24); -#endif -} - - -/* Does the des encryption. */ - -void SMBNTencrypt_hash(const uchar nt_hash[16], uchar *c8, uchar *p24) -{ - uchar p21[21]; - - memset(p21,'\0',21); - memcpy(p21, nt_hash, 16); - SMBOWFencrypt(p21, c8, p24); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); - dump_data(100, p21, 16); - dump_data(100, c8, 8); - dump_data(100, p24, 24); -#endif -} - -/* Does the NT MD4 hash then des encryption. Plaintext version of the above. */ - -void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) -{ - uchar nt_hash[16]; - E_md4hash(passwd, nt_hash); - SMBNTencrypt_hash(nt_hash, c8, p24); -} - -/* Does the md5 encryption from the Key Response for NTLMv2. */ -void SMBOWFencrypt_ntv2(const uchar kr[16], - const DATA_BLOB *srv_chal, - const DATA_BLOB *cli_chal, - uchar resp_buf[16]) -{ - HMACMD5Context ctx; - - hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(srv_chal->data, srv_chal->length, &ctx); - hmac_md5_update(cli_chal->data, cli_chal->length, &ctx); - hmac_md5_final(resp_buf, &ctx); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); - dump_data(100, srv_chal->data, srv_chal->length); - dump_data(100, cli_chal->data, cli_chal->length); - dump_data(100, resp_buf, 16); -#endif -} - -void SMBsesskeygen_ntv2(const uchar kr[16], - const uchar * nt_resp, uint8 sess_key[16]) -{ - /* a very nice, 128 bit, variable session key */ - - HMACMD5Context ctx; - - hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(nt_resp, 16, &ctx); - hmac_md5_final((unsigned char *)sess_key, &ctx); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBsesskeygen_ntv2:\n")); - dump_data(100, sess_key, 16); -#endif -} - -void SMBsesskeygen_ntv1(const uchar kr[16], - const uchar * nt_resp, uint8 sess_key[16]) -{ - /* yes, this session key does not change - yes, this - is a problem - but it is 128 bits */ - - mdfour((unsigned char *)sess_key, kr, 16); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBsesskeygen_ntv1:\n")); - dump_data(100, sess_key, 16); -#endif -} - -void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16], - const uchar lm_resp[24], /* only uses 8 */ - uint8 sess_key[16]) -{ - uchar p24[24]; - uchar partial_lm_hash[16]; - - memcpy(partial_lm_hash, lm_hash, 8); - memset(partial_lm_hash + 8, 0xbd, 8); - - SMBOWFencrypt(partial_lm_hash, lm_resp, p24); - - memcpy(sess_key, p24, 16); - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBsesskeygen_lmv1_jerry:\n")); - dump_data(100, sess_key, 16); -#endif -} - -DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, - const char *domain) -{ - DATA_BLOB names_blob = data_blob_null; - - msrpc_gen(&names_blob, "aaa", - NTLMSSP_NAME_TYPE_DOMAIN, domain, - NTLMSSP_NAME_TYPE_SERVER, hostname, - 0, ""); - return names_blob; -} - -static DATA_BLOB NTLMv2_generate_client_data(const DATA_BLOB *names_blob) -{ - uchar client_chal[8]; - DATA_BLOB response = data_blob_null; - char long_date[8]; - - generate_random_buffer(client_chal, sizeof(client_chal)); - - put_long_date(long_date, time(NULL)); - - /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */ - - msrpc_gen(&response, "ddbbdb", - 0x00000101, /* Header */ - 0, /* 'Reserved' */ - long_date, 8, /* Timestamp */ - client_chal, 8, /* client challenge */ - 0, /* Unknown */ - names_blob->data, names_blob->length); /* End of name list */ - - return response; -} - -static DATA_BLOB NTLMv2_generate_response(const uchar ntlm_v2_hash[16], - const DATA_BLOB *server_chal, - const DATA_BLOB *names_blob) -{ - uchar ntlmv2_response[16]; - DATA_BLOB ntlmv2_client_data; - DATA_BLOB final_response; - - /* NTLMv2 */ - /* generate some data to pass into the response function - including - the hostname and domain name of the server */ - ntlmv2_client_data = NTLMv2_generate_client_data(names_blob); - - /* Given that data, and the challenge from the server, generate a response */ - SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response); - - final_response = data_blob(NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length); - - memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response)); - - memcpy(final_response.data+sizeof(ntlmv2_response), - ntlmv2_client_data.data, ntlmv2_client_data.length); - - data_blob_free(&ntlmv2_client_data); - - return final_response; -} - -static DATA_BLOB LMv2_generate_response(const uchar ntlm_v2_hash[16], - const DATA_BLOB *server_chal) -{ - uchar lmv2_response[16]; - DATA_BLOB lmv2_client_data = data_blob(NULL, 8); - DATA_BLOB final_response = data_blob(NULL, 24); - - /* LMv2 */ - /* client-supplied random data */ - generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length); - - /* Given that data, and the challenge from the server, generate a response */ - SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response); - memcpy(final_response.data, lmv2_response, sizeof(lmv2_response)); - - /* after the first 16 bytes is the random data we generated above, - so the server can verify us with it */ - memcpy(final_response.data+sizeof(lmv2_response), - lmv2_client_data.data, lmv2_client_data.length); - - data_blob_free(&lmv2_client_data); - - return final_response; -} - -bool SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uchar nt_hash[16], - const DATA_BLOB *server_chal, - const DATA_BLOB *names_blob, - DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *user_session_key) -{ - uchar ntlm_v2_hash[16]; - - /* We don't use the NT# directly. Instead we use it mashed up with - the username and domain. - This prevents username swapping during the auth exchange - */ - if (!ntv2_owf_gen(nt_hash, user, domain, False, ntlm_v2_hash)) { - return False; - } - - if (nt_response) { - *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, - names_blob); - if (user_session_key) { - *user_session_key = data_blob(NULL, 16); - - /* The NTLMv2 calculations also provide a session key, for signing etc later */ - /* use only the first 16 bytes of nt_response for session key */ - SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, user_session_key->data); - } - } - - /* LMv2 */ - - if (lm_response) { - *lm_response = LMv2_generate_response(ntlm_v2_hash, server_chal); - } - - return True; -} - -/* Plaintext version of the above. */ - -bool SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, - const DATA_BLOB *server_chal, - const DATA_BLOB *names_blob, - DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *user_session_key) -{ - uchar nt_hash[16]; - E_md4hash(password, nt_hash); - - return SMBNTLMv2encrypt_hash(user, domain, nt_hash, - server_chal, - names_blob, - lm_response, nt_response, - user_session_key); -} - -/*********************************************************** - encode a password buffer with a unicode password. The buffer - is filled with random data to make it harder to attack. -************************************************************/ -bool encode_pw_buffer(uint8 buffer[516], const char *password, int string_flags) -{ - uchar new_pw[512]; - size_t new_pw_len; - - /* the incoming buffer can be any alignment. */ - string_flags |= STR_NOALIGN; - - new_pw_len = push_string_check(new_pw, - password, - sizeof(new_pw), string_flags); - - memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); - - generate_random_buffer(buffer, 512 - new_pw_len); - - /* - * The length of the new password is in the last 4 bytes of - * the data buffer. - */ - SIVAL(buffer, 512, new_pw_len); - ZERO_STRUCT(new_pw); - return True; -} - - -/*********************************************************** - decode a password buffer - *new_pw_len is the length in bytes of the possibly mulitbyte - returned password including termination. -************************************************************/ - -bool decode_pw_buffer(TALLOC_CTX *ctx, - uint8 in_buffer[516], - char **pp_new_pwrd, - uint32 *new_pw_len, - int string_flags) -{ - int byte_len=0; - - *pp_new_pwrd = NULL; - *new_pw_len = 0; - - /* the incoming buffer can be any alignment. */ - string_flags |= STR_NOALIGN; - - /* - Warning !!! : This function is called from some rpc call. - The password IN the buffer may be a UNICODE string. - The password IN new_pwrd is an ASCII string - If you reuse that code somewhere else check first. - */ - - /* The length of the new password is in the last 4 bytes of the data buffer. */ - - byte_len = IVAL(in_buffer, 512); - -#ifdef DEBUG_PASSWORD - dump_data(100, in_buffer, 516); -#endif - - /* Password cannot be longer than the size of the password buffer */ - if ( (byte_len < 0) || (byte_len > 512)) { - DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len)); - DEBUG(0, ("decode_pw_buffer: check that 'encrypt passwords = yes'\n")); - return false; - } - - /* decode into the return buffer. */ - *new_pw_len = pull_string_talloc(ctx, - NULL, - 0, - pp_new_pwrd, - &in_buffer[512 - byte_len], - byte_len, - string_flags); - - if (!*pp_new_pwrd || *new_pw_len == 0) { - DEBUG(0, ("decode_pw_buffer: pull_string_talloc failed\n")); - return false; - } - -#ifdef DEBUG_PASSWORD - DEBUG(100,("decode_pw_buffer: new_pwrd: ")); - dump_data(100, (uint8 *)*pp_new_pwrd, *new_pw_len); - DEBUG(100,("multibyte len:%d\n", *new_pw_len)); - DEBUG(100,("original char len:%d\n", byte_len/2)); -#endif - - return true; -} - -/*********************************************************** - Decode an arc4 encrypted password change buffer. -************************************************************/ - -void encode_or_decode_arc4_passwd_buffer(unsigned char pw_buf[532], const DATA_BLOB *psession_key) -{ - struct MD5Context tctx; - unsigned char key_out[16]; - - /* Confounder is last 16 bytes. */ - - MD5Init(&tctx); - MD5Update(&tctx, &pw_buf[516], 16); - MD5Update(&tctx, psession_key->data, psession_key->length); - MD5Final(key_out, &tctx); - /* arc4 with key_out. */ - SamOEMhash(pw_buf, key_out, 516); -} - -/*********************************************************** - Encrypt/Decrypt used for LSA secrets and trusted domain - passwords. -************************************************************/ - -void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key, int forward) -{ - int i, k; - - for (i=0,k=0; - i<in->length; - i += 8, k += 7) { - uint8 bin[8], bout[8], key[7]; - - memset(bin, 0, 8); - memcpy(bin, &in->data[i], MIN(8, in->length-i)); - - if (k + 7 > session_key->length) { - k = (session_key->length - k); - } - memcpy(key, &session_key->data[k], 7); - - des_crypt56(bout, bin, key, forward?1:0); - - memcpy(&out->data[i], bout, MIN(8, in->length-i)); - } -} - -/* Decrypts password-blob with session-key - * @param nt_hash NT hash for the session key - * @param data_in DATA_BLOB encrypted password - * - * Returns cleartext password in CH_UNIX - * Caller must free the returned string - */ - -char *decrypt_trustdom_secret(uint8_t nt_hash[16], DATA_BLOB *data_in) -{ - DATA_BLOB data_out, sess_key; - uint32_t length; - uint32_t version; - fstring cleartextpwd; - - if (!data_in || !nt_hash) - return NULL; - - /* hashed twice with md4 */ - mdfour(nt_hash, nt_hash, 16); - - /* 16-Byte session-key */ - sess_key = data_blob(nt_hash, 16); - if (sess_key.data == NULL) - return NULL; - - data_out = data_blob(NULL, data_in->length); - if (data_out.data == NULL) - return NULL; - - /* decrypt with des3 */ - sess_crypt_blob(&data_out, data_in, &sess_key, 0); - - /* 4 Byte length, 4 Byte version */ - length = IVAL(data_out.data, 0); - version = IVAL(data_out.data, 4); - - if (length > data_in->length - 8) { - DEBUG(0,("decrypt_trustdom_secret: invalid length (%d)\n", length)); - return NULL; - } - - if (version != 1) { - DEBUG(0,("decrypt_trustdom_secret: unknown version number (%d)\n", version)); - return NULL; - } - - rpcstr_pull(cleartextpwd, data_out.data + 8, sizeof(fstring), length, 0 ); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("decrypt_trustdom_secret: length is: %d, version is: %d, password is: %s\n", - length, version, cleartextpwd)); -#endif - - data_blob_free(&data_out); - data_blob_free(&sess_key); - - return SMB_STRDUP(cleartextpwd); - -} - -/* encode a wkssvc_PasswordBuffer: - * - * similar to samr_CryptPasswordEx. Different: 8byte confounder (instead of - * 16byte), confounder in front of the 516 byte buffer (instead of after that - * buffer), calling MD5Update() first with session_key and then with confounder - * (vice versa in samr) - Guenther */ - -void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, - const char *pwd, - DATA_BLOB *session_key, - struct wkssvc_PasswordBuffer **pwd_buf) -{ - uint8_t buffer[516]; - struct MD5Context ctx; - struct wkssvc_PasswordBuffer *my_pwd_buf = NULL; - DATA_BLOB confounded_session_key; - int confounder_len = 8; - uint8_t confounder[8]; - - my_pwd_buf = talloc_zero(mem_ctx, struct wkssvc_PasswordBuffer); - if (!my_pwd_buf) { - return; - } - - confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); - - encode_pw_buffer(buffer, pwd, STR_UNICODE); - - generate_random_buffer((uint8_t *)confounder, confounder_len); - - MD5Init(&ctx); - MD5Update(&ctx, session_key->data, session_key->length); - MD5Update(&ctx, confounder, confounder_len); - MD5Final(confounded_session_key.data, &ctx); - - SamOEMhashBlob(buffer, 516, &confounded_session_key); - - memcpy(&my_pwd_buf->data[0], confounder, confounder_len); - memcpy(&my_pwd_buf->data[8], buffer, 516); - - data_blob_free(&confounded_session_key); - - *pwd_buf = my_pwd_buf; -} - -WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, - struct wkssvc_PasswordBuffer *pwd_buf, - DATA_BLOB *session_key, - char **pwd) -{ - uint8_t buffer[516]; - struct MD5Context ctx; - uint32_t pwd_len; - - DATA_BLOB confounded_session_key; - - int confounder_len = 8; - uint8_t confounder[8]; - - *pwd = NULL; - - if (!pwd_buf) { - return WERR_BAD_PASSWORD; - } - - if (session_key->length != 16) { - DEBUG(10,("invalid session key\n")); - return WERR_BAD_PASSWORD; - } - - confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); - - memcpy(&confounder, &pwd_buf->data[0], confounder_len); - memcpy(&buffer, &pwd_buf->data[8], 516); - - MD5Init(&ctx); - MD5Update(&ctx, session_key->data, session_key->length); - MD5Update(&ctx, confounder, confounder_len); - MD5Final(confounded_session_key.data, &ctx); - - SamOEMhashBlob(buffer, 516, &confounded_session_key); - - if (!decode_pw_buffer(mem_ctx, buffer, pwd, &pwd_len, STR_UNICODE)) { - data_blob_free(&confounded_session_key); - return WERR_BAD_PASSWORD; - } - - data_blob_free(&confounded_session_key); - - return WERR_OK; -} - -DATA_BLOB decrypt_drsuapi_blob(TALLOC_CTX *mem_ctx, - const DATA_BLOB *session_key, - bool rcrypt, - uint32_t rid, - const DATA_BLOB *buffer) -{ - DATA_BLOB confounder; - DATA_BLOB enc_buffer; - - struct MD5Context md5; - uint8_t _enc_key[16]; - DATA_BLOB enc_key; - - DATA_BLOB dec_buffer; - - uint32_t crc32_given; - uint32_t crc32_calc; - DATA_BLOB checked_buffer; - - DATA_BLOB plain_buffer; - - /* - * the combination "c[3] s[1] e[1] d[0]..." - * was successful!!!!!!!!!!!!!!!!!!!!!!!!!! - */ - - /* - * the first 16 bytes at the beginning are the confounder - * followed by the 4 byte crc32 checksum - */ - if (buffer->length < 20) { - return data_blob_const(NULL, 0); - } - confounder = data_blob_const(buffer->data, 16); - enc_buffer = data_blob_const(buffer->data + 16, buffer->length - 16); - - /* - * build the encryption key md5 over the session key followed - * by the confounder - * - * here the gensec session key is used and - * not the dcerpc ncacn_ip_tcp "SystemLibraryDTC" key! - */ - enc_key = data_blob_const(_enc_key, sizeof(_enc_key)); - MD5Init(&md5); - MD5Update(&md5, session_key->data, session_key->length); - MD5Update(&md5, confounder.data, confounder.length); - MD5Final(enc_key.data, &md5); - - /* - * copy the encrypted buffer part and - * decrypt it using the created encryption key using arcfour - */ - dec_buffer = data_blob_talloc(mem_ctx, enc_buffer.data, enc_buffer.length); - if (!dec_buffer.data) { - return data_blob_const(NULL, 0); - } - SamOEMhashBlob(dec_buffer.data, dec_buffer.length, &enc_key); - - /* - * the first 4 byte are the crc32 checksum - * of the remaining bytes - */ - crc32_given = IVAL(dec_buffer.data, 0); - crc32_calc = crc32_calc_buffer(dec_buffer.data + 4 , dec_buffer.length - 4); - if (crc32_given != crc32_calc) { - DEBUG(1,("CRC32: given[0x%08X] calc[0x%08X]\n", - crc32_given, crc32_calc)); - return data_blob_const(NULL, 0); - } - checked_buffer = data_blob_talloc(mem_ctx, dec_buffer.data + 4, dec_buffer.length - 4); - if (!checked_buffer.data) { - return data_blob_const(NULL, 0); - } - - /* - * some attributes seem to be in a usable form after this decryption - * (supplementalCredentials, priorValue, currentValue, trustAuthOutgoing, - * trustAuthIncoming, initialAuthOutgoing, initialAuthIncoming) - * At least supplementalCredentials contains plaintext - * like "Primary:Kerberos" (in unicode form) - * - * some attributes seem to have some additional encryption - * dBCSPwd, unicodePwd, ntPwdHistory, lmPwdHistory - * - * it's the sam_rid_crypt() function, as the value is constant, - * so it doesn't depend on sessionkeys. - */ - if (rcrypt) { - uint32_t i, num_hashes; - - if ((checked_buffer.length % 16) != 0) { - return data_blob_const(NULL, 0); - } - - plain_buffer = data_blob_talloc(mem_ctx, checked_buffer.data, checked_buffer.length); - if (!plain_buffer.data) { - return data_blob_const(NULL, 0); - } - - num_hashes = plain_buffer.length / 16; - for (i = 0; i < num_hashes; i++) { - uint32_t offset = i * 16; - sam_pwd_hash(rid, checked_buffer.data + offset, plain_buffer.data + offset, 0); - } - } else { - plain_buffer = checked_buffer; - } - - return plain_buffer; -} - - diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 5b6bc00c57..929816e92d 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" /********************************************************* Change the domain password on the PDC. diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index fd715d201f..c36cda5ecd 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -23,6 +23,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index c79caf2d36..f55b77f675 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 35ce8bb41a..d548fe9ee9 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -44,6 +44,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index 2b507d0c4d..2fab765d87 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -23,7 +23,7 @@ such as the local SID and machine trust password */ #include "includes.h" - +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 5f115e537b..00d7f8515b 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" /**************************************************************************** Wrapper function that uses the auth and auth2 calls to set up a NETLOGON @@ -40,7 +41,7 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, NTSTATUS result = NT_STATUS_UNSUCCESSFUL; struct netr_Credential clnt_chal_send; struct netr_Credential srv_chal_recv; - struct dcinfo *dc; + struct netr_Credentials *dc; bool retried = false; SMB_ASSERT(ndr_syntax_id_equal(&cli->abstract_syntax, @@ -203,9 +204,9 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli, memcpy(key, cli->dc->sess_key, 8); memcpy(lm_owf, lm_owf_user_pwd, 16); - SamOEMhash(lm_owf, key, 16); + arcfour_crypt(lm_owf, key, 16); memcpy(nt_owf, nt_owf_user_pwd, 16); - SamOEMhash(nt_owf, key, 16); + arcfour_crypt(nt_owf, key, 16); #ifdef DEBUG_PASSWORD DEBUG(100,("encrypt of lm owf password:")); @@ -408,12 +409,12 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli, } if (memcmp(zeros, validation.sam3->base.key.key, 16) != 0) { - SamOEMhash(validation.sam3->base.key.key, + arcfour_crypt(validation.sam3->base.key.key, cli->dc->sess_key, 16); } if (memcmp(zeros, validation.sam3->base.LMSessKey.key, 8) != 0) { - SamOEMhash(validation.sam3->base.LMSessKey.key, + arcfour_crypt(validation.sam3->base.LMSessKey.key, cli->dc->sess_key, 8); } @@ -525,12 +526,12 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli, } if (memcmp(zeros, validation.sam3->base.key.key, 16) != 0) { - SamOEMhash(validation.sam3->base.key.key, + arcfour_crypt(validation.sam3->base.key.key, cli->dc->sess_key, 16); } if (memcmp(zeros, validation.sam3->base.LMSessKey.key, 8) != 0) { - SamOEMhash(validation.sam3->base.LMSessKey.key, + arcfour_crypt(validation.sam3->base.LMSessKey.key, cli->dc->sess_key, 8); } diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index a8cc33f585..2832a6d1c3 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" #include "librpc/gen_ndr/cli_epmapper.h" #undef DBGC_CLASS diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index 86bc041374..5a0dff2965 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" /* User change password */ @@ -115,7 +116,7 @@ NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli, encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE); - SamOEMhash(new_lm_password.data, old_nt_hash, 516); + arcfour_crypt(new_lm_password.data, old_nt_hash, 516); E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash); } else { ZERO_STRUCT(new_lm_password); @@ -124,7 +125,7 @@ NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli, encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE); - SamOEMhash(new_nt_password.data, old_nt_hash, 516); + arcfour_crypt(new_nt_password.data, old_nt_hash, 516); E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); result = rpccli_samr_ChangePasswordUser2(cli, mem_ctx, @@ -221,7 +222,7 @@ NTSTATUS rpccli_samr_chgpasswd_user3(struct rpc_pipe_client *cli, encode_pw_buffer(new_lm_password.data, newpassword, STR_UNICODE); - SamOEMhash(new_lm_password.data, old_nt_hash, 516); + arcfour_crypt(new_lm_password.data, old_nt_hash, 516); E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash); } else { ZERO_STRUCT(new_lm_password); @@ -230,7 +231,7 @@ NTSTATUS rpccli_samr_chgpasswd_user3(struct rpc_pipe_client *cli, encode_pw_buffer(new_nt_password.data, newpassword, STR_UNICODE); - SamOEMhash(new_nt_password.data, old_nt_hash, 516); + arcfour_crypt(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, diff --git a/source3/rpc_client/init_netlogon.c b/source3/rpc_client/init_netlogon.c index 793b9c7de5..cb49381eac 100644 --- a/source3/rpc_client/init_netlogon.c +++ b/source3/rpc_client/init_netlogon.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" /******************************************************************* inits a structure. @@ -259,7 +260,7 @@ NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info, MIN(sizeof(user_session_key.key), server_info->user_session_key.length)); if (pipe_session_key) { - SamOEMhash(user_session_key.key, pipe_session_key, 16); + arcfour_crypt(user_session_key.key, pipe_session_key, 16); } } if (server_info->lm_session_key.length) { @@ -268,7 +269,7 @@ NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info, MIN(sizeof(lm_session_key.key), server_info->lm_session_key.length)); if (pipe_session_key) { - SamOEMhash(lm_session_key.key, pipe_session_key, 8); + arcfour_crypt(lm_session_key.key, pipe_session_key, 8); } } @@ -418,7 +419,7 @@ void init_netr_CryptPassword(const char *pwd, encode_pw_buffer(password_buf.data, pwd, STR_UNICODE); - SamOEMhash(password_buf.data, session_key, 516); + arcfour_crypt(password_buf.data, session_key, 516); memcpy(pwd_buf->data, password_buf.data, 512); pwd_buf->length = IVAL(password_buf.data, 512); } diff --git a/source3/rpc_client/init_samr.c b/source3/rpc_client/init_samr.c index ecc6310510..6843869965 100644 --- a/source3/rpc_client/init_samr.c +++ b/source3/rpc_client/init_samr.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" /************************************************************************* inits a samr_CryptPasswordEx structure @@ -44,7 +45,7 @@ void init_samr_CryptPasswordEx(const char *pwd, session_key->length); MD5Final(confounded_session_key.data, &md5_ctx); - SamOEMhashBlob(pwbuf, 516, &confounded_session_key); + arcfour_crypt_blob(pwbuf, 516, &confounded_session_key); memcpy(&pwbuf[516], confounder, 16); memcpy(pwd_buf->data, pwbuf, sizeof(pwbuf)); @@ -62,5 +63,5 @@ void init_samr_CryptPassword(const char *pwd, /* samr_CryptPassword */ encode_pw_buffer(pwd_buf->data, pwd, STR_UNICODE); - SamOEMhashBlob(pwd_buf->data, 516, session_key); + arcfour_crypt_blob(pwd_buf->data, 516, session_key); } diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index dfbd6dac74..0f4829dec3 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -1373,7 +1373,7 @@ bool prs_hash1(prs_struct *ps, uint32 offset, int len) dump_data(100, (uint8 *)ps->sess_key, 16); dump_data(100, (uint8 *)q, len); #endif - SamOEMhash((uchar *) q, (const unsigned char *)ps->sess_key, len); + arcfour_crypt((uchar *) q, (const unsigned char *)ps->sess_key, len); #ifdef DEBUG_PASSWORD dump_data(100, (uint8 *)q, len); @@ -1468,7 +1468,7 @@ static void schannel_deal_with_seq_num(struct schannel_auth_struct *a, dump_data_pw("sequence_key:\n", sequence_key, sizeof(sequence_key)); dump_data_pw("seq_num (before):\n", verf->seq_num, sizeof(verf->seq_num)); - SamOEMhash(verf->seq_num, sequence_key, 8); + arcfour_crypt(verf->seq_num, sequence_key, 8); dump_data_pw("seq_num (after):\n", verf->seq_num, sizeof(verf->seq_num)); } @@ -1554,13 +1554,13 @@ void schannel_encode(struct schannel_auth_struct *a, enum pipe_auth_level auth_l /* encode the verification data */ dump_data_pw("verf->confounder:\n", verf->confounder, sizeof(verf->confounder)); - SamOEMhash(verf->confounder, sealing_key, 8); + arcfour_crypt(verf->confounder, sealing_key, 8); dump_data_pw("verf->confounder_enc:\n", verf->confounder, sizeof(verf->confounder)); /* encode the packet payload */ dump_data_pw("data:\n", (const unsigned char *)data, data_len); - SamOEMhash((unsigned char *)data, sealing_key, data_len); + arcfour_crypt((unsigned char *)data, sealing_key, data_len); dump_data_pw("data_enc:\n", (const unsigned char *)data, data_len); } @@ -1652,14 +1652,14 @@ bool schannel_decode(struct schannel_auth_struct *a, enum pipe_auth_level auth_l /* extract the verification data */ dump_data_pw("verf->confounder:\n", verf->confounder, sizeof(verf->confounder)); - SamOEMhash(verf->confounder, sealing_key, 8); + arcfour_crypt(verf->confounder, sealing_key, 8); dump_data_pw("verf->confounder_dec:\n", verf->confounder, sizeof(verf->confounder)); /* extract the packet payload */ dump_data_pw("data :\n", (const unsigned char *)data, data_len); - SamOEMhash((unsigned char *)data, sealing_key, data_len); + arcfour_crypt((unsigned char *)data, sealing_key, data_len); dump_data_pw("datadec:\n", (const unsigned char *)data, data_len); } diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index 0c83144a90..c5e2ca7c71 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -25,6 +25,7 @@ /* This is the implementation of the netlogon pipe. */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" extern userdom_struct current_user_info; diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 7881ca62ea..187c721dfb 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -32,6 +32,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -3822,7 +3823,7 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, struct samu *pwd) { char *plaintext_buf = NULL; - uint32 len = 0; + size_t len = 0; uint32_t acct_ctrl; NTSTATUS status; @@ -3849,7 +3850,7 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, id23->password.data, &plaintext_buf, &len, - STR_UNICODE)) { + CH_UTF16)) { return NT_STATUS_WRONG_PASSWORD; } @@ -3911,7 +3912,7 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, static bool set_user_info_pw(uint8 *pass, struct samu *pwd) { - uint32 len = 0; + size_t len = 0; char *plaintext_buf = NULL; uint32 acct_ctrl; @@ -3924,7 +3925,7 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd) pass, &plaintext_buf, &len, - STR_UNICODE)) { + CH_UTF16)) { return False; } @@ -4223,8 +4224,8 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, if (!p->server_info->user_session_key.length) { status = NT_STATUS_NO_USER_SESSION_KEY; } - SamOEMhashBlob(info->info23.password.data, 516, - &p->server_info->user_session_key); + arcfour_crypt_blob(info->info23.password.data, 516, + &p->server_info->user_session_key); dump_data(100, info->info23.password.data, 516); @@ -4236,9 +4237,9 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, if (!p->server_info->user_session_key.length) { status = NT_STATUS_NO_USER_SESSION_KEY; } - SamOEMhashBlob(info->info24.password.data, - 516, - &p->server_info->user_session_key); + arcfour_crypt_blob(info->info24.password.data, + 516, + &p->server_info->user_session_key); dump_data(100, info->info24.password.data, 516); diff --git a/source3/rpc_server/srv_wkssvc_nt.c b/source3/rpc_server/srv_wkssvc_nt.c index 7071b55e7c..8d2e73b5a5 100644 --- a/source3/rpc_server/srv_wkssvc_nt.c +++ b/source3/rpc_server/srv_wkssvc_nt.c @@ -24,6 +24,7 @@ #include "includes.h" #include "libnet/libnet.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c index 722a0a3832..cf2b1ae563 100644 --- a/source3/rpcclient/cmd_lsarpc.c +++ b/source3/rpcclient/cmd_lsarpc.c @@ -22,6 +22,7 @@ #include "includes.h" #include "rpcclient.h" +#include "../libcli/auth/libcli_auth.h" /* useful function to allow entering a name instead of a SID and * looking it up automatically */ @@ -947,27 +948,22 @@ static NTSTATUS cmd_lsa_query_secobj(struct rpc_pipe_client *cli, } static void display_trust_dom_info_4(struct lsa_TrustDomainInfoPassword *p, - uint8_t nt_hash[16]) + uint8_t session_key[16]) { char *pwd, *pwd_old; - DATA_BLOB data = data_blob(NULL, p->password->length); - DATA_BLOB data_old = data_blob(NULL, p->old_password->length); + DATA_BLOB data = data_blob_const(p->password->data, p->password->length); + DATA_BLOB data_old = data_blob_const(p->old_password->data, p->old_password->length); + DATA_BLOB session_key_blob = data_blob_const(session_key, sizeof(session_key)); - memcpy(data.data, p->password->data, p->password->length); - memcpy(data_old.data, p->old_password->data, p->old_password->length); - - pwd = decrypt_trustdom_secret(nt_hash, &data); - pwd_old = decrypt_trustdom_secret(nt_hash, &data_old); + pwd = sess_decrypt_string(talloc_tos(), &data, &session_key_blob); + pwd_old = sess_decrypt_string(talloc_tos(), &data_old, &session_key_blob); d_printf("Password:\t%s\n", pwd); d_printf("Old Password:\t%s\n", pwd_old); - SAFE_FREE(pwd); - SAFE_FREE(pwd_old); - - data_blob_free(&data); - data_blob_free(&data_old); + talloc_free(pwd); + talloc_free(pwd_old); } static void display_trust_dom_info(TALLOC_CTX *mem_ctx, diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c index 45df488018..abc2455e75 100644 --- a/source3/rpcclient/cmd_netlogon.c +++ b/source3/rpcclient/cmd_netlogon.c @@ -21,6 +21,7 @@ #include "includes.h" #include "rpcclient.h" +#include "../libcli/auth/libcli_auth.h" static WERROR cmd_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int argc, diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index 428984db13..83cec72318 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -24,6 +24,7 @@ #include "includes.h" #include "rpcclient.h" +#include "../libcli/auth/libcli_auth.h" extern DOM_SID domain_sid; diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index a202dcc5f3..6fd6b4f6d9 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -21,6 +21,7 @@ #include "includes.h" #include "rpcclient.h" +#include "../libcli/auth/libcli_auth.h" DOM_SID domain_sid; diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index ccab71c0a2..72f06fb2ed 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -46,6 +46,7 @@ */ #include "includes.h" +#include "../libcli/auth/libcli_auth.h" static NTSTATUS check_oem_password(const char *user, uchar password_encrypted_with_lm_hash[516], @@ -832,7 +833,7 @@ static NTSTATUS check_oem_password(const char *user, const uint8 *encryption_key; const uint8 *lanman_pw, *nt_pw; uint32 acct_ctrl; - uint32 new_pw_len; + size_t new_pw_len; uchar new_nt_hash[16]; uchar new_lm_hash[16]; uchar verifier[16]; @@ -919,13 +920,13 @@ static NTSTATUS check_oem_password(const char *user, /* * Decrypt the password with the key */ - SamOEMhash( password_encrypted, encryption_key, 516); + arcfour_crypt( password_encrypted, encryption_key, 516); if (!decode_pw_buffer(talloc_tos(), password_encrypted, pp_new_passwd, &new_pw_len, - nt_pass_set ? STR_UNICODE : STR_ASCII)) { + nt_pass_set ? CH_UTF16 : CH_DOS)) { TALLOC_FREE(sampass); return NT_STATUS_WRONG_PASSWORD; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 04b1145e58..72b4ba0742 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -26,6 +26,7 @@ #include "includes.h" #include "version.h" #include "smbd/globals.h" +#include "../libcli/auth/libcli_auth.h" extern enum protocol_types Protocol; diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 21881ba6a9..2651a8d034 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -22,6 +22,7 @@ #include "includes.h" #include "utils/net.h" +#include "../libcli/auth/libcli_auth.h" static int net_mode_share; static bool sync_files(struct copy_clistate *cp_clistate, const char *mask); @@ -5738,7 +5739,8 @@ static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd, NTSTATUS nt_status; union lsa_TrustedDomainInfo *info = NULL; char *cleartextpwd = NULL; - uint8_t nt_hash[16]; + uint8_t session_key[16]; + DATA_BLOB session_key_blob; DATA_BLOB data; nt_status = rpccli_lsa_QueryTrustedDomainInfoBySid(pipe_hnd, mem_ctx, @@ -5755,12 +5757,13 @@ static NTSTATUS vampire_trusted_domain(struct rpc_pipe_client *pipe_hnd, data = data_blob(info->password.password->data, info->password.password->length); - if (!rpccli_get_pwd_hash(pipe_hnd, nt_hash)) { + if (!rpccli_get_pwd_hash(pipe_hnd, session_key)) { DEBUG(0, ("Could not retrieve password hash\n")); goto done; } - cleartextpwd = decrypt_trustdom_secret(nt_hash, &data); + session_key_blob = data_blob_const(session_key, sizeof(session_key)); + cleartextpwd = sess_decrypt_string(mem_ctx, &data, &session_key_blob); if (cleartextpwd == NULL) { DEBUG(0,("retrieved NULL password\n")); diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index 7f3515ce75..58d6cdc5af 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -20,6 +20,7 @@ #include "includes.h" #include "utils/net.h" +#include "../libcli/auth/libcli_auth.h" /* Macro for checking RPC error codes to make things more readable */ diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index e8bd9fbd2b..838aaf5216 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -25,6 +25,7 @@ #include "includes.h" #include "utils/ntlm_auth.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -1977,7 +1978,7 @@ static void manage_ntlm_change_password_1_request(struct ntlm_auth_state *state, encode_pw_buffer(new_lm_pswd.data, newpswd, STR_UNICODE); - SamOEMhash(new_lm_pswd.data, old_nt_hash, 516); + arcfour_crypt(new_lm_pswd.data, old_nt_hash, 516); E_old_pw_hash(new_nt_hash, old_lm_hash, old_lm_hash_enc.data); } else { @@ -1990,7 +1991,7 @@ static void manage_ntlm_change_password_1_request(struct ntlm_auth_state *state, encode_pw_buffer(new_nt_pswd.data, newpswd, STR_UNICODE); - SamOEMhash(new_nt_pswd.data, old_nt_hash, 516); + arcfour_crypt(new_nt_pswd.data, old_nt_hash, 516); E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.data); } diff --git a/source3/utils/ntlm_auth_diagnostics.c b/source3/utils/ntlm_auth_diagnostics.c index cea4b084f7..0178823801 100644 --- a/source3/utils/ntlm_auth_diagnostics.c +++ b/source3/utils/ntlm_auth_diagnostics.c @@ -23,6 +23,7 @@ #include "includes.h" #include "utils/ntlm_auth.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -72,7 +73,7 @@ static bool test_lm_ntlm_broken(enum ntlm_break break_which) SMBNTencrypt(opt_password,chall.data,nt_response.data); E_md4hash(opt_password, nt_hash); - SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + SMBsesskeygen_ntv1(nt_hash, session_key.data); switch (break_which) { case BREAK_NONE: @@ -257,7 +258,7 @@ static bool test_ntlm_in_both(void) SMBNTencrypt(opt_password,chall.data,nt_response.data); E_md4hash(opt_password, nt_hash); - SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + SMBsesskeygen_ntv1(nt_hash, session_key.data); E_deshash(opt_password, lm_hash); @@ -316,7 +317,7 @@ static bool test_lmv2_ntlmv2_broken(enum ntlm_break break_which) DATA_BLOB ntlmv2_response = data_blob_null; DATA_BLOB lmv2_response = data_blob_null; DATA_BLOB ntlmv2_session_key = data_blob_null; - DATA_BLOB names_blob = NTLMv2_generate_names_blob(get_winbind_netbios_name(), get_winbind_domain()); + DATA_BLOB names_blob = NTLMv2_generate_names_blob(NULL, get_winbind_netbios_name(), get_winbind_domain()); uchar user_session_key[16]; DATA_BLOB chall = get_challenge(); @@ -326,9 +327,9 @@ static bool test_lmv2_ntlmv2_broken(enum ntlm_break break_which) flags |= WBFLAG_PAM_USER_SESSION_KEY; - if (!SMBNTLMv2encrypt(opt_username, opt_domain, opt_password, &chall, + if (!SMBNTLMv2encrypt(NULL, opt_username, opt_domain, opt_password, &chall, &names_blob, - &lmv2_response, &ntlmv2_response, + &lmv2_response, &ntlmv2_response, NULL, &ntlmv2_session_key)) { data_blob_free(&names_blob); return False; diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index 66166bf292..5c1b71897d 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -26,6 +26,7 @@ #include "includes.h" #include "winbindd.h" #include "tdb_validate.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index ed0a33a5f2..bcb3a8dfad 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -60,6 +60,7 @@ #include "includes.h" #include "winbindd.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND diff --git a/source3/winbindd/winbindd_cred_cache.c b/source3/winbindd/winbindd_cred_cache.c index ff6d0f3df7..f11f75762d 100644 --- a/source3/winbindd/winbindd_cred_cache.c +++ b/source3/winbindd/winbindd_cred_cache.c @@ -23,6 +23,7 @@ #include "includes.h" #include "winbindd.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND diff --git a/source3/winbindd/winbindd_creds.c b/source3/winbindd/winbindd_creds.c index 9c7acd64e6..2f64f8b689 100644 --- a/source3/winbindd/winbindd_creds.c +++ b/source3/winbindd/winbindd_creds.c @@ -21,6 +21,7 @@ #include "includes.h" #include "winbindd.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 54bcac2b04..23de20f0d3 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -24,6 +24,7 @@ #include "includes.h" #include "winbindd.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -1238,13 +1239,13 @@ NTSTATUS winbindd_dual_pam_auth_samlogon(struct winbindd_domain *domain, the server's domain at this point. The 'server name' is also dodgy... */ - names_blob = NTLMv2_generate_names_blob(global_myname(), lp_workgroup()); + names_blob = NTLMv2_generate_names_blob(state->mem_ctx, global_myname(), lp_workgroup()); - if (!SMBNTLMv2encrypt(name_user, name_domain, + if (!SMBNTLMv2encrypt(NULL, name_user, name_domain, state->request.data.auth.pass, &server_chal, &names_blob, - &lm_response, &nt_response, NULL)) { + &lm_response, &nt_response, NULL, NULL)) { data_blob_free(&names_blob); data_blob_free(&server_chal); DEBUG(0, ("winbindd_pam_auth: SMBNTLMv2encrypt() failed!\n")); |