smbd/negprot.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    negprot reply code
00004    Copyright (C) Andrew Tridgell 1992-1998
00005    
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015    
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 */
00020 
00021 #include "includes.h"
00022 
00023 extern fstring remote_proto;
00024 extern enum protocol_types Protocol;
00025 extern int max_recv;
00026 
00027 BOOL global_encrypted_passwords_negotiated = False;
00028 BOOL global_spnego_negotiated = False;
00029 struct auth_context *negprot_global_auth_context = NULL;
00030 
00031 static void get_challenge(char buff[8]) 
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 }
00052 
00053 /****************************************************************************
00054  Reply for the core protocol.
00055 ****************************************************************************/
00056 
00057 static int reply_corep(char *inbuf, char *outbuf)
00058 {
00059         int outsize = set_message(outbuf,1,0,True);
00060 
00061         Protocol = PROTOCOL_CORE;
00062         
00063         return outsize;
00064 }
00065 
00066 /****************************************************************************
00067  Reply for the coreplus protocol.
00068 ****************************************************************************/
00069 
00070 static int reply_coreplus(char *inbuf, char *outbuf)
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 }
00084 
00085 /****************************************************************************
00086  Reply for the lanman 1.0 protocol.
00087 ****************************************************************************/
00088 
00089 static int reply_lanman1(char *inbuf, char *outbuf)
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 }
00126 
00127 /****************************************************************************
00128  Reply for the lanman 2.0 protocol.
00129 ****************************************************************************/
00130 
00131 static int reply_lanman2(char *inbuf, char *outbuf)
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 }
00167 
00168 /****************************************************************************
00169  Generate the spnego negprot reply blob. Return the number of bytes used.
00170 ****************************************************************************/
00171 
00172 static DATA_BLOB negprot_spnego(void)
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 }
00237 
00238 /****************************************************************************
00239  Reply for the nt protocol.
00240 ****************************************************************************/
00241 
00242 static int reply_nt1(char *inbuf, char *outbuf)
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 }
00372 
00373 /* these are the protocol lists used for auto architecture detection:
00374 
00375 WinNT 3.51:
00376 protocol [PC NETWORK PROGRAM 1.0]
00377 protocol [XENIX CORE]
00378 protocol [MICROSOFT NETWORKS 1.03]
00379 protocol [LANMAN1.0]
00380 protocol [Windows for Workgroups 3.1a]
00381 protocol [LM1.2X002]
00382 protocol [LANMAN2.1]
00383 protocol [NT LM 0.12]
00384 
00385 Win95:
00386 protocol [PC NETWORK PROGRAM 1.0]
00387 protocol [XENIX CORE]
00388 protocol [MICROSOFT NETWORKS 1.03]
00389 protocol [LANMAN1.0]
00390 protocol [Windows for Workgroups 3.1a]
00391 protocol [LM1.2X002]
00392 protocol [LANMAN2.1]
00393 protocol [NT LM 0.12]
00394 
00395 Win2K:
00396 protocol [PC NETWORK PROGRAM 1.0]
00397 protocol [LANMAN1.0]
00398 protocol [Windows for Workgroups 3.1a]
00399 protocol [LM1.2X002]
00400 protocol [LANMAN2.1]
00401 protocol [NT LM 0.12]
00402 
00403 Vista:
00404 protocol [PC NETWORK PROGRAM 1.0]
00405 protocol [LANMAN1.0]
00406 protocol [Windows for Workgroups 3.1a]
00407 protocol [LM1.2X002]
00408 protocol [LANMAN2.1]
00409 protocol [NT LM 0.12]
00410 protocol [SMB 2.001]
00411 
00412 OS/2:
00413 protocol [PC NETWORK PROGRAM 1.0]
00414 protocol [XENIX CORE]
00415 protocol [LANMAN1.0]
00416 protocol [LM1.2X002]
00417 protocol [LANMAN2.1]
00418 */
00419 
00420 /*
00421   * Modified to recognize the architecture of the remote machine better.
00422   *
00423   * This appears to be the matrix of which protocol is used by which
00424   * MS product.
00425        Protocol                       WfWg    Win95   WinNT  Win2K  OS/2 Vista
00426        PC NETWORK PROGRAM 1.0          1       1       1      1      1     1
00427        XENIX CORE                                      2             2
00428        MICROSOFT NETWORKS 3.0          2       2       
00429        DOS LM1.2X002                   3       3       
00430        MICROSOFT NETWORKS 1.03                         3
00431        DOS LANMAN2.1                   4       4       
00432        LANMAN1.0                                       4      2      3     2
00433        Windows for Workgroups 3.1a     5       5       5      3            3
00434        LM1.2X002                                       6      4      4     4
00435        LANMAN2.1                                       7      5      5     5
00436        NT LM 0.12                              6       8      6            6
00437        SMB 2.001                                                           7
00438   *
00439   *  tim@fsg.com 09/29/95
00440   *  Win2K added by matty 17/7/99
00441   */
00442   
00443 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
00444 #define ARCH_WIN95    0x2
00445 #define ARCH_WINNT    0x4
00446 #define ARCH_WIN2K    0xC      /* Win2K is like NT */
00447 #define ARCH_OS2      0x14     /* Again OS/2 is like NT */
00448 #define ARCH_SAMBA    0x20
00449 #define ARCH_CIFSFS   0x40
00450 #define ARCH_VISTA    0x8C     /* Vista is like XP/2K */
00451  
00452 #define ARCH_ALL      0x7F
00453  
00454 /* List of supported protocols, most desired first */
00455 static const struct {
00456         const char *proto_name;
00457         const char *short_name;
00458         int (*proto_reply_fn)(char *, char *);
00459         int protocol_level;
00460 } supported_protocols[] = {
00461         {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
00462         {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
00463         {"POSIX 2",                 "NT1",      reply_nt1,      PROTOCOL_NT1},
00464         {"LANMAN2.1",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
00465         {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
00466         {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
00467         {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
00468         {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
00469         {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
00470         {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
00471         {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
00472         {NULL,NULL,NULL,0},
00473 };
00474 
00475 /****************************************************************************
00476  Reply to a negprot.
00477  conn POINTER CAN BE NULL HERE !
00478 ****************************************************************************/
00479 
00480 int reply_negprot(connection_struct *conn, 
00481                   char *inbuf,char *outbuf, int dum_size, 
00482                   int dum_buffsize)
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 }

Sambaに対してSat Aug 29 21:23:24 2009に生成されました。  doxygen 1.4.7