diff options
author | Andrew Bartlett <abartlet@samba.org> | 2002-08-26 03:08:37 +0000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2002-08-26 03:08:37 +0000 |
commit | 2560c73026ced1917a04f0e670f51ebcc984bb86 (patch) | |
tree | 15268b52aebbca2359da4296f5a30c53249e8603 | |
parent | 53749c1342a70d51639eecab8bbe6e402a74af93 (diff) | |
download | samba-2560c73026ced1917a04f0e670f51ebcc984bb86.tar.gz samba-2560c73026ced1917a04f0e670f51ebcc984bb86.tar.bz2 samba-2560c73026ced1917a04f0e670f51ebcc984bb86.zip |
Updates!
- Don't print an uninitialised buffer in service.c
- Change some charcnv.c functions to take smb_ucs2_t ** instead of void **
- Update NTLMv2 code to use dynamic buffers
- Update experimental SMB signing code - still more work to do
- Move sys_getgrouplist() to SAFE_FREE() and do a DEBUG() on initgroups()
failure.
Andrew Bartlett
(This used to be commit de1964f7fa855022258a84556b266100b917444b)
-rw-r--r-- | source3/auth/auth_sam.c | 5 | ||||
-rw-r--r-- | source3/lib/charcnv.c | 8 | ||||
-rw-r--r-- | source3/lib/system_smbd.c | 5 | ||||
-rw-r--r-- | source3/libsmb/cliconnect.c | 74 | ||||
-rw-r--r-- | source3/libsmb/clientgen.c | 7 | ||||
-rw-r--r-- | source3/libsmb/clireadwrite.c | 2 | ||||
-rw-r--r-- | source3/libsmb/smbencrypt.c | 60 | ||||
-rw-r--r-- | source3/smbd/mangle_hash.c | 2 | ||||
-rw-r--r-- | source3/smbd/service.c | 2 |
9 files changed, 113 insertions, 52 deletions
diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index ca611c46b9..bc98f46dc2 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -106,7 +106,10 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response, client_key_data = data_blob(ntv2_response.data+16, ntv2_response.length-16); memcpy(client_response, ntv2_response.data, sizeof(client_response)); - ntv2_owf_gen(part_passwd, user, domain, kr); + if (!ntv2_owf_gen(part_passwd, user, domain, kr)) { + return False; + } + SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, value_from_encryption); if (user_sess_key != NULL) { diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index 03337cbf26..cd8aa4fe55 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -434,12 +434,12 @@ int push_ucs2(const void *base_ptr, void *dest, const char *src, int dest_len, i * @retval The number of bytes occupied by the string in the destination * or -1 in case of error. **/ -int push_ucs2_talloc(TALLOC_CTX *ctx, void **dest, const char *src) +int push_ucs2_talloc(TALLOC_CTX *ctx, smb_ucs2_t **dest, const char *src) { int src_len = strlen(src)+1; *dest = NULL; - return convert_string_talloc(ctx, CH_UNIX, CH_UCS2, src, src_len, dest); + return convert_string_talloc(ctx, CH_UNIX, CH_UCS2, src, src_len, (void **)dest); } /** @@ -450,12 +450,12 @@ int push_ucs2_talloc(TALLOC_CTX *ctx, void **dest, const char *src) * @retval The number of bytes occupied by the string in the destination * or -1 in case of error. **/ -int push_ucs2_allocate(void **dest, const char *src) +int push_ucs2_allocate(smb_ucs2_t **dest, const char *src) { int src_len = strlen(src)+1; *dest = NULL; - return convert_string_allocate(CH_UNIX, CH_UCS2, src, src_len, dest); + return convert_string_allocate(CH_UNIX, CH_UCS2, src, src_len, (void **)dest); } /**************************************************************************** diff --git a/source3/lib/system_smbd.c b/source3/lib/system_smbd.c index 5eda37d903..0cd3086945 100644 --- a/source3/lib/system_smbd.c +++ b/source3/lib/system_smbd.c @@ -61,13 +61,14 @@ static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups, in ngrp_saved = getgroups(ngrp_saved, gids_saved); if (ngrp_saved == -1) { - free(gids_saved); + SAFE_FREE(gids_saved); /* very strange! */ return -1; } if (initgroups(user, gid) != 0) { - free(gids_saved); + DEBUG(0, ("getgrouplist_internals: initgroups() failed!\n")); + SAFE_FREE(gids_saved); return -1; } diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 7db377c25f..ded5a843f3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -237,6 +237,23 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, return True; } +static void set_signing_on_cli (struct cli_state *cli, char* pass, uint8 response[24]) +{ + uint8 zero_sig[8]; + ZERO_STRUCT(zero_sig); + if (memcmp(&cli->outbuf[smb_ss_field], zero_sig, 8) != 0) { + cli->sign_info.use_smb_signing = True; + cli_calculate_mac_key(cli, pass, response); + } +} + +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 @@ -256,7 +273,6 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, uchar pword[24]; uchar ntpword[24]; char *p; - BOOL tried_signing = False; if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) { return False; @@ -268,12 +284,12 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, ntpasslen = 24; SMBencrypt(pass,cli->secblob.data,pword); SMBNTencrypt(pass,cli->secblob.data,ntpword); - if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) { - cli_calculate_mac_key(cli, pass, ntpword); - tried_signing = True; - } + + set_temp_signing_on_cli(cli); + } else { - /* pre-encrypted password supplied. Only used for security=server, can't do + /* pre-encrypted password supplied. Only used for + security=server, can't do signing becouse we don't have oringial key */ memcpy(pword, pass, 24); if (ntpasslen == 24) { @@ -307,22 +323,16 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); + if (!cli_send_smb(cli)) { + return False; + } + if (!cli_receive_smb(cli)) { - if (tried_signing) { - /* We only use it if we have a successful non-guest connect */ - cli->sign_info.use_smb_signing = False; - } return False; } show_msg(cli->inbuf); - if (tried_signing && (cli_is_error(cli) || SVAL(cli->inbuf,smb_vwv2) /* guest */)) { - /* We only use it if we have a successful non-guest connect */ - cli->sign_info.use_smb_signing = False; - } - if (cli_is_error(cli)) { return False; } @@ -337,6 +347,11 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, fstrcpy(cli->user_name, user); + if (passlen != 24) { + /* Have plaintext orginal */ + set_signing_on_cli(cli, pass, ntpword); + } + return True; } @@ -360,6 +375,9 @@ 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); @@ -375,8 +393,8 @@ 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); + if (!cli_receive_smb(cli)) return blob2; @@ -451,7 +469,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, uint32 neg_flags; neg_flags = NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_LM_KEY | + NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM; memset(sess_key, 0, 16); @@ -525,7 +543,13 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, data_blob_free(&auth); data_blob_free(&blob); - return !cli_is_error(cli); + if (cli_is_error(cli)) { + return False; + } + + set_signing_on_cli(cli, pass, nthash); + + return True; } /**************************************************************************** @@ -541,9 +565,6 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, int i; BOOL got_kerberos_mechanism = False; - /* spnego security cannot use SMB signing (for now). */ - cli->sign_info.use_smb_signing = False; - DEBUG(2,("Doing spnego session setup (blob length=%d)\n", cli->secblob.length)); /* the server might not even do spnego */ @@ -643,6 +664,9 @@ BOOL cli_session_setup(struct cli_state *cli, return cli_session_setup_plaintext(cli, user, pass, workgroup); } + /* Indidicate signing */ + + /* if the server supports extended security then use SPNEGO */ if (cli->capabilities & CAP_EXTENDED_SECURITY) { return cli_session_setup_spnego(cli, user, pass, workgroup); @@ -891,12 +915,8 @@ BOOL cli_negprot(struct cli_state *cli) smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } - /* A way to attempt to force SMB signing */ - if (getenv("CLI_FORCE_SMB_SIGNING")) + if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) cli->sign_info.negotiated_smb_signing = True; - - if (cli->sign_info.negotiated_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) - cli->sign_info.negotiated_smb_signing = False; } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9ae3882301..560d391320 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -160,7 +160,8 @@ void cli_setup_packet(struct cli_state *cli) if (cli->use_spnego) { flags2 |= FLAGS2_EXTENDED_SECURITY; } - if (cli->sign_info.use_smb_signing) + if (cli->sign_info.use_smb_signing + || cli->sign_info.temp_smb_signing) flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(cli->outbuf,smb_flg2, flags2); } @@ -245,6 +246,10 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->force_dos_errors = True; } + /* A way to attempt to force SMB signing */ + if (getenv("CLI_FORCE_SMB_SIGNING")) + cli->sign_info.negotiated_smb_signing = True; + if (!cli->outbuf || !cli->inbuf) goto error; diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 756a6cce2f..875df11dca 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -127,7 +127,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ return total; } -#if 0 /* relies on client_recieve_smb(), now a static in libsmb/clientgen.c */ +#if 0 /* relies on client_receive_smb(), now a static in libsmb/clientgen.c */ /* This call is INCOMPATIBLE with SMB signing. If you remove the #if 0 you must fix ensure you don't attempt to sign the packets - data diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index dfa355a7ec..db265c4bf7 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -116,39 +116,63 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) } /* Does both the NTLMv2 owfs of a user's password */ -void ntv2_owf_gen(const uchar owf[16], - const char *user_n, const char *domain_n, uchar kr_buf[16]) +BOOL ntv2_owf_gen(const uchar owf[16], + const char *user_in, const char *domain_in, uchar kr_buf[16]) { - pstring user_u; - pstring dom_u; + smb_ucs2_t *user; + smb_ucs2_t *domain; + + int user_byte_len; + int domain_byte_len; + HMACMD5Context ctx; - int user_l = strlen(user_n); - int domain_l = strlen(domain_n); + user_byte_len = push_ucs2_allocate(&user, user_in); + if (user_byte_len < 0) { + DEBUG(0, ("push_uss2_allocate() for user returned %d (probably malloc() failure)\n", user_byte_len)); + return False; + } - push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); - push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); + domain_byte_len = push_ucs2_allocate(&domain, domain_in); + if (domain_byte_len < 0) { + DEBUG(0, ("push_uss2_allocate() for domain returned %d (probably malloc() failure)\n", user_byte_len)); + return False; + } + + strupper_w(user); + strupper_w(domain); + + /* We don't want null termination */ + user_byte_len = user_byte_len - 2; + domain_byte_len = domain_byte_len - 2; + + SMB_ASSERT(user_byte_len >= 0); + SMB_ASSERT(domain_byte_len >= 0); hmac_md5_init_limK_to_64(owf, 16, &ctx); - hmac_md5_update((const unsigned char *)user_u, user_l * 2, &ctx); - hmac_md5_update((const unsigned char *)dom_u, domain_l * 2, &ctx); + hmac_md5_update((const unsigned char *)user, user_byte_len, &ctx); + hmac_md5_update((const unsigned char *)domain, domain_byte_len, &ctx); hmac_md5_final(kr_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); - dump_data(100, user_u, user_l * 2); - dump_data(100, dom_u, domain_l * 2); + dump_data(100, (const char *)user, user_byte_len); + dump_data(100, (const char *)domain, domain_byte_len); dump_data(100, owf, 16); dump_data(100, kr_buf, 16); #endif + + SAFE_FREE(user); + SAFE_FREE(domain); + return True; } /* Does the des encryption from the NT or LM MD4 hash. */ void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24]) { uchar p21[21]; - - memset(p21,'\0',21); + + ZERO_STRUCT(p21); memcpy(p21, passwd, 16); E_P24(p21, c8, p24); @@ -362,6 +386,12 @@ 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; } @@ -380,6 +410,8 @@ void cli_caclulate_sign_mac(struct cli_state *cli) 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++; diff --git a/source3/smbd/mangle_hash.c b/source3/smbd/mangle_hash.c index 1d4697474c..0446a953ff 100644 --- a/source3/smbd/mangle_hash.c +++ b/source3/smbd/mangle_hash.c @@ -730,7 +730,7 @@ static void name_map(char *OutName, BOOL need83, BOOL cache83) DEBUG(5,("name_map( %s, need83 = %s, cache83 = %s)\n", OutName, need83 ? "True" : "False", cache83 ? "True" : "False")); - if (push_ucs2_allocate((void **)&OutName_ucs2, OutName) < 0) { + if (push_ucs2_allocate(&OutName_ucs2, OutName) < 0) { DEBUG(0, ("push_ucs2_allocate failed!\n")); return; } diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 7c38cf5793..d475451e6b 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -808,7 +808,7 @@ connection_struct *make_connection(const char *service_in, DATA_BLOB password, } else if ((lp_security() != SEC_SHARE) && (vuser->homes_snum != -1) && strequal(service_in, lp_servicename(vuser->homes_snum))) { DATA_BLOB no_pw = data_blob(NULL, 0); - DEBUG(5, ("making a connection to 'homes' service [%s] created at session setup time\n", service)); + DEBUG(5, ("making a connection to 'homes' service [%s] created at session setup time\n", service_in)); return make_connection_snum(vuser->homes_snum, vuser, no_pw, dev, status); |