📄 negprot.c
字号:
/* Unix SMB/CIFS implementation. negprot reply code Copyright (C) Andrew Tridgell 1992-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 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"extern fstring remote_proto;extern enum protocol_types Protocol;extern int max_recv;BOOL global_encrypted_passwords_negotiated = False;BOOL global_spnego_negotiated = False;struct auth_context *negprot_global_auth_context = NULL;static void get_challenge(char buff[8]) { NTSTATUS nt_status; const uint8 *cryptkey; /* We might be called more than once, muliple negprots are premitted */ if (negprot_global_auth_context) { DEBUG(3, ("get challenge: is this a secondary negprot? negprot_global_auth_context is non-NULL!\n")); (negprot_global_auth_context->free)(&negprot_global_auth_context); } DEBUG(10, ("get challenge: creating negprot_global_auth_context\n")); if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&negprot_global_auth_context))) { DEBUG(0, ("make_auth_context_subsystem returned %s", nt_errstr(nt_status))); smb_panic("cannot make_negprot_global_auth_context!\n"); } DEBUG(10, ("get challenge: getting challenge\n")); cryptkey = negprot_global_auth_context->get_ntlm_challenge(negprot_global_auth_context); memcpy(buff, cryptkey, 8);}/**************************************************************************** Reply for the core protocol.****************************************************************************/static int reply_corep(char *inbuf, char *outbuf){ int outsize = set_message(outbuf,1,0,True); Protocol = PROTOCOL_CORE; return outsize;}/**************************************************************************** Reply for the coreplus protocol.****************************************************************************/static int reply_coreplus(char *inbuf, char *outbuf){ int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0); int outsize = set_message(outbuf,13,0,True); SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support readbraw and writebraw (possibly) */ /* Reply, SMBlockread, SMBwritelock supported. */ SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD); SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */ Protocol = PROTOCOL_COREPLUS; return outsize;}/**************************************************************************** Reply for the lanman 1.0 protocol.****************************************************************************/static int reply_lanman1(char *inbuf, char *outbuf){ int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0); int secword=0; time_t t = time(NULL); global_encrypted_passwords_negotiated = lp_encrypted_passwords(); if (lp_security()>=SEC_USER) secword |= NEGOTIATE_SECURITY_USER_LEVEL; if (global_encrypted_passwords_negotiated) secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; set_message(outbuf,13,global_encrypted_passwords_negotiated?8:0,True); SSVAL(outbuf,smb_vwv1,secword); /* Create a token value and add it to the outgoing packet. */ if (global_encrypted_passwords_negotiated) { get_challenge(smb_buf(outbuf)); SSVAL(outbuf,smb_vwv11, 8); } Protocol = PROTOCOL_LANMAN1; /* Reply, SMBlockread, SMBwritelock supported. */ SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD); SSVAL(outbuf,smb_vwv2,max_recv); SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */ SSVAL(outbuf,smb_vwv4,1); SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support readbraw writebraw (possibly) */ SIVAL(outbuf,smb_vwv6,sys_getpid()); SSVAL(outbuf,smb_vwv10, set_server_zone_offset(t)/60); srv_put_dos_date(outbuf,smb_vwv8,t); return (smb_len(outbuf)+4);}/**************************************************************************** Reply for the lanman 2.0 protocol.****************************************************************************/static int reply_lanman2(char *inbuf, char *outbuf){ int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0); int secword=0; time_t t = time(NULL); global_encrypted_passwords_negotiated = lp_encrypted_passwords(); if (lp_security()>=SEC_USER) secword |= NEGOTIATE_SECURITY_USER_LEVEL; if (global_encrypted_passwords_negotiated) secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; set_message(outbuf,13,global_encrypted_passwords_negotiated?8:0,True); SSVAL(outbuf,smb_vwv1,secword); SIVAL(outbuf,smb_vwv6,sys_getpid()); /* Create a token value and add it to the outgoing packet. */ if (global_encrypted_passwords_negotiated) { get_challenge(smb_buf(outbuf)); SSVAL(outbuf,smb_vwv11, 8); } Protocol = PROTOCOL_LANMAN2; /* Reply, SMBlockread, SMBwritelock supported. */ SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD); SSVAL(outbuf,smb_vwv2,max_recv); SSVAL(outbuf,smb_vwv3,lp_maxmux()); SSVAL(outbuf,smb_vwv4,1); SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */ SSVAL(outbuf,smb_vwv10, set_server_zone_offset(t)/60); srv_put_dos_date(outbuf,smb_vwv8,t); return (smb_len(outbuf)+4);}/**************************************************************************** Generate the spnego negprot reply blob. Return the number of bytes used.****************************************************************************/static int negprot_spnego(char *p, uint8 *pkeylen){ DATA_BLOB blob; nstring dos_name; fstring unix_name; char guid[17]; const char *OIDs_krb5[] = {OID_KERBEROS5, OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; const char *OIDs_plain[] = {OID_NTLMSSP, NULL}; int len; global_spnego_negotiated = True; ZERO_STRUCT(guid); safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1); strlower_m(unix_name); push_ascii_nstring(dos_name, unix_name); safe_strcpy(guid, dos_name, sizeof(guid)-1);#ifdef DEVELOPER /* valgrind fixer... */ { size_t sl = strlen(guid); if (sizeof(guid)-sl) memset(&guid[sl], '\0', sizeof(guid)-sl); }#endif /* strangely enough, NT does not sent the single OID NTLMSSP when not a ADS member, it sends no OIDs at all OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)" Our sessionsetup code now handles raw NTLMSSP connects, so we can go back to doing what W2K3 does here. This is needed to make PocketPC 2003 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133 for details. JRA. */ if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {#if 0 /* Code for PocketPC client */ blob = data_blob(guid, 16);#else /* Code for standalone WXP client */ blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");#endif } else { fstring myname; char *host_princ_s = NULL; name_to_fqdn(myname, global_myname()); strlower_m(myname); asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm()); blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s); SAFE_FREE(host_princ_s); } memcpy(p, blob.data, blob.length); len = blob.length; if (len > 256) { DEBUG(0,("negprot_spnego: blob length too long (%d)\n", len)); len = 255; } data_blob_free(&blob); if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) { *pkeylen = 0; } else { *pkeylen = len; } return len;}/**************************************************************************** Reply for the nt protocol.****************************************************************************/static int reply_nt1(char *inbuf, char *outbuf){ /* dual names + lock_and_read + nt SMBs + remote API calls */ int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ| CAP_LEVEL_II_OPLOCKS; int secword=0; char *p, *q; BOOL negotiate_spnego = False; time_t t = time(NULL); global_encrypted_passwords_negotiated = lp_encrypted_passwords(); /* do spnego in user level security if the client supports it and we can do encrypted passwords */ if (global_encrypted_passwords_negotiated && (lp_security() != SEC_SHARE) && lp_use_spnego() && (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) { negotiate_spnego = True; capabilities |= CAP_EXTENDED_SECURITY; add_to_common_flags2(FLAGS2_EXTENDED_SECURITY); /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply (already partially constructed. */ SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_EXTENDED_SECURITY); } capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE; if (lp_unix_extensions()) { capabilities |= CAP_UNIX; } if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64)) capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS; if (SMB_OFF_T_BITS == 64) capabilities |= CAP_LARGE_FILES; if (lp_readraw() && lp_writeraw()) capabilities |= CAP_RAW_MODE; if (lp_nt_status_support()) capabilities |= CAP_STATUS32;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -