1*5331Samw /* 2*5331Samw * CDDL HEADER START 3*5331Samw * 4*5331Samw * The contents of this file are subject to the terms of the 5*5331Samw * Common Development and Distribution License (the "License"). 6*5331Samw * You may not use this file except in compliance with the License. 7*5331Samw * 8*5331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5331Samw * or http://www.opensolaris.org/os/licensing. 10*5331Samw * See the License for the specific language governing permissions 11*5331Samw * and limitations under the License. 12*5331Samw * 13*5331Samw * When distributing Covered Code, include this CDDL HEADER in each 14*5331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5331Samw * If applicable, add the following below this CDDL HEADER, with the 16*5331Samw * fields enclosed by brackets "[]" replaced with your own identifying 17*5331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 18*5331Samw * 19*5331Samw * CDDL HEADER END 20*5331Samw */ 21*5331Samw /* 22*5331Samw * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23*5331Samw * Use is subject to license terms. 24*5331Samw */ 25*5331Samw 26*5331Samw #pragma ident "%Z%%M% %I% %E% SMI" 27*5331Samw 28*5331Samw /* 29*5331Samw * Notes on the virtual circuit (VC) values in the SMB Negotiate 30*5331Samw * response and SessionSetupAndx request. 31*5331Samw * 32*5331Samw * A virtual circuit (VC) represents a connection between a client and a 33*5331Samw * server using a reliable, session oriented transport protocol, such as 34*5331Samw * NetBIOS or TCP/IP. Originally, each SMB session was restricted to a 35*5331Samw * single underlying transport connection, i.e. a single NetBIOS session, 36*5331Samw * which limited performance for raw data transfers. 37*5331Samw * 38*5331Samw * The intention behind multiple VCs was to improve performance by 39*5331Samw * allowing parallelism over each NetBIOS session. For example, raw data 40*5331Samw * could be transmitted using a different VC from other types of SMB 41*5331Samw * requests to remove the interleaving restriction while a raw transfer 42*5331Samw * is in progress. So the MaxNumberVcs field was added to the negotiate 43*5331Samw * response to make the number of VCs configurable and to allow servers 44*5331Samw * to specify how many they were prepared to support per session 45*5331Samw * connection. This turned out to be difficult to manage and, with 46*5331Samw * technology improvements, it has become obsolete. 47*5331Samw * 48*5331Samw * Servers should set the MaxNumberVcs value in the Negotiate response 49*5331Samw * to 1. Clients should probably ignore it. If a server receives a 50*5331Samw * SessionSetupAndx with a VC value of 0, it should close all other 51*5331Samw * VCs to that client. If it receives a non-zero VC, it should leave 52*5331Samw * other VCs in tact. 53*5331Samw * 54*5331Samw */ 55*5331Samw 56*5331Samw /* 57*5331Samw * SMB: negotiate 58*5331Samw * 59*5331Samw * Client Request Description 60*5331Samw * ============================ ======================================= 61*5331Samw * 62*5331Samw * UCHAR WordCount; Count of parameter words = 0 63*5331Samw * USHORT ByteCount; Count of data bytes; min = 2 64*5331Samw * struct { 65*5331Samw * UCHAR BufferFormat; 0x02 -- Dialect 66*5331Samw * UCHAR DialectName[]; ASCII null-terminated string 67*5331Samw * } Dialects[]; 68*5331Samw * 69*5331Samw * The Client sends a list of dialects that it can communicate with. The 70*5331Samw * response is a selection of one of those dialects (numbered 0 through n) 71*5331Samw * or -1 (hex FFFF) indicating that none of the dialects were acceptable. 72*5331Samw * The negotiate message is binding on the virtual circuit and must be 73*5331Samw * sent. One and only one negotiate message may be sent, subsequent 74*5331Samw * negotiate requests will be rejected with an error response and no action 75*5331Samw * will be taken. 76*5331Samw * 77*5331Samw * The protocol does not impose any particular structure to the dialect 78*5331Samw * strings. Implementors of particular protocols may choose to include, 79*5331Samw * for example, version numbers in the string. 80*5331Samw * 81*5331Samw * If the server does not understand any of the dialect strings, or if PC 82*5331Samw * NETWORK PROGRAM 1.0 is the chosen dialect, the response format is 83*5331Samw * 84*5331Samw * Server Response Description 85*5331Samw * ============================ ======================================= 86*5331Samw * 87*5331Samw * UCHAR WordCount; Count of parameter words = 1 88*5331Samw * USHORT DialectIndex; Index of selected dialect 89*5331Samw * USHORT ByteCount; Count of data bytes = 0 90*5331Samw * 91*5331Samw * If the chosen dialect is greater than core up to and including 92*5331Samw * LANMAN2.1, the protocol response format is 93*5331Samw * 94*5331Samw * Server Response Description 95*5331Samw * ============================ ======================================= 96*5331Samw * 97*5331Samw * UCHAR WordCount; Count of parameter words = 13 98*5331Samw * USHORT DialectIndex; Index of selected dialect 99*5331Samw * USHORT SecurityMode; Security mode: 100*5331Samw * bit 0: 0 = share, 1 = user 101*5331Samw * bit 1: 1 = use challenge/response 102*5331Samw * authentication 103*5331Samw * USHORT MaxBufferSize; Max transmit buffer size (>= 1024) 104*5331Samw * USHORT MaxMpxCount; Max pending multiplexed requests 105*5331Samw * USHORT MaxNumberVcs; Max VCs between client and server 106*5331Samw * USHORT RawMode; Raw modes supported: 107*5331Samw * bit 0: 1 = Read Raw supported 108*5331Samw * bit 1: 1 = Write Raw supported 109*5331Samw * ULONG SessionKey; Unique token identifying this session 110*5331Samw * SMB_TIME ServerTime; Current time at server 111*5331Samw * SMB_DATE ServerDate; Current date at server 112*5331Samw * USHORT ServerTimeZone; Current time zone at server 113*5331Samw * USHORT EncryptionKeyLength; MBZ if this is not LM2.1 114*5331Samw * USHORT Reserved; MBZ 115*5331Samw * USHORT ByteCount Count of data bytes 116*5331Samw * UCHAR EncryptionKey[]; The challenge encryption key 117*5331Samw * STRING PrimaryDomain[]; The server's primary domain 118*5331Samw * 119*5331Samw * MaxBufferSize is the size of the largest message which the client can 120*5331Samw * legitimately send to the server 121*5331Samw * 122*5331Samw * If bit0 of the Flags field is set in the negotiate response, this 123*5331Samw * indicates the server supports the SMB_COM_LOCK_AND_READ and 124*5331Samw * SMB_COM_WRITE_AND_UNLOCK client requests. 125*5331Samw * 126*5331Samw * If the SecurityMode field indicates the server is running in user mode, 127*5331Samw * the client must send appropriate SMB_COM_SESSION_SETUP_ANDX requests 128*5331Samw * before the server will allow the client to access resources. If the 129*5331Samw * SecurityMode fields indicates the client should use challenge/response 130*5331Samw * authentication, the client should use the authentication mechanism 131*5331Samw * specified in section 2.10. 132*5331Samw * 133*5331Samw * Clients should submit no more than MaxMpxCount distinct unanswered SMBs 134*5331Samw * to the server when using multiplexed reads or writes (see sections 5.13 135*5331Samw * and 5.25) 136*5331Samw * 137*5331Samw * Clients using the "MICROSOFT NETWORKS 1.03" dialect use a different 138*5331Samw * form of raw reads than documented here, and servers are better off 139*5331Samw * setting RawMode in this response to 0 for such sessions. 140*5331Samw * 141*5331Samw * If the negotiated dialect is "DOS LANMAN2.1" or "LANMAN2.1", then 142*5331Samw * PrimaryDomain string should be included in this response. 143*5331Samw * 144*5331Samw * If the negotiated dialect is NT LM 0.12, the response format is 145*5331Samw * 146*5331Samw * Server Response Description 147*5331Samw * ========================== ========================================= 148*5331Samw * 149*5331Samw * UCHAR WordCount; Count of parameter words = 17 150*5331Samw * USHORT DialectIndex; Index of selected dialect 151*5331Samw * UCHAR SecurityMode; Security mode: 152*5331Samw * bit 0: 0 = share, 1 = user 153*5331Samw * bit 1: 1 = encrypt passwords 154*5331Samw * USHORT MaxMpxCount; Max pending multiplexed requests 155*5331Samw * USHORT MaxNumberVcs; Max VCs between client and server 156*5331Samw * ULONG MaxBufferSize; Max transmit buffer size 157*5331Samw * ULONG MaxRawSize; Maximum raw buffer size 158*5331Samw * ULONG SessionKey; Unique token identifying this session 159*5331Samw * ULONG Capabilities; Server capabilities 160*5331Samw * ULONG SystemTimeLow; System (UTC) time of the server (low). 161*5331Samw * ULONG SystemTimeHigh; System (UTC) time of the server (high). 162*5331Samw * USHORT ServerTimeZone; Time zone of server (min from UTC) 163*5331Samw * UCHAR EncryptionKeyLength; Length of encryption key. 164*5331Samw * USHORT ByteCount; Count of data bytes 165*5331Samw * UCHAR EncryptionKey[]; The challenge encryption key 166*5331Samw * UCHAR OemDomainName[]; The name of the domain (in OEM chars) 167*5331Samw * 168*5331Samw * In addition to the definitions above, MaxBufferSize is the size of the 169*5331Samw * largest message which the client can legitimately send to the server. 170*5331Samw * If the client is using a connectionless protocol, MaxBufferSize must be 171*5331Samw * set to the smaller of the server's internal buffer size and the amount 172*5331Samw * of data which can be placed in a response packet. 173*5331Samw * 174*5331Samw * MaxRawSize specifies the maximum message size the server can send or 175*5331Samw * receive for SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. 176*5331Samw * 177*5331Samw * Connectionless clients must set Sid to 0 in the SMB request header. 178*5331Samw * 179*5331Samw * Capabilities allows the server to tell the client what it supports. 180*5331Samw * The bit definitions defined in cifs.h. Bit 0x2000 used to be set in 181*5331Samw * the negotiate response capabilities but it caused problems with 182*5331Samw * Windows 2000. It is probably not valid, it doesn't appear in the 183*5331Samw * CIFS spec. 184*5331Samw * 185*5331Samw * 4.1.1.1 Errors 186*5331Samw * 187*5331Samw * SUCCESS/SUCCESS 188*5331Samw * ERRSRV/ERRerror 189*5331Samw */ 190*5331Samw #include <sys/types.h> 191*5331Samw #include <sys/strsubr.h> 192*5331Samw #include <sys/socketvar.h> 193*5331Samw #include <sys/socket.h> 194*5331Samw #include <sys/random.h> 195*5331Samw #include <netinet/in.h> 196*5331Samw #include <smbsrv/smb_incl.h> 197*5331Samw #include <smbsrv/smbinfo.h> 198*5331Samw #include <smbsrv/smb_i18n.h> 199*5331Samw 200*5331Samw 201*5331Samw /* 202*5331Samw * Maximum buffer size for DOS: chosen to be the same as NT. 203*5331Samw * Do not change this value, DOS is very sensitive to it. 204*5331Samw */ 205*5331Samw #define SMB_DOS_MAXBUF 0x1104 206*5331Samw 207*5331Samw /* 208*5331Samw * Maximum buffer size for NT: configurable based on the client environment. 209*5331Samw * IR104720 Experiments with Windows 2000 indicate that we achieve better 210*5331Samw * SmbWriteX performance with a buffer size of 64KB instead of the 37KB 211*5331Samw * used with Windows NT4.0. Previous experiments with NT4.0 resulted in 212*5331Samw * directory listing problems so this buffer size is configurable based 213*5331Samw * on the end-user environment. When in doubt use 37KB. 214*5331Samw */ 215*5331Samw int smb_maxbufsize = SMB_NT_MAXBUF(37); 216*5331Samw 217*5331Samw /* 218*5331Samw * The DOS TCP rcvbuf is set to 8700 because DOS 6.1 seems to have problems 219*5331Samw * with other values. DOS 6.1 seems to depend on a window value of 8700 to 220*5331Samw * send the next set of data. If we return a window value of 40KB, after 221*5331Samw * sending 8700 bytes of data, it will start the next set of data from 40KB 222*5331Samw * instead of 8.7k. Why 8.7k? We have no idea; it is the value that NT uses. 223*5331Samw * September 2000. 224*5331Samw * 225*5331Samw * IR104720 Increased smb_nt_tcp_rcvbuf from 40KB to just under 1MB to allow 226*5331Samw * for a larger TCP window sizei based on observations of Windows 2000 and 227*5331Samw * performance testing. March 2003. 228*5331Samw */ 229*5331Samw uint32_t smb_dos_tcp_rcvbuf = 8700; 230*5331Samw uint32_t smb_nt_tcp_rcvbuf = 1048560; /* scale factor of 4 */ 231*5331Samw 232*5331Samw static void smb_get_security_info( 233*5331Samw struct smb_request *sr, 234*5331Samw unsigned short *secmode, 235*5331Samw unsigned char *key, 236*5331Samw unsigned char *keylen, 237*5331Samw uint32_t *sesskey); 238*5331Samw 239*5331Samw /* 240*5331Samw * Function: int smb_com_negotiate(struct smb_request *) 241*5331Samw */ 242*5331Samw 243*5331Samw int 244*5331Samw smb_com_negotiate(struct smb_request *sr) 245*5331Samw { 246*5331Samw int dialect = 0; 247*5331Samw int this_dialect; 248*5331Samw unsigned char keylen; 249*5331Samw int sel_pos = -1; 250*5331Samw int pos; 251*5331Samw char key[32]; 252*5331Samw char *p; 253*5331Samw timestruc_t time_val; 254*5331Samw unsigned short secmode; 255*5331Samw uint32_t sesskey; 256*5331Samw uint32_t capabilities = 0; 257*5331Samw 258*5331Samw unsigned short max_mpx_count; 259*5331Samw WORD tz_correction; 260*5331Samw char ipaddr_buf[INET_ADDRSTRLEN]; 261*5331Samw 262*5331Samw if (sr->session->s_state != SMB_SESSION_STATE_ESTABLISHED) { 263*5331Samw /* The protocol has already been negotiated. */ 264*5331Samw smbsr_raise_error(sr, ERRSRV, ERRerror); 265*5331Samw /* NOTREACHED */ 266*5331Samw } 267*5331Samw 268*5331Samw for (pos = 0; 269*5331Samw sr->smb_data.chain_offset < sr->smb_data.max_bytes; 270*5331Samw pos++) { 271*5331Samw if (smb_decode_mbc(&sr->smb_data, "%L", sr, &p) != 0) { 272*5331Samw smbsr_raise_error(sr, ERRSRV, ERRerror); 273*5331Samw /* NOTREACHED */ 274*5331Samw } 275*5331Samw 276*5331Samw this_dialect = smb_xlate_dialect_str_to_cd(p); 277*5331Samw 278*5331Samw if (this_dialect < 0) 279*5331Samw continue; 280*5331Samw 281*5331Samw if (dialect < this_dialect) { 282*5331Samw dialect = this_dialect; 283*5331Samw sel_pos = pos; 284*5331Samw } 285*5331Samw } 286*5331Samw if (sel_pos < 0) { 287*5331Samw smbsr_raise_error(sr, ERRSRV, ERRerror); 288*5331Samw /* NOTREACHED */ 289*5331Samw } 290*5331Samw 291*5331Samw smb_get_security_info(sr, &secmode, (unsigned char *)key, 292*5331Samw &keylen, &sesskey); 293*5331Samw 294*5331Samw (void) microtime(&time_val); 295*5331Samw 296*5331Samw tz_correction = -(WORD)(smb_get_gmtoff() / 60); /* tz correct. (min) */ 297*5331Samw 298*5331Samw switch (dialect) { 299*5331Samw case DIALECT_UNKNOWN: 300*5331Samw case PC_NETWORK_PROGRAM_1_0: /* core */ 301*5331Samw (void) sosetsockopt(sr->session->sock, SOL_SOCKET, SO_RCVBUF, 302*5331Samw (const void *)&smb_dos_tcp_rcvbuf, 303*5331Samw sizeof (smb_dos_tcp_rcvbuf)); 304*5331Samw smbsr_encode_result(sr, 1, 0, "bww", 1, sel_pos, 0); 305*5331Samw break; 306*5331Samw 307*5331Samw case Windows_for_Workgroups_3_1a: 308*5331Samw case PCLAN1_0: 309*5331Samw case MICROSOFT_NETWORKS_1_03: 310*5331Samw case MICROSOFT_NETWORKS_3_0: 311*5331Samw case LANMAN1_0: 312*5331Samw case LM1_2X002: 313*5331Samw case DOS_LM1_2X002: 314*5331Samw (void) sosetsockopt(sr->session->sock, SOL_SOCKET, SO_RCVBUF, 315*5331Samw (const void *)&smb_dos_tcp_rcvbuf, 316*5331Samw sizeof (smb_dos_tcp_rcvbuf)); 317*5331Samw sr->smb_flg |= SMB_FLAGS_LOCK_AND_READ_OK; 318*5331Samw smbsr_encode_result(sr, 13, VAR_BCC, 319*5331Samw "(wct) b" "(dix) w" "(sec) w" "(mbs) w" 320*5331Samw "(mmc) w" "(mnv) w" "(raw) w" "(key) l" 321*5331Samw "(tim/dat) Y" "(tz) w" "(ekl) w" 322*5331Samw "(mbz) 2.""(bcc) w" "(key) #c", 323*5331Samw 13, /* wct */ 324*5331Samw sel_pos, /* dialect index */ 325*5331Samw secmode, /* security mode */ 326*5331Samw SMB_DOS_MAXBUF, /* max buffer size */ 327*5331Samw 1, /* max MPX (temporary) */ 328*5331Samw 1, /* max VCs (temporary, ambiguous) */ 329*5331Samw 3, /* raw mode (s/b 3) */ 330*5331Samw sesskey, /* session key */ 331*5331Samw time_val.tv_sec, /* server time/date */ 332*5331Samw tz_correction, /* see smb_get_gmtoff */ 333*5331Samw (short)keylen, /* Encryption Key Length */ 334*5331Samw /* reserved field handled 2. */ 335*5331Samw VAR_BCC, 336*5331Samw (int)keylen, 337*5331Samw key); /* encryption key */ 338*5331Samw break; 339*5331Samw 340*5331Samw case DOS_LANMAN2_1: 341*5331Samw case LANMAN2_1: 342*5331Samw (void) sosetsockopt(sr->session->sock, SOL_SOCKET, SO_RCVBUF, 343*5331Samw (const void *)&smb_dos_tcp_rcvbuf, 344*5331Samw sizeof (smb_dos_tcp_rcvbuf)); 345*5331Samw sr->smb_flg |= SMB_FLAGS_LOCK_AND_READ_OK; 346*5331Samw smbsr_encode_result(sr, 13, VAR_BCC, 347*5331Samw "(wct) b" "(dix) w" "(sec) w" "(mbs) w" 348*5331Samw "(mmc) w" "(mnv) w" "(raw) w" "(key) l" 349*5331Samw "(tim/dat) Y" "(tz) w" "(ekl) w" 350*5331Samw "(mbz) 2.""(bcc) w" "(key) #c" "(dom) s", 351*5331Samw 13, /* wct */ 352*5331Samw sel_pos, /* dialect index */ 353*5331Samw secmode, /* security mode */ 354*5331Samw SMB_DOS_MAXBUF, /* max buffer size */ 355*5331Samw 1, /* max MPX (temporary) */ 356*5331Samw 1, /* max VCs (temporary, ambiguous) */ 357*5331Samw 3, /* raw mode (s/b 3) */ 358*5331Samw sesskey, /* session key */ 359*5331Samw time_val.tv_sec, /* server time/date */ 360*5331Samw tz_correction, 361*5331Samw (short)keylen, /* Encryption Key Length */ 362*5331Samw /* reserved field handled 2. */ 363*5331Samw VAR_BCC, 364*5331Samw (int)keylen, 365*5331Samw key, /* encryption key */ 366*5331Samw smb_info.si.skc_resource_domain); 367*5331Samw break; 368*5331Samw 369*5331Samw case NT_LM_0_12: 370*5331Samw (void) sosetsockopt(sr->session->sock, SOL_SOCKET, SO_RCVBUF, 371*5331Samw (const void *)&smb_nt_tcp_rcvbuf, 372*5331Samw sizeof (smb_nt_tcp_rcvbuf)); 373*5331Samw capabilities = CAP_LARGE_FILES 374*5331Samw | CAP_NT_SMBS 375*5331Samw | CAP_STATUS32 376*5331Samw | CAP_NT_FIND 377*5331Samw | CAP_RAW_MODE 378*5331Samw | CAP_LEVEL_II_OPLOCKS 379*5331Samw | CAP_LOCK_AND_READ 380*5331Samw | CAP_RPC_REMOTE_APIS 381*5331Samw | CAP_LARGE_READX; 382*5331Samw 383*5331Samw /* 384*5331Samw * UNICODE support is required to enable support for long 385*5331Samw * share names and long file names and streams. 386*5331Samw */ 387*5331Samw 388*5331Samw capabilities |= CAP_UNICODE; 389*5331Samw 390*5331Samw 391*5331Samw /* 392*5331Samw * Turn off Extended Security Negotiation 393*5331Samw */ 394*5331Samw sr->smb_flg2 &= ~SMB_FLAGS2_EXT_SEC; 395*5331Samw 396*5331Samw /* 397*5331Samw * Allow SMB signatures if security challenge response enabled 398*5331Samw */ 399*5331Samw if ((secmode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && 400*5331Samw smb_info.si.skc_signing_enable) { 401*5331Samw secmode |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED; 402*5331Samw if (smb_info.si.skc_signing_required) 403*5331Samw secmode |= 404*5331Samw NEGOTIATE_SECURITY_SIGNATURES_REQUIRED; 405*5331Samw 406*5331Samw sr->session->secmode = secmode; 407*5331Samw } 408*5331Samw 409*5331Samw (void) inet_ntop(AF_INET, (char *)&sr->session->ipaddr, 410*5331Samw ipaddr_buf, sizeof (ipaddr_buf)); 411*5331Samw /*LINTED E_ASSIGN_NARROW_CONV (uint16_t)*/ 412*5331Samw max_mpx_count = smb_info.si.skc_maxworkers; 413*5331Samw 414*5331Samw smbsr_encode_result(sr, 17, VAR_BCC, 415*5331Samw "(wct) b" "(dix) w" "(sec) b" "(mmc) w" 416*5331Samw "(mnv) w" "(mbs) l" "(raw) l" "(key) l" 417*5331Samw "(cap) l" "(tim) T" "(tz) w" "(ekl) b" 418*5331Samw "(bcc) w" "(key) #c" "(dom) Z", 419*5331Samw 17, /* wct */ 420*5331Samw sel_pos, /* dialect index */ 421*5331Samw secmode, /* security mode */ 422*5331Samw max_mpx_count, /* max MPX (temporary) */ 423*5331Samw 1, /* max VCs (temporary, ambiguous) */ 424*5331Samw (DWORD)smb_maxbufsize, /* max buffer size */ 425*5331Samw 0xFFFF, /* max raw size */ 426*5331Samw sesskey, /* session key */ 427*5331Samw capabilities, 428*5331Samw &time_val, /* system time */ 429*5331Samw tz_correction, 430*5331Samw keylen, /* Encryption Key Length */ 431*5331Samw VAR_BCC, 432*5331Samw (int)keylen, 433*5331Samw key, /* encryption key */ 434*5331Samw smb_info.si.skc_resource_domain); 435*5331Samw break; 436*5331Samw 437*5331Samw default: 438*5331Samw /* Just to make sure. */ 439*5331Samw ASSERT(0); 440*5331Samw smbsr_raise_error(sr, ERRSRV, ERRerror); 441*5331Samw /* NOTREACHED */ 442*5331Samw } 443*5331Samw 444*5331Samw /* 445*5331Samw * Save the agreed dialect. Note that this value is also 446*5331Samw * used to detect and reject attempts to re-negotiate. 447*5331Samw */ 448*5331Samw sr->session->dialect = dialect; 449*5331Samw sr->session->s_state = SMB_SESSION_STATE_NEGOTIATED; 450*5331Samw return (SDRC_NORMAL_REPLY); 451*5331Samw } 452*5331Samw 453*5331Samw static void 454*5331Samw smb_get_security_info( 455*5331Samw struct smb_request *sr, 456*5331Samw unsigned short *secmode, 457*5331Samw unsigned char *key, 458*5331Samw unsigned char *keylen, 459*5331Samw uint32_t *sesskey) 460*5331Samw { 461*5331Samw uchar_t tmp_key[8]; 462*5331Samw 463*5331Samw (void) random_get_pseudo_bytes(tmp_key, 8); 464*5331Samw bcopy(tmp_key, &sr->session->challenge_key, 8); 465*5331Samw sr->session->challenge_len = 8; 466*5331Samw *keylen = 8; 467*5331Samw bcopy(tmp_key, key, 8); 468*5331Samw 469*5331Samw sr->session->secmode = NEGOTIATE_SECURITY_CHALLENGE_RESPONSE| 470*5331Samw NEGOTIATE_SECURITY_USER_LEVEL; 471*5331Samw 472*5331Samw (void) random_get_pseudo_bytes(tmp_key, 4); 473*5331Samw sr->session->sesskey = tmp_key[0] | tmp_key[1] << 8 | 474*5331Samw tmp_key[2] << 16 | tmp_key[3] << 24; 475*5331Samw 476*5331Samw *secmode = sr->session->secmode; 477*5331Samw *sesskey = sr->session->sesskey; 478*5331Samw } 479