1613a2f6bSGordon Ross /* 2613a2f6bSGordon Ross * Copyright (c) 2000-2001 Boris Popov 3613a2f6bSGordon Ross * All rights reserved. 4613a2f6bSGordon Ross * 5613a2f6bSGordon Ross * Redistribution and use in source and binary forms, with or without 6613a2f6bSGordon Ross * modification, are permitted provided that the following conditions 7613a2f6bSGordon Ross * are met: 8613a2f6bSGordon Ross * 1. Redistributions of source code must retain the above copyright 9613a2f6bSGordon Ross * notice, this list of conditions and the following disclaimer. 10613a2f6bSGordon Ross * 2. Redistributions in binary form must reproduce the above copyright 11613a2f6bSGordon Ross * notice, this list of conditions and the following disclaimer in the 12613a2f6bSGordon Ross * documentation and/or other materials provided with the distribution. 13613a2f6bSGordon Ross * 3. All advertising materials mentioning features or use of this software 14613a2f6bSGordon Ross * must display the following acknowledgement: 15613a2f6bSGordon Ross * This product includes software developed by Boris Popov. 16613a2f6bSGordon Ross * 4. Neither the name of the author nor the names of any co-contributors 17613a2f6bSGordon Ross * may be used to endorse or promote products derived from this software 18613a2f6bSGordon Ross * without specific prior written permission. 19613a2f6bSGordon Ross * 20613a2f6bSGordon Ross * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21613a2f6bSGordon Ross * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22613a2f6bSGordon Ross * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23613a2f6bSGordon Ross * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24613a2f6bSGordon Ross * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25613a2f6bSGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26613a2f6bSGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27613a2f6bSGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28613a2f6bSGordon Ross * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29613a2f6bSGordon Ross * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30613a2f6bSGordon Ross * SUCH DAMAGE. 31613a2f6bSGordon Ross */ 32613a2f6bSGordon Ross 33613a2f6bSGordon Ross /* 34*ae3d7f90SGordon Ross * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 35613a2f6bSGordon Ross */ 36613a2f6bSGordon Ross 37613a2f6bSGordon Ross /* 38613a2f6bSGordon Ross * SMB Negotiate Protocol, and related. 39613a2f6bSGordon Ross * Copied from the driver: smb_smb.c 40613a2f6bSGordon Ross */ 41613a2f6bSGordon Ross 42613a2f6bSGordon Ross #include <errno.h> 43613a2f6bSGordon Ross #include <stdio.h> 44613a2f6bSGordon Ross #include <stdlib.h> 45613a2f6bSGordon Ross #include <unistd.h> 46613a2f6bSGordon Ross #include <strings.h> 47613a2f6bSGordon Ross #include <netdb.h> 48613a2f6bSGordon Ross #include <libintl.h> 49613a2f6bSGordon Ross #include <xti.h> 50613a2f6bSGordon Ross #include <assert.h> 51613a2f6bSGordon Ross 52613a2f6bSGordon Ross #include <sys/types.h> 53613a2f6bSGordon Ross #include <sys/time.h> 54613a2f6bSGordon Ross #include <sys/byteorder.h> 55613a2f6bSGordon Ross #include <sys/socket.h> 56613a2f6bSGordon Ross #include <sys/fcntl.h> 57613a2f6bSGordon Ross 58613a2f6bSGordon Ross #include <netinet/in.h> 59613a2f6bSGordon Ross #include <netinet/tcp.h> 60613a2f6bSGordon Ross #include <arpa/inet.h> 61613a2f6bSGordon Ross 62613a2f6bSGordon Ross #include <netsmb/smb.h> 63613a2f6bSGordon Ross #include <netsmb/smb_lib.h> 64613a2f6bSGordon Ross #include <netsmb/netbios.h> 65613a2f6bSGordon Ross #include <netsmb/nb_lib.h> 66613a2f6bSGordon Ross #include <netsmb/smb_dev.h> 67613a2f6bSGordon Ross 68613a2f6bSGordon Ross #include "charsets.h" 69613a2f6bSGordon Ross #include "private.h" 70613a2f6bSGordon Ross 71613a2f6bSGordon Ross /* 72613a2f6bSGordon Ross * SMB dialects that we know about. 73613a2f6bSGordon Ross */ 74613a2f6bSGordon Ross struct smb_dialect { 75613a2f6bSGordon Ross int d_id; 76613a2f6bSGordon Ross const char *d_name; 77613a2f6bSGordon Ross }; 78613a2f6bSGordon Ross static struct smb_dialect smb_dialects[] = { 79613a2f6bSGordon Ross {SMB_DIALECT_CORE, "PC NETWORK PROGRAM 1.0"}, 80613a2f6bSGordon Ross {SMB_DIALECT_LANMAN1_0, "LANMAN1.0"}, 81613a2f6bSGordon Ross {SMB_DIALECT_LANMAN2_0, "LM1.2X002"}, 82613a2f6bSGordon Ross {SMB_DIALECT_LANMAN2_1, "LANMAN2.1"}, 83613a2f6bSGordon Ross {SMB_DIALECT_NTLM0_12, "NT LM 0.12"}, 84613a2f6bSGordon Ross {-1, NULL} 85613a2f6bSGordon Ross }; 86613a2f6bSGordon Ross 87613a2f6bSGordon Ross #define SMB_DIALECT_MAX \ 88613a2f6bSGordon Ross (sizeof (smb_dialects) / sizeof (struct smb_dialect) - 2) 89613a2f6bSGordon Ross 90613a2f6bSGordon Ross /* 91613a2f6bSGordon Ross * SMB Negotiate Protocol 92613a2f6bSGordon Ross * Based on code from the driver: smb_smb.c 93613a2f6bSGordon Ross * 94613a2f6bSGordon Ross * If using Extended Security, oblob (output) 95613a2f6bSGordon Ross * will hold the initial security "hint". 96613a2f6bSGordon Ross */ 97613a2f6bSGordon Ross int 98613a2f6bSGordon Ross smb_negprot(struct smb_ctx *ctx, struct mbdata *oblob) 99613a2f6bSGordon Ross { 100613a2f6bSGordon Ross struct smb_sopt *sv = &ctx->ct_sopt; 101613a2f6bSGordon Ross struct smb_iods *is = &ctx->ct_iods; 102613a2f6bSGordon Ross struct smb_rq *rqp; 103613a2f6bSGordon Ross struct mbdata *mbp; 104613a2f6bSGordon Ross struct smb_dialect *dp; 105613a2f6bSGordon Ross int err, len; 10602d09e03SGordon Ross uint8_t wc, eklen; 107613a2f6bSGordon Ross uint16_t dindex, bc; 108613a2f6bSGordon Ross int will_sign = 0; 109613a2f6bSGordon Ross 110613a2f6bSGordon Ross /* 111613a2f6bSGordon Ross * Initialize: vc_hflags and vc_hflags2. 112613a2f6bSGordon Ross * Note: ctx->ct_hflags* are copied into the 113*ae3d7f90SGordon Ross * (per request) rqp->rq_hflags* by smb_rq_init. 114*ae3d7f90SGordon Ross * 115*ae3d7f90SGordon Ross * Like Windows, set FLAGS2_UNICODE in our first request, 116*ae3d7f90SGordon Ross * even though technically we don't yet know whether the 117*ae3d7f90SGordon Ross * server supports Unicode. Will clear this flag below 118*ae3d7f90SGordon Ross * if we find out it doesn't. Need to do this because 119*ae3d7f90SGordon Ross * some servers reject all non-Unicode requests. 120613a2f6bSGordon Ross */ 121613a2f6bSGordon Ross ctx->ct_hflags = SMB_FLAGS_CASELESS; 122*ae3d7f90SGordon Ross ctx->ct_hflags2 = SMB_FLAGS2_KNOWS_LONG_NAMES | 123*ae3d7f90SGordon Ross SMB_FLAGS2_ERR_STATUS | SMB_FLAGS2_UNICODE; 124613a2f6bSGordon Ross 125613a2f6bSGordon Ross /* 126613a2f6bSGordon Ross * Sould we offer extended security? 127613a2f6bSGordon Ross * We'll turn this back off below if 128613a2f6bSGordon Ross * the server doesn't support it. 129613a2f6bSGordon Ross */ 130613a2f6bSGordon Ross if (ctx->ct_vopt & SMBVOPT_EXT_SEC) 131613a2f6bSGordon Ross ctx->ct_hflags2 |= SMB_FLAGS2_EXT_SEC; 132613a2f6bSGordon Ross 133613a2f6bSGordon Ross /* 134613a2f6bSGordon Ross * The initial UID needs to be zero, 135613a2f6bSGordon Ross * or Windows XP says "bad user". 136613a2f6bSGordon Ross * The initial TID is all ones, but 137613a2f6bSGordon Ross * we don't use it or store it here 138613a2f6bSGordon Ross * because the driver handles that. 139613a2f6bSGordon Ross */ 140613a2f6bSGordon Ross is->is_smbuid = 0; 141613a2f6bSGordon Ross 142613a2f6bSGordon Ross /* 143613a2f6bSGordon Ross * In case we're reconnecting, 144613a2f6bSGordon Ross * free previous stuff. 145613a2f6bSGordon Ross */ 146613a2f6bSGordon Ross ctx->ct_mac_seqno = 0; 147613a2f6bSGordon Ross if (ctx->ct_mackey != NULL) { 148613a2f6bSGordon Ross free(ctx->ct_mackey); 149613a2f6bSGordon Ross ctx->ct_mackey = NULL; 150613a2f6bSGordon Ross ctx->ct_mackeylen = 0; 151613a2f6bSGordon Ross } 152613a2f6bSGordon Ross 153613a2f6bSGordon Ross sv = &ctx->ct_sopt; 154613a2f6bSGordon Ross bzero(sv, sizeof (struct smb_sopt)); 155613a2f6bSGordon Ross 156613a2f6bSGordon Ross err = smb_rq_init(ctx, SMB_COM_NEGOTIATE, &rqp); 157613a2f6bSGordon Ross if (err) 158613a2f6bSGordon Ross return (err); 159613a2f6bSGordon Ross 160613a2f6bSGordon Ross /* 161613a2f6bSGordon Ross * Build the SMB request. 162613a2f6bSGordon Ross */ 163613a2f6bSGordon Ross mbp = &rqp->rq_rq; 164613a2f6bSGordon Ross mb_put_uint8(mbp, 0); /* word count */ 165613a2f6bSGordon Ross smb_rq_bstart(rqp); 166613a2f6bSGordon Ross for (dp = smb_dialects; dp->d_id != -1; dp++) { 167613a2f6bSGordon Ross mb_put_uint8(mbp, SMB_DT_DIALECT); 168613a2f6bSGordon Ross mb_put_astring(mbp, dp->d_name); 169613a2f6bSGordon Ross } 170613a2f6bSGordon Ross smb_rq_bend(rqp); 171613a2f6bSGordon Ross 172613a2f6bSGordon Ross /* 173613a2f6bSGordon Ross * This does the OTW call 174613a2f6bSGordon Ross */ 175613a2f6bSGordon Ross err = smb_rq_internal(ctx, rqp); 176613a2f6bSGordon Ross if (err) { 177613a2f6bSGordon Ross DPRINT("call failed, err %d", err); 178613a2f6bSGordon Ross goto errout; 179613a2f6bSGordon Ross } 180613a2f6bSGordon Ross if (rqp->rq_status != 0) { 181613a2f6bSGordon Ross DPRINT("nt status 0x%x", rqp->rq_status); 182613a2f6bSGordon Ross err = EBADRPC; 183613a2f6bSGordon Ross goto errout; 184613a2f6bSGordon Ross } 185613a2f6bSGordon Ross 186613a2f6bSGordon Ross /* 187613a2f6bSGordon Ross * Decode the response 188613a2f6bSGordon Ross * 189613a2f6bSGordon Ross * Comments to right show names as described in 190613a2f6bSGordon Ross * The Microsoft SMB Protocol spec. [MS-SMB] 191613a2f6bSGordon Ross * section 2.2.3 192613a2f6bSGordon Ross */ 193613a2f6bSGordon Ross mbp = &rqp->rq_rp; 19402d09e03SGordon Ross (void) md_get_uint8(mbp, &wc); 19502d09e03SGordon Ross err = md_get_uint16le(mbp, &dindex); 196613a2f6bSGordon Ross if (err || dindex > SMB_DIALECT_MAX) { 197613a2f6bSGordon Ross DPRINT("err %d dindex %d", err, (int)dindex); 198613a2f6bSGordon Ross goto errout; 199613a2f6bSGordon Ross } 200613a2f6bSGordon Ross dp = smb_dialects + dindex; 201613a2f6bSGordon Ross sv->sv_proto = dp->d_id; 202613a2f6bSGordon Ross DPRINT("Dialect %s", dp->d_name); 203613a2f6bSGordon Ross if (dp->d_id < SMB_DIALECT_NTLM0_12) { 204613a2f6bSGordon Ross /* XXX: User-visible warning too? */ 205613a2f6bSGordon Ross DPRINT("old dialect %s", dp->d_name); 206613a2f6bSGordon Ross goto errout; 207613a2f6bSGordon Ross } 208613a2f6bSGordon Ross if (wc != 17) { 209613a2f6bSGordon Ross DPRINT("bad wc %d", (int)wc); 210613a2f6bSGordon Ross goto errout; 211613a2f6bSGordon Ross } 21202d09e03SGordon Ross md_get_uint8(mbp, &sv->sv_sm); /* SecurityMode */ 21302d09e03SGordon Ross md_get_uint16le(mbp, &sv->sv_maxmux); /* MaxMpxCount */ 21402d09e03SGordon Ross md_get_uint16le(mbp, &sv->sv_maxvcs); /* MaxCountVCs */ 21502d09e03SGordon Ross md_get_uint32le(mbp, &sv->sv_maxtx); /* MaxBufferSize */ 21602d09e03SGordon Ross md_get_uint32le(mbp, &sv->sv_maxraw); /* MaxRawSize */ 21702d09e03SGordon Ross md_get_uint32le(mbp, &sv->sv_skey); /* SessionKey */ 21802d09e03SGordon Ross md_get_uint32le(mbp, &sv->sv_caps); /* Capabilities */ 21902d09e03SGordon Ross md_get_mem(mbp, NULL, 8, MB_MSYSTEM); /* SystemTime(s) */ 22002d09e03SGordon Ross md_get_uint16le(mbp, (uint16_t *)&sv->sv_tz); 22102d09e03SGordon Ross md_get_uint8(mbp, &eklen); /* EncryptionKeyLength */ 22202d09e03SGordon Ross err = md_get_uint16le(mbp, &bc); /* ByteCount */ 223613a2f6bSGordon Ross if (err) 224613a2f6bSGordon Ross goto errout; 225613a2f6bSGordon Ross 226613a2f6bSGordon Ross /* BEGIN CSTYLED */ 227613a2f6bSGordon Ross /* 228613a2f6bSGordon Ross * Will we do SMB signing? Or block the connection? 229613a2f6bSGordon Ross * The table below describes this logic. References: 230613a2f6bSGordon Ross * [Windows Server Protocols: MS-SMB, sec. 3.2.4.2.3] 231613a2f6bSGordon Ross * http://msdn.microsoft.com/en-us/library/cc212511.aspx 232613a2f6bSGordon Ross * http://msdn.microsoft.com/en-us/library/cc212929.aspx 233613a2f6bSGordon Ross * 234613a2f6bSGordon Ross * Srv/Cli | Required | Enabled | If Required | Disabled 235613a2f6bSGordon Ross * ------------+----------+------------+-------------+----------- 236613a2f6bSGordon Ross * Required | Signed | Signed | Signed | Blocked [1] 237613a2f6bSGordon Ross * ------------+----------+------------+-------------+----------- 238613a2f6bSGordon Ross * Enabled | Signed | Signed | Not Signed | Not Signed 239613a2f6bSGordon Ross * ------------+----------+------------+-------------+----------- 240613a2f6bSGordon Ross * If Required | Signed | Not Signed | Not Signed | Not Signed 241613a2f6bSGordon Ross * ------------+----------+------------+-------------+----------- 242613a2f6bSGordon Ross * Disabled | Blocked | Not Signed | Not Signed | Not Signed 243613a2f6bSGordon Ross * 244613a2f6bSGordon Ross * [1] Like Windows 2003 and later, we don't really implement 245613a2f6bSGordon Ross * the "Disabled" setting. Instead we implement "If Required", 246613a2f6bSGordon Ross * so we always sign if the server requires signing. 247613a2f6bSGordon Ross */ 248613a2f6bSGordon Ross /* END CSTYLED */ 249613a2f6bSGordon Ross 250613a2f6bSGordon Ross if (sv->sv_sm & SMB_SM_SIGS_REQUIRE) { 251613a2f6bSGordon Ross /* 252613a2f6bSGordon Ross * Server requires signing. We will sign, 253613a2f6bSGordon Ross * even if local setting is "disabled". 254613a2f6bSGordon Ross */ 255613a2f6bSGordon Ross will_sign = 1; 256613a2f6bSGordon Ross } else if (sv->sv_sm & SMB_SM_SIGS) { 257613a2f6bSGordon Ross /* 258613a2f6bSGordon Ross * Server enables signing (client's option). 259613a2f6bSGordon Ross * If enabled locally, do signing. 260613a2f6bSGordon Ross */ 261613a2f6bSGordon Ross if (ctx->ct_vopt & SMBVOPT_SIGNING_ENABLED) 262613a2f6bSGordon Ross will_sign = 1; 263613a2f6bSGordon Ross /* else not signing. */ 264613a2f6bSGordon Ross } else { 265613a2f6bSGordon Ross /* 266613a2f6bSGordon Ross * Server does not support signing. 267613a2f6bSGordon Ross * If we "require" it, bail now. 268613a2f6bSGordon Ross */ 269613a2f6bSGordon Ross if (ctx->ct_vopt & SMBVOPT_SIGNING_REQUIRED) { 270613a2f6bSGordon Ross DPRINT("Client requires signing " 271613a2f6bSGordon Ross "but server has it disabled."); 272613a2f6bSGordon Ross err = EBADRPC; 273613a2f6bSGordon Ross goto errout; 274613a2f6bSGordon Ross } 275613a2f6bSGordon Ross } 276613a2f6bSGordon Ross 277613a2f6bSGordon Ross if (will_sign) { 278613a2f6bSGordon Ross ctx->ct_vcflags |= SMBV_WILL_SIGN; 279613a2f6bSGordon Ross } 280613a2f6bSGordon Ross DPRINT("Security signatures: %d", will_sign); 281613a2f6bSGordon Ross 282*ae3d7f90SGordon Ross /* See comment above re. FLAGS2_UNICODE */ 283*ae3d7f90SGordon Ross if (sv->sv_caps & SMB_CAP_UNICODE) 284613a2f6bSGordon Ross ctx->ct_vcflags |= SMBV_UNICODE; 285*ae3d7f90SGordon Ross else 286*ae3d7f90SGordon Ross ctx->ct_hflags2 &= ~SMB_FLAGS2_UNICODE; 287613a2f6bSGordon Ross 288613a2f6bSGordon Ross if ((sv->sv_caps & SMB_CAP_STATUS32) == 0) { 289613a2f6bSGordon Ross /* 290613a2f6bSGordon Ross * They don't do NT error codes. 291613a2f6bSGordon Ross * 292613a2f6bSGordon Ross * If we send requests with 293613a2f6bSGordon Ross * SMB_FLAGS2_ERR_STATUS set in 294613a2f6bSGordon Ross * Flags2, Windows 98, at least, 295613a2f6bSGordon Ross * appears to send replies with that 296613a2f6bSGordon Ross * bit set even though it sends back 297613a2f6bSGordon Ross * DOS error codes. (They probably 298613a2f6bSGordon Ross * just use the request header as 299613a2f6bSGordon Ross * a template for the reply header, 300613a2f6bSGordon Ross * and don't bother clearing that bit.) 301613a2f6bSGordon Ross * 302613a2f6bSGordon Ross * Therefore, we clear that bit in 303613a2f6bSGordon Ross * our vc_hflags2 field. 304613a2f6bSGordon Ross */ 305613a2f6bSGordon Ross ctx->ct_hflags2 &= ~SMB_FLAGS2_ERR_STATUS; 306613a2f6bSGordon Ross } 307613a2f6bSGordon Ross if (dp->d_id == SMB_DIALECT_NTLM0_12 && 308613a2f6bSGordon Ross sv->sv_maxtx < 4096 && 309613a2f6bSGordon Ross (sv->sv_caps & SMB_CAP_NT_SMBS) == 0) { 310613a2f6bSGordon Ross ctx->ct_vcflags |= SMBV_WIN95; 311613a2f6bSGordon Ross DPRINT("Win95 detected"); 312613a2f6bSGordon Ross } 313613a2f6bSGordon Ross 314613a2f6bSGordon Ross /* 315613a2f6bSGordon Ross * The rest of the message varies depending on 316613a2f6bSGordon Ross * whether we've negotiated "extended security". 317613a2f6bSGordon Ross * 318613a2f6bSGordon Ross * With extended security, we have: 319613a2f6bSGordon Ross * Server_GUID (length 16) 320613a2f6bSGordon Ross * Security_BLOB 321613a2f6bSGordon Ross * Otherwise we have: 322613a2f6bSGordon Ross * EncryptionKey (length is eklen) 323613a2f6bSGordon Ross * PrimaryDomain 324613a2f6bSGordon Ross */ 325613a2f6bSGordon Ross if (sv->sv_caps & SMB_CAP_EXT_SECURITY) { 326613a2f6bSGordon Ross struct mbuf *m; 327613a2f6bSGordon Ross DPRINT("Ext.Security: yes"); 328613a2f6bSGordon Ross 329613a2f6bSGordon Ross /* 330613a2f6bSGordon Ross * Skip the server GUID. 331613a2f6bSGordon Ross */ 33202d09e03SGordon Ross err = md_get_mem(mbp, NULL, SMB_GUIDLEN, MB_MSYSTEM); 333613a2f6bSGordon Ross if (err) 334613a2f6bSGordon Ross goto errout; 335613a2f6bSGordon Ross /* 336613a2f6bSGordon Ross * Remainder is the security blob. 337613a2f6bSGordon Ross * Note: eklen "must be ignored" [MS-SMB] 338613a2f6bSGordon Ross */ 339613a2f6bSGordon Ross len = (int)bc - SMB_GUIDLEN; 340613a2f6bSGordon Ross if (len < 0) 341613a2f6bSGordon Ross goto errout; 342613a2f6bSGordon Ross 343613a2f6bSGordon Ross /* 344613a2f6bSGordon Ross * Get the (optional) SPNEGO "hint". 345613a2f6bSGordon Ross */ 34602d09e03SGordon Ross err = md_get_mbuf(mbp, len, &m); 347613a2f6bSGordon Ross if (err) 348613a2f6bSGordon Ross goto errout; 349613a2f6bSGordon Ross mb_initm(oblob, m); 350613a2f6bSGordon Ross oblob->mb_count = len; 351613a2f6bSGordon Ross } else { 352613a2f6bSGordon Ross DPRINT("Ext.Security: no"); 353613a2f6bSGordon Ross ctx->ct_hflags2 &= ~SMB_FLAGS2_EXT_SEC; 354613a2f6bSGordon Ross 355613a2f6bSGordon Ross /* 356613a2f6bSGordon Ross * Save the "Encryption Key" (the challenge). 357613a2f6bSGordon Ross * 358613a2f6bSGordon Ross * Sanity check: make sure the sec. blob length 359613a2f6bSGordon Ross * isn't bigger than the byte count. 360613a2f6bSGordon Ross */ 361613a2f6bSGordon Ross if (bc < eklen || eklen < NTLM_CHAL_SZ) { 362613a2f6bSGordon Ross err = EBADRPC; 363613a2f6bSGordon Ross goto errout; 364613a2f6bSGordon Ross } 36502d09e03SGordon Ross err = md_get_mem(mbp, ctx->ct_ntlm_chal, 36602d09e03SGordon Ross NTLM_CHAL_SZ, MB_MSYSTEM); 367613a2f6bSGordon Ross /* 368613a2f6bSGordon Ross * Server domain follows (ignored) 369613a2f6bSGordon Ross * Note: NOT aligned(2) - unusual! 370613a2f6bSGordon Ross */ 371613a2f6bSGordon Ross } 372613a2f6bSGordon Ross 373613a2f6bSGordon Ross smb_rq_done(rqp); 374613a2f6bSGordon Ross 375613a2f6bSGordon Ross /* 376613a2f6bSGordon Ross * A few sanity checks on what we received, 377613a2f6bSGordon Ross * becuse we will send these in ssnsetup. 378613a2f6bSGordon Ross * 379613a2f6bSGordon Ross * Maximum outstanding requests (we care), 380613a2f6bSGordon Ross * and Max. VCs (we only use one). Also, 381613a2f6bSGordon Ross * MaxBufferSize lower limit per spec. 382613a2f6bSGordon Ross */ 383613a2f6bSGordon Ross if (sv->sv_maxmux < 1) 384613a2f6bSGordon Ross sv->sv_maxmux = 1; 385613a2f6bSGordon Ross if (sv->sv_maxvcs < 1) 386613a2f6bSGordon Ross sv->sv_maxvcs = 1; 387613a2f6bSGordon Ross if (sv->sv_maxtx < 1024) 388613a2f6bSGordon Ross sv->sv_maxtx = 1024; 389613a2f6bSGordon Ross 390613a2f6bSGordon Ross /* 391613a2f6bSGordon Ross * Maximum transfer size. 392613a2f6bSGordon Ross * Sanity checks: 393613a2f6bSGordon Ross * 394613a2f6bSGordon Ross * Let's be conservative about an upper limit here. 395613a2f6bSGordon Ross * Win2k uses 16644 (and others) so 32k should be a 396613a2f6bSGordon Ross * reasonable sanity limit for this value. 397613a2f6bSGordon Ross * 398613a2f6bSGordon Ross * Note that this limit does NOT affect READX/WRITEX 399613a2f6bSGordon Ross * with CAP_LARGE_..., which we nearly always use. 400613a2f6bSGordon Ross */ 401613a2f6bSGordon Ross is->is_txmax = sv->sv_maxtx; 402613a2f6bSGordon Ross if (is->is_txmax > 0x8000) 403613a2f6bSGordon Ross is->is_txmax = 0x8000; 404613a2f6bSGordon Ross 405613a2f6bSGordon Ross /* 406613a2f6bSGordon Ross * Max read/write sizes, WITHOUT overhead. 407613a2f6bSGordon Ross * This is just the payload size, so we must 408613a2f6bSGordon Ross * leave room for the SMB headers, etc. 409613a2f6bSGordon Ross * This is just the ct_txmax value, but 410613a2f6bSGordon Ross * reduced and rounded down. Tricky bit: 411613a2f6bSGordon Ross * 412613a2f6bSGordon Ross * Servers typically give us a value that's 413613a2f6bSGordon Ross * some nice "round" number, i.e 0x4000 plus 414613a2f6bSGordon Ross * some overhead, i.e. Win2k: 16644==0x4104 415613a2f6bSGordon Ross * Subtract for the SMB header (32) and the 416613a2f6bSGordon Ross * SMB command word and byte vectors (34?), 417613a2f6bSGordon Ross * then round down to a 512 byte multiple. 418613a2f6bSGordon Ross */ 419613a2f6bSGordon Ross len = is->is_txmax - 68; 420613a2f6bSGordon Ross len &= 0xFE00; 421613a2f6bSGordon Ross /* XXX: Not sure yet which of these to keep. */ 422613a2f6bSGordon Ross is->is_rwmax = len; 423613a2f6bSGordon Ross is->is_rxmax = len; 424613a2f6bSGordon Ross is->is_wxmax = len; 425613a2f6bSGordon Ross 426613a2f6bSGordon Ross return (0); 427613a2f6bSGordon Ross 428613a2f6bSGordon Ross errout: 429613a2f6bSGordon Ross smb_rq_done(rqp); 430613a2f6bSGordon Ross if (err == 0) 431613a2f6bSGordon Ross err = EBADRPC; 432613a2f6bSGordon Ross return (err); 433613a2f6bSGordon Ross } 434