1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-29 02:50:28 +03:00

Rework Samba3 to use new libcli/auth code (partial)

This commit is mostly to cope with the removal of SamOemHash (replaced
by arcfour_crypt()) and other collisions (such as changed function
arguments compared to Samba3).

We still provide creds_hash3 until Samba3 uses the credentials code in
netlogon server

Andrew Bartlett
This commit is contained in:
Andrew Bartlett 2009-03-16 21:27:58 +11:00
parent fd3be5c4e5
commit f28f113d8e
48 changed files with 198 additions and 2520 deletions

View File

@ -35,12 +35,51 @@ struct creds_CredentialState {
struct dom_sid *sid;
};
/* for the timebeing, use the same neg flags as Samba3. */
/* 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
#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 */
/*
(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)
*/
#define NETLOGON_NEG_AUTH2_ADS_FLAGS (0x200fbffb | NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_128BIT | NETLOGON_NEG_SCHANNEL)

View File

@ -18,7 +18,10 @@
#define __LIBCLI_AUTH_H__
#include "librpc/gen_ndr/netlogon.h"
#include "librpc/gen_ndr/wkssvc.h"
#include "libcli/auth/credentials.h"
#include "libcli/auth/ntlm_check.h"
#include "libcli/auth/proto.h"
#include "libcli/auth/msrpc_parse.h"
#endif /* __LIBCLI_AUTH_H__ */

View File

@ -23,7 +23,6 @@
#include "../lib/crypto/crypto.h"
#include "librpc/gen_ndr/netlogon.h"
#include "libcli/auth/libcli_auth.h"
#include "auth/ntlm/ntlm_check.h"
/****************************************************************************
Core of smb password checking routine.

View File

@ -23,6 +23,7 @@
#include "includes.h"
#include "winbind_client.h"
#include "libwbclient/wbclient.h"
#include "../libcli/auth/libcli_auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
@ -1323,11 +1324,11 @@ static bool wbinfo_auth_crap(char *username)
server_chal = data_blob(params.password.response.challenge, 8);
/* Pretend this is a login to 'us', for blob purposes */
names_blob = NTLMv2_generate_names_blob(global_myname(), lp_workgroup());
names_blob = NTLMv2_generate_names_blob(NULL, global_myname(), lp_workgroup());
if (!SMBNTLMv2encrypt(name_user, name_domain, pass, &server_chal,
if (!SMBNTLMv2encrypt(NULL, name_user, name_domain, pass, &server_chal,
&names_blob,
&lm, &nt, NULL)) {
&lm, &nt, NULL, NULL)) {
data_blob_free(&names_blob);
data_blob_free(&server_chal);
SAFE_FREE(pass);

View File

@ -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

View File

@ -19,6 +19,7 @@
*/
#include "includes.h"
#include "../libcli/auth/libcli_auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_AUTH

View File

@ -18,6 +18,7 @@
*/
#include "includes.h"
#include "../libcli/auth/libcli_auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_AUTH

View File

@ -21,6 +21,7 @@
*/
#include "includes.h"
#include "../libcli/auth/libcli_auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_AUTH

View File

@ -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:"));

View File

@ -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);

View File

@ -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,

View File

@ -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;
}

View File

@ -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.

View File

@ -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)
void cred_hash3(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw)
{
dc->sequence = time(NULL);
unsigned char key2[8];
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)
{
dc->sequence += 2;
creds_step(dc);
creds_reseed(dc);
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);
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -19,6 +19,7 @@
*/
#include "includes.h"
#include "../libcli/auth/libcli_auth.h"
/*********************************************************
Change the domain password on the PDC.

View File

@ -23,6 +23,7 @@
*/
#include "includes.h"
#include "../libcli/auth/libcli_auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_PASSDB

View File

@ -22,6 +22,7 @@
*/
#include "includes.h"
#include "../libcli/auth/libcli_auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_PASSDB

View File

@ -44,6 +44,7 @@
*/
#include "includes.h"
#include "../libcli/auth/libcli_auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_PASSDB

View File

@ -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

View File

@ -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);
}

View File

@ -18,6 +18,7 @@
*/
#include "includes.h"
#include "../libcli/auth/libcli_auth.h"
#include "librpc/gen_ndr/cli_epmapper.h"
#undef DBGC_CLASS

View File

@ -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,

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -24,6 +24,7 @@
#include "includes.h"
#include "rpcclient.h"
#include "../libcli/auth/libcli_auth.h"
extern DOM_SID domain_sid;

View File

@ -21,6 +21,7 @@
#include "includes.h"
#include "rpcclient.h"
#include "../libcli/auth/libcli_auth.h"
DOM_SID domain_sid;

View File

@ -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;
}

View File

@ -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;

View File

@ -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"));

View File

@ -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 */

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -60,6 +60,7 @@
#include "includes.h"
#include "winbindd.h"
#include "../libcli/auth/libcli_auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND

View File

@ -23,6 +23,7 @@
#include "includes.h"
#include "winbindd.h"
#include "../libcli/auth/libcli_auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND

View File

@ -21,6 +21,7 @@
#include "includes.h"
#include "winbindd.h"
#include "../libcli/auth/libcli_auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND

View File

@ -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"));