From adfefcdcb6e9d8ea0458a11b6f684a5cf231c3ba Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 01:16:40 +0000 Subject: Try to get heimdal working with HEAD. - Provide generic functions for - get valid encryption types - free encryption types - Add encryption type parm to generic function create_kerberos_key_from_string() - Try to merge the two versions (between HEAD and SAMBA_3_0) of kerberos_verify.c I think this should work for both MIT and heimdal, in HEAD. If all goes smooth, I'll move it over to 3.0 soon... (This used to be commit 45e409fc8da9f26cf888e13d004392660d7c55d4) --- source3/libsmb/clikrb5.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index e380d80bcc..c13f663381 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -74,7 +74,8 @@ int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, - krb5_keyblock *key) + krb5_keyblock *key, + krb5_enctype enctype) { int ret; krb5_data salt; @@ -85,14 +86,15 @@ DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); return ret; } - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); + krb5_use_enctype(context, &eblock, enctype); return krb5_string_to_key(context, &eblock, key, password, &salt); } #elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, - krb5_keyblock *key) + krb5_keyblock *key, + krb5_enctype enctype) { int ret; krb5_salt salt; @@ -102,13 +104,41 @@ DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); return ret; } - return krb5_string_to_key_salt(context, ENCTYPE_DES_CBC_MD5, password->data, + return krb5_string_to_key_salt(context, enctype, password->data, salt, key); } #else __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS #endif +#if defined(HAVE_KRB5_GET_PERMITTED_ENCTYPES) +krb5_error_code get_kerberos_allowed_etypes(krb5_context context, + krb5_enctype **enctypes) +{ + return krb5_get_permitted_enctypes(context, enctypes); +} +#elif defined(HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES) +krb5_error_code get_kerberos_allowed_etypes(krb5_context context, + krb5_enctype **enctypes) +{ + return krb5_get_default_in_tkt_etypes(context, enctypes); +} +#else + __ERROR_XX_UNKNOWN_GET_ENCTYPES_FUNCTIONS +#endif + +#if defined(HAVE_KRB5_FREE_KTYPES) +void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes) +{ + return krb5_free_ktypes(context, enctypes); +} +#else +void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes) +{ + return free(enctypes); +} +#endif + #if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, -- cgit From 3b541bdcfe14d30d961a5de20d382af179c381ee Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 03:19:30 +0000 Subject: Get non-krb systems to compile. How the heck do I keep something from being sucked into proto.h? (This used to be commit 7e84497882df5bf933ab7ae7fe9af3728393202c) --- source3/libsmb/clikrb5.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index c13f663381..2e07dfdb66 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -127,17 +127,18 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, __ERROR_XX_UNKNOWN_GET_ENCTYPES_FUNCTIONS #endif -#if defined(HAVE_KRB5_FREE_KTYPES) -void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes) + /* the following is defined as krb5_error_code to keep it from + being sucked into proto.h */ +krb5_error_code free_kerberos_etypes(krb5_context context, + krb5_enctype *enctypes) { - return krb5_free_ktypes(context, enctypes); -} +#if defined(HAVE_KRB5_FREE_KTYPES) + krb5_free_ktypes(context, enctypes); #else -void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes) -{ - return free(enctypes); -} + SAFE_FREE(enctypes); #endif + return 0; +} #if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, -- cgit From f145c2e350db43e401cd477eff89fdef136e7f6c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 19 Feb 2003 10:12:14 +0000 Subject: Only do a kinit if we got told to use kerberos. Andrew Bartlett (This used to be commit 6af9ec50e010d171cf5287f40ec774e79e4a93fe) --- source3/libsmb/cliconnect.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 487b184dd6..c57f92eea9 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -630,19 +630,19 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, /* If password is set we reauthenticate to kerberos server * and do not store results */ - if (*pass) { - int ret; - - use_in_memory_ccache(); - ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */); - - if (ret){ - DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); - return False; - } - } - if (got_kerberos_mechanism && cli->use_kerberos) { + if (*pass) { + int ret; + + use_in_memory_ccache(); + ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */); + + if (ret){ + DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); + return False; + } + } + return cli_session_setup_kerberos(cli, principal, workgroup); } #endif -- cgit From 231f7375590110046ed67b7b337ac2e12d257736 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 19 Feb 2003 11:30:52 +0000 Subject: After a talloc_zero(), we don't need to ZERO_STRUCTP too.. (This used to be commit 4fe8066394143c64c79c052c00f0d747e872103a) --- source3/libsmb/ntlmssp.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index e4398dad17..e1509f6b63 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -307,8 +307,6 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(*ntlmssp_state); - (*ntlmssp_state)->mem_ctx = mem_ctx; (*ntlmssp_state)->get_challenge = get_challenge; @@ -552,8 +550,6 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(*ntlmssp_state); - (*ntlmssp_state)->mem_ctx = mem_ctx; (*ntlmssp_state)->get_global_myname = global_myname; -- cgit From ffcee0c95e05f652f4eebf9b9d46bd51d059891b Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 15:22:46 +0000 Subject: Correct way to keep fucntion from proto.h (This used to be commit 762b072efb0d6801775a874494cb19ea3d61fa97) --- source3/libsmb/clikrb5.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 2e07dfdb66..da120622ea 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -127,17 +127,14 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, __ERROR_XX_UNKNOWN_GET_ENCTYPES_FUNCTIONS #endif - /* the following is defined as krb5_error_code to keep it from - being sucked into proto.h */ -krb5_error_code free_kerberos_etypes(krb5_context context, - krb5_enctype *enctypes) + void free_kerberos_etypes(krb5_context context, + krb5_enctype *enctypes) { #if defined(HAVE_KRB5_FREE_KTYPES) - krb5_free_ktypes(context, enctypes); + return krb5_free_ktypes(context, enctypes); #else - SAFE_FREE(enctypes); + return SAFE_FREE(enctypes); #endif - return 0; } #if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) -- cgit From f15ed71fbba9d3762f4e8a1382b65d6291a2a065 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 15:46:15 +0000 Subject: Can't return SAFE_FREE...put on its own line. (This used to be commit 9f1a4809b503f050189d5f87a294b7d8675b1e95) --- source3/libsmb/clikrb5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index da120622ea..96e737166c 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -133,7 +133,8 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, #if defined(HAVE_KRB5_FREE_KTYPES) return krb5_free_ktypes(context, enctypes); #else - return SAFE_FREE(enctypes); + SAFE_FREE(enctypes); + return; #endif } -- cgit From e1c987abf2c716e26d2484a89e23507d1d2a9c5e Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 21 Feb 2003 05:07:51 +0000 Subject: Doesn't anyone run ./configure.developer anymore? (This used to be commit 09be123c6c1b67621eaf6c8ffb3016eccd375e5b) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index c57f92eea9..901daf4b09 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -453,7 +453,7 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) /**************************************************************************** Use in-memory credentials cache ****************************************************************************/ -static void use_in_memory_ccache() { +static void use_in_memory_ccache(void) { setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1); } -- cgit From 23553b48e6bd21481ca32c4b3ee54fc1aded4174 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 21 Feb 2003 14:35:02 +0000 Subject: Fix IRIX build...void fn can't return another void fn (This used to be commit df3c7c9cbb275e9c35356b4f1cab1a741de6f500) --- source3/libsmb/clikrb5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 96e737166c..bef6998a49 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -131,7 +131,8 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype *enctypes) { #if defined(HAVE_KRB5_FREE_KTYPES) - return krb5_free_ktypes(context, enctypes); + krb5_free_ktypes(context, enctypes); + return; #else SAFE_FREE(enctypes); return; -- cgit From eb64538dba772a9846c05e2712839dbaa12c39a1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 11:09:21 +0000 Subject: Patch from Luke Howard to add mutual kerberos authentication, and SMB session keys for kerberos authentication. Andrew Bartlett (This used to be commit 8b798f03dbbdd670ff9af4eb46f7b0845c611e0f) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clikrb5.c | 56 +++++++++++++++++++++++++++++++++++++-------- source3/libsmb/clispnego.c | 29 ++++++++++++----------- 3 files changed, 64 insertions(+), 23 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 901daf4b09..4962ffa3c9 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. client connect/disconnect routines Copyright (C) Andrew Tridgell 1994-1998 - Copyright (C) Andrew Barteltt 2001-2003 + Copyright (C) Andrew Bartlett 2001-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 diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index bef6998a49..47dec1f171 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5 routines for active directory Copyright (C) Andrew Tridgell 2001 - Copyright (C) Luke Howard 2002 + Copyright (C) Luke Howard 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 @@ -23,6 +23,16 @@ #ifdef HAVE_KRB5 +#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE +#define KRB5_KEY_TYPE(k) ((k)->keytype) +#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) +#define KRB5_KEY_DATA(k) ((k)->keyvalue.data) +#else +#define KRB5_KEY_TYPE(k) ((k)->enctype) +#define KRB5_KEY_LENGTH(k) ((k)->length) +#define KRB5_KEY_DATA(k) ((k)->contents) +#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ + #ifndef HAVE_KRB5_SET_REAL_TIME /* * This function is not in the Heimdal mainline. @@ -124,7 +134,7 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, return krb5_get_default_in_tkt_etypes(context, enctypes); } #else - __ERROR_XX_UNKNOWN_GET_ENCTYPES_FUNCTIONS +#error UNKNOWN_GET_ENCTYPES_FUNCTIONS #endif void free_kerberos_etypes(krb5_context context, @@ -305,12 +315,12 @@ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) DATA_BLOB ret; krb5_enctype enc_types[] = { #ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_DES_CBC_CRC, - ENCTYPE_NULL}; - + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_CRC, + ENCTYPE_NULL}; + retval = krb5_init_context(&context); if (retval) { DEBUG(1,("krb5_init_context failed (%s)\n", @@ -355,11 +365,39 @@ failed: return data_blob(NULL, 0); } +BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) + { + krb5_keyblock *skey; + BOOL ret = False; + + memset(session_key, 0, 16); + +#ifdef ENCTYPE_ARCFOUR_HMAC + if (krb5_auth_con_getremotesubkey(context, auth_context, &skey) == 0 && skey != NULL) { + if (KRB5_KEY_TYPE(skey) == + ENCTYPE_ARCFOUR_HMAC + && KRB5_KEY_LENGTH(skey) == 16) { + memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); + ret = True; + } + krb5_free_keyblock(context, skey); + } +#endif /* ENCTYPE_ARCFOUR_HMAC */ + + return ret; + } #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ - DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) +DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); } + +BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context ac, uint8 session_key[16]) + { + DEBUG(0,("NO KERBEROS SUPPORT\n")); + memset(session_key, 0, 16); + return False; + } #endif diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index e93f1855dd..dfa8f80146 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -3,6 +3,7 @@ simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 Copyright (C) Jim McDonough 2002 + Copyright (C) Luke Howard 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 @@ -259,7 +260,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se /* generate a krb5 GSS-API wrapper packet given a ticket */ -DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) +DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, uint8 tok_id[2]) { ASN1_DATA data; DATA_BLOB ret; @@ -268,7 +269,8 @@ DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) asn1_push_tag(&data, ASN1_APPLICATION(0)); asn1_write_OID(&data, OID_KERBEROS5); - asn1_write_BOOLEAN(&data, 0); + + asn1_write(&data, tok_id, 2); asn1_write(&data, ticket.data, ticket.length); asn1_pop_tag(&data); @@ -286,7 +288,7 @@ DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) /* parse a krb5 GSS-API wrapper packet giving a ticket */ -BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) +BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) { BOOL ret; ASN1_DATA data; @@ -295,15 +297,15 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) asn1_load(&data, blob); asn1_start_tag(&data, ASN1_APPLICATION(0)); asn1_check_OID(&data, OID_KERBEROS5); - asn1_check_BOOLEAN(&data, 0); data_remaining = asn1_tag_remaining(&data); - if (data_remaining < 1) { + if (data_remaining < 3) { data.has_error = True; } else { - - *ticket = data_blob(data.data, data_remaining); + asn1_read(&data, tok_id, 2); + data_remaining -= 2; + *ticket = data_blob(NULL, data_remaining); asn1_read(&data, ticket->data, ticket->length); } @@ -330,7 +332,7 @@ DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) tkt = krb5_get_ticket(principal, time_offset); /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap(tkt); + tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); /* and wrap that in a shiny SPNEGO wrapper */ targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); @@ -438,9 +440,10 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) } /* - generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much. + generate a minimal SPNEGO response packet. Doesn't contain much. */ -DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) +DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, + const char *mechOID) { ASN1_DATA data; DATA_BLOB ret; @@ -462,13 +465,13 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) asn1_write_enumerated(&data, negResult); asn1_pop_tag(&data); - if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { + if (reply->data != NULL) { asn1_push_tag(&data,ASN1_CONTEXT(1)); - asn1_write_OID(&data, OID_NTLMSSP); + asn1_write_OID(&data, mechOID); asn1_pop_tag(&data); asn1_push_tag(&data,ASN1_CONTEXT(2)); - asn1_write_OctetString(&data, ntlmssp_reply->data, ntlmssp_reply->length); + asn1_write_OctetString(&data, reply->data, reply->length); asn1_pop_tag(&data); } -- cgit From 79aaa35ea5e8c74ff7755ec650aca88cc7e4cf7e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 21:07:03 +0000 Subject: Clean up non-krb5 breakages from my modifications to luke howard's patch. Andrew Bartlett (This used to be commit 32fd0c49009e38022523cc5c14567dd55de08206) --- source3/libsmb/clikrb5.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 47dec1f171..6b0c7ddaf2 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -365,7 +365,7 @@ failed: return data_blob(NULL, 0); } -BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) + BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) { krb5_keyblock *skey; BOOL ret = False; @@ -394,10 +394,4 @@ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) return data_blob(NULL, 0); } -BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context ac, uint8 session_key[16]) - { - DEBUG(0,("NO KERBEROS SUPPORT\n")); - memset(session_key, 0, 16); - return False; - } #endif -- cgit From 7d581bebd437cd66000a1cac4b74b1ec4408f672 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 25 Feb 2003 23:30:46 +0000 Subject: Fix unused variable warning when ENCTYPE_ARCFOUR_HMAC is not defined. (This used to be commit 92abafa62894a125c5a09fc92f5056e4d8b51089) --- source3/libsmb/clikrb5.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 6b0c7ddaf2..5edc56daa9 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -367,7 +367,9 @@ failed: BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) { +#ifdef ENCTYPE_ARCFOUR_HMAC krb5_keyblock *skey; +#endif BOOL ret = False; memset(session_key, 0, 16); -- cgit From ca80787248bfe7fe8dff12486ba32520f6910341 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 26 Feb 2003 12:23:03 +0000 Subject: Netlogon-unigroup changes needed for the winbind RID-to-SID conversion. This changes the cache format, which will simply invalidate existing entries, leaving them dead in the cache. Andrew Bartlett (This used to be commit 3fc179362ea849db23490b971a9f64f943e7f7f8) --- source3/libsmb/netlogon_unigrp.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/netlogon_unigrp.c b/source3/libsmb/netlogon_unigrp.c index fa2fe32f35..466410d800 100644 --- a/source3/libsmb/netlogon_unigrp.c +++ b/source3/libsmb/netlogon_unigrp.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#define UNIGROUP_PREFIX "UNIGROUP" /* Handle for netlogon_unigrp.tdb database. It is used internally @@ -50,17 +51,22 @@ BOOL uni_group_cache_init(void) BOOL uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) { TDB_DATA key,data; - fstring keystr; - int i; + fstring keystr, sid_string; + DOM_SID user_sid; + unsigned int i; if (!uni_group_cache_init()) { DEBUG(0,("uni_group_cache_store_netlogon: cannot open netlogon_unigrp.tdb for write!\n")); return False; } - /* Prepare key as DOMAIN-SID/USER-RID string */ - slprintf(keystr, sizeof(keystr), "%s/%d", - sid_string_static(&user->dom_sid.sid), user->user_rid); + sid_copy(&user_sid, &user->dom_sid.sid); + sid_append_rid(&user_sid, user->user_rid); + + /* Prepare key as USER-SID string */ + slprintf(keystr, sizeof(keystr), "%s/%s", + UNIGROUP_PREFIX, + sid_to_string(sid_string, &user_sid)); key.dptr = keystr; key.dsize = strlen(keystr) + 1; @@ -90,14 +96,15 @@ BOOL uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) and elements are array[0] ... array[num_elements-1] */ -uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, +DOM_SID **uni_group_cache_fetch(DOM_SID *domain, DOM_SID *user_sid, TALLOC_CTX *mem_ctx, uint32 *num_groups) { TDB_DATA key,data; fstring keystr; - uint32 *groups; + DOM_SID **groups; uint32 i; uint32 group_count; + fstring sid_string; if (!domain) { DEBUG(1,("uni_group_cache_fetch: expected non-null domain sid\n")); @@ -123,8 +130,9 @@ uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, *num_groups = 0; /* Fetch universal groups */ - slprintf(keystr, sizeof(keystr), "%s/%d", - sid_string_static(domain), user_rid); + slprintf(keystr, sizeof(keystr), "%s/%s", + UNIGROUP_PREFIX, + sid_to_string(sid_string, user_sid)); key.dptr = keystr; key.dsize = strlen(keystr) + 1; data = tdb_fetch(netlogon_unigrp_tdb, key); @@ -136,12 +144,17 @@ uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, /* Transfer data to receiver's memory context */ group_count = IVAL(&((uint32*)data.dptr)[0],0); - groups = talloc(mem_ctx, (group_count)*sizeof(uint32)); + groups = talloc(mem_ctx, (group_count)*sizeof(*groups)); if (groups) { for(i=0; i Date: Sat, 1 Mar 2003 01:07:18 +0000 Subject: the new DEVELOPER checks for string overflows have (as expected) broken a lot of stuff. These two macros are meant to make life easier when fixing these bugs. I'm guessing we will see more macros like this (eg. fstrcpy_base) (This used to be commit 50389c0cb2504d7941ec691af21d6a20ae5c5de7) --- source3/libsmb/clirap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index f8f840abaa..24108d40f3 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -221,10 +221,10 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p = param; SSVAL(p,0,0x68); /* api number */ p += 2; - pstrcpy(p,"WrLehDz"); + pstrcpy_base(p,"WrLehDz", param); p = skip_string(p,1); - pstrcpy(p,"B16BBDz"); + pstrcpy_base(p,"B16BBDz", param); p = skip_string(p,1); SSVAL(p,0,uLevel); @@ -233,7 +233,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, SIVAL(p,0,stype); p += 4; - p += push_pstring(p, workgroup); + p += push_pstring_base(p, workgroup, param); if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ -- cgit From aa543f1345a2a10b65d6f3162f7db81b96db3d6a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 3 Mar 2003 08:35:49 +0000 Subject: Add const (This used to be commit 251b91f46988053eccc53f814a23ed5ca787c852) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index dfa8f80146..53f7eb6e7d 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -260,7 +260,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se /* generate a krb5 GSS-API wrapper packet given a ticket */ -DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, uint8 tok_id[2]) +DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8 tok_id[2]) { ASN1_DATA data; DATA_BLOB ret; -- cgit From 3042cfb7fabe25cc06e5cf6c49c2716c1112b6d2 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 3 Mar 2003 17:43:33 +0000 Subject: Do my janitorial duties to encourage others to do so. Fix lingering large offset problems in smbtar etc. (This used to be commit c416eec2f2a38eebfcda5868999d474628037f1e) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 07b1ff6b6f..31d7ea5911 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -805,7 +805,7 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ ****************************************************************************/ BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, size_t *size, + uint16 *attr, SMB_BIG_UINT *size, time_t *c_time, time_t *a_time, time_t *m_time) { memset(cli->outbuf,'\0',smb_size); -- cgit From fe45e6d79a61df5f25e461603ff93c563da186b7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Mar 2003 00:54:07 +0000 Subject: Connectathon fix. W2K -> W2K over port 445 doing a tconX does the full \\server\share syntax, not just a "share" tconX syntax. This broke interop with a vendor. Jeremy. (This used to be commit 9d7ea5585c873156ede4b56e43a0d4d75077283a) --- source3/libsmb/cliconnect.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4962ffa3c9..49b0004ac2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -780,13 +780,8 @@ BOOL cli_send_tconX(struct cli_state *cli, } } - if (cli->port == 445) { - slprintf(fullshare, sizeof(fullshare)-1, - "%s", share); - } else { - slprintf(fullshare, sizeof(fullshare)-1, - "\\\\%s\\%s", cli->desthost, share); - } + slprintf(fullshare, sizeof(fullshare)-1, + "\\\\%s\\%s", cli->desthost, share); set_message(cli->outbuf,4, 0, True); SCVAL(cli->outbuf,smb_com,SMBtconX); -- cgit From 1cdafbf17ebbcb1840cdb1bde3b49600406ed904 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Mar 2003 01:30:26 +0000 Subject: Writable string const fixes. Jeremy. (This used to be commit 60b0cfc8a5b6275d3460ebc6bf17d0f08e25b67e) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 62b94761ad..18ce5e4bd9 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1263,7 +1263,7 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int * /* If it's our domain then use the 'password server' parameter. */ if (strequal(domain, lp_workgroup())) { - char *p; + const char *p; char *pserver = lp_passwordserver(); /* UNIX charset. */ fstring name; int num_addresses = 0; -- cgit From bbf8961b284a877b5cfa4101e0fd677664a867f1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 8 Mar 2003 05:18:08 +0000 Subject: Make it clear that this is a fstrcpy(). (This used to be commit c2a266b7b661d319e13982bfdbc3a86e8502b8a4) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9598f4ac96..6ef7a7bd9c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -200,8 +200,8 @@ void cli_setup_bcc(struct cli_state *cli, void *p) void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) { /* copy_nt_creds(&cli->usr, usr); */ - safe_strcpy(cli->domain , usr->domain , sizeof(usr->domain )-1); - safe_strcpy(cli->user_name, usr->user_name, sizeof(usr->user_name)-1); + fstrcpy(cli->domain , usr->domain); + fstrcpy(cli->user_name, usr->user_name); memcpy(&cli->pwd, &usr->pwd, sizeof(usr->pwd)); cli->ntlmssp_flags = usr->ntlmssp_flags; cli->ntlmssp_cli_flgs = usr != NULL ? usr->ntlmssp_flags : 0; -- cgit From 2ed7730f2d498a446dc7281e652d02a9dd2d94cf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 Mar 2003 09:23:09 +0000 Subject: Change the way we sign SMB packets, to a function pointer interface. The intention is to allow for NTLMSSP and kerberos signing of packets, but for now it's just what I call 'simple' signing. (aka SMB signing per the SNIA spec) Andrew Bartlett (This used to be commit b9cf95c3dc04a45de71fb16e85c1bfbae50e6d8f) --- source3/libsmb/cliconnect.c | 47 +------ source3/libsmb/clientgen.c | 8 +- source3/libsmb/smb_signing.c | 329 +++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/smbencrypt.c | 100 +------------ 4 files changed, 338 insertions(+), 146 deletions(-) create mode 100644 source3/libsmb/smb_signing.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 49b0004ac2..589c7b36bb 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -228,39 +228,11 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, return True; } -static void set_signing_on_cli (struct cli_state *cli, uint8 user_session_key[16], DATA_BLOB response) -{ - uint8 zero_sig[8]; - ZERO_STRUCT(zero_sig); - - DEBUG(5, ("Server returned security sig:\n")); - dump_data(5, &cli->inbuf[smb_ss_field], 8); - - if (cli->sign_info.use_smb_signing) { - DEBUG(5, ("smb signing already active on connection\n")); - } else if (memcmp(&cli->inbuf[smb_ss_field], zero_sig, 8) != 0) { - - DEBUG(3, ("smb signing enabled!\n")); - cli->sign_info.use_smb_signing = True; - cli_calculate_mac_key(cli, user_session_key, response); - } else { - DEBUG(5, ("smb signing NOT enabled!\n")); - } -} - static void set_cli_session_key (struct cli_state *cli, DATA_BLOB session_key) { memcpy(cli->user_session_key, session_key.data, MIN(session_key.length, sizeof(cli->user_session_key))); } - -static void set_temp_signing_on_cli(struct cli_state *cli) -{ - if (cli->sign_info.negotiated_smb_signing) - cli->sign_info.temp_smb_signing = True; -} - - /**************************************************************************** do a NT1 NTLM/LM encrypted session setup @param cli client state to create do session setup on @@ -310,8 +282,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - - set_temp_signing_on_cli(cli); + cli_simple_set_signing(cli, session_key.data, nt_response); } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -374,14 +345,14 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (session_key.data) { /* Have plaintext orginal */ set_cli_session_key(cli, session_key); - set_signing_on_cli(cli, session_key.data, nt_response); } + ret = True; end: data_blob_free(&lm_response); data_blob_free(&nt_response); data_blob_free(&session_key); - return True; + return ret; } /**************************************************************************** @@ -403,8 +374,6 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) set_message(cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); - set_temp_signing_on_cli(cli); - cli_setup_packet(cli); SCVAL(cli->outbuf,smb_vwv0,0xFF); @@ -883,11 +852,6 @@ BOOL cli_negprot(struct cli_state *cli) int numprots; int plength; - if (cli->sign_info.use_smb_signing) { - DEBUG(0, ("Cannot send negprot again, particularly after setting up SMB Signing\n")); - return False; - } - if (cli->protocol < PROTOCOL_NT1) cli->use_spnego = False; @@ -1013,11 +977,6 @@ BOOL cli_session_request(struct cli_state *cli, if (cli->port == 445) return True; - if (cli->sign_info.use_smb_signing) { - DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n")); - return False; - } - /* send a session request (RFC 1002) */ /* setup the packet length * Remove four bytes from the length count, since the length diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6ef7a7bd9c..3cae643c38 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -177,9 +177,6 @@ void cli_setup_packet(struct cli_state *cli) flags2 |= FLAGS2_32_BIT_ERROR_CODES; if (cli->use_spnego) flags2 |= FLAGS2_EXTENDED_SECURITY; - if (cli->sign_info.use_smb_signing - || cli->sign_info.temp_smb_signing) - flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(cli->outbuf,smb_flg2, flags2); } } @@ -262,6 +259,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = True; + /* initialise signing */ + cli_null_set_signing(cli); + if (lp_client_signing()) cli->sign_info.allow_smb_signing = True; @@ -303,6 +303,7 @@ void cli_close_connection(struct cli_state *cli) SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); + cli_free_signing_context(cli); data_blob_free(&cli->secblob); if (cli->mem_ctx) { @@ -314,6 +315,7 @@ void cli_close_connection(struct cli_state *cli) close(cli->fd); cli->fd = -1; cli->smb_rw_error = 0; + } /**************************************************************************** diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c new file mode 100644 index 0000000000..b3a6351893 --- /dev/null +++ b/source3/libsmb/smb_signing.c @@ -0,0 +1,329 @@ +/* + Unix SMB/CIFS implementation. + SMB Signing Code + Copyright (C) Jeremy Allison 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +struct smb_basic_signing_context { + DATA_BLOB mac_key; + uint32 send_seq_num; + uint32 reply_seq_num; +}; + +/*********************************************************** + SMB signing - Common code before we set a new signing implementation +************************************************************/ + +static BOOL set_smb_signing_common(struct cli_state *cli) +{ + if (cli->sign_info.doing_signing) { + return False; + } + + if (cli->sign_info.free_signing_context) + cli->sign_info.free_signing_context(cli); + + /* These calls are INCONPATIBLE with SMB signing */ + cli->readbraw_supported = False; + cli->writebraw_supported = False; + + return True; +} + +/*********************************************************** + SMB signing - Common code for 'real' implementations +************************************************************/ + +static BOOL set_smb_signing_real_common(struct cli_state *cli) +{ + if (cli->sign_info.mandetory_signing) { + DEBUG(5, ("Mandetory SMB signing enabled!\n")); + cli->sign_info.doing_signing = True; + } + + DEBUG(5, ("SMB signing enabled!\n")); + + return True; +} + +static void mark_packet_signed(struct cli_state *cli) +{ + uint16 flags2; + flags2 = SVAL(cli->outbuf,smb_flg2); + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; + SSVAL(cli->outbuf,smb_flg2, flags2); +} + +/*********************************************************** + SMB signing - Simple implementation - calculate a MAC to send. +************************************************************/ + +static void cli_simple_sign_outgoing_message(struct cli_state *cli) +{ + unsigned char calc_md5_mac[16]; + struct MD5Context md5_ctx; + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + */ + SIVAL(cli->outbuf, smb_ss_field, + data->send_seq_num); + SIVAL(cli->outbuf, smb_ss_field + 4, 0); + + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(cli); + + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, data->mac_key.data, + data->mac_key.length); + MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); + MD5Final(calc_md5_mac, &md5_ctx); + + DEBUG(10, ("sent SMB signiture of\n")); + dump_data(10, calc_md5_mac, 8); + + memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); + +/* cli->outbuf[smb_ss_field+2]=0; + Uncomment this to test if the remote server actually verifies signitures...*/ + data->send_seq_num++; + data->reply_seq_num = data->send_seq_num; + data->send_seq_num++; +} + +/*********************************************************** + SMB signing - Simple implementation - check a MAC sent by server. +************************************************************/ + +static BOOL cli_simple_check_incoming_message(struct cli_state *cli) +{ + BOOL good; + unsigned char calc_md5_mac[16]; + unsigned char server_sent_mac[8]; + struct MD5Context md5_ctx; + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + */ + + memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); + + DEBUG(10, ("got SMB signiture of\n")); + dump_data(10, server_sent_mac, 8); + + SIVAL(cli->inbuf, smb_ss_field, data->reply_seq_num); + SIVAL(cli->inbuf, smb_ss_field + 4, 0); + + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, data->mac_key.data, + data->mac_key.length); + MD5Update(&md5_ctx, cli->inbuf + 4, smb_len(cli->inbuf)); + MD5Final(calc_md5_mac, &md5_ctx); + + good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + + if (good && !cli->sign_info.doing_signing) { + cli->sign_info.doing_signing = True; + } + + if (!good) { + DEBUG(1, ("SMB signiture check failed!\n")); + } + + return good; +} + +/*********************************************************** + SMB signing - Simple implementation - free signing context +************************************************************/ + +static void cli_simple_free_signing_context(struct cli_state *cli) +{ + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + data_blob_free(&data->mac_key); + SAFE_FREE(cli->sign_info.signing_context); + + return; +} + +/*********************************************************** + SMB signing - Simple implementation - setup the MAC key. +************************************************************/ + +void cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) +{ + struct smb_basic_signing_context *data; + + if (!set_smb_signing_common(cli)) { + return; + } + + if (!set_smb_signing_real_common(cli)) { + return; + } + + data = smb_xmalloc(sizeof(*data)); + cli->sign_info.signing_context = data; + + data->mac_key = data_blob(NULL, MIN(response.length + 16, 40)); + + memcpy(&data->mac_key.data[0], user_session_key, 16); + memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16)); + + /* Initialise the sequence number */ + data->send_seq_num = 0; + + cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; + cli->sign_info.check_incoming_message = cli_simple_check_incoming_message; + cli->sign_info.free_signing_context = cli_simple_free_signing_context; +} + +/*********************************************************** + SMB signing - NULL implementation - calculate a MAC to send. +************************************************************/ + +static void cli_null_sign_outgoing_message(struct cli_state *cli) +{ + static uchar zeros[8]; + memcpy(&cli->outbuf[smb_ss_field], zeros, sizeof(zeros)); +} + +/*********************************************************** + SMB signing - NULL implementation - check a MAC sent by server. +************************************************************/ + +static BOOL cli_null_check_incoming_message(struct cli_state *cli) +{ + return True; +} + +/*********************************************************** + SMB signing - NULL implementation - free signing context +************************************************************/ + +static void cli_null_free_signing_context(struct cli_state *cli) +{ + return; +} + +/*********************************************************** + SMB signing - NULL implementation - setup the MAC key. +************************************************************/ + +void cli_null_set_signing(struct cli_state *cli) +{ + struct smb_basic_sign_data *data; + + if (!set_smb_signing_common(cli)) { + return; + } + + cli->sign_info.signing_context = NULL; + + cli->sign_info.sign_outgoing_message = cli_null_sign_outgoing_message; + cli->sign_info.check_incoming_message = cli_null_check_incoming_message; + cli->sign_info.free_signing_context = cli_null_free_signing_context; +} + +/*********************************************************** + SMB signing - TEMP implementation - calculate a MAC to send. +************************************************************/ + +static void cli_temp_sign_outgoing_message(struct cli_state *cli) +{ + memcpy(&cli->outbuf[smb_ss_field], "SignRequest", 8); + return; +} + +/*********************************************************** + SMB signing - TEMP implementation - check a MAC sent by server. +************************************************************/ + +static BOOL cli_temp_check_incoming_message(struct cli_state *cli) +{ + return True; +} + +/*********************************************************** + SMB signing - TEMP implementation - free signing context +************************************************************/ + +static void cli_temp_free_signing_context(struct cli_state *cli) +{ + return; +} + +/*********************************************************** + SMB signing - NULL implementation - setup the MAC key. +************************************************************/ + +void cli_temp_set_signing(struct cli_state *cli) +{ + if (!set_smb_signing_common(cli)) { + return; + } + + cli->sign_info.signing_context = NULL; + + cli->sign_info.sign_outgoing_message = cli_temp_sign_outgoing_message; + cli->sign_info.check_incoming_message = cli_temp_check_incoming_message; + cli->sign_info.free_signing_context = cli_temp_free_signing_context; +} + +/** + * Free the singing context + */ + +void cli_free_signing_context(struct cli_state *cli) +{ + if (cli->sign_info.free_signing_context) + cli->sign_info.free_signing_context(cli); + + cli_null_set_signing(cli); +} + +void cli_caclulate_sign_mac(struct cli_state *cli) +{ + cli->sign_info.sign_outgoing_message(cli); +} + +BOOL cli_check_sign_mac(struct cli_state *cli) +{ + BOOL good; + good = cli->sign_info.check_incoming_message(cli); + + if (!good) { + if (cli->sign_info.doing_signing) { + return False; + } else { + cli_free_signing_context(cli); + } + } + + return True; +} + diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index aa9391325f..28160d9609 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -295,7 +295,7 @@ void SMBsesskeygen_ntv1(const uchar kr[16], #endif } -DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], +static DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], DATA_BLOB server_chal, size_t client_chal_length) { uchar ntlmv2_response[16]; @@ -416,101 +416,3 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, return True; } - -/*********************************************************** - SMB signing - setup the MAC key. -************************************************************/ - -void cli_calculate_mac_key(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) -{ - - memcpy(&cli->sign_info.mac_key[0], user_session_key, 16); - memcpy(&cli->sign_info.mac_key[16],response.data, MIN(response.length, 40 - 16)); - cli->sign_info.mac_key_len = MIN(response.length + 16, 40); - cli->sign_info.use_smb_signing = True; - - /* These calls are INCONPATIBLE with SMB signing */ - cli->readbraw_supported = False; - cli->writebraw_supported = False; - - /* Reset the sequence number in case we had a previous (aborted) attempt */ - cli->sign_info.send_seq_num = 2; -} - -/*********************************************************** - SMB signing - calculate a MAC to send. -************************************************************/ - -void cli_caclulate_sign_mac(struct cli_state *cli) -{ - unsigned char calc_md5_mac[16]; - struct MD5Context md5_ctx; - - if (cli->sign_info.temp_smb_signing) { - memcpy(&cli->outbuf[smb_ss_field], "SignRequest", 8); - cli->sign_info.temp_smb_signing = False; - return; - } - - if (!cli->sign_info.use_smb_signing) { - return; - } - - /* - * Firstly put the sequence number into the first 4 bytes. - * and zero out the next 4 bytes. - */ - SIVAL(cli->outbuf, smb_ss_field, cli->sign_info.send_seq_num); - SIVAL(cli->outbuf, smb_ss_field + 4, 0); - - /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ - MD5Init(&md5_ctx); - MD5Update(&md5_ctx, cli->sign_info.mac_key, cli->sign_info.mac_key_len); - MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); - MD5Final(calc_md5_mac, &md5_ctx); - - memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); - -/* cli->outbuf[smb_ss_field+2]=0; - Uncomment this to test if the remote server actually verifies signitures...*/ - cli->sign_info.send_seq_num++; - cli->sign_info.reply_seq_num = cli->sign_info.send_seq_num; - cli->sign_info.send_seq_num++; -} - -/*********************************************************** - SMB signing - check a MAC sent by server. -************************************************************/ - -BOOL cli_check_sign_mac(struct cli_state *cli) -{ - unsigned char calc_md5_mac[16]; - unsigned char server_sent_mac[8]; - struct MD5Context md5_ctx; - - if (cli->sign_info.temp_smb_signing) { - return True; - } - - if (!cli->sign_info.use_smb_signing) { - return True; - } - - /* - * Firstly put the sequence number into the first 4 bytes. - * and zero out the next 4 bytes. - */ - - memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - - SIVAL(cli->inbuf, smb_ss_field, cli->sign_info.reply_seq_num); - SIVAL(cli->inbuf, smb_ss_field + 4, 0); - - /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ - MD5Init(&md5_ctx); - MD5Update(&md5_ctx, cli->sign_info.mac_key, cli->sign_info.mac_key_len); - MD5Update(&md5_ctx, cli->inbuf + 4, smb_len(cli->inbuf)); - MD5Final(calc_md5_mac, &md5_ctx); - - return (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); -} -- cgit From 2b6a6df0f65caccb31c78008539d24f8c4a2f72a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 Mar 2003 21:09:28 +0000 Subject: Try not to clobber the session request. (This used to be commit 05cffbee56f0556f550b4d14f3111bd7db972621) --- source3/libsmb/smb_signing.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index b3a6351893..581d18fef7 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -208,8 +208,10 @@ void cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ static void cli_null_sign_outgoing_message(struct cli_state *cli) { - static uchar zeros[8]; - memcpy(&cli->outbuf[smb_ss_field], zeros, sizeof(zeros)); + /* we can't zero out the sig, as we might be trying to send a + session request - which is NBT-level, not SMB level and doesn't + have the feild */ + return; } /*********************************************************** @@ -295,7 +297,7 @@ void cli_temp_set_signing(struct cli_state *cli) } /** - * Free the singing context + * Free the singing context */ void cli_free_signing_context(struct cli_state *cli) @@ -306,11 +308,21 @@ void cli_free_signing_context(struct cli_state *cli) cli_null_set_signing(cli); } +/** + * Sign a packet with the current mechinism + */ + void cli_caclulate_sign_mac(struct cli_state *cli) { cli->sign_info.sign_outgoing_message(cli); } +/** + * Check a packet with the current mechinism + * @return False if we had an established signing connection + * which had a back checksum, True otherwise + */ + BOOL cli_check_sign_mac(struct cli_state *cli) { BOOL good; -- cgit From e9a94cd2c9cab4518603620259dae44b40d9049e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 10 Mar 2003 02:14:35 +0000 Subject: Further work on NTLMSSP-based SMB signing. Current status is that I cannnot get Win2k to send a valid signiture in it's session setup reply - which it will give to win2k clients. So, I need to look at becoming 'more like MS', but for now I'll get this code into the tree. It's actually based on the TNG cli_pipe_ntlmssp.c, as it was slightly easier to understand than our own (but only the utility functions remain in any way intact...). This includes the mysical 'NTLM2' code - I have no idea if it actually works. (I couldn't get TNG to use it for its pipes either). Andrew Bartlett (This used to be commit a034a5e381ba5612be21e2ba640d11f82cd945da) --- source3/libsmb/cliconnect.c | 47 ++++++++-- source3/libsmb/ntlmssp.c | 37 +++++--- source3/libsmb/ntlmssp_sign.c | 208 ++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/smb_signing.c | 180 ++++++++++++++++++++++++++++++------ 4 files changed, 424 insertions(+), 48 deletions(-) create mode 100644 source3/libsmb/ntlmssp_sign.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 589c7b36bb..36b6f609f5 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -356,15 +356,13 @@ end: } /**************************************************************************** - Send a extended security session setup blob, returning a reply blob. + Send a extended security session setup blob ****************************************************************************/ -static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) +static BOOL cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob) { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; - DATA_BLOB blob2 = data_blob(NULL, 0); - uint32 len; capabilities |= CAP_EXTENDED_SECURITY; @@ -389,7 +387,18 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); + return cli_send_smb(cli); +} + +/**************************************************************************** + Send a extended security session setup blob, returning a reply blob. +****************************************************************************/ + +static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli) +{ + DATA_BLOB blob2 = data_blob(NULL, 0); + char *p; + size_t len; if (!cli_receive_smb(cli)) return blob2; @@ -418,6 +427,20 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) return blob2; } +/**************************************************************************** + Send a extended security session setup blob, returning a reply blob. +****************************************************************************/ + +static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) +{ + DATA_BLOB blob2 = data_blob(NULL, 0); + if (!cli_session_setup_blob_send(cli, blob)) { + return blob2; + } + + return cli_session_setup_blob_receive(cli); +} + #ifdef HAVE_KRB5 /**************************************************************************** Use in-memory credentials cache @@ -471,6 +494,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, DATA_BLOB blob_in = data_blob(NULL, 0); DATA_BLOB blob_out; + cli_temp_set_signing(cli); + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { return False; } @@ -501,8 +526,15 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, } /* now send that blob on its way */ - blob = cli_session_setup_blob(cli, msg1); + if (!cli_session_setup_blob_send(cli, msg1)) { + return False; + } data_blob_free(&msg1); + + cli_ntlmssp_set_signing(cli, ntlmssp_state); + + blob = cli_session_setup_blob_receive(cli); + nt_status = cli_nt_error(cli); } @@ -539,6 +571,9 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, set_cli_session_key(cli, ntlmssp_state->session_key); } + /* we have a reference conter on ntlmssp_state, if we are signing + then the state will be kept by the signing engine */ + if (!NT_STATUS_IS_OK(ntlmssp_client_end(&ntlmssp_state))) { return False; } diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index e1509f6b63..5722b8efcd 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -81,7 +81,7 @@ static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) /** * Determine correct target name flags for reply, given server role - * and negoitated falgs + * and negotiated flags * * @param ntlmssp_state NTLMSSP State * @param neg_flags The flags from the packet @@ -291,7 +291,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, /** * Create an NTLMSSP state machine * - * @param ntlmssp_state NTLMSSP State, allocated by this funciton + * @param ntlmssp_state NTLMSSP State, allocated by this function */ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) @@ -322,7 +322,7 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) /** * End an NTLMSSP state machine * - * @param ntlmssp_state NTLMSSP State, free()ed by this funciton + * @param ntlmssp_state NTLMSSP State, free()ed by this function */ NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) @@ -431,7 +431,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st DATA_BLOB session_key = data_blob(NULL, 0); uint8 datagram_sess_key[16]; - ZERO_STRUCT(datagram_sess_key); + generate_random_buffer(datagram_sess_key, sizeof(datagram_sess_key), False); if (!msrpc_parse(&reply, "CdBd", "NTLMSSP", @@ -508,8 +508,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - - data_blob_free(&challenge_blob); /* this generates the actual auth packet */ if (!msrpc_gen(next_request, auth_gen_string, @@ -520,7 +518,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->get_global_myname(), - datagram_sess_key, 0, + datagram_sess_key, 16, ntlmssp_state->neg_flags)) { data_blob_free(&lm_response); @@ -529,9 +527,14 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st return NT_STATUS_NO_MEMORY; } - data_blob_free(&lm_response); - data_blob_free(&nt_response); + data_blob_free(&ntlmssp_state->chal); + data_blob_free(&ntlmssp_state->lm_resp); + data_blob_free(&ntlmssp_state->nt_resp); + data_blob_free(&ntlmssp_state->session_key); + ntlmssp_state->chal = challenge_blob; + ntlmssp_state->lm_resp = lm_response; + ntlmssp_state->nt_resp = nt_response; ntlmssp_state->session_key = session_key; return NT_STATUS_MORE_PROCESSING_REQUIRED; @@ -558,10 +561,12 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) (*ntlmssp_state)->unicode = True; (*ntlmssp_state)->neg_flags = - NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_REQUEST_TARGET; + (*ntlmssp_state)->ref_count = 1; + return NT_STATUS_OK; } @@ -569,8 +574,16 @@ NTSTATUS ntlmssp_client_end(NTLMSSP_CLIENT_STATE **ntlmssp_state) { TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; - data_blob_free(&(*ntlmssp_state)->session_key); - talloc_destroy(mem_ctx); + (*ntlmssp_state)->ref_count--; + + if ((*ntlmssp_state)->ref_count == 0) { + data_blob_free(&(*ntlmssp_state)->chal); + data_blob_free(&(*ntlmssp_state)->lm_resp); + data_blob_free(&(*ntlmssp_state)->nt_resp); + data_blob_free(&(*ntlmssp_state)->session_key); + talloc_destroy(mem_ctx); + } + *ntlmssp_state = NULL; return NT_STATUS_OK; } diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c new file mode 100644 index 0000000000..f51d532319 --- /dev/null +++ b/source3/libsmb/ntlmssp_sign.c @@ -0,0 +1,208 @@ +/* + * Unix SMB/CIFS implementation. + * Version 3.0 + * NTLMSSP Signing routines + * Copyright (C) Luke Kenneth Casson Leighton 1996-2001 + * Copyright (C) Andrew Bartlett 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 2 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, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "includes.h" + +#define CLI_SIGN "session key to client-to-server signing key magic constant" +#define CLI_SEAL "session key to client-to-server sealing key magic constant" +#define SRV_SIGN "session key to server-to-client signing key magic constant" +#define SRV_SEAL "session key to server-to-client sealing key magic constant" + +static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len) +{ + unsigned char index_i = hash[256]; + unsigned char index_j = hash[257]; + int ind; + + for (ind = 0; ind < len; ind++) + { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += hash[index_i]; + + tc = hash[index_i]; + hash[index_i] = hash[index_j]; + hash[index_j] = tc; + + t = hash[index_i] + hash[index_j]; + data[ind] = data[ind] ^ hash[t]; + } + + hash[256] = index_i; + hash[257] = index_j; +} + +static void calc_hash(unsigned char *hash, const char *k2, int k2l) +{ + unsigned char j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) + { + hash[ind] = (unsigned char)ind; + } + + for (ind = 0; ind < 256; ind++) + { + unsigned char tc; + + j += (hash[ind] + k2[ind%k2l]); + + tc = hash[ind]; + hash[ind] = hash[j]; + hash[j] = tc; + } + + hash[256] = 0; + hash[257] = 0; +} + +static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], + const char encrypted_response[16], + const char *constant) +{ + struct MD5Context ctx3; + + MD5Init(&ctx3); + MD5Update(&ctx3, encrypted_response, 5); + MD5Update(&ctx3, constant, strlen(constant)); + MD5Final(digest, &ctx3); + + calc_hash(hash, digest, 16); +} + +static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_state, + const uchar *data, size_t length, + DATA_BLOB *sig) +{ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + HMACMD5Context ctx; + char seq_num[4]; + uchar digest[16]; + SIVAL(seq_num, 0, &ntlmssp_state->ntlmssp_seq_num); + + hmac_md5_init_limK_to_64(ntlmssp_state->cli_sign_const, 16, &ctx); + hmac_md5_update(seq_num, 4, &ctx); + hmac_md5_update(data, length, &ctx); + hmac_md5_final(digest, &ctx); + + if (!msrpc_gen(sig, "Bd", digest, sizeof(digest), ntlmssp_state->ntlmssp_seq_num)) { + return NT_STATUS_NO_MEMORY; + } + + NTLMSSPcalc_ap(ntlmssp_state->cli_seal_hash, sig->data, sig->length); + } else { + uint32 crc; + crc = crc32_calc_buffer(data, length); + if (!msrpc_gen(sig, "ddd", 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + return NT_STATUS_NO_MEMORY; + } + + NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data, sig->length); + } + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, + const uchar *data, size_t length, + DATA_BLOB *sig) +{ + ntlmssp_state->ntlmssp_seq_num++; + return ntlmssp_make_packet_signiture(ntlmssp_state, data, length, sig); +} + +/** + * Check the signature of an incoming packet + * @note caller *must* check that the signature is the size it expects + * + */ + +NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, + const uchar *data, size_t length, + const DATA_BLOB *sig) +{ + DATA_BLOB local_sig; + NTSTATUS nt_status; + + if (sig->length < 8) { + DEBUG(0, ("NTLMSSP packet check failed due to short signiture (%u bytes)!\n", + sig->length)); + } + + nt_status = ntlmssp_make_packet_signiture(ntlmssp_state, data, + length, &local_sig); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status))); + return nt_status; + } + + if (memcmp(sig->data, local_sig.data, MIN(sig->length, local_sig.length)) == 0) { + return NT_STATUS_OK; + } else { + DEBUG(0, ("NTLMSSP packet check failed due to invalid signiture!\n")); + return NT_STATUS_ACCESS_DENIED; + } +} + +/** + Initialise the state for NTLMSSP signing. +*/ +NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) +{ + unsigned char p24[24]; + unsigned char lm_hash[16]; + + if (!ntlmssp_state->lm_resp.data) { + /* can't sign or check signitures yet */ + return NT_STATUS_UNSUCCESSFUL; + } + + E_deshash(ntlmssp_state->password, lm_hash); + + NTLMSSPOWFencrypt(lm_hash, ntlmssp_state->lm_resp.data, p24); + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) + { + calc_ntlmv2_hash(ntlmssp_state->cli_sign_hash, ntlmssp_state->cli_sign_const, p24, CLI_SIGN); + calc_ntlmv2_hash(ntlmssp_state->cli_seal_hash, ntlmssp_state->cli_seal_const, p24, CLI_SEAL); + calc_ntlmv2_hash(ntlmssp_state->srv_sign_hash, ntlmssp_state->srv_sign_const, p24, SRV_SIGN); + calc_ntlmv2_hash(ntlmssp_state->srv_seal_hash, ntlmssp_state->srv_seal_const, p24, SRV_SEAL); + } + else + { + char k2[8]; + memcpy(k2, p24, 5); + k2[5] = 0xe5; + k2[6] = 0x38; + k2[7] = 0xb0; + + calc_hash(ntlmssp_state->ntlmssp_hash, k2, 8); + } + + ntlmssp_state->ntlmssp_seq_num = 0; + + ZERO_STRUCT(lm_hash); + return NT_STATUS_OK; +} diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 581d18fef7..40359c5c8c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -33,6 +33,11 @@ struct smb_basic_signing_context { static BOOL set_smb_signing_common(struct cli_state *cli) { + if (!cli->sign_info.negotiated_smb_signing + && !cli->sign_info.mandetory_signing) { + return False; + } + if (cli->sign_info.doing_signing) { return False; } @@ -40,7 +45,7 @@ static BOOL set_smb_signing_common(struct cli_state *cli) if (cli->sign_info.free_signing_context) cli->sign_info.free_signing_context(cli); - /* These calls are INCONPATIBLE with SMB signing */ + /* These calls are INCOMPATIBLE with SMB signing */ cli->readbraw_supported = False; cli->writebraw_supported = False; @@ -54,7 +59,7 @@ static BOOL set_smb_signing_common(struct cli_state *cli) static BOOL set_smb_signing_real_common(struct cli_state *cli) { if (cli->sign_info.mandetory_signing) { - DEBUG(5, ("Mandetory SMB signing enabled!\n")); + DEBUG(5, ("Mandatory SMB signing enabled!\n")); cli->sign_info.doing_signing = True; } @@ -71,6 +76,28 @@ static void mark_packet_signed(struct cli_state *cli) SSVAL(cli->outbuf,smb_flg2, flags2); } +static BOOL signing_good(struct cli_state *cli, BOOL good) +{ + DEBUG(10, ("got SMB signature of\n")); + dump_data(10,&cli->outbuf[smb_ss_field] , 8); + + if (good && !cli->sign_info.doing_signing) { + cli->sign_info.doing_signing = True; + } + + if (!good) { + if (cli->sign_info.doing_signing) { + DEBUG(1, ("SMB signature check failed!\n")); + return False; + } else { + DEBUG(3, ("Server did not sign reply correctly\n")); + cli_free_signing_context(cli); + return False; + } + } + return True; +} + /*********************************************************** SMB signing - Simple implementation - calculate a MAC to send. ************************************************************/ @@ -99,7 +126,7 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); MD5Final(calc_md5_mac, &md5_ctx); - DEBUG(10, ("sent SMB signiture of\n")); + DEBUG(10, ("sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); @@ -130,7 +157,7 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - DEBUG(10, ("got SMB signiture of\n")); + DEBUG(10, ("got SMB signature of\n")); dump_data(10, server_sent_mac, 8); SIVAL(cli->inbuf, smb_ss_field, data->reply_seq_num); @@ -145,15 +172,7 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); - if (good && !cli->sign_info.doing_signing) { - cli->sign_info.doing_signing = True; - } - - if (!good) { - DEBUG(1, ("SMB signiture check failed!\n")); - } - - return good; + return signing_good(cli, good); } /*********************************************************** @@ -174,16 +193,16 @@ static void cli_simple_free_signing_context(struct cli_state *cli) SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -void cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) +BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) { struct smb_basic_signing_context *data; if (!set_smb_signing_common(cli)) { - return; + return False; } if (!set_smb_signing_real_common(cli)) { - return; + return False; } data = smb_xmalloc(sizeof(*data)); @@ -194,12 +213,105 @@ void cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ memcpy(&data->mac_key.data[0], user_session_key, 16); memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16)); - /* Initialise the sequence number */ + /* Initialize the sequence number */ data->send_seq_num = 0; cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; cli->sign_info.check_incoming_message = cli_simple_check_incoming_message; cli->sign_info.free_signing_context = cli_simple_free_signing_context; + + return True; +} + +/*********************************************************** + SMB signing - NTLMSSP implementation - calculate a MAC to send. +************************************************************/ + +static void cli_ntlmssp_sign_outgoing_message(struct cli_state *cli) +{ + NTSTATUS nt_status; + DATA_BLOB sig; + NTLMSSP_CLIENT_STATE *ntlmssp_state = cli->sign_info.signing_context; + + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(cli); + + nt_status = ntlmssp_client_sign_packet(ntlmssp_state, cli->outbuf + 4, + smb_len(cli->outbuf), &sig); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("NTLMSSP signing failed with %s\n", nt_errstr(nt_status))); + return; + } + + DEBUG(10, ("sent SMB signature of\n")); + dump_data(10, sig.data, MIN(sig.length, 8)); + memcpy(&cli->outbuf[smb_ss_field], sig.data, MIN(sig.length, 8)); + + data_blob_free(&sig); +} + +/*********************************************************** + SMB signing - NTLMSSP implementation - check a MAC sent by server. +************************************************************/ + +static BOOL cli_ntlmssp_check_incoming_message(struct cli_state *cli) +{ + BOOL good; + NTSTATUS nt_status; + DATA_BLOB sig = data_blob(&cli->outbuf[smb_ss_field], 8); + + NTLMSSP_CLIENT_STATE *ntlmssp_state = cli->sign_info.signing_context; + + nt_status = ntlmssp_client_check_packet(ntlmssp_state, cli->outbuf + 4, + smb_len(cli->outbuf), &sig); + + data_blob_free(&sig); + + good = NT_STATUS_IS_OK(nt_status); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(5, ("NTLMSSP signing failed with %s\n", nt_errstr(nt_status))); + } + + return signing_good(cli, good); +} + +/*********************************************************** + SMB signing - NTLMSSP implementation - free signing context +************************************************************/ + +static void cli_ntlmssp_free_signing_context(struct cli_state *cli) +{ + ntlmssp_client_end((NTLMSSP_CLIENT_STATE **)&cli->sign_info.signing_context); +} + +/*********************************************************** + SMB signing - NTLMSSP implementation - setup the MAC key. +************************************************************/ + +BOOL cli_ntlmssp_set_signing(struct cli_state *cli, + NTLMSSP_CLIENT_STATE *ntlmssp_state) +{ + if (!set_smb_signing_common(cli)) { + return False; + } + + if (!NT_STATUS_IS_OK(ntlmssp_client_sign_init(ntlmssp_state))) { + return False; + } + + if (!set_smb_signing_real_common(cli)) { + return False; + } + + cli->sign_info.signing_context = ntlmssp_state; + ntlmssp_state->ref_count++; + + cli->sign_info.sign_outgoing_message = cli_ntlmssp_sign_outgoing_message; + cli->sign_info.check_incoming_message = cli_ntlmssp_check_incoming_message; + cli->sign_info.free_signing_context = cli_ntlmssp_free_signing_context; + + return True; } /*********************************************************** @@ -210,7 +322,7 @@ static void cli_null_sign_outgoing_message(struct cli_state *cli) { /* we can't zero out the sig, as we might be trying to send a session request - which is NBT-level, not SMB level and doesn't - have the feild */ + have the field */ return; } @@ -232,23 +344,24 @@ static void cli_null_free_signing_context(struct cli_state *cli) return; } -/*********************************************************** +/** SMB signing - NULL implementation - setup the MAC key. -************************************************************/ -void cli_null_set_signing(struct cli_state *cli) + @note Used as an initialisation only - it will not correctly + shut down a real signing mechinism +*/ + +BOOL cli_null_set_signing(struct cli_state *cli) { struct smb_basic_sign_data *data; - if (!set_smb_signing_common(cli)) { - return; - } - cli->sign_info.signing_context = NULL; cli->sign_info.sign_outgoing_message = cli_null_sign_outgoing_message; cli->sign_info.check_incoming_message = cli_null_check_incoming_message; cli->sign_info.free_signing_context = cli_null_free_signing_context; + + return True; } /*********************************************************** @@ -257,7 +370,12 @@ void cli_null_set_signing(struct cli_state *cli) static void cli_temp_sign_outgoing_message(struct cli_state *cli) { - memcpy(&cli->outbuf[smb_ss_field], "SignRequest", 8); + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(cli); + + /* I wonder what BSRSPYL stands for - but this is what MS + actually sends! */ + memcpy(&cli->outbuf[smb_ss_field], "BSRSPYL ", 8); return; } @@ -283,10 +401,10 @@ static void cli_temp_free_signing_context(struct cli_state *cli) SMB signing - NULL implementation - setup the MAC key. ************************************************************/ -void cli_temp_set_signing(struct cli_state *cli) +BOOL cli_temp_set_signing(struct cli_state *cli) { if (!set_smb_signing_common(cli)) { - return; + return False; } cli->sign_info.signing_context = NULL; @@ -294,6 +412,8 @@ void cli_temp_set_signing(struct cli_state *cli) cli->sign_info.sign_outgoing_message = cli_temp_sign_outgoing_message; cli->sign_info.check_incoming_message = cli_temp_check_incoming_message; cli->sign_info.free_signing_context = cli_temp_free_signing_context; + + return True; } /** @@ -309,7 +429,7 @@ void cli_free_signing_context(struct cli_state *cli) } /** - * Sign a packet with the current mechinism + * Sign a packet with the current mechanism */ void cli_caclulate_sign_mac(struct cli_state *cli) @@ -318,7 +438,7 @@ void cli_caclulate_sign_mac(struct cli_state *cli) } /** - * Check a packet with the current mechinism + * Check a packet with the current mechanism * @return False if we had an established signing connection * which had a back checksum, True otherwise */ -- cgit From 06c4d9a8ff4373227ba6a418b8af627aaddbc4d0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 10 Mar 2003 16:59:29 +0000 Subject: Some conversion to pstrcpy_base. Volker (This used to be commit 329911e43681b724cb0579aad77b4a658759d7ba) --- source3/libsmb/clirap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 24108d40f3..a1845b2e16 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -85,19 +85,19 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) p = param; SSVAL(p,0,132); /* api number */ p += 2; - pstrcpy(p,"OOWb54WrLh"); + pstrcpy_base(p,"OOWb54WrLh",param); p = skip_string(p,1); - pstrcpy(p,"WB21BWDWWDDDDDDDzzzD"); + pstrcpy_base(p,"WB21BWDWWDDDDDDDzzzD",param); p = skip_string(p,1); SSVAL(p,0,1); p += 2; - pstrcpy(p,user); + pstrcpy_base(p,user,param); strupper(p); p += 21; p++; p += 15; p++; - pstrcpy(p, workstation); + pstrcpy_base(p, workstation, param); strupper(p); p += 16; SSVAL(p, 0, CLI_BUFFER_SIZE); @@ -145,9 +145,9 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co p = param; SSVAL(p,0,0); /* api number */ p += 2; - pstrcpy(p,"WrLeh"); + pstrcpy_base(p,"WrLeh",param); p = skip_string(p,1); - pstrcpy(p,"B13BWz"); + pstrcpy_base(p,"B13BWz",param); p = skip_string(p,1); SSVAL(p,0,1); /* -- cgit From ddfed383a0791986c6d08fde67840e99424ebb1a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Mar 2003 22:24:12 +0000 Subject: Change size parameters from signed to unsigned to fix up warnings. Jeremy. (This used to be commit 2e9880ef7c259b67eb75edc8098b734c3b7b22c1) --- source3/libsmb/clifile.c | 12 +-- source3/libsmb/clilist.c | 2 +- source3/libsmb/clirap.c | 38 ++++---- source3/libsmb/clitrans.c | 233 ++++++++++++++++++++++++++++++++-------------- 4 files changed, 190 insertions(+), 95 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 31d7ea5911..f61787abde 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -29,8 +29,8 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, const char *fname_dst, BOOL hard_link) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; char param[sizeof(pstring)+6]; pstring data; @@ -123,8 +123,8 @@ BOOL cli_unix_hardlink(struct cli_state *cli, const char *fname_src, const char static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, uint32 mode, uint32 uid, uint32 gid) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; char param[sizeof(pstring)+6]; char data[100]; @@ -335,8 +335,8 @@ BOOL cli_rmdir(struct cli_state *cli, const char *dname) int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) { - int data_len = 1; - int param_len = 6; + unsigned int data_len = 1; + unsigned int param_len = 6; uint16 setup = TRANSACT2_SETFILEINFO; pstring param; unsigned char data; diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 89ab5d6414..3884e4da82 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -154,7 +154,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, int ff_dir_handle=0; int loop_count = 0; char *rparam=NULL, *rdata=NULL; - int param_len, data_len; + unsigned int param_len, data_len; uint16 setup; pstring param; diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index a1845b2e16..b38e7d5c23 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -41,8 +41,8 @@ BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name, data, data_count, max_data_count); return (cli_receive_trans(cli, SMBtrans, - rparam, (int *)rparam_count, - rdata, (int *)rdata_count)); + rparam, (unsigned int *)rparam_count, + rdata, (unsigned int *)rdata_count)); } /**************************************************************************** @@ -51,8 +51,8 @@ call a remote api BOOL cli_api(struct cli_state *cli, char *param, int prcnt, int mprcnt, char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt) + char **rparam, unsigned int *rprcnt, + char **rdata, unsigned int *rdrcnt) { cli_send_trans(cli,SMBtrans, PIPE_LANMAN, /* Name */ @@ -286,8 +286,8 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char char *p = param; unsigned char old_pw_hash[16]; unsigned char new_pw_hash[16]; - int data_len; - int param_len = 0; + unsigned int data_len; + unsigned int param_len = 0; char *rparam = NULL; char *rdata = NULL; int rprcnt, rdrcnt; @@ -368,9 +368,9 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, size_t *size, uint16 *mode) { - int data_len = 0; - int param_len = 0; - int rparam_len, rdata_len; + unsigned int data_len = 0; + unsigned int param_len = 0; + unsigned int rparam_len, rdata_len; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -449,8 +449,8 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, time_t *w_time, size_t *size, uint16 *mode, SMB_INO_T *ino) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -518,8 +518,8 @@ send a qfileinfo QUERY_FILE_NAME_INFO call BOOL cli_qfilename(struct cli_state *cli, int fnum, pstring name) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -563,8 +563,8 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, SMB_INO_T *ino) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -631,8 +631,8 @@ send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -677,8 +677,8 @@ send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call ****************************************************************************/ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 3d862a1796..7e3357a8cc 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -24,18 +24,19 @@ /**************************************************************************** - send a SMB trans or trans2 request - ****************************************************************************/ + Send a SMB trans or trans2 request. +****************************************************************************/ + BOOL cli_send_trans(struct cli_state *cli, int trans, const char *pipe_name, int fid, int flags, - uint16 *setup, int lsetup, int msetup, - char *param, int lparam, int mparam, - char *data, int ldata, int mdata) + uint16 *setup, unsigned int lsetup, unsigned int msetup, + char *param, unsigned int lparam, unsigned int mparam, + char *data, unsigned int ldata, unsigned int mdata) { int i; - int this_ldata,this_lparam; - int tot_data=0,tot_param=0; + unsigned int this_ldata,this_lparam; + unsigned int tot_data=0,tot_param=0; char *outdata,*outparam; char *p; int pipe_name_len=0; @@ -83,14 +84,13 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!cli_receive_smb(cli) || - cli_is_error(cli)) { + if (!cli_receive_smb(cli) || cli_is_error(cli)) return(False); - } tot_data = this_ldata; tot_param = this_lparam; @@ -123,7 +123,8 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; tot_data += this_ldata; tot_param += this_lparam; @@ -133,17 +134,17 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, return(True); } - /**************************************************************************** - receive a SMB trans or trans2 response allocating the necessary memory - ****************************************************************************/ + Receive a SMB trans or trans2 response allocating the necessary memory. +****************************************************************************/ + BOOL cli_receive_trans(struct cli_state *cli,int trans, - char **param, int *param_len, - char **data, int *data_len) + char **param, unsigned int *param_len, + char **data, unsigned int *data_len) { - int total_data=0; - int total_param=0; - int this_data,this_param; + unsigned int total_data=0; + unsigned int total_param=0; + unsigned int this_data,this_param; NTSTATUS status; char *tdata; char *tparam; @@ -170,9 +171,8 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, */ status = cli_nt_error(cli); - if (NT_STATUS_IS_ERR(status)) { + if (NT_STATUS_IS_ERR(status)) return False; - } /* parse out the lengths */ total_data = SVAL(cli->inbuf,smb_tdrcnt); @@ -199,7 +199,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, *param = tparam; } - while (1) { + for (;;) { this_data = SVAL(cli->inbuf,smb_drcnt); this_param = SVAL(cli->inbuf,smb_prcnt); @@ -209,21 +209,59 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, return False; } - if (this_data) - memcpy(*data + SVAL(cli->inbuf,smb_drdisp), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_droff), - this_data); - if (this_param) - memcpy(*param + SVAL(cli->inbuf,smb_prdisp), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_proff), - this_param); + if (this_data + *data_len < this_data || + this_data + *data_len < *data_len || + this_param + *param_len < this_param || + this_param + *param_len < *param_len) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + + if (this_data) { + unsigned int data_offset_out = SVAL(cli->inbuf,smb_drdisp); + unsigned int data_offset_in = SVAL(cli->inbuf,smb_droff); + + if (data_offset_out > total_data || + data_offset_out + this_data > total_data || + data_offset_out + this_data < data_offset_out || + data_offset_out + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + if (data_offset_in > cli->bufsize || + data_offset_in + this_data > cli->bufsize || + data_offset_in + this_data < data_offset_in || + data_offset_in + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + + memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); + } + if (this_param) { + unsigned int param_offset_out = SVAL(cli->inbuf,smb_prdisp); + unsigned int param_offset_in = SVAL(cli->inbuf,smb_proff); + + if (param_offset_out > total_param || + param_offset_out + this_param > total_param || + param_offset_out + this_param < param_offset_out || + param_offset_out + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_trans\n")); + return False; + } + if (param_offset_in > cli->bufsize || + param_offset_in + this_param > cli->bufsize || + param_offset_in + this_param < param_offset_in || + param_offset_in + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_trans\n")); + return False; + } + + memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); + } *data_len += this_data; *param_len += this_param; - /* parse out the total lengths again - they can shrink! */ - total_data = SVAL(cli->inbuf,smb_tdrcnt); - total_param = SVAL(cli->inbuf,smb_tprcnt); - if (total_data <= *data_len && total_param <= *param_len) break; @@ -242,27 +280,35 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { return(False); } + + /* parse out the total lengths again - they can shrink! */ + if (SVAL(cli->inbuf,smb_tdrcnt) < total_data) + total_data = SVAL(cli->inbuf,smb_tdrcnt); + if (SVAL(cli->inbuf,smb_tprcnt) < total_param) + total_param = SVAL(cli->inbuf,smb_tprcnt); + + if (total_data <= *data_len && total_param <= *param_len) + break; + } return(True); } - - - /**************************************************************************** - send a SMB nttrans request - ****************************************************************************/ + Send a SMB nttrans request. +****************************************************************************/ + BOOL cli_send_nt_trans(struct cli_state *cli, int function, int flags, - uint16 *setup, int lsetup, int msetup, - char *param, int lparam, int mparam, - char *data, int ldata, int mdata) + uint16 *setup, unsigned int lsetup, unsigned int msetup, + char *param, unsigned int lparam, unsigned int mparam, + char *data, unsigned int ldata, unsigned int mdata) { - int i; - int this_ldata,this_lparam; - int tot_data=0,tot_param=0; + unsigned int i; + unsigned int this_ldata,this_lparam; + unsigned int tot_data=0,tot_param=0; char *outdata,*outparam; this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ @@ -301,14 +347,13 @@ BOOL cli_send_nt_trans(struct cli_state *cli, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!cli_receive_smb(cli) || - cli_is_error(cli)) { + if (!cli_receive_smb(cli) || cli_is_error(cli)) return(False); - } tot_data = this_ldata; tot_param = this_lparam; @@ -340,7 +385,8 @@ BOOL cli_send_nt_trans(struct cli_state *cli, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; tot_data += this_ldata; tot_param += this_lparam; @@ -355,13 +401,14 @@ BOOL cli_send_nt_trans(struct cli_state *cli, /**************************************************************************** receive a SMB nttrans response allocating the necessary memory ****************************************************************************/ + BOOL cli_receive_nt_trans(struct cli_state *cli, - char **param, int *param_len, - char **data, int *data_len) + char **param, unsigned int *param_len, + char **data, unsigned int *data_len) { - int total_data=0; - int total_param=0; - int this_data,this_param; + unsigned int total_data=0; + unsigned int total_param=0; + unsigned int this_data,this_param; uint8 eclass; uint32 ecode; char *tdata; @@ -423,25 +470,65 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (this_data + *data_len > total_data || this_param + *param_len > total_param) { - DEBUG(1,("Data overflow in cli_receive_trans\n")); + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + return False; + } + + if (this_data + *data_len < this_data || + this_data + *data_len < *data_len || + this_param + *param_len < this_param || + this_param + *param_len < *param_len) { + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); return False; } - if (this_data) - memcpy(*data + SVAL(cli->inbuf,smb_ntr_DataDisplacement), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_ntr_DataOffset), - this_data); - if (this_param) - memcpy(*param + SVAL(cli->inbuf,smb_ntr_ParameterDisplacement), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_ntr_ParameterOffset), - this_param); + if (this_data) { + unsigned int data_offset_out = SVAL(cli->inbuf,smb_ntr_DataDisplacement); + unsigned int data_offset_in = SVAL(cli->inbuf,smb_ntr_DataOffset); + + if (data_offset_out > total_data || + data_offset_out + this_data > total_data || + data_offset_out + this_data < data_offset_out || + data_offset_out + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + return False; + } + if (data_offset_in > cli->bufsize || + data_offset_in + this_data > cli->bufsize || + data_offset_in + this_data < data_offset_in || + data_offset_in + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + return False; + } + + memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); + } + + if (this_param) { + unsigned int param_offset_out = SVAL(cli->inbuf,smb_ntr_ParameterDisplacement); + unsigned int param_offset_in = SVAL(cli->inbuf,smb_ntr_ParameterOffset); + + if (param_offset_out > total_param || + param_offset_out + this_param > total_param || + param_offset_out + this_param < param_offset_out || + param_offset_out + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); + return False; + } + if (param_offset_in > cli->bufsize || + param_offset_in + this_param > cli->bufsize || + param_offset_in + this_param < param_offset_in || + param_offset_in + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); + return False; + } + + memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); + } + *data_len += this_data; *param_len += this_param; - /* parse out the total lengths again - they can shrink! */ - total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); - total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); - if (total_data <= *data_len && total_param <= *param_len) break; @@ -462,6 +549,14 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, !(eclass == ERRDOS && ecode == ERRmoredata)) return(False); } + /* parse out the total lengths again - they can shrink! */ + if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data) + total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); + if (SVAL(cli->inbuf,smb_ntr_TotalParameterCount) < total_param) + total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); + + if (total_data <= *data_len && total_param <= *param_len) + break; } return(True); -- cgit From 3b104f6e2dc56c5edcf0278e7e43d4993e7db368 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 13 Mar 2003 04:34:31 +0000 Subject: win2000 can take much longer than the specified time to respond to a lock - so to make the torture tests valid I give it a grace time of 10 seconds instead of 2 (This used to be commit c9c9e9eb26ec3042395637d14a6661d04a629ccc) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index f61787abde..8e84963c09 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -633,7 +633,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, cli_send_smb(cli); if (timeout != 0) { - cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 10*1000); } if (!cli_receive_smb(cli)) { -- cgit From e37372f4d6e10204adf272f978524751420e890f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 14 Mar 2003 10:02:12 +0000 Subject: Found by metze with the clobber-region check - if it's a pstring, use pstrcpy(). Andrew Bartlett (This used to be commit f9c3c93f55cac774e576fd5975c0582e0b334d6a) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 8e84963c09..d86f36405d 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -948,7 +948,7 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path) pstring path2; char *p; - safe_strcpy(path2,path,sizeof(pstring)); + pstrcpy(path2,path); trim_string(path2,NULL,"\\"); if (!*path2) *path2 = '\\'; -- cgit From 33c8a6779d490bd1aa722231a59a3b68343dbc17 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Fri, 14 Mar 2003 17:05:13 +0000 Subject: /tmp/newfun.msg (This used to be commit 3f4cb7b2c4d9b54b41bcc184ccfd00032e2b021b) --- source3/libsmb/trust_passwd.c | 116 ---------------------------- source3/libsmb/trusts_util.c | 174 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 174 insertions(+), 116 deletions(-) delete mode 100644 source3/libsmb/trust_passwd.c create mode 100644 source3/libsmb/trusts_util.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c deleted file mode 100644 index cf9fd58b13..0000000000 --- a/source3/libsmb/trust_passwd.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Routines to change trust account passwords. - * Copyright (C) Andrew Bartlett 2001. - * - * 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 2 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, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "includes.h" - -/********************************************************* - Change the domain password on the PDC. - - Just changes the password betwen the two values specified. - - Caller must have the cli connected to the netlogon pipe - already. -**********************************************************/ -static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx, - unsigned char orig_trust_passwd_hash[16], - unsigned char new_trust_passwd_hash[16]) -{ - NTSTATUS result; - uint32 neg_flags = 0x000001ff; - - result = cli_nt_setup_creds(cli, get_sec_chan(), orig_trust_passwd_hash, &neg_flags, 2); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", - nt_errstr(result))); - return result; - } - - result = cli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("just_change_the_password: unable to change password (%s)!\n", - nt_errstr(result))); - } - return result; -} - -/********************************************************* - Change the domain password on the PDC. - Store the password ourselves, but use the supplied password - Caller must have already setup the connection to the NETLOGON pipe -**********************************************************/ - -NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, - unsigned char orig_trust_passwd_hash[16]) -{ - unsigned char new_trust_passwd_hash[16]; - char *new_trust_passwd; - char *str; - NTSTATUS nt_status; - - /* Create a random machine account password */ - str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); - new_trust_passwd = talloc_strdup(mem_ctx, str); - - E_md4hash(new_trust_passwd, new_trust_passwd_hash); - - nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash, - new_trust_passwd_hash); - - if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", - timestring(False))); - /* - * Return the result of trying to write the new password - * back into the trust account file. - */ - if (!secrets_store_machine_password(new_trust_passwd)) { - nt_status = NT_STATUS_UNSUCCESSFUL; - } - } - - return nt_status; -} - -/********************************************************* - Change the domain password on the PDC. - Do most of the legwork ourselfs. Caller must have - already setup the connection to the NETLOGON pipe -**********************************************************/ - -NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, - const char *domain) -{ - unsigned char old_trust_passwd_hash[16]; - char *up_domain; - - up_domain = talloc_strdup(mem_ctx, domain); - - if (!secrets_fetch_trust_account_password(domain, - old_trust_passwd_hash, - NULL)) { - DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain)); - return NT_STATUS_UNSUCCESSFUL; - } - - return trust_pw_change_and_store_it(cli, mem_ctx, old_trust_passwd_hash); - -} diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c new file mode 100644 index 0000000000..055851f6b7 --- /dev/null +++ b/source3/libsmb/trusts_util.c @@ -0,0 +1,174 @@ +/* + * Unix SMB/CIFS implementation. + * Routines to operate on various trust relationships + * Copyright (C) Andrew Bartlett 2001 + * Copyright (C) Rafal Szczesniak 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 2 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, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +/********************************************************* + Change the domain password on the PDC. + + Just changes the password betwen the two values specified. + + Caller must have the cli connected to the netlogon pipe + already. +**********************************************************/ +static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx, + unsigned char orig_trust_passwd_hash[16], + unsigned char new_trust_passwd_hash[16]) +{ + NTSTATUS result; + uint32 neg_flags = 0x000001ff; + + result = cli_nt_setup_creds(cli, get_sec_chan(), orig_trust_passwd_hash, &neg_flags, 2); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", + nt_errstr(result))); + return result; + } + + result = cli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(0,("just_change_the_password: unable to change password (%s)!\n", + nt_errstr(result))); + } + return result; +} + +/********************************************************* + Change the domain password on the PDC. + Store the password ourselves, but use the supplied password + Caller must have already setup the connection to the NETLOGON pipe +**********************************************************/ + +NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, + unsigned char orig_trust_passwd_hash[16]) +{ + unsigned char new_trust_passwd_hash[16]; + char *new_trust_passwd; + char *str; + NTSTATUS nt_status; + + /* Create a random machine account password */ + str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); + new_trust_passwd = talloc_strdup(mem_ctx, str); + + E_md4hash(new_trust_passwd, new_trust_passwd_hash); + + nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash, + new_trust_passwd_hash); + + if (NT_STATUS_IS_OK(nt_status)) { + DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", + timestring(False))); + /* + * Return the result of trying to write the new password + * back into the trust account file. + */ + if (!secrets_store_machine_password(new_trust_passwd)) { + nt_status = NT_STATUS_UNSUCCESSFUL; + } + } + + return nt_status; +} + +/********************************************************* + Change the domain password on the PDC. + Do most of the legwork ourselfs. Caller must have + already setup the connection to the NETLOGON pipe +**********************************************************/ + +NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, + const char *domain) +{ + unsigned char old_trust_passwd_hash[16]; + char *up_domain; + + up_domain = talloc_strdup(mem_ctx, domain); + + if (!secrets_fetch_trust_account_password(domain, + old_trust_passwd_hash, + NULL)) { + DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain)); + return NT_STATUS_UNSUCCESSFUL; + } + + return trust_pw_change_and_store_it(cli, mem_ctx, old_trust_passwd_hash); + +} + + +/** + * Verify whether or not given domain is trusted. + * + * @param domain_name name of the domain to be verified + * @return true if domain is one of the trusted once or + * false if otherwise + **/ + +BOOL is_trusted_domain(const char* dom_name) +{ + int enum_ctx = 0; + const int trustdom_size = 10; + int num_domains, i; + TRUSTDOM **domains; + NTSTATUS result; + fstring trustdom_name; + DOM_SID trustdom_sid; + TALLOC_CTX *mem_ctx; + + /* + * Query the secrets db as an ultimate source of information + * about trusted domain names. This is PDC or BDC case. + */ + mem_ctx = talloc_init("is_trusted_domain"); + + do { + result = secrets_get_trusted_domains(mem_ctx, &enum_ctx, trustdom_size, + &num_domains, &domains); + /* compare each returned entry against incoming connection's domain */ + for (i = 0; i < num_domains; i++) { + pull_ucs2_fstring(trustdom_name, domains[i]->name); + if (strequal(trustdom_name, dom_name)) { + talloc_destroy(mem_ctx); + return True; + } + } + } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); + + /* + * Query the trustdom_cache updated periodically. The only + * way for domain member server. + */ + if (trustdom_cache_enable() && + trustdom_cache_fetch(dom_name, &trustdom_sid)) { + trustdom_cache_shutdown(); + return True; + } + + /* + * if nothing's been found, then give up here, although + * the last resort might be to query the PDC. + */ + return False; +} + -- cgit From 9db9982cd34d36d8b23e94a4063761c8b6aa9e17 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Fri, 14 Mar 2003 17:20:13 +0000 Subject: We haven't implemented The Singing Contexts so far. Who knows what .NET server brings, though ...? ;-) Rafal (This used to be commit d81b0d26903004be6a99ac029dd531fd18947268) --- source3/libsmb/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 40359c5c8c..c3538ee9fd 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -417,7 +417,7 @@ BOOL cli_temp_set_signing(struct cli_state *cli) } /** - * Free the singing context + * Free the signing context */ void cli_free_signing_context(struct cli_state *cli) -- cgit From 6fe590983b5d4dca8cea82eaa8dfb7b3a13bc3d1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2003 06:43:37 +0000 Subject: Add const, and a signed/unsigned fix. (This used to be commit f07a93eaeba20f5704f43c7f02141adc564db136) --- source3/libsmb/clitrans.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 7e3357a8cc..3d3cd427d7 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -31,10 +31,10 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, const char *pipe_name, int fid, int flags, uint16 *setup, unsigned int lsetup, unsigned int msetup, - char *param, unsigned int lparam, unsigned int mparam, - char *data, unsigned int ldata, unsigned int mdata) + const char *param, unsigned int lparam, unsigned int mparam, + const char *data, unsigned int ldata, unsigned int mdata) { - int i; + unsigned int i; unsigned int this_ldata,this_lparam; unsigned int tot_data=0,tot_param=0; char *outdata,*outparam; -- cgit From 16ec110b0f1fe45b598a04e171397d97c3cb5aef Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2003 06:45:19 +0000 Subject: client-side smbpasswd fixes - use pstrcpy_base to avoid clobber_region bugs Andrew Bartlett (This used to be commit 7ab6559369b4e6ee3c5269d8cff04e5a39f6b493) --- source3/libsmb/clirap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index b38e7d5c23..224c37046c 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -281,7 +281,7 @@ Send a SamOEMChangePassword command BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, const char *old_password) { - char param[16+sizeof(fstring)]; + pstring param; char data[532]; char *p = param; unsigned char old_pw_hash[16]; @@ -300,11 +300,11 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char SSVAL(p,0,214); /* SamOEMChangePassword command. */ p += 2; - pstrcpy(p, "zsT"); + pstrcpy_base(p, "zsT", param); p = skip_string(p,1); - pstrcpy(p, "B516B16"); + pstrcpy_base(p, "B516B16", param); p = skip_string(p,1); - pstrcpy(p,user); + pstrcpy_base(p,user, param); p = skip_string(p,1); SSVAL(p,0,532); p += 2; @@ -317,7 +317,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char */ E_deshash(old_password, old_pw_hash); - clistr_push(cli, dos_new_password, new_password, -1, STR_TERMINATE|STR_ASCII); + clistr_push(cli, dos_new_password, new_password, sizeof(dos_new_password), STR_TERMINATE|STR_ASCII); if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) return False; @@ -685,7 +685,7 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin int count=8; char *p; BOOL ret; - int len; + unsigned int len; p = param; memset(p, 0, 6); -- cgit From dc7c505dec59329c5dde35763febab3547f6d642 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2003 06:46:05 +0000 Subject: Be parinoid, malloc an extra SAFETY_MARGIN on the client's inbuf and outbuf. Andrew Bartlett (This used to be commit 2effcae13f9dfbff40b34d32c7fd82118c3fd096) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3cae643c38..d969193089 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -245,8 +245,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->timeout = 20000; /* Timeout is in milliseconds. */ cli->bufsize = CLI_BUFFER_SIZE+4; cli->max_xmit = cli->bufsize; - cli->outbuf = (char *)malloc(cli->bufsize); - cli->inbuf = (char *)malloc(cli->bufsize); + cli->outbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); + cli->inbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; cli->use_spnego = lp_client_use_spnego(); -- cgit From a4ba0496846924df4688cf3678940ec3b14e6376 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2003 06:46:43 +0000 Subject: Specify buffer sizes (This used to be commit aa12379b3fd9646199a8ff3f217ec7dfef1942a5) --- source3/libsmb/cliconnect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 36b6f609f5..763878f9b3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -66,7 +66,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, memcpy(pword, pass, passlen); } else if (passlen > 0) { /* Plaintext mode needed, assume plaintext supplied. */ - passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE); + passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); } /* send a session setup command */ @@ -778,7 +778,7 @@ BOOL cli_send_tconX(struct cli_state *cli, /* * Non-encrypted passwords - convert to DOS codepage before using. */ - passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE); + passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); } else { memcpy(pword, pass, passlen); } -- cgit From eca1293fadf8774f016e18ca56ac200546ca70ba Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2003 06:51:57 +0000 Subject: specify the size of these buffers (This used to be commit f6ea572cd57d4e655d387fe225a5d7122d587a9b) --- source3/libsmb/clilist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 3884e4da82..5bd1283ab7 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -178,7 +178,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,6,info_level); SIVAL(param,8,0); p = param+12; - p += clistr_push(cli, param+12, mask, -1, + p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } else { setup = TRANSACT2_FINDNEXT; @@ -188,7 +188,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SIVAL(param,6,0); /* ff_resume_key */ SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ p = param+12; - p += clistr_push(cli, param+12, mask, -1, + p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } -- cgit From 3b5bc93e9db4df6ded2eef7b32bda74328b04811 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2003 07:14:55 +0000 Subject: String handling parinoia fixes. This patch enables the compile-time checking of strings assable by means of sizeof(). (Original code had the configure check reversed). This is extended to all safe_strcpy() users, push_string and pull_string, as well as the cli and srv derivitives. There is an attempt to cap strings at the end of the cli buffer, and clobber_region() of the speified length (when not -1 :-). Becouse of the way they are declared, the 'overmalloc a string' users of safe_strcpy() have been changed to use overmalloc_safe_strcpy() (which skips some of the checks). This whole ball of mud worked fine, until I pulled out my 'fix' for our statcache. When jeremy fixes that, we should be able to get back to testing this stuff. This patch also includes a 'marker' of the last caller to clobber_region (ie, the function that called pstrcpy() that called clobber_region) to assist in debugging problems that may have smashed the stack. This is printed at smb_panic() time. (Original idea and patch by metze). It also removes some unsused functions, and #if 0's some others that are unused but probably should be used in the near future. For now, this patch gives us some confidence on one class of trivial parsing error in our code. Andrew Bartlett (This used to be commit 31f4827acc2a2f00399a5528fc83a0dae5cebaf4) --- source3/libsmb/clistr.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 3c9964368e..97a3fa6cc9 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -20,24 +20,38 @@ #include "includes.h" -int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags) +size_t clistr_push_fn(const char *function, unsigned int line, + struct cli_state *cli, void *dest, + const char *src, int dest_len, int flags) { - return push_string(cli->outbuf, dest, src, dest_len, flags); + size_t buf_used = PTR_DIFF(dest, cli->outbuf); + if (dest_len == -1) { + if (((ptrdiff_t)dest < (ptrdiff_t)cli->outbuf) || (buf_used > cli->bufsize)) { + DEBUG(0, ("Pushing string of 'unlimited' length into non-SMB buffer!\n")); + return push_string_fn(function, line, cli->outbuf, dest, src, -1, flags); + } + return push_string_fn(function, line, cli->outbuf, dest, src, cli->bufsize - buf_used, flags); + } + + /* 'normal' push into size-specified buffer */ + return push_string_fn(function, line, cli->outbuf, dest, src, dest_len, flags); } -int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, - int flags) +size_t clistr_pull_fn(const char *function, unsigned int line, + struct cli_state *cli, char *dest, const void *src, + int dest_len, int src_len, + int flags) { - return pull_string(cli->inbuf, dest, src, dest_len, src_len, flags); + return pull_string_fn(function, line, cli->inbuf, dest, src, dest_len, src_len, flags); } -int clistr_align_out(struct cli_state *cli, const void *p, int flags) +size_t clistr_align_out(struct cli_state *cli, const void *p, int flags) { return align_string(cli->outbuf, p, flags); } -int clistr_align_in(struct cli_state *cli, const void *p, int flags) +size_t clistr_align_in(struct cli_state *cli, const void *p, int flags) { return align_string(cli->inbuf, p, flags); } -- cgit From 02704f973347f05af5ebcb0d4a494a6102199536 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2003 08:18:29 +0000 Subject: Minor fixes. - signed/unsigned - quieten warning about assignment as truth value - whitespace Andrew Bartlett (This used to be commit a13ce0df4b4a776fa635a1fb804dd00d195f58d0) --- source3/libsmb/trusts_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 055851f6b7..f7b2c2e3a6 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -152,9 +152,9 @@ BOOL is_trusted_domain(const char* dom_name) talloc_destroy(mem_ctx); return True; } - } + } } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); - + /* * Query the trustdom_cache updated periodically. The only * way for domain member server. -- cgit From 0ab29d6186135bd66c4154b545ac8323232a6f2e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Mar 2003 04:42:57 +0000 Subject: Fix a memory leak - 'smbcontrol smbd pool-usage' is your freind! Andrew Bartlett (This used to be commit a12e8524997e329a4f4cd766d6371e384698795a) --- source3/libsmb/trusts_util.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index f7b2c2e3a6..b8f84ba890 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -155,6 +155,8 @@ BOOL is_trusted_domain(const char* dom_name) } } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); + talloc_destroy(mem_ctx); + /* * Query the trustdom_cache updated periodically. The only * way for domain member server. -- cgit