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 /* 34ae3d7f90SGordon Ross * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 35*85e6b674SGordon Ross * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 36613a2f6bSGordon Ross */ 37613a2f6bSGordon Ross 38613a2f6bSGordon Ross /* 39613a2f6bSGordon Ross * SMB Negotiate Protocol, and related. 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" 69*85e6b674SGordon Ross #include "smb_crypt.h" 70613a2f6bSGordon Ross #include "private.h" 71613a2f6bSGordon Ross 72613a2f6bSGordon Ross /* 73613a2f6bSGordon Ross * SMB dialects that we know about. 74613a2f6bSGordon Ross */ 75613a2f6bSGordon Ross struct smb_dialect { 76613a2f6bSGordon Ross int d_id; 77613a2f6bSGordon Ross const char *d_name; 78613a2f6bSGordon Ross }; 79613a2f6bSGordon Ross static struct smb_dialect smb_dialects[] = { 80613a2f6bSGordon Ross {SMB_DIALECT_CORE, "PC NETWORK PROGRAM 1.0"}, 81613a2f6bSGordon Ross {SMB_DIALECT_LANMAN1_0, "LANMAN1.0"}, 82613a2f6bSGordon Ross {SMB_DIALECT_LANMAN2_0, "LM1.2X002"}, 83613a2f6bSGordon Ross {SMB_DIALECT_LANMAN2_1, "LANMAN2.1"}, 84613a2f6bSGordon Ross {SMB_DIALECT_NTLM0_12, "NT LM 0.12"}, 85613a2f6bSGordon Ross {-1, NULL} 86613a2f6bSGordon Ross }; 87613a2f6bSGordon Ross 88613a2f6bSGordon Ross #define SMB_DIALECT_MAX \ 89613a2f6bSGordon Ross (sizeof (smb_dialects) / sizeof (struct smb_dialect) - 2) 90613a2f6bSGordon Ross 91*85e6b674SGordon Ross static const uint32_t smb_clnt_caps_mask = 92*85e6b674SGordon Ross SMB_CAP_UNICODE | 93*85e6b674SGordon Ross SMB_CAP_LARGE_FILES | 94*85e6b674SGordon Ross SMB_CAP_NT_SMBS | 95*85e6b674SGordon Ross SMB_CAP_STATUS32 | 96*85e6b674SGordon Ross SMB_CAP_EXT_SECURITY; 97*85e6b674SGordon Ross 98613a2f6bSGordon Ross /* 99613a2f6bSGordon Ross * SMB Negotiate Protocol 100613a2f6bSGordon Ross * Based on code from the driver: smb_smb.c 101613a2f6bSGordon Ross * 102613a2f6bSGordon Ross * If using Extended Security, oblob (output) 103613a2f6bSGordon Ross * will hold the initial security "hint". 104613a2f6bSGordon Ross */ 105613a2f6bSGordon Ross int 106613a2f6bSGordon Ross smb_negprot(struct smb_ctx *ctx, struct mbdata *oblob) 107613a2f6bSGordon Ross { 108613a2f6bSGordon Ross struct smb_sopt *sv = &ctx->ct_sopt; 109613a2f6bSGordon Ross struct smb_iods *is = &ctx->ct_iods; 110613a2f6bSGordon Ross struct smb_rq *rqp; 111613a2f6bSGordon Ross struct mbdata *mbp; 112613a2f6bSGordon Ross struct smb_dialect *dp; 113613a2f6bSGordon Ross int err, len; 11402d09e03SGordon Ross uint8_t wc, eklen; 115613a2f6bSGordon Ross uint16_t dindex, bc; 116613a2f6bSGordon Ross int will_sign = 0; 117613a2f6bSGordon Ross 118613a2f6bSGordon Ross /* 119613a2f6bSGordon Ross * Initialize: vc_hflags and vc_hflags2. 120613a2f6bSGordon Ross * Note: ctx->ct_hflags* are copied into the 121ae3d7f90SGordon Ross * (per request) rqp->rq_hflags* by smb_rq_init. 122ae3d7f90SGordon Ross * 123ae3d7f90SGordon Ross * Like Windows, set FLAGS2_UNICODE in our first request, 124ae3d7f90SGordon Ross * even though technically we don't yet know whether the 125ae3d7f90SGordon Ross * server supports Unicode. Will clear this flag below 126ae3d7f90SGordon Ross * if we find out it doesn't. Need to do this because 127ae3d7f90SGordon Ross * some servers reject all non-Unicode requests. 128613a2f6bSGordon Ross */ 129*85e6b674SGordon Ross ctx->ct_hflags = 130*85e6b674SGordon Ross SMB_FLAGS_CASELESS | 131*85e6b674SGordon Ross SMB_FLAGS_CANONICAL_PATHNAMES; 132*85e6b674SGordon Ross ctx->ct_hflags2 = 133*85e6b674SGordon Ross SMB_FLAGS2_KNOWS_LONG_NAMES | 134*85e6b674SGordon Ross SMB_FLAGS2_KNOWS_EAS | 135*85e6b674SGordon Ross /* SMB_FLAGS2_IS_LONG_NAME |? */ 136*85e6b674SGordon Ross /* EXT_SEC (see below) */ 137*85e6b674SGordon Ross SMB_FLAGS2_ERR_STATUS | 138*85e6b674SGordon Ross SMB_FLAGS2_UNICODE; 139613a2f6bSGordon Ross 140613a2f6bSGordon Ross /* 141613a2f6bSGordon Ross * Sould we offer extended security? 142613a2f6bSGordon Ross * We'll turn this back off below if 143613a2f6bSGordon Ross * the server doesn't support it. 144613a2f6bSGordon Ross */ 145613a2f6bSGordon Ross if (ctx->ct_vopt & SMBVOPT_EXT_SEC) 146613a2f6bSGordon Ross ctx->ct_hflags2 |= SMB_FLAGS2_EXT_SEC; 147613a2f6bSGordon Ross 148613a2f6bSGordon Ross /* 149613a2f6bSGordon Ross * The initial UID needs to be zero, 150613a2f6bSGordon Ross * or Windows XP says "bad user". 151613a2f6bSGordon Ross * The initial TID is all ones, but 152613a2f6bSGordon Ross * we don't use it or store it here 153613a2f6bSGordon Ross * because the driver handles that. 154613a2f6bSGordon Ross */ 155613a2f6bSGordon Ross is->is_smbuid = 0; 156613a2f6bSGordon Ross 157613a2f6bSGordon Ross /* 158613a2f6bSGordon Ross * In case we're reconnecting, 159613a2f6bSGordon Ross * free previous stuff. 160613a2f6bSGordon Ross */ 161613a2f6bSGordon Ross ctx->ct_mac_seqno = 0; 162613a2f6bSGordon Ross if (ctx->ct_mackey != NULL) { 163613a2f6bSGordon Ross free(ctx->ct_mackey); 164613a2f6bSGordon Ross ctx->ct_mackey = NULL; 165613a2f6bSGordon Ross ctx->ct_mackeylen = 0; 166613a2f6bSGordon Ross } 167613a2f6bSGordon Ross 168613a2f6bSGordon Ross sv = &ctx->ct_sopt; 169613a2f6bSGordon Ross bzero(sv, sizeof (struct smb_sopt)); 170613a2f6bSGordon Ross 171613a2f6bSGordon Ross err = smb_rq_init(ctx, SMB_COM_NEGOTIATE, &rqp); 172613a2f6bSGordon Ross if (err) 173613a2f6bSGordon Ross return (err); 174613a2f6bSGordon Ross 175613a2f6bSGordon Ross /* 176613a2f6bSGordon Ross * Build the SMB request. 177613a2f6bSGordon Ross */ 178613a2f6bSGordon Ross mbp = &rqp->rq_rq; 179613a2f6bSGordon Ross mb_put_uint8(mbp, 0); /* word count */ 180613a2f6bSGordon Ross smb_rq_bstart(rqp); 181613a2f6bSGordon Ross for (dp = smb_dialects; dp->d_id != -1; dp++) { 182613a2f6bSGordon Ross mb_put_uint8(mbp, SMB_DT_DIALECT); 183613a2f6bSGordon Ross mb_put_astring(mbp, dp->d_name); 184613a2f6bSGordon Ross } 185613a2f6bSGordon Ross smb_rq_bend(rqp); 186613a2f6bSGordon Ross 187613a2f6bSGordon Ross /* 188613a2f6bSGordon Ross * This does the OTW call 189613a2f6bSGordon Ross */ 190613a2f6bSGordon Ross err = smb_rq_internal(ctx, rqp); 191613a2f6bSGordon Ross if (err) { 192613a2f6bSGordon Ross DPRINT("call failed, err %d", err); 193613a2f6bSGordon Ross goto errout; 194613a2f6bSGordon Ross } 195613a2f6bSGordon Ross if (rqp->rq_status != 0) { 196613a2f6bSGordon Ross DPRINT("nt status 0x%x", rqp->rq_status); 197613a2f6bSGordon Ross err = EBADRPC; 198613a2f6bSGordon Ross goto errout; 199613a2f6bSGordon Ross } 200613a2f6bSGordon Ross 201613a2f6bSGordon Ross /* 202613a2f6bSGordon Ross * Decode the response 203613a2f6bSGordon Ross * 204613a2f6bSGordon Ross * Comments to right show names as described in 205613a2f6bSGordon Ross * The Microsoft SMB Protocol spec. [MS-SMB] 206613a2f6bSGordon Ross * section 2.2.3 207613a2f6bSGordon Ross */ 208613a2f6bSGordon Ross mbp = &rqp->rq_rp; 20902d09e03SGordon Ross (void) md_get_uint8(mbp, &wc); 21002d09e03SGordon Ross err = md_get_uint16le(mbp, &dindex); 211613a2f6bSGordon Ross if (err || dindex > SMB_DIALECT_MAX) { 212613a2f6bSGordon Ross DPRINT("err %d dindex %d", err, (int)dindex); 213613a2f6bSGordon Ross goto errout; 214613a2f6bSGordon Ross } 215613a2f6bSGordon Ross dp = smb_dialects + dindex; 216613a2f6bSGordon Ross sv->sv_proto = dp->d_id; 217613a2f6bSGordon Ross DPRINT("Dialect %s", dp->d_name); 218613a2f6bSGordon Ross if (dp->d_id < SMB_DIALECT_NTLM0_12) { 219613a2f6bSGordon Ross /* XXX: User-visible warning too? */ 220613a2f6bSGordon Ross DPRINT("old dialect %s", dp->d_name); 221613a2f6bSGordon Ross goto errout; 222613a2f6bSGordon Ross } 223613a2f6bSGordon Ross if (wc != 17) { 224613a2f6bSGordon Ross DPRINT("bad wc %d", (int)wc); 225613a2f6bSGordon Ross goto errout; 226613a2f6bSGordon Ross } 22702d09e03SGordon Ross md_get_uint8(mbp, &sv->sv_sm); /* SecurityMode */ 22802d09e03SGordon Ross md_get_uint16le(mbp, &sv->sv_maxmux); /* MaxMpxCount */ 22902d09e03SGordon Ross md_get_uint16le(mbp, &sv->sv_maxvcs); /* MaxCountVCs */ 23002d09e03SGordon Ross md_get_uint32le(mbp, &sv->sv_maxtx); /* MaxBufferSize */ 23102d09e03SGordon Ross md_get_uint32le(mbp, &sv->sv_maxraw); /* MaxRawSize */ 23202d09e03SGordon Ross md_get_uint32le(mbp, &sv->sv_skey); /* SessionKey */ 23302d09e03SGordon Ross md_get_uint32le(mbp, &sv->sv_caps); /* Capabilities */ 23402d09e03SGordon Ross md_get_mem(mbp, NULL, 8, MB_MSYSTEM); /* SystemTime(s) */ 23502d09e03SGordon Ross md_get_uint16le(mbp, (uint16_t *)&sv->sv_tz); 23602d09e03SGordon Ross md_get_uint8(mbp, &eklen); /* EncryptionKeyLength */ 23702d09e03SGordon Ross err = md_get_uint16le(mbp, &bc); /* ByteCount */ 238613a2f6bSGordon Ross if (err) 239613a2f6bSGordon Ross goto errout; 240613a2f6bSGordon Ross 241613a2f6bSGordon Ross /* BEGIN CSTYLED */ 242613a2f6bSGordon Ross /* 243613a2f6bSGordon Ross * Will we do SMB signing? Or block the connection? 244613a2f6bSGordon Ross * The table below describes this logic. References: 245613a2f6bSGordon Ross * [Windows Server Protocols: MS-SMB, sec. 3.2.4.2.3] 246613a2f6bSGordon Ross * http://msdn.microsoft.com/en-us/library/cc212511.aspx 247613a2f6bSGordon Ross * http://msdn.microsoft.com/en-us/library/cc212929.aspx 248613a2f6bSGordon Ross * 249613a2f6bSGordon Ross * Srv/Cli | Required | Enabled | If Required | Disabled 250613a2f6bSGordon Ross * ------------+----------+------------+-------------+----------- 251613a2f6bSGordon Ross * Required | Signed | Signed | Signed | Blocked [1] 252613a2f6bSGordon Ross * ------------+----------+------------+-------------+----------- 253613a2f6bSGordon Ross * Enabled | Signed | Signed | Not Signed | Not Signed 254613a2f6bSGordon Ross * ------------+----------+------------+-------------+----------- 255613a2f6bSGordon Ross * If Required | Signed | Not Signed | Not Signed | Not Signed 256613a2f6bSGordon Ross * ------------+----------+------------+-------------+----------- 257613a2f6bSGordon Ross * Disabled | Blocked | Not Signed | Not Signed | Not Signed 258613a2f6bSGordon Ross * 259613a2f6bSGordon Ross * [1] Like Windows 2003 and later, we don't really implement 260613a2f6bSGordon Ross * the "Disabled" setting. Instead we implement "If Required", 261613a2f6bSGordon Ross * so we always sign if the server requires signing. 262613a2f6bSGordon Ross */ 263613a2f6bSGordon Ross /* END CSTYLED */ 264613a2f6bSGordon Ross 265613a2f6bSGordon Ross if (sv->sv_sm & SMB_SM_SIGS_REQUIRE) { 266613a2f6bSGordon Ross /* 267613a2f6bSGordon Ross * Server requires signing. We will sign, 268613a2f6bSGordon Ross * even if local setting is "disabled". 269613a2f6bSGordon Ross */ 270613a2f6bSGordon Ross will_sign = 1; 271613a2f6bSGordon Ross } else if (sv->sv_sm & SMB_SM_SIGS) { 272613a2f6bSGordon Ross /* 273613a2f6bSGordon Ross * Server enables signing (client's option). 274613a2f6bSGordon Ross * If enabled locally, do signing. 275613a2f6bSGordon Ross */ 276613a2f6bSGordon Ross if (ctx->ct_vopt & SMBVOPT_SIGNING_ENABLED) 277613a2f6bSGordon Ross will_sign = 1; 278613a2f6bSGordon Ross /* else not signing. */ 279613a2f6bSGordon Ross } else { 280613a2f6bSGordon Ross /* 281613a2f6bSGordon Ross * Server does not support signing. 282613a2f6bSGordon Ross * If we "require" it, bail now. 283613a2f6bSGordon Ross */ 284613a2f6bSGordon Ross if (ctx->ct_vopt & SMBVOPT_SIGNING_REQUIRED) { 285613a2f6bSGordon Ross DPRINT("Client requires signing " 286613a2f6bSGordon Ross "but server has it disabled."); 287613a2f6bSGordon Ross err = EBADRPC; 288613a2f6bSGordon Ross goto errout; 289613a2f6bSGordon Ross } 290613a2f6bSGordon Ross } 291613a2f6bSGordon Ross 292613a2f6bSGordon Ross if (will_sign) { 293613a2f6bSGordon Ross ctx->ct_vcflags |= SMBV_WILL_SIGN; 294613a2f6bSGordon Ross } 295613a2f6bSGordon Ross DPRINT("Security signatures: %d", will_sign); 296613a2f6bSGordon Ross 297ae3d7f90SGordon Ross /* See comment above re. FLAGS2_UNICODE */ 298ae3d7f90SGordon Ross if (sv->sv_caps & SMB_CAP_UNICODE) 299613a2f6bSGordon Ross ctx->ct_vcflags |= SMBV_UNICODE; 300ae3d7f90SGordon Ross else 301ae3d7f90SGordon Ross ctx->ct_hflags2 &= ~SMB_FLAGS2_UNICODE; 302613a2f6bSGordon Ross 303613a2f6bSGordon Ross if ((sv->sv_caps & SMB_CAP_STATUS32) == 0) { 304613a2f6bSGordon Ross /* 305613a2f6bSGordon Ross * They don't do NT error codes. 306613a2f6bSGordon Ross * 307613a2f6bSGordon Ross * If we send requests with 308613a2f6bSGordon Ross * SMB_FLAGS2_ERR_STATUS set in 309613a2f6bSGordon Ross * Flags2, Windows 98, at least, 310613a2f6bSGordon Ross * appears to send replies with that 311613a2f6bSGordon Ross * bit set even though it sends back 312613a2f6bSGordon Ross * DOS error codes. (They probably 313613a2f6bSGordon Ross * just use the request header as 314613a2f6bSGordon Ross * a template for the reply header, 315613a2f6bSGordon Ross * and don't bother clearing that bit.) 316613a2f6bSGordon Ross * 317613a2f6bSGordon Ross * Therefore, we clear that bit in 318613a2f6bSGordon Ross * our vc_hflags2 field. 319613a2f6bSGordon Ross */ 320613a2f6bSGordon Ross ctx->ct_hflags2 &= ~SMB_FLAGS2_ERR_STATUS; 321613a2f6bSGordon Ross } 322613a2f6bSGordon Ross if (dp->d_id == SMB_DIALECT_NTLM0_12 && 323613a2f6bSGordon Ross sv->sv_maxtx < 4096 && 324613a2f6bSGordon Ross (sv->sv_caps & SMB_CAP_NT_SMBS) == 0) { 325613a2f6bSGordon Ross ctx->ct_vcflags |= SMBV_WIN95; 326613a2f6bSGordon Ross DPRINT("Win95 detected"); 327613a2f6bSGordon Ross } 328613a2f6bSGordon Ross 329613a2f6bSGordon Ross /* 330613a2f6bSGordon Ross * The rest of the message varies depending on 331613a2f6bSGordon Ross * whether we've negotiated "extended security". 332613a2f6bSGordon Ross * 333613a2f6bSGordon Ross * With extended security, we have: 334613a2f6bSGordon Ross * Server_GUID (length 16) 335613a2f6bSGordon Ross * Security_BLOB 336613a2f6bSGordon Ross * Otherwise we have: 337613a2f6bSGordon Ross * EncryptionKey (length is eklen) 338613a2f6bSGordon Ross * PrimaryDomain 339613a2f6bSGordon Ross */ 340613a2f6bSGordon Ross if (sv->sv_caps & SMB_CAP_EXT_SECURITY) { 341613a2f6bSGordon Ross struct mbuf *m; 342613a2f6bSGordon Ross DPRINT("Ext.Security: yes"); 343613a2f6bSGordon Ross 344613a2f6bSGordon Ross /* 345613a2f6bSGordon Ross * Skip the server GUID. 346613a2f6bSGordon Ross */ 34702d09e03SGordon Ross err = md_get_mem(mbp, NULL, SMB_GUIDLEN, MB_MSYSTEM); 348613a2f6bSGordon Ross if (err) 349613a2f6bSGordon Ross goto errout; 350613a2f6bSGordon Ross /* 351613a2f6bSGordon Ross * Remainder is the security blob. 352613a2f6bSGordon Ross * Note: eklen "must be ignored" [MS-SMB] 353613a2f6bSGordon Ross */ 354613a2f6bSGordon Ross len = (int)bc - SMB_GUIDLEN; 355613a2f6bSGordon Ross if (len < 0) 356613a2f6bSGordon Ross goto errout; 357613a2f6bSGordon Ross 358613a2f6bSGordon Ross /* 359613a2f6bSGordon Ross * Get the (optional) SPNEGO "hint". 360613a2f6bSGordon Ross */ 36102d09e03SGordon Ross err = md_get_mbuf(mbp, len, &m); 362613a2f6bSGordon Ross if (err) 363613a2f6bSGordon Ross goto errout; 364613a2f6bSGordon Ross mb_initm(oblob, m); 365613a2f6bSGordon Ross oblob->mb_count = len; 366613a2f6bSGordon Ross } else { 367613a2f6bSGordon Ross DPRINT("Ext.Security: no"); 368613a2f6bSGordon Ross ctx->ct_hflags2 &= ~SMB_FLAGS2_EXT_SEC; 369613a2f6bSGordon Ross 370613a2f6bSGordon Ross /* 371613a2f6bSGordon Ross * Save the "Encryption Key" (the challenge). 372613a2f6bSGordon Ross * 373613a2f6bSGordon Ross * Sanity check: make sure the sec. blob length 374613a2f6bSGordon Ross * isn't bigger than the byte count. 375613a2f6bSGordon Ross */ 376613a2f6bSGordon Ross if (bc < eklen || eklen < NTLM_CHAL_SZ) { 377613a2f6bSGordon Ross err = EBADRPC; 378613a2f6bSGordon Ross goto errout; 379613a2f6bSGordon Ross } 380*85e6b674SGordon Ross err = md_get_mem(mbp, ctx->ct_srv_chal, 38102d09e03SGordon Ross NTLM_CHAL_SZ, MB_MSYSTEM); 382613a2f6bSGordon Ross /* 383613a2f6bSGordon Ross * Server domain follows (ignored) 384613a2f6bSGordon Ross * Note: NOT aligned(2) - unusual! 385613a2f6bSGordon Ross */ 386613a2f6bSGordon Ross } 387613a2f6bSGordon Ross 388613a2f6bSGordon Ross smb_rq_done(rqp); 389613a2f6bSGordon Ross 390613a2f6bSGordon Ross /* 391613a2f6bSGordon Ross * A few sanity checks on what we received, 392613a2f6bSGordon Ross * becuse we will send these in ssnsetup. 393613a2f6bSGordon Ross * 394613a2f6bSGordon Ross * Maximum outstanding requests (we care), 395613a2f6bSGordon Ross * and Max. VCs (we only use one). Also, 396613a2f6bSGordon Ross * MaxBufferSize lower limit per spec. 397613a2f6bSGordon Ross */ 398613a2f6bSGordon Ross if (sv->sv_maxmux < 1) 399613a2f6bSGordon Ross sv->sv_maxmux = 1; 400613a2f6bSGordon Ross if (sv->sv_maxvcs < 1) 401613a2f6bSGordon Ross sv->sv_maxvcs = 1; 402613a2f6bSGordon Ross if (sv->sv_maxtx < 1024) 403613a2f6bSGordon Ross sv->sv_maxtx = 1024; 404613a2f6bSGordon Ross 405613a2f6bSGordon Ross /* 406613a2f6bSGordon Ross * Maximum transfer size. 407613a2f6bSGordon Ross * Sanity checks: 408613a2f6bSGordon Ross * 409613a2f6bSGordon Ross * Let's be conservative about an upper limit here. 410613a2f6bSGordon Ross * Win2k uses 16644 (and others) so 32k should be a 411613a2f6bSGordon Ross * reasonable sanity limit for this value. 412613a2f6bSGordon Ross * 413613a2f6bSGordon Ross * Note that this limit does NOT affect READX/WRITEX 414613a2f6bSGordon Ross * with CAP_LARGE_..., which we nearly always use. 415613a2f6bSGordon Ross */ 416613a2f6bSGordon Ross is->is_txmax = sv->sv_maxtx; 417613a2f6bSGordon Ross if (is->is_txmax > 0x8000) 418613a2f6bSGordon Ross is->is_txmax = 0x8000; 419613a2f6bSGordon Ross 420613a2f6bSGordon Ross /* 421613a2f6bSGordon Ross * Max read/write sizes, WITHOUT overhead. 422613a2f6bSGordon Ross * This is just the payload size, so we must 423613a2f6bSGordon Ross * leave room for the SMB headers, etc. 424613a2f6bSGordon Ross * This is just the ct_txmax value, but 425613a2f6bSGordon Ross * reduced and rounded down. Tricky bit: 426613a2f6bSGordon Ross * 427613a2f6bSGordon Ross * Servers typically give us a value that's 428613a2f6bSGordon Ross * some nice "round" number, i.e 0x4000 plus 429613a2f6bSGordon Ross * some overhead, i.e. Win2k: 16644==0x4104 430613a2f6bSGordon Ross * Subtract for the SMB header (32) and the 431613a2f6bSGordon Ross * SMB command word and byte vectors (34?), 432613a2f6bSGordon Ross * then round down to a 512 byte multiple. 433613a2f6bSGordon Ross */ 434613a2f6bSGordon Ross len = is->is_txmax - 68; 435613a2f6bSGordon Ross len &= 0xFE00; 436613a2f6bSGordon Ross /* XXX: Not sure yet which of these to keep. */ 437613a2f6bSGordon Ross is->is_rwmax = len; 438613a2f6bSGordon Ross is->is_rxmax = len; 439613a2f6bSGordon Ross is->is_wxmax = len; 440613a2f6bSGordon Ross 441*85e6b674SGordon Ross /* 442*85e6b674SGordon Ross * Most of the "capability" bits we offer in session setup 443*85e6b674SGordon Ross * are just copied from those offered by the server. 444*85e6b674SGordon Ross */ 445*85e6b674SGordon Ross ctx->ct_clnt_caps = sv->sv_caps & smb_clnt_caps_mask; 446*85e6b674SGordon Ross 447*85e6b674SGordon Ross /* Get the client nonce. */ 448*85e6b674SGordon Ross (void) smb_get_urandom(ctx->ct_clnonce, NTLM_CHAL_SZ); 449*85e6b674SGordon Ross 450613a2f6bSGordon Ross return (0); 451613a2f6bSGordon Ross 452613a2f6bSGordon Ross errout: 453613a2f6bSGordon Ross smb_rq_done(rqp); 454613a2f6bSGordon Ross if (err == 0) 455613a2f6bSGordon Ross err = EBADRPC; 456613a2f6bSGordon Ross return (err); 457613a2f6bSGordon Ross } 458