関数 | |
static void | get_challenge (char buff[8]) |
static int | reply_corep (char *inbuf, char *outbuf) |
static int | reply_coreplus (char *inbuf, char *outbuf) |
static int | reply_lanman1 (char *inbuf, char *outbuf) |
static int | reply_lanman2 (char *inbuf, char *outbuf) |
static DATA_BLOB | negprot_spnego (void) |
static int | reply_nt1 (char *inbuf, char *outbuf) |
int | reply_negprot (connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize) |
変数 | |
fstring | remote_proto |
enum protocol_types | Protocol |
int | max_recv |
BOOL | global_encrypted_passwords_negotiated = False |
BOOL | global_spnego_negotiated = False |
auth_context * | negprot_global_auth_context = NULL |
struct { | |
const char * proto_name | |
const char * short_name | |
int(* proto_reply_fn )(char *, char *) | |
int protocol_level | |
} | supported_protocols [] |
static void get_challenge | ( | char | buff[8] | ) | [static] |
参照先 auth_context::free・auth_context::get_ntlm_challenge・make_auth_context_subsystem()・negprot_global_auth_context・nt_errstr()・smb_panic().
00032 { 00033 NTSTATUS nt_status; 00034 const uint8 *cryptkey; 00035 00036 /* We might be called more than once, multiple negprots are 00037 * permitted */ 00038 if (negprot_global_auth_context) { 00039 DEBUG(3, ("get challenge: is this a secondary negprot? negprot_global_auth_context is non-NULL!\n")); 00040 (negprot_global_auth_context->free)(&negprot_global_auth_context); 00041 } 00042 00043 DEBUG(10, ("get challenge: creating negprot_global_auth_context\n")); 00044 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&negprot_global_auth_context))) { 00045 DEBUG(0, ("make_auth_context_subsystem returned %s", nt_errstr(nt_status))); 00046 smb_panic("cannot make_negprot_global_auth_context!\n"); 00047 } 00048 DEBUG(10, ("get challenge: getting challenge\n")); 00049 cryptkey = negprot_global_auth_context->get_ntlm_challenge(negprot_global_auth_context); 00050 memcpy(buff, cryptkey, 8); 00051 }
static int reply_corep | ( | char * | inbuf, | |
char * | outbuf | |||
) | [static] |
参照先 Protocol・PROTOCOL_CORE・set_message().
00058 { 00059 int outsize = set_message(outbuf,1,0,True); 00060 00061 Protocol = PROTOCOL_CORE; 00062 00063 return outsize; 00064 }
static int reply_coreplus | ( | char * | inbuf, | |
char * | outbuf | |||
) | [static] |
参照先 Protocol・PROTOCOL_COREPLUS・raw・set_message().
00071 { 00072 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0); 00073 int outsize = set_message(outbuf,13,0,True); 00074 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support 00075 readbraw and writebraw (possibly) */ 00076 /* Reply, SMBlockread, SMBwritelock supported. */ 00077 SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD); 00078 SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */ 00079 00080 Protocol = PROTOCOL_COREPLUS; 00081 00082 return outsize; 00083 }
static int reply_lanman1 | ( | char * | inbuf, | |
char * | outbuf | |||
) | [static] |
参照先 get_challenge()・global_encrypted_passwords_negotiated・max_recv・Protocol・PROTOCOL_LANMAN1・raw・SEC_USER・set_message()・set_server_zone_offset()・srv_put_dos_date()・sys_getpid()・t.
00090 { 00091 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0); 00092 int secword=0; 00093 time_t t = time(NULL); 00094 00095 global_encrypted_passwords_negotiated = lp_encrypted_passwords(); 00096 00097 if (lp_security()>=SEC_USER) 00098 secword |= NEGOTIATE_SECURITY_USER_LEVEL; 00099 if (global_encrypted_passwords_negotiated) 00100 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; 00101 00102 set_message(outbuf,13,global_encrypted_passwords_negotiated?8:0,True); 00103 SSVAL(outbuf,smb_vwv1,secword); 00104 /* Create a token value and add it to the outgoing packet. */ 00105 if (global_encrypted_passwords_negotiated) { 00106 get_challenge(smb_buf(outbuf)); 00107 SSVAL(outbuf,smb_vwv11, 8); 00108 } 00109 00110 Protocol = PROTOCOL_LANMAN1; 00111 00112 /* Reply, SMBlockread, SMBwritelock supported. */ 00113 SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD); 00114 SSVAL(outbuf,smb_vwv2,max_recv); 00115 SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */ 00116 SSVAL(outbuf,smb_vwv4,1); 00117 SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support 00118 readbraw writebraw (possibly) */ 00119 SIVAL(outbuf,smb_vwv6,sys_getpid()); 00120 SSVAL(outbuf,smb_vwv10, set_server_zone_offset(t)/60); 00121 00122 srv_put_dos_date(outbuf,smb_vwv8,t); 00123 00124 return (smb_len(outbuf)+4); 00125 }
static int reply_lanman2 | ( | char * | inbuf, | |
char * | outbuf | |||
) | [static] |
参照先 get_challenge()・global_encrypted_passwords_negotiated・max_recv・Protocol・PROTOCOL_LANMAN2・raw・SEC_USER・set_message()・set_server_zone_offset()・srv_put_dos_date()・sys_getpid()・t.
00132 { 00133 int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0); 00134 int secword=0; 00135 time_t t = time(NULL); 00136 00137 global_encrypted_passwords_negotiated = lp_encrypted_passwords(); 00138 00139 if (lp_security()>=SEC_USER) 00140 secword |= NEGOTIATE_SECURITY_USER_LEVEL; 00141 if (global_encrypted_passwords_negotiated) 00142 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; 00143 00144 set_message(outbuf,13,global_encrypted_passwords_negotiated?8:0,True); 00145 SSVAL(outbuf,smb_vwv1,secword); 00146 SIVAL(outbuf,smb_vwv6,sys_getpid()); 00147 00148 /* Create a token value and add it to the outgoing packet. */ 00149 if (global_encrypted_passwords_negotiated) { 00150 get_challenge(smb_buf(outbuf)); 00151 SSVAL(outbuf,smb_vwv11, 8); 00152 } 00153 00154 Protocol = PROTOCOL_LANMAN2; 00155 00156 /* Reply, SMBlockread, SMBwritelock supported. */ 00157 SCVAL(outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD); 00158 SSVAL(outbuf,smb_vwv2,max_recv); 00159 SSVAL(outbuf,smb_vwv3,lp_maxmux()); 00160 SSVAL(outbuf,smb_vwv4,1); 00161 SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */ 00162 SSVAL(outbuf,smb_vwv10, set_server_zone_offset(t)/60); 00163 srv_put_dos_date(outbuf,smb_vwv8,t); 00164 00165 return (smb_len(outbuf)+4); 00166 }
static DATA_BLOB negprot_spnego | ( | void | ) | [static] |
参照先 asprintf()・data_blob()・global_myname・global_spnego_negotiated・myname・name_to_fqdn()・push_ascii_nstring()・SEC_ADS・spnego_gen_negTokenInit()・strlower_m().
参照元 reply_nt1().
00173 { 00174 DATA_BLOB blob; 00175 nstring dos_name; 00176 fstring unix_name; 00177 #ifdef DEVELOPER 00178 size_t slen; 00179 #endif 00180 char guid[17]; 00181 const char *OIDs_krb5[] = {OID_KERBEROS5, 00182 OID_KERBEROS5_OLD, 00183 OID_NTLMSSP, 00184 NULL}; 00185 const char *OIDs_plain[] = {OID_NTLMSSP, NULL}; 00186 00187 global_spnego_negotiated = True; 00188 00189 memset(guid, '\0', sizeof(guid)); 00190 00191 safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1); 00192 strlower_m(unix_name); 00193 push_ascii_nstring(dos_name, unix_name); 00194 safe_strcpy(guid, dos_name, sizeof(guid)-1); 00195 00196 #ifdef DEVELOPER 00197 /* Fix valgrind 'uninitialized bytes' issue. */ 00198 slen = strlen(dos_name); 00199 if (slen < sizeof(guid)) { 00200 memset(guid+slen, '\0', sizeof(guid) - slen); 00201 } 00202 #endif 00203 00204 /* strangely enough, NT does not sent the single OID NTLMSSP when 00205 not a ADS member, it sends no OIDs at all 00206 00207 OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know 00208 about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)" 00209 00210 Our sessionsetup code now handles raw NTLMSSP connects, so we can go 00211 back to doing what W2K3 does here. This is needed to make PocketPC 2003 00212 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133 00213 for details. JRA. 00214 00215 */ 00216 00217 if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) { 00218 #if 0 00219 /* Code for PocketPC client */ 00220 blob = data_blob(guid, 16); 00221 #else 00222 /* Code for standalone WXP client */ 00223 blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE"); 00224 #endif 00225 } else { 00226 fstring myname; 00227 char *host_princ_s = NULL; 00228 name_to_fqdn(myname, global_myname()); 00229 strlower_m(myname); 00230 asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm()); 00231 blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s); 00232 SAFE_FREE(host_princ_s); 00233 } 00234 00235 return blob; 00236 }
static int reply_nt1 | ( | char * | inbuf, | |
char * | outbuf | |||
) | [static] |
参照先 add_to_common_flags2()・data_blob_::data・data_blob_free()・exit_server_cleanly()・get_challenge()・get_remote_arch()・global_encrypted_passwords_negotiated・data_blob_::length・lp_workgroup()・max_recv・negprot_spnego()・Protocol・PROTOCOL_NT1・put_long_date()・RA_SAMBA・RA_VISTA・SEC_SHARE・SEC_USER・set_message()・set_message_end()・set_remote_arch()・set_server_zone_offset()・srv_set_signing_negotiated()・sys_getpid()・t.
00243 { 00244 /* dual names + lock_and_read + nt SMBs + remote API calls */ 00245 int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ| 00246 CAP_LEVEL_II_OPLOCKS; 00247 00248 int secword=0; 00249 char *p, *q; 00250 BOOL negotiate_spnego = False; 00251 time_t t = time(NULL); 00252 00253 global_encrypted_passwords_negotiated = lp_encrypted_passwords(); 00254 00255 /* Check the flags field to see if this is Vista. 00256 WinXP sets it and Vista does not. But we have to 00257 distinguish from NT which doesn't set it either. */ 00258 00259 if ( (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY) && 00260 ((SVAL(inbuf, smb_flg2) & FLAGS2_UNKNOWN_BIT4) == 0) ) 00261 { 00262 if (get_remote_arch() != RA_SAMBA) { 00263 set_remote_arch( RA_VISTA ); 00264 } 00265 } 00266 00267 /* do spnego in user level security if the client 00268 supports it and we can do encrypted passwords */ 00269 00270 if (global_encrypted_passwords_negotiated && 00271 (lp_security() != SEC_SHARE) && 00272 lp_use_spnego() && 00273 (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) { 00274 negotiate_spnego = True; 00275 capabilities |= CAP_EXTENDED_SECURITY; 00276 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY); 00277 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply (already 00278 partially constructed. */ 00279 SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_EXTENDED_SECURITY); 00280 } 00281 00282 capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE; 00283 00284 if (lp_unix_extensions()) { 00285 capabilities |= CAP_UNIX; 00286 } 00287 00288 if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64)) 00289 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS; 00290 00291 if (SMB_OFF_T_BITS == 64) 00292 capabilities |= CAP_LARGE_FILES; 00293 00294 if (lp_readraw() && lp_writeraw()) 00295 capabilities |= CAP_RAW_MODE; 00296 00297 if (lp_nt_status_support()) 00298 capabilities |= CAP_STATUS32; 00299 00300 if (lp_host_msdfs()) 00301 capabilities |= CAP_DFS; 00302 00303 if (lp_security() >= SEC_USER) 00304 secword |= NEGOTIATE_SECURITY_USER_LEVEL; 00305 if (global_encrypted_passwords_negotiated) 00306 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; 00307 00308 if (lp_server_signing()) { 00309 if (lp_security() >= SEC_USER) { 00310 secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED; 00311 /* No raw mode with smb signing. */ 00312 capabilities &= ~CAP_RAW_MODE; 00313 if (lp_server_signing() == Required) 00314 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED; 00315 srv_set_signing_negotiated(); 00316 } else { 00317 DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n")); 00318 if (lp_server_signing() == Required) { 00319 exit_server_cleanly("reply_nt1: smb signing required and share level security selected."); 00320 } 00321 } 00322 } 00323 00324 set_message(outbuf,17,0,True); 00325 00326 SCVAL(outbuf,smb_vwv1,secword); 00327 00328 Protocol = PROTOCOL_NT1; 00329 00330 SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */ 00331 SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */ 00332 SIVAL(outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */ 00333 SIVAL(outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */ 00334 SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */ 00335 SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */ 00336 put_long_date(outbuf+smb_vwv11+1,t); 00337 SSVALS(outbuf,smb_vwv15+1,set_server_zone_offset(t)/60); 00338 00339 p = q = smb_buf(outbuf); 00340 if (!negotiate_spnego) { 00341 /* Create a token value and add it to the outgoing packet. */ 00342 if (global_encrypted_passwords_negotiated) { 00343 /* note that we do not send a challenge at all if 00344 we are using plaintext */ 00345 get_challenge(p); 00346 SCVAL(outbuf,smb_vwv16+1,8); 00347 p += 8; 00348 } 00349 p += srvstr_push(outbuf, p, lp_workgroup(), BUFFER_SIZE - (p-outbuf), 00350 STR_UNICODE|STR_TERMINATE|STR_NOALIGN); 00351 DEBUG(3,("not using SPNEGO\n")); 00352 } else { 00353 DATA_BLOB spnego_blob = negprot_spnego(); 00354 00355 if (spnego_blob.data == NULL) { 00356 return ERROR_NT(NT_STATUS_NO_MEMORY); 00357 } 00358 00359 memcpy(p, spnego_blob.data, spnego_blob.length); 00360 p += spnego_blob.length; 00361 data_blob_free(&spnego_blob); 00362 00363 SCVAL(outbuf,smb_vwv16+1, 0); 00364 DEBUG(3,("using SPNEGO\n")); 00365 } 00366 00367 SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */ 00368 set_message_end(outbuf, p); 00369 00370 return (smb_len(outbuf)+4); 00371 }
int reply_negprot | ( | connection_struct * | conn, | |
char * | inbuf, | |||
char * | outbuf, | |||
int | dum_size, | |||
int | dum_buffsize | |||
) |
参照先 claim_connection()・exit_server_cleanly()・get_remote_arch()・proto_name・Protocol・protocol_level・PROTOCOL_NT1・RA_CIFSFS・RA_OS2・RA_SAMBA・RA_UNKNOWN・RA_VISTA・RA_WFWG・RA_WIN2K・RA_WIN95・RA_WINNT・reload_services()・remote_proto・set_message()・set_remote_arch()・short_name・strcsequal()・strequal()・supported_protocols.
00483 { 00484 int outsize = set_message(outbuf,1,0,True); 00485 int Index=0; 00486 int choice= -1; 00487 int protocol; 00488 char *p; 00489 int bcc = SVAL(smb_buf(inbuf),-2); 00490 int arch = ARCH_ALL; 00491 00492 static BOOL done_negprot = False; 00493 00494 START_PROFILE(SMBnegprot); 00495 00496 if (done_negprot) { 00497 END_PROFILE(SMBnegprot); 00498 exit_server_cleanly("multiple negprot's are not permitted"); 00499 } 00500 done_negprot = True; 00501 00502 p = smb_buf(inbuf)+1; 00503 while (p < (smb_buf(inbuf) + bcc)) { 00504 Index++; 00505 DEBUG(3,("Requested protocol [%s]\n",p)); 00506 if (strcsequal(p,"Windows for Workgroups 3.1a")) 00507 arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K ); 00508 else if (strcsequal(p,"DOS LM1.2X002")) 00509 arch &= ( ARCH_WFWG | ARCH_WIN95 ); 00510 else if (strcsequal(p,"DOS LANMAN2.1")) 00511 arch &= ( ARCH_WFWG | ARCH_WIN95 ); 00512 else if (strcsequal(p,"NT LM 0.12")) 00513 arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K | ARCH_CIFSFS); 00514 else if (strcsequal(p,"SMB 2.001")) 00515 arch = ARCH_VISTA; 00516 else if (strcsequal(p,"LANMAN2.1")) 00517 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 ); 00518 else if (strcsequal(p,"LM1.2X002")) 00519 arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 ); 00520 else if (strcsequal(p,"MICROSOFT NETWORKS 1.03")) 00521 arch &= ARCH_WINNT; 00522 else if (strcsequal(p,"XENIX CORE")) 00523 arch &= ( ARCH_WINNT | ARCH_OS2 ); 00524 else if (strcsequal(p,"Samba")) { 00525 arch = ARCH_SAMBA; 00526 break; 00527 } else if (strcsequal(p,"POSIX 2")) { 00528 arch = ARCH_CIFSFS; 00529 break; 00530 } 00531 00532 p += strlen(p) + 2; 00533 } 00534 00535 /* CIFSFS can send one arch only, NT LM 0.12. */ 00536 if (Index == 1 && (arch & ARCH_CIFSFS)) { 00537 arch = ARCH_CIFSFS; 00538 } 00539 00540 switch ( arch ) { 00541 case ARCH_CIFSFS: 00542 set_remote_arch(RA_CIFSFS); 00543 break; 00544 case ARCH_SAMBA: 00545 set_remote_arch(RA_SAMBA); 00546 break; 00547 case ARCH_WFWG: 00548 set_remote_arch(RA_WFWG); 00549 break; 00550 case ARCH_WIN95: 00551 set_remote_arch(RA_WIN95); 00552 break; 00553 case ARCH_WINNT: 00554 if(SVAL(inbuf,smb_flg2)==FLAGS2_WIN2K_SIGNATURE) 00555 set_remote_arch(RA_WIN2K); 00556 else 00557 set_remote_arch(RA_WINNT); 00558 break; 00559 case ARCH_WIN2K: 00560 /* Vista may have been set in the negprot so don't 00561 override it here */ 00562 if ( get_remote_arch() != RA_VISTA ) 00563 set_remote_arch(RA_WIN2K); 00564 break; 00565 case ARCH_VISTA: 00566 set_remote_arch(RA_VISTA); 00567 break; 00568 case ARCH_OS2: 00569 set_remote_arch(RA_OS2); 00570 break; 00571 default: 00572 set_remote_arch(RA_UNKNOWN); 00573 break; 00574 } 00575 00576 /* possibly reload - change of architecture */ 00577 reload_services(True); 00578 00579 /* moved from the netbios session setup code since we don't have that 00580 when the client connects to port 445. Of course there is a small 00581 window where we are listening to messages -- jerry */ 00582 00583 claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL); 00584 00585 /* Check for protocols, most desirable first */ 00586 for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) { 00587 p = smb_buf(inbuf)+1; 00588 Index = 0; 00589 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) && 00590 (supported_protocols[protocol].protocol_level >= lp_minprotocol())) 00591 while (p < (smb_buf(inbuf) + bcc)) { 00592 if (strequal(p,supported_protocols[protocol].proto_name)) 00593 choice = Index; 00594 Index++; 00595 p += strlen(p) + 2; 00596 } 00597 if(choice != -1) 00598 break; 00599 } 00600 00601 SSVAL(outbuf,smb_vwv0,choice); 00602 if(choice != -1) { 00603 fstrcpy(remote_proto,supported_protocols[protocol].short_name); 00604 reload_services(True); 00605 outsize = supported_protocols[protocol].proto_reply_fn(inbuf, outbuf); 00606 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name)); 00607 } else { 00608 DEBUG(0,("No protocol supported !\n")); 00609 } 00610 SSVAL(outbuf,smb_vwv0,choice); 00611 00612 DEBUG( 5, ( "negprot index=%d\n", choice ) ); 00613 00614 if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) { 00615 exit_server_cleanly("SMB signing is required and " 00616 "client negotiated a downlevel protocol"); 00617 } 00618 00619 END_PROFILE(SMBnegprot); 00620 return(outsize); 00621 }
enum protocol_types Protocol |
int max_recv |
BOOL global_spnego_negotiated = False |
struct auth_context* negprot_global_auth_context = NULL |
const char* proto_name |
const char* short_name |
int(* proto_reply_fn)(char *, char *) |
int protocol_level |
struct { ... } supported_protocols[] [static] |
参照元 reply_negprot().