1*613a2f6bSGordon Ross /* 2*613a2f6bSGordon Ross * Copyright (c) 2000-2001 Boris Popov 3*613a2f6bSGordon Ross * All rights reserved. 4*613a2f6bSGordon Ross * 5*613a2f6bSGordon Ross * Redistribution and use in source and binary forms, with or without 6*613a2f6bSGordon Ross * modification, are permitted provided that the following conditions 7*613a2f6bSGordon Ross * are met: 8*613a2f6bSGordon Ross * 1. Redistributions of source code must retain the above copyright 9*613a2f6bSGordon Ross * notice, this list of conditions and the following disclaimer. 10*613a2f6bSGordon Ross * 2. Redistributions in binary form must reproduce the above copyright 11*613a2f6bSGordon Ross * notice, this list of conditions and the following disclaimer in the 12*613a2f6bSGordon Ross * documentation and/or other materials provided with the distribution. 13*613a2f6bSGordon Ross * 3. All advertising materials mentioning features or use of this software 14*613a2f6bSGordon Ross * must display the following acknowledgement: 15*613a2f6bSGordon Ross * This product includes software developed by Boris Popov. 16*613a2f6bSGordon Ross * 4. Neither the name of the author nor the names of any co-contributors 17*613a2f6bSGordon Ross * may be used to endorse or promote products derived from this software 18*613a2f6bSGordon Ross * without specific prior written permission. 19*613a2f6bSGordon Ross * 20*613a2f6bSGordon Ross * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21*613a2f6bSGordon Ross * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22*613a2f6bSGordon Ross * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23*613a2f6bSGordon Ross * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24*613a2f6bSGordon Ross * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25*613a2f6bSGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26*613a2f6bSGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27*613a2f6bSGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28*613a2f6bSGordon Ross * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29*613a2f6bSGordon Ross * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30*613a2f6bSGordon Ross * SUCH DAMAGE. 31*613a2f6bSGordon Ross */ 32*613a2f6bSGordon Ross 33*613a2f6bSGordon Ross /* 34*613a2f6bSGordon Ross * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 35*613a2f6bSGordon Ross * Use is subject to license terms. 36*613a2f6bSGordon Ross */ 37*613a2f6bSGordon Ross 38*613a2f6bSGordon Ross /* 39*613a2f6bSGordon Ross * SMB Negotiate Protocol, and related. 40*613a2f6bSGordon Ross * Copied from the driver: smb_smb.c 41*613a2f6bSGordon Ross */ 42*613a2f6bSGordon Ross 43*613a2f6bSGordon Ross #include <errno.h> 44*613a2f6bSGordon Ross #include <stdio.h> 45*613a2f6bSGordon Ross #include <stdlib.h> 46*613a2f6bSGordon Ross #include <unistd.h> 47*613a2f6bSGordon Ross #include <strings.h> 48*613a2f6bSGordon Ross #include <netdb.h> 49*613a2f6bSGordon Ross #include <libintl.h> 50*613a2f6bSGordon Ross #include <xti.h> 51*613a2f6bSGordon Ross #include <assert.h> 52*613a2f6bSGordon Ross 53*613a2f6bSGordon Ross #include <sys/types.h> 54*613a2f6bSGordon Ross #include <sys/time.h> 55*613a2f6bSGordon Ross #include <sys/byteorder.h> 56*613a2f6bSGordon Ross #include <sys/socket.h> 57*613a2f6bSGordon Ross #include <sys/fcntl.h> 58*613a2f6bSGordon Ross 59*613a2f6bSGordon Ross #include <netinet/in.h> 60*613a2f6bSGordon Ross #include <netinet/tcp.h> 61*613a2f6bSGordon Ross #include <arpa/inet.h> 62*613a2f6bSGordon Ross 63*613a2f6bSGordon Ross #include <netsmb/smb.h> 64*613a2f6bSGordon Ross #include <netsmb/smb_lib.h> 65*613a2f6bSGordon Ross #include <netsmb/netbios.h> 66*613a2f6bSGordon Ross #include <netsmb/nb_lib.h> 67*613a2f6bSGordon Ross #include <netsmb/smb_dev.h> 68*613a2f6bSGordon Ross 69*613a2f6bSGordon Ross #include "charsets.h" 70*613a2f6bSGordon Ross #include "private.h" 71*613a2f6bSGordon Ross 72*613a2f6bSGordon Ross /* 73*613a2f6bSGordon Ross * SMB dialects that we know about. 74*613a2f6bSGordon Ross */ 75*613a2f6bSGordon Ross struct smb_dialect { 76*613a2f6bSGordon Ross int d_id; 77*613a2f6bSGordon Ross const char *d_name; 78*613a2f6bSGordon Ross }; 79*613a2f6bSGordon Ross static struct smb_dialect smb_dialects[] = { 80*613a2f6bSGordon Ross {SMB_DIALECT_CORE, "PC NETWORK PROGRAM 1.0"}, 81*613a2f6bSGordon Ross {SMB_DIALECT_LANMAN1_0, "LANMAN1.0"}, 82*613a2f6bSGordon Ross {SMB_DIALECT_LANMAN2_0, "LM1.2X002"}, 83*613a2f6bSGordon Ross {SMB_DIALECT_LANMAN2_1, "LANMAN2.1"}, 84*613a2f6bSGordon Ross {SMB_DIALECT_NTLM0_12, "NT LM 0.12"}, 85*613a2f6bSGordon Ross {-1, NULL} 86*613a2f6bSGordon Ross }; 87*613a2f6bSGordon Ross 88*613a2f6bSGordon Ross #define SMB_DIALECT_MAX \ 89*613a2f6bSGordon Ross (sizeof (smb_dialects) / sizeof (struct smb_dialect) - 2) 90*613a2f6bSGordon Ross 91*613a2f6bSGordon Ross /* 92*613a2f6bSGordon Ross * SMB Negotiate Protocol 93*613a2f6bSGordon Ross * Based on code from the driver: smb_smb.c 94*613a2f6bSGordon Ross * 95*613a2f6bSGordon Ross * If using Extended Security, oblob (output) 96*613a2f6bSGordon Ross * will hold the initial security "hint". 97*613a2f6bSGordon Ross */ 98*613a2f6bSGordon Ross int 99*613a2f6bSGordon Ross smb_negprot(struct smb_ctx *ctx, struct mbdata *oblob) 100*613a2f6bSGordon Ross { 101*613a2f6bSGordon Ross struct smb_sopt *sv = &ctx->ct_sopt; 102*613a2f6bSGordon Ross struct smb_iods *is = &ctx->ct_iods; 103*613a2f6bSGordon Ross struct smb_rq *rqp; 104*613a2f6bSGordon Ross struct mbdata *mbp; 105*613a2f6bSGordon Ross struct smb_dialect *dp; 106*613a2f6bSGordon Ross int err, len; 107*613a2f6bSGordon Ross uint8_t wc, stime[8], eklen; 108*613a2f6bSGordon Ross uint16_t dindex, bc; 109*613a2f6bSGordon Ross int will_sign = 0; 110*613a2f6bSGordon Ross 111*613a2f6bSGordon Ross /* 112*613a2f6bSGordon Ross * Initialize: vc_hflags and vc_hflags2. 113*613a2f6bSGordon Ross * Note: ctx->ct_hflags* are copied into the 114*613a2f6bSGordon Ross * (per request) rqp->rq_hflags* by smb_rq_init, 115*613a2f6bSGordon Ross * so changing them after that call will not 116*613a2f6bSGordon Ross * affect THIS request. 117*613a2f6bSGordon Ross */ 118*613a2f6bSGordon Ross ctx->ct_hflags = SMB_FLAGS_CASELESS; 119*613a2f6bSGordon Ross ctx->ct_hflags2 = (SMB_FLAGS2_ERR_STATUS | 120*613a2f6bSGordon Ross SMB_FLAGS2_KNOWS_LONG_NAMES); 121*613a2f6bSGordon Ross 122*613a2f6bSGordon Ross /* 123*613a2f6bSGordon Ross * Sould we offer extended security? 124*613a2f6bSGordon Ross * We'll turn this back off below if 125*613a2f6bSGordon Ross * the server doesn't support it. 126*613a2f6bSGordon Ross */ 127*613a2f6bSGordon Ross if (ctx->ct_vopt & SMBVOPT_EXT_SEC) 128*613a2f6bSGordon Ross ctx->ct_hflags2 |= SMB_FLAGS2_EXT_SEC; 129*613a2f6bSGordon Ross 130*613a2f6bSGordon Ross /* 131*613a2f6bSGordon Ross * The initial UID needs to be zero, 132*613a2f6bSGordon Ross * or Windows XP says "bad user". 133*613a2f6bSGordon Ross * The initial TID is all ones, but 134*613a2f6bSGordon Ross * we don't use it or store it here 135*613a2f6bSGordon Ross * because the driver handles that. 136*613a2f6bSGordon Ross */ 137*613a2f6bSGordon Ross is->is_smbuid = 0; 138*613a2f6bSGordon Ross 139*613a2f6bSGordon Ross /* 140*613a2f6bSGordon Ross * In case we're reconnecting, 141*613a2f6bSGordon Ross * free previous stuff. 142*613a2f6bSGordon Ross */ 143*613a2f6bSGordon Ross ctx->ct_mac_seqno = 0; 144*613a2f6bSGordon Ross if (ctx->ct_mackey != NULL) { 145*613a2f6bSGordon Ross free(ctx->ct_mackey); 146*613a2f6bSGordon Ross ctx->ct_mackey = NULL; 147*613a2f6bSGordon Ross ctx->ct_mackeylen = 0; 148*613a2f6bSGordon Ross } 149*613a2f6bSGordon Ross 150*613a2f6bSGordon Ross sv = &ctx->ct_sopt; 151*613a2f6bSGordon Ross bzero(sv, sizeof (struct smb_sopt)); 152*613a2f6bSGordon Ross 153*613a2f6bSGordon Ross err = smb_rq_init(ctx, SMB_COM_NEGOTIATE, &rqp); 154*613a2f6bSGordon Ross if (err) 155*613a2f6bSGordon Ross return (err); 156*613a2f6bSGordon Ross 157*613a2f6bSGordon Ross /* 158*613a2f6bSGordon Ross * Build the SMB request. 159*613a2f6bSGordon Ross */ 160*613a2f6bSGordon Ross mbp = &rqp->rq_rq; 161*613a2f6bSGordon Ross mb_put_uint8(mbp, 0); /* word count */ 162*613a2f6bSGordon Ross smb_rq_bstart(rqp); 163*613a2f6bSGordon Ross for (dp = smb_dialects; dp->d_id != -1; dp++) { 164*613a2f6bSGordon Ross mb_put_uint8(mbp, SMB_DT_DIALECT); 165*613a2f6bSGordon Ross mb_put_astring(mbp, dp->d_name); 166*613a2f6bSGordon Ross } 167*613a2f6bSGordon Ross smb_rq_bend(rqp); 168*613a2f6bSGordon Ross 169*613a2f6bSGordon Ross /* 170*613a2f6bSGordon Ross * This does the OTW call 171*613a2f6bSGordon Ross */ 172*613a2f6bSGordon Ross err = smb_rq_internal(ctx, rqp); 173*613a2f6bSGordon Ross if (err) { 174*613a2f6bSGordon Ross DPRINT("call failed, err %d", err); 175*613a2f6bSGordon Ross goto errout; 176*613a2f6bSGordon Ross } 177*613a2f6bSGordon Ross if (rqp->rq_status != 0) { 178*613a2f6bSGordon Ross DPRINT("nt status 0x%x", rqp->rq_status); 179*613a2f6bSGordon Ross err = EBADRPC; 180*613a2f6bSGordon Ross goto errout; 181*613a2f6bSGordon Ross } 182*613a2f6bSGordon Ross 183*613a2f6bSGordon Ross /* 184*613a2f6bSGordon Ross * Decode the response 185*613a2f6bSGordon Ross * 186*613a2f6bSGordon Ross * Comments to right show names as described in 187*613a2f6bSGordon Ross * The Microsoft SMB Protocol spec. [MS-SMB] 188*613a2f6bSGordon Ross * section 2.2.3 189*613a2f6bSGordon Ross */ 190*613a2f6bSGordon Ross mbp = &rqp->rq_rp; 191*613a2f6bSGordon Ross (void) mb_get_uint8(mbp, &wc); 192*613a2f6bSGordon Ross err = mb_get_uint16le(mbp, &dindex); 193*613a2f6bSGordon Ross if (err || dindex > SMB_DIALECT_MAX) { 194*613a2f6bSGordon Ross DPRINT("err %d dindex %d", err, (int)dindex); 195*613a2f6bSGordon Ross goto errout; 196*613a2f6bSGordon Ross } 197*613a2f6bSGordon Ross dp = smb_dialects + dindex; 198*613a2f6bSGordon Ross sv->sv_proto = dp->d_id; 199*613a2f6bSGordon Ross DPRINT("Dialect %s", dp->d_name); 200*613a2f6bSGordon Ross if (dp->d_id < SMB_DIALECT_NTLM0_12) { 201*613a2f6bSGordon Ross /* XXX: User-visible warning too? */ 202*613a2f6bSGordon Ross DPRINT("old dialect %s", dp->d_name); 203*613a2f6bSGordon Ross goto errout; 204*613a2f6bSGordon Ross } 205*613a2f6bSGordon Ross if (wc != 17) { 206*613a2f6bSGordon Ross DPRINT("bad wc %d", (int)wc); 207*613a2f6bSGordon Ross goto errout; 208*613a2f6bSGordon Ross } 209*613a2f6bSGordon Ross mb_get_uint8(mbp, &sv->sv_sm); /* SecurityMode */ 210*613a2f6bSGordon Ross mb_get_uint16le(mbp, &sv->sv_maxmux); /* MaxMpxCount */ 211*613a2f6bSGordon Ross mb_get_uint16le(mbp, &sv->sv_maxvcs); /* MaxCountVCs */ 212*613a2f6bSGordon Ross mb_get_uint32le(mbp, &sv->sv_maxtx); /* MaxBufferSize */ 213*613a2f6bSGordon Ross mb_get_uint32le(mbp, &sv->sv_maxraw); /* MaxRawSize */ 214*613a2f6bSGordon Ross mb_get_uint32le(mbp, &sv->sv_skey); /* SessionKey */ 215*613a2f6bSGordon Ross mb_get_uint32le(mbp, &sv->sv_caps); /* Capabilities */ 216*613a2f6bSGordon Ross mb_get_mem(mbp, (char *)stime, 8); /* SystemTime(s) */ 217*613a2f6bSGordon Ross mb_get_uint16le(mbp, (uint16_t *)&sv->sv_tz); 218*613a2f6bSGordon Ross mb_get_uint8(mbp, &eklen); /* EncryptionKeyLength */ 219*613a2f6bSGordon Ross err = mb_get_uint16le(mbp, &bc); /* ByteCount */ 220*613a2f6bSGordon Ross if (err) 221*613a2f6bSGordon Ross goto errout; 222*613a2f6bSGordon Ross 223*613a2f6bSGordon Ross /* BEGIN CSTYLED */ 224*613a2f6bSGordon Ross /* 225*613a2f6bSGordon Ross * Will we do SMB signing? Or block the connection? 226*613a2f6bSGordon Ross * The table below describes this logic. References: 227*613a2f6bSGordon Ross * [Windows Server Protocols: MS-SMB, sec. 3.2.4.2.3] 228*613a2f6bSGordon Ross * http://msdn.microsoft.com/en-us/library/cc212511.aspx 229*613a2f6bSGordon Ross * http://msdn.microsoft.com/en-us/library/cc212929.aspx 230*613a2f6bSGordon Ross * 231*613a2f6bSGordon Ross * Srv/Cli | Required | Enabled | If Required | Disabled 232*613a2f6bSGordon Ross * ------------+----------+------------+-------------+----------- 233*613a2f6bSGordon Ross * Required | Signed | Signed | Signed | Blocked [1] 234*613a2f6bSGordon Ross * ------------+----------+------------+-------------+----------- 235*613a2f6bSGordon Ross * Enabled | Signed | Signed | Not Signed | Not Signed 236*613a2f6bSGordon Ross * ------------+----------+------------+-------------+----------- 237*613a2f6bSGordon Ross * If Required | Signed | Not Signed | Not Signed | Not Signed 238*613a2f6bSGordon Ross * ------------+----------+------------+-------------+----------- 239*613a2f6bSGordon Ross * Disabled | Blocked | Not Signed | Not Signed | Not Signed 240*613a2f6bSGordon Ross * 241*613a2f6bSGordon Ross * [1] Like Windows 2003 and later, we don't really implement 242*613a2f6bSGordon Ross * the "Disabled" setting. Instead we implement "If Required", 243*613a2f6bSGordon Ross * so we always sign if the server requires signing. 244*613a2f6bSGordon Ross */ 245*613a2f6bSGordon Ross /* END CSTYLED */ 246*613a2f6bSGordon Ross 247*613a2f6bSGordon Ross if (sv->sv_sm & SMB_SM_SIGS_REQUIRE) { 248*613a2f6bSGordon Ross /* 249*613a2f6bSGordon Ross * Server requires signing. We will sign, 250*613a2f6bSGordon Ross * even if local setting is "disabled". 251*613a2f6bSGordon Ross */ 252*613a2f6bSGordon Ross will_sign = 1; 253*613a2f6bSGordon Ross } else if (sv->sv_sm & SMB_SM_SIGS) { 254*613a2f6bSGordon Ross /* 255*613a2f6bSGordon Ross * Server enables signing (client's option). 256*613a2f6bSGordon Ross * If enabled locally, do signing. 257*613a2f6bSGordon Ross */ 258*613a2f6bSGordon Ross if (ctx->ct_vopt & SMBVOPT_SIGNING_ENABLED) 259*613a2f6bSGordon Ross will_sign = 1; 260*613a2f6bSGordon Ross /* else not signing. */ 261*613a2f6bSGordon Ross } else { 262*613a2f6bSGordon Ross /* 263*613a2f6bSGordon Ross * Server does not support signing. 264*613a2f6bSGordon Ross * If we "require" it, bail now. 265*613a2f6bSGordon Ross */ 266*613a2f6bSGordon Ross if (ctx->ct_vopt & SMBVOPT_SIGNING_REQUIRED) { 267*613a2f6bSGordon Ross DPRINT("Client requires signing " 268*613a2f6bSGordon Ross "but server has it disabled."); 269*613a2f6bSGordon Ross err = EBADRPC; 270*613a2f6bSGordon Ross goto errout; 271*613a2f6bSGordon Ross } 272*613a2f6bSGordon Ross } 273*613a2f6bSGordon Ross 274*613a2f6bSGordon Ross if (will_sign) { 275*613a2f6bSGordon Ross ctx->ct_vcflags |= SMBV_WILL_SIGN; 276*613a2f6bSGordon Ross } 277*613a2f6bSGordon Ross DPRINT("Security signatures: %d", will_sign); 278*613a2f6bSGordon Ross 279*613a2f6bSGordon Ross if (sv->sv_caps & SMB_CAP_UNICODE) { 280*613a2f6bSGordon Ross ctx->ct_vcflags |= SMBV_UNICODE; 281*613a2f6bSGordon Ross ctx->ct_hflags2 |= SMB_FLAGS2_UNICODE; 282*613a2f6bSGordon Ross 283*613a2f6bSGordon Ross } 284*613a2f6bSGordon Ross if ((sv->sv_caps & SMB_CAP_STATUS32) == 0) { 285*613a2f6bSGordon Ross /* 286*613a2f6bSGordon Ross * They don't do NT error codes. 287*613a2f6bSGordon Ross * 288*613a2f6bSGordon Ross * If we send requests with 289*613a2f6bSGordon Ross * SMB_FLAGS2_ERR_STATUS set in 290*613a2f6bSGordon Ross * Flags2, Windows 98, at least, 291*613a2f6bSGordon Ross * appears to send replies with that 292*613a2f6bSGordon Ross * bit set even though it sends back 293*613a2f6bSGordon Ross * DOS error codes. (They probably 294*613a2f6bSGordon Ross * just use the request header as 295*613a2f6bSGordon Ross * a template for the reply header, 296*613a2f6bSGordon Ross * and don't bother clearing that bit.) 297*613a2f6bSGordon Ross * 298*613a2f6bSGordon Ross * Therefore, we clear that bit in 299*613a2f6bSGordon Ross * our vc_hflags2 field. 300*613a2f6bSGordon Ross */ 301*613a2f6bSGordon Ross ctx->ct_hflags2 &= ~SMB_FLAGS2_ERR_STATUS; 302*613a2f6bSGordon Ross } 303*613a2f6bSGordon Ross if (dp->d_id == SMB_DIALECT_NTLM0_12 && 304*613a2f6bSGordon Ross sv->sv_maxtx < 4096 && 305*613a2f6bSGordon Ross (sv->sv_caps & SMB_CAP_NT_SMBS) == 0) { 306*613a2f6bSGordon Ross ctx->ct_vcflags |= SMBV_WIN95; 307*613a2f6bSGordon Ross DPRINT("Win95 detected"); 308*613a2f6bSGordon Ross } 309*613a2f6bSGordon Ross 310*613a2f6bSGordon Ross /* 311*613a2f6bSGordon Ross * The rest of the message varies depending on 312*613a2f6bSGordon Ross * whether we've negotiated "extended security". 313*613a2f6bSGordon Ross * 314*613a2f6bSGordon Ross * With extended security, we have: 315*613a2f6bSGordon Ross * Server_GUID (length 16) 316*613a2f6bSGordon Ross * Security_BLOB 317*613a2f6bSGordon Ross * Otherwise we have: 318*613a2f6bSGordon Ross * EncryptionKey (length is eklen) 319*613a2f6bSGordon Ross * PrimaryDomain 320*613a2f6bSGordon Ross */ 321*613a2f6bSGordon Ross if (sv->sv_caps & SMB_CAP_EXT_SECURITY) { 322*613a2f6bSGordon Ross struct mbuf *m; 323*613a2f6bSGordon Ross DPRINT("Ext.Security: yes"); 324*613a2f6bSGordon Ross 325*613a2f6bSGordon Ross /* 326*613a2f6bSGordon Ross * Skip the server GUID. 327*613a2f6bSGordon Ross */ 328*613a2f6bSGordon Ross err = mb_get_mem(mbp, NULL, SMB_GUIDLEN); 329*613a2f6bSGordon Ross if (err) 330*613a2f6bSGordon Ross goto errout; 331*613a2f6bSGordon Ross /* 332*613a2f6bSGordon Ross * Remainder is the security blob. 333*613a2f6bSGordon Ross * Note: eklen "must be ignored" [MS-SMB] 334*613a2f6bSGordon Ross */ 335*613a2f6bSGordon Ross len = (int)bc - SMB_GUIDLEN; 336*613a2f6bSGordon Ross if (len < 0) 337*613a2f6bSGordon Ross goto errout; 338*613a2f6bSGordon Ross 339*613a2f6bSGordon Ross /* 340*613a2f6bSGordon Ross * Get the (optional) SPNEGO "hint". 341*613a2f6bSGordon Ross */ 342*613a2f6bSGordon Ross err = mb_get_mbuf(mbp, len, &m); 343*613a2f6bSGordon Ross if (err) 344*613a2f6bSGordon Ross goto errout; 345*613a2f6bSGordon Ross mb_initm(oblob, m); 346*613a2f6bSGordon Ross oblob->mb_count = len; 347*613a2f6bSGordon Ross } else { 348*613a2f6bSGordon Ross DPRINT("Ext.Security: no"); 349*613a2f6bSGordon Ross ctx->ct_hflags2 &= ~SMB_FLAGS2_EXT_SEC; 350*613a2f6bSGordon Ross 351*613a2f6bSGordon Ross /* 352*613a2f6bSGordon Ross * Save the "Encryption Key" (the challenge). 353*613a2f6bSGordon Ross * 354*613a2f6bSGordon Ross * Sanity check: make sure the sec. blob length 355*613a2f6bSGordon Ross * isn't bigger than the byte count. 356*613a2f6bSGordon Ross */ 357*613a2f6bSGordon Ross if (bc < eklen || eklen < NTLM_CHAL_SZ) { 358*613a2f6bSGordon Ross err = EBADRPC; 359*613a2f6bSGordon Ross goto errout; 360*613a2f6bSGordon Ross } 361*613a2f6bSGordon Ross err = mb_get_mem(mbp, (char *)ctx->ct_ntlm_chal, NTLM_CHAL_SZ); 362*613a2f6bSGordon Ross /* 363*613a2f6bSGordon Ross * Server domain follows (ignored) 364*613a2f6bSGordon Ross * Note: NOT aligned(2) - unusual! 365*613a2f6bSGordon Ross */ 366*613a2f6bSGordon Ross } 367*613a2f6bSGordon Ross 368*613a2f6bSGordon Ross smb_rq_done(rqp); 369*613a2f6bSGordon Ross 370*613a2f6bSGordon Ross /* 371*613a2f6bSGordon Ross * A few sanity checks on what we received, 372*613a2f6bSGordon Ross * becuse we will send these in ssnsetup. 373*613a2f6bSGordon Ross * 374*613a2f6bSGordon Ross * Maximum outstanding requests (we care), 375*613a2f6bSGordon Ross * and Max. VCs (we only use one). Also, 376*613a2f6bSGordon Ross * MaxBufferSize lower limit per spec. 377*613a2f6bSGordon Ross */ 378*613a2f6bSGordon Ross if (sv->sv_maxmux < 1) 379*613a2f6bSGordon Ross sv->sv_maxmux = 1; 380*613a2f6bSGordon Ross if (sv->sv_maxvcs < 1) 381*613a2f6bSGordon Ross sv->sv_maxvcs = 1; 382*613a2f6bSGordon Ross if (sv->sv_maxtx < 1024) 383*613a2f6bSGordon Ross sv->sv_maxtx = 1024; 384*613a2f6bSGordon Ross 385*613a2f6bSGordon Ross /* 386*613a2f6bSGordon Ross * Maximum transfer size. 387*613a2f6bSGordon Ross * Sanity checks: 388*613a2f6bSGordon Ross * 389*613a2f6bSGordon Ross * Let's be conservative about an upper limit here. 390*613a2f6bSGordon Ross * Win2k uses 16644 (and others) so 32k should be a 391*613a2f6bSGordon Ross * reasonable sanity limit for this value. 392*613a2f6bSGordon Ross * 393*613a2f6bSGordon Ross * Note that this limit does NOT affect READX/WRITEX 394*613a2f6bSGordon Ross * with CAP_LARGE_..., which we nearly always use. 395*613a2f6bSGordon Ross */ 396*613a2f6bSGordon Ross is->is_txmax = sv->sv_maxtx; 397*613a2f6bSGordon Ross if (is->is_txmax > 0x8000) 398*613a2f6bSGordon Ross is->is_txmax = 0x8000; 399*613a2f6bSGordon Ross 400*613a2f6bSGordon Ross /* 401*613a2f6bSGordon Ross * Max read/write sizes, WITHOUT overhead. 402*613a2f6bSGordon Ross * This is just the payload size, so we must 403*613a2f6bSGordon Ross * leave room for the SMB headers, etc. 404*613a2f6bSGordon Ross * This is just the ct_txmax value, but 405*613a2f6bSGordon Ross * reduced and rounded down. Tricky bit: 406*613a2f6bSGordon Ross * 407*613a2f6bSGordon Ross * Servers typically give us a value that's 408*613a2f6bSGordon Ross * some nice "round" number, i.e 0x4000 plus 409*613a2f6bSGordon Ross * some overhead, i.e. Win2k: 16644==0x4104 410*613a2f6bSGordon Ross * Subtract for the SMB header (32) and the 411*613a2f6bSGordon Ross * SMB command word and byte vectors (34?), 412*613a2f6bSGordon Ross * then round down to a 512 byte multiple. 413*613a2f6bSGordon Ross */ 414*613a2f6bSGordon Ross len = is->is_txmax - 68; 415*613a2f6bSGordon Ross len &= 0xFE00; 416*613a2f6bSGordon Ross /* XXX: Not sure yet which of these to keep. */ 417*613a2f6bSGordon Ross is->is_rwmax = len; 418*613a2f6bSGordon Ross is->is_rxmax = len; 419*613a2f6bSGordon Ross is->is_wxmax = len; 420*613a2f6bSGordon Ross 421*613a2f6bSGordon Ross return (0); 422*613a2f6bSGordon Ross 423*613a2f6bSGordon Ross errout: 424*613a2f6bSGordon Ross smb_rq_done(rqp); 425*613a2f6bSGordon Ross if (err == 0) 426*613a2f6bSGordon Ross err = EBADRPC; 427*613a2f6bSGordon Ross return (err); 428*613a2f6bSGordon Ross } 429