root/source3/smbd/negprot.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_challenge
  2. reply_corep
  3. reply_coreplus
  4. reply_lanman1
  5. reply_lanman2
  6. negprot_spnego
  7. reply_nt1
  8. reply_negprot

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    negprot reply code
   4    Copyright (C) Andrew Tridgell 1992-1998
   5    Copyright (C) Volker Lendecke 2007
   6    
   7    This program is free software; you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation; either version 3 of the License, or
  10    (at your option) any later version.
  11    
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16    
  17    You should have received a copy of the GNU General Public License
  18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19 */
  20 
  21 #include "includes.h"
  22 #include "smbd/globals.h"
  23 
  24 extern fstring remote_proto;
  25 extern enum protocol_types Protocol;
  26 
  27 static void get_challenge(uint8 buff[8])
     /* [<][>][^][v][top][bottom][index][help] */
  28 {
  29         NTSTATUS nt_status;
  30 
  31         /* We might be called more than once, multiple negprots are
  32          * permitted */
  33         if (negprot_global_auth_context) {
  34                 DEBUG(3, ("get challenge: is this a secondary negprot?  negprot_global_auth_context is non-NULL!\n"));
  35                 (negprot_global_auth_context->free)(&negprot_global_auth_context);
  36         }
  37 
  38         DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
  39         if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&negprot_global_auth_context))) {
  40                 DEBUG(0, ("make_auth_context_subsystem returned %s", nt_errstr(nt_status)));
  41                 smb_panic("cannot make_negprot_global_auth_context!");
  42         }
  43         DEBUG(10, ("get challenge: getting challenge\n"));
  44         negprot_global_auth_context->get_ntlm_challenge(
  45                 negprot_global_auth_context, buff);
  46 }
  47 
  48 /****************************************************************************
  49  Reply for the core protocol.
  50 ****************************************************************************/
  51 
  52 static void reply_corep(struct smb_request *req, uint16 choice)
     /* [<][>][^][v][top][bottom][index][help] */
  53 {
  54         reply_outbuf(req, 1, 0);
  55         SSVAL(req->outbuf, smb_vwv0, choice);
  56 
  57         Protocol = PROTOCOL_CORE;
  58 }
  59 
  60 /****************************************************************************
  61  Reply for the coreplus protocol.
  62 ****************************************************************************/
  63 
  64 static void reply_coreplus(struct smb_request *req, uint16 choice)
     /* [<][>][^][v][top][bottom][index][help] */
  65 {
  66         int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
  67 
  68         reply_outbuf(req, 13, 0);
  69 
  70         SSVAL(req->outbuf,smb_vwv0,choice);
  71         SSVAL(req->outbuf,smb_vwv5,raw); /* tell redirector we support
  72                         readbraw and writebraw (possibly) */
  73         /* Reply, SMBlockread, SMBwritelock supported. */
  74         SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
  75         SSVAL(req->outbuf,smb_vwv1,0x1); /* user level security, don't
  76                                           * encrypt */
  77         Protocol = PROTOCOL_COREPLUS;
  78 }
  79 
  80 /****************************************************************************
  81  Reply for the lanman 1.0 protocol.
  82 ****************************************************************************/
  83 
  84 static void reply_lanman1(struct smb_request *req, uint16 choice)
     /* [<][>][^][v][top][bottom][index][help] */
  85 {
  86         int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
  87         int secword=0;
  88         time_t t = time(NULL);
  89 
  90         global_encrypted_passwords_negotiated = lp_encrypted_passwords();
  91 
  92         if (lp_security()>=SEC_USER)
  93                 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
  94         if (global_encrypted_passwords_negotiated)
  95                 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
  96 
  97         reply_outbuf(req, 13, global_encrypted_passwords_negotiated?8:0);
  98 
  99         SSVAL(req->outbuf,smb_vwv0,choice);
 100         SSVAL(req->outbuf,smb_vwv1,secword);
 101         /* Create a token value and add it to the outgoing packet. */
 102         if (global_encrypted_passwords_negotiated) {
 103                 get_challenge((uint8 *)smb_buf(req->outbuf));
 104                 SSVAL(req->outbuf,smb_vwv11, 8);
 105         }
 106 
 107         Protocol = PROTOCOL_LANMAN1;
 108 
 109         /* Reply, SMBlockread, SMBwritelock supported. */
 110         SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
 111         SSVAL(req->outbuf,smb_vwv2,max_recv);
 112         SSVAL(req->outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
 113         SSVAL(req->outbuf,smb_vwv4,1);
 114         SSVAL(req->outbuf,smb_vwv5,raw); /* tell redirector we support
 115                 readbraw writebraw (possibly) */
 116         SIVAL(req->outbuf,smb_vwv6,sys_getpid());
 117         SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
 118 
 119         srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
 120 
 121         return;
 122 }
 123 
 124 /****************************************************************************
 125  Reply for the lanman 2.0 protocol.
 126 ****************************************************************************/
 127 
 128 static void reply_lanman2(struct smb_request *req, uint16 choice)
     /* [<][>][^][v][top][bottom][index][help] */
 129 {
 130         int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
 131         int secword=0;
 132         time_t t = time(NULL);
 133 
 134         global_encrypted_passwords_negotiated = lp_encrypted_passwords();
 135   
 136         if (lp_security()>=SEC_USER)
 137                 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
 138         if (global_encrypted_passwords_negotiated)
 139                 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
 140 
 141         reply_outbuf(req, 13, global_encrypted_passwords_negotiated?8:0);
 142 
 143         SSVAL(req->outbuf,smb_vwv0,choice);
 144         SSVAL(req->outbuf,smb_vwv1,secword);
 145         SIVAL(req->outbuf,smb_vwv6,sys_getpid());
 146 
 147         /* Create a token value and add it to the outgoing packet. */
 148         if (global_encrypted_passwords_negotiated) {
 149                 get_challenge((uint8 *)smb_buf(req->outbuf));
 150                 SSVAL(req->outbuf,smb_vwv11, 8);
 151         }
 152 
 153         Protocol = PROTOCOL_LANMAN2;
 154 
 155         /* Reply, SMBlockread, SMBwritelock supported. */
 156         SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
 157         SSVAL(req->outbuf,smb_vwv2,max_recv);
 158         SSVAL(req->outbuf,smb_vwv3,lp_maxmux());
 159         SSVAL(req->outbuf,smb_vwv4,1);
 160         SSVAL(req->outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
 161         SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
 162         srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
 163 }
 164 
 165 /****************************************************************************
 166  Generate the spnego negprot reply blob. Return the number of bytes used.
 167 ****************************************************************************/
 168 
 169 static DATA_BLOB negprot_spnego(void)
     /* [<][>][^][v][top][bottom][index][help] */
 170 {
 171         DATA_BLOB blob;
 172         nstring dos_name;
 173         fstring unix_name;
 174 #ifdef DEVELOPER
 175         size_t slen;
 176 #endif
 177         char guid[17];
 178         const char *OIDs_krb5[] = {OID_KERBEROS5,
 179                                    OID_KERBEROS5_OLD,
 180                                    OID_NTLMSSP,
 181                                    NULL};
 182         const char *OIDs_plain[] = {OID_NTLMSSP, NULL};
 183 
 184         global_spnego_negotiated = True;
 185 
 186         memset(guid, '\0', sizeof(guid));
 187 
 188         safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1);
 189         strlower_m(unix_name);
 190         push_ascii_nstring(dos_name, unix_name);
 191         safe_strcpy(guid, dos_name, sizeof(guid)-1);
 192 
 193 #ifdef DEVELOPER
 194         /* Fix valgrind 'uninitialized bytes' issue. */
 195         slen = strlen(dos_name);
 196         if (slen < sizeof(guid)) {
 197                 memset(guid+slen, '\0', sizeof(guid) - slen);
 198         }
 199 #endif
 200 
 201         /* strangely enough, NT does not sent the single OID NTLMSSP when
 202            not a ADS member, it sends no OIDs at all
 203 
 204            OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
 205                    about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
 206 
 207            Our sessionsetup code now handles raw NTLMSSP connects, so we can go
 208            back to doing what W2K3 does here. This is needed to make PocketPC 2003
 209            CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
 210            for details. JRA.
 211 
 212         */
 213 
 214         if (lp_security() != SEC_ADS && !USE_KERBEROS_KEYTAB) {
 215 #if 0
 216                 /* Code for PocketPC client */
 217                 blob = data_blob(guid, 16);
 218 #else
 219                 /* Code for standalone WXP client */
 220                 blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
 221 #endif
 222         } else {
 223                 fstring myname;
 224                 char *host_princ_s = NULL;
 225                 name_to_fqdn(myname, global_myname());
 226                 strlower_m(myname);
 227                 if (asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm())
 228                     == -1) {
 229                         return data_blob_null;
 230                 }
 231                 blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s);
 232                 SAFE_FREE(host_princ_s);
 233         }
 234 
 235         return blob;
 236 }
 237 
 238 /****************************************************************************
 239  Reply for the nt protocol.
 240 ****************************************************************************/
 241 
 242 static void reply_nt1(struct smb_request *req, uint16 choice)
     /* [<][>][^][v][top][bottom][index][help] */
 243 {
 244         /* dual names + lock_and_read + nt SMBs + remote API calls */
 245         int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
 246                 CAP_LEVEL_II_OPLOCKS;
 247 
 248         int secword=0;
 249         char *p, *q;
 250         bool negotiate_spnego = False;
 251         time_t t = time(NULL);
 252         ssize_t ret;
 253 
 254         global_encrypted_passwords_negotiated = lp_encrypted_passwords();
 255 
 256         /* Check the flags field to see if this is Vista.
 257            WinXP sets it and Vista does not. But we have to 
 258            distinguish from NT which doesn't set it either. */
 259 
 260         if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
 261                 ((req->flags2 & FLAGS2_UNKNOWN_BIT4) == 0) )
 262         {
 263                 if (get_remote_arch() != RA_SAMBA) {
 264                         set_remote_arch( RA_VISTA );
 265                 }
 266         }
 267 
 268         reply_outbuf(req,17,0);
 269 
 270         /* do spnego in user level security if the client
 271            supports it and we can do encrypted passwords */
 272         
 273         if (global_encrypted_passwords_negotiated && 
 274             (lp_security() != SEC_SHARE) &&
 275             lp_use_spnego() &&
 276             (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
 277                 negotiate_spnego = True;
 278                 capabilities |= CAP_EXTENDED_SECURITY;
 279                 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
 280                 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
 281                    (already partially constructed. */
 282                 SSVAL(req->outbuf, smb_flg2,
 283                       req->flags2 | FLAGS2_EXTENDED_SECURITY);
 284         }
 285         
 286         capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
 287 
 288         if (lp_unix_extensions()) {
 289                 capabilities |= CAP_UNIX;
 290         }
 291         
 292         if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
 293                 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
 294         
 295         if (SMB_OFF_T_BITS == 64)
 296                 capabilities |= CAP_LARGE_FILES;
 297 
 298         if (lp_readraw() && lp_writeraw())
 299                 capabilities |= CAP_RAW_MODE;
 300         
 301         if (lp_nt_status_support())
 302                 capabilities |= CAP_STATUS32;
 303         
 304         if (lp_host_msdfs())
 305                 capabilities |= CAP_DFS;
 306         
 307         if (lp_security() >= SEC_USER)
 308                 secword |= NEGOTIATE_SECURITY_USER_LEVEL;
 309         if (global_encrypted_passwords_negotiated)
 310                 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
 311         
 312         if (lp_server_signing()) {
 313                 if (lp_security() >= SEC_USER) {
 314                         secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
 315                         /* No raw mode with smb signing. */
 316                         capabilities &= ~CAP_RAW_MODE;
 317                         if (lp_server_signing() == Required)
 318                                 secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
 319                         srv_set_signing_negotiated();
 320                 } else {
 321                         DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
 322                         if (lp_server_signing() == Required) {
 323                                 exit_server_cleanly("reply_nt1: smb signing required and share level security selected.");
 324                         }
 325                 }
 326         }
 327 
 328         SSVAL(req->outbuf,smb_vwv0,choice);
 329         SCVAL(req->outbuf,smb_vwv1,secword);
 330         
 331         Protocol = PROTOCOL_NT1;
 332         
 333         SSVAL(req->outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
 334         SSVAL(req->outbuf,smb_vwv2+1,1); /* num vcs */
 335         SIVAL(req->outbuf,smb_vwv3+1,max_recv); /* max buffer. LOTS! */
 336         SIVAL(req->outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
 337         SIVAL(req->outbuf,smb_vwv7+1,sys_getpid()); /* session key */
 338         SIVAL(req->outbuf,smb_vwv9+1,capabilities); /* capabilities */
 339         put_long_date((char *)req->outbuf+smb_vwv11+1,t);
 340         SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
 341         
 342         p = q = smb_buf(req->outbuf);
 343         if (!negotiate_spnego) {
 344                 /* Create a token value and add it to the outgoing packet. */
 345                 if (global_encrypted_passwords_negotiated) {
 346                         uint8 chal[8];
 347                         /* note that we do not send a challenge at all if
 348                            we are using plaintext */
 349                         get_challenge(chal);
 350                         ret = message_push_blob(
 351                                 &req->outbuf, data_blob_const(chal, sizeof(chal)));
 352                         if (ret == -1) {
 353                                 DEBUG(0, ("Could not push challenge\n"));
 354                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
 355                                 return;
 356                         }
 357                         SCVAL(req->outbuf, smb_vwv16+1, ret);
 358                         p += ret;
 359                 }
 360                 ret = message_push_string(&req->outbuf, lp_workgroup(),
 361                                           STR_UNICODE|STR_TERMINATE
 362                                           |STR_NOALIGN);
 363                 if (ret == -1) {
 364                         DEBUG(0, ("Could not push challenge\n"));
 365                         reply_nterror(req, NT_STATUS_NO_MEMORY);
 366                         return;
 367                 }
 368                 DEBUG(3,("not using SPNEGO\n"));
 369         } else {
 370                 DATA_BLOB spnego_blob = negprot_spnego();
 371 
 372                 if (spnego_blob.data == NULL) {
 373                         reply_nterror(req, NT_STATUS_NO_MEMORY);
 374                         return;
 375                 }
 376 
 377                 ret = message_push_blob(&req->outbuf, spnego_blob);
 378                 if (ret == -1) {
 379                         DEBUG(0, ("Could not push spnego blob\n"));
 380                         reply_nterror(req, NT_STATUS_NO_MEMORY);
 381                         return;
 382                 }
 383                 p += ret;
 384                 data_blob_free(&spnego_blob);
 385 
 386                 SCVAL(req->outbuf,smb_vwv16+1, 0);
 387                 DEBUG(3,("using SPNEGO\n"));
 388         }
 389         
 390         SSVAL(req->outbuf,smb_vwv17, p - q); /* length of challenge+domain
 391                                               * strings */
 392 
 393         return;
 394 }
 395 
 396 /* these are the protocol lists used for auto architecture detection:
 397 
 398 WinNT 3.51:
 399 protocol [PC NETWORK PROGRAM 1.0]
 400 protocol [XENIX CORE]
 401 protocol [MICROSOFT NETWORKS 1.03]
 402 protocol [LANMAN1.0]
 403 protocol [Windows for Workgroups 3.1a]
 404 protocol [LM1.2X002]
 405 protocol [LANMAN2.1]
 406 protocol [NT LM 0.12]
 407 
 408 Win95:
 409 protocol [PC NETWORK PROGRAM 1.0]
 410 protocol [XENIX CORE]
 411 protocol [MICROSOFT NETWORKS 1.03]
 412 protocol [LANMAN1.0]
 413 protocol [Windows for Workgroups 3.1a]
 414 protocol [LM1.2X002]
 415 protocol [LANMAN2.1]
 416 protocol [NT LM 0.12]
 417 
 418 Win2K:
 419 protocol [PC NETWORK PROGRAM 1.0]
 420 protocol [LANMAN1.0]
 421 protocol [Windows for Workgroups 3.1a]
 422 protocol [LM1.2X002]
 423 protocol [LANMAN2.1]
 424 protocol [NT LM 0.12]
 425 
 426 Vista:
 427 protocol [PC NETWORK PROGRAM 1.0]
 428 protocol [LANMAN1.0]
 429 protocol [Windows for Workgroups 3.1a]
 430 protocol [LM1.2X002]
 431 protocol [LANMAN2.1]
 432 protocol [NT LM 0.12]
 433 protocol [SMB 2.001]
 434 
 435 OS/2:
 436 protocol [PC NETWORK PROGRAM 1.0]
 437 protocol [XENIX CORE]
 438 protocol [LANMAN1.0]
 439 protocol [LM1.2X002]
 440 protocol [LANMAN2.1]
 441 */
 442 
 443 /*
 444   * Modified to recognize the architecture of the remote machine better.
 445   *
 446   * This appears to be the matrix of which protocol is used by which
 447   * MS product.
 448        Protocol                       WfWg    Win95   WinNT  Win2K  OS/2 Vista
 449        PC NETWORK PROGRAM 1.0          1       1       1      1      1     1
 450        XENIX CORE                                      2             2
 451        MICROSOFT NETWORKS 3.0          2       2       
 452        DOS LM1.2X002                   3       3       
 453        MICROSOFT NETWORKS 1.03                         3
 454        DOS LANMAN2.1                   4       4       
 455        LANMAN1.0                                       4      2      3     2
 456        Windows for Workgroups 3.1a     5       5       5      3            3
 457        LM1.2X002                                       6      4      4     4
 458        LANMAN2.1                                       7      5      5     5
 459        NT LM 0.12                              6       8      6            6
 460        SMB 2.001                                                           7
 461   *
 462   *  tim@fsg.com 09/29/95
 463   *  Win2K added by matty 17/7/99
 464   */
 465   
 466 #define ARCH_WFWG     0x3      /* This is a fudge because WfWg is like Win95 */
 467 #define ARCH_WIN95    0x2
 468 #define ARCH_WINNT    0x4
 469 #define ARCH_WIN2K    0xC      /* Win2K is like NT */
 470 #define ARCH_OS2      0x14     /* Again OS/2 is like NT */
 471 #define ARCH_SAMBA    0x20
 472 #define ARCH_CIFSFS   0x40
 473 #define ARCH_VISTA    0x8C     /* Vista is like XP/2K */
 474  
 475 #define ARCH_ALL      0x7F
 476  
 477 /* List of supported protocols, most desired first */
 478 static const struct {
 479         const char *proto_name;
 480         const char *short_name;
 481         void (*proto_reply_fn)(struct smb_request *req, uint16 choice);
 482         int protocol_level;
 483 } supported_protocols[] = {
 484         {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
 485         {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
 486         {"POSIX 2",                 "NT1",      reply_nt1,      PROTOCOL_NT1},
 487         {"LANMAN2.1",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
 488         {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
 489         {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
 490         {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
 491         {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
 492         {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
 493         {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
 494         {"PC NETWORK PROGRAM 1.0",  "CORE",     reply_corep,    PROTOCOL_CORE}, 
 495         {NULL,NULL,NULL,0},
 496 };
 497 
 498 /****************************************************************************
 499  Reply to a negprot.
 500  conn POINTER CAN BE NULL HERE !
 501 ****************************************************************************/
 502 
 503 void reply_negprot(struct smb_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 504 {
 505         int choice= -1;
 506         int protocol;
 507         const char *p;
 508         int arch = ARCH_ALL;
 509         int num_cliprotos;
 510         char **cliprotos;
 511         int i;
 512         size_t converted_size;
 513 
 514         START_PROFILE(SMBnegprot);
 515 
 516         if (done_negprot) {
 517                 END_PROFILE(SMBnegprot);
 518                 exit_server_cleanly("multiple negprot's are not permitted");
 519         }
 520         done_negprot = True;
 521 
 522         if (req->buflen == 0) {
 523                 DEBUG(0, ("negprot got no protocols\n"));
 524                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
 525                 END_PROFILE(SMBnegprot);
 526                 return;
 527         }
 528 
 529         if (req->buf[req->buflen-1] != '\0') {
 530                 DEBUG(0, ("negprot protocols not 0-terminated\n"));
 531                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
 532                 END_PROFILE(SMBnegprot);
 533                 return;
 534         }
 535 
 536         p = (const char *)req->buf + 1;
 537 
 538         num_cliprotos = 0;
 539         cliprotos = NULL;
 540 
 541         while (smbreq_bufrem(req, p) > 0) {
 542 
 543                 char **tmp;
 544 
 545                 tmp = TALLOC_REALLOC_ARRAY(talloc_tos(), cliprotos, char *,
 546                                            num_cliprotos+1);
 547                 if (tmp == NULL) {
 548                         DEBUG(0, ("talloc failed\n"));
 549                         TALLOC_FREE(cliprotos);
 550                         reply_nterror(req, NT_STATUS_NO_MEMORY);
 551                         END_PROFILE(SMBnegprot);
 552                         return;
 553                 }
 554 
 555                 cliprotos = tmp;
 556 
 557                 if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
 558                                        &converted_size)) {
 559                         DEBUG(0, ("pull_ascii_talloc failed\n"));
 560                         TALLOC_FREE(cliprotos);
 561                         reply_nterror(req, NT_STATUS_NO_MEMORY);
 562                         END_PROFILE(SMBnegprot);
 563                         return;
 564                 }
 565 
 566                 DEBUG(3, ("Requested protocol [%s]\n",
 567                           cliprotos[num_cliprotos]));
 568 
 569                 num_cliprotos += 1;
 570                 p += strlen(p) + 2;
 571         }
 572 
 573         for (i=0; i<num_cliprotos; i++) {
 574                 if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a"))
 575                         arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT
 576                                   | ARCH_WIN2K );
 577                 else if (strcsequal(cliprotos[i], "DOS LM1.2X002"))
 578                         arch &= ( ARCH_WFWG | ARCH_WIN95 );
 579                 else if (strcsequal(cliprotos[i], "DOS LANMAN2.1"))
 580                         arch &= ( ARCH_WFWG | ARCH_WIN95 );
 581                 else if (strcsequal(cliprotos[i], "NT LM 0.12"))
 582                         arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K
 583                                   | ARCH_CIFSFS);
 584                 else if (strcsequal(cliprotos[i], "SMB 2.001"))
 585                         arch = ARCH_VISTA;              
 586                 else if (strcsequal(cliprotos[i], "LANMAN2.1"))
 587                         arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
 588                 else if (strcsequal(cliprotos[i], "LM1.2X002"))
 589                         arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
 590                 else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03"))
 591                         arch &= ARCH_WINNT;
 592                 else if (strcsequal(cliprotos[i], "XENIX CORE"))
 593                         arch &= ( ARCH_WINNT | ARCH_OS2 );
 594                 else if (strcsequal(cliprotos[i], "Samba")) {
 595                         arch = ARCH_SAMBA;
 596                         break;
 597                 } else if (strcsequal(cliprotos[i], "POSIX 2")) {
 598                         arch = ARCH_CIFSFS;
 599                         break;
 600                 }
 601         }
 602 
 603         /* CIFSFS can send one arch only, NT LM 0.12. */
 604         if (i == 1 && (arch & ARCH_CIFSFS)) {
 605                 arch = ARCH_CIFSFS;
 606         }
 607 
 608         switch ( arch ) {
 609                 case ARCH_CIFSFS:
 610                         set_remote_arch(RA_CIFSFS);
 611                         break;
 612                 case ARCH_SAMBA:
 613                         set_remote_arch(RA_SAMBA);
 614                         break;
 615                 case ARCH_WFWG:
 616                         set_remote_arch(RA_WFWG);
 617                         break;
 618                 case ARCH_WIN95:
 619                         set_remote_arch(RA_WIN95);
 620                         break;
 621                 case ARCH_WINNT:
 622                         if(req->flags2 == FLAGS2_WIN2K_SIGNATURE)
 623                                 set_remote_arch(RA_WIN2K);
 624                         else
 625                                 set_remote_arch(RA_WINNT);
 626                         break;
 627                 case ARCH_WIN2K:
 628                         /* Vista may have been set in the negprot so don't 
 629                            override it here */
 630                         if ( get_remote_arch() != RA_VISTA )
 631                                 set_remote_arch(RA_WIN2K);
 632                         break;
 633                 case ARCH_VISTA:
 634                         set_remote_arch(RA_VISTA);
 635                         break;
 636                 case ARCH_OS2:
 637                         set_remote_arch(RA_OS2);
 638                         break;
 639                 default:
 640                         set_remote_arch(RA_UNKNOWN);
 641                 break;
 642         }
 643  
 644         /* possibly reload - change of architecture */
 645         reload_services(True);      
 646         
 647         /* moved from the netbios session setup code since we don't have that 
 648            when the client connects to port 445.  Of course there is a small
 649            window where we are listening to messages   -- jerry */
 650 
 651         claim_connection(
 652                 NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
 653     
 654         /* Check for protocols, most desirable first */
 655         for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
 656                 i = 0;
 657                 if ((supported_protocols[protocol].protocol_level <= lp_maxprotocol()) &&
 658                                 (supported_protocols[protocol].protocol_level >= lp_minprotocol()))
 659                         while (i < num_cliprotos) {
 660                                 if (strequal(cliprotos[i],supported_protocols[protocol].proto_name))
 661                                         choice = i;
 662                                 i++;
 663                         }
 664                 if(choice != -1)
 665                         break;
 666         }
 667   
 668         if(choice != -1) {
 669                 fstrcpy(remote_proto,supported_protocols[protocol].short_name);
 670                 reload_services(True);          
 671                 supported_protocols[protocol].proto_reply_fn(req, choice);
 672                 DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
 673         } else {
 674                 DEBUG(0,("No protocol supported !\n"));
 675                 reply_outbuf(req, 1, 0);
 676                 SSVAL(req->outbuf, smb_vwv0, choice);
 677         }
 678   
 679         DEBUG( 5, ( "negprot index=%d\n", choice ) );
 680 
 681         if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
 682                 exit_server_cleanly("SMB signing is required and "
 683                         "client negotiated a downlevel protocol");
 684         }
 685 
 686         TALLOC_FREE(cliprotos);
 687         END_PROFILE(SMBnegprot);
 688         return;
 689 }

/* [<][>][^][v][top][bottom][index][help] */