smb_smb.c revision 4bff34e37def8a90f9194d81bc345c52ba20086a
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Copyright (c) 2000-2001 Boris Popov
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Redistribution and use in source and binary forms, with or without
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * modification, are permitted provided that the following conditions
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 1. Redistributions of source code must retain the above copyright
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * notice, this list of conditions and the following disclaimer.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 2. Redistributions in binary form must reproduce the above copyright
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * notice, this list of conditions and the following disclaimer in the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * documentation and/or other materials provided with the distribution.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 3. All advertising materials mentioning features or use of this software
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * must display the following acknowledgement:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This product includes software developed by Boris Popov.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 4. Neither the name of the author nor the names of any co-contributors
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * may be used to endorse or promote products derived from this software
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * without specific prior written permission.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * SUCH DAMAGE.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * $Id: smb_smb.c,v 1.35.100.2 2005/06/02 00:55:39 lindak Exp $
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Use is subject to license terms.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#pragma ident "%Z%%M% %I% %E% SMI"
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * various SMB requests. Most of the routines merely packs data into mbufs.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Largest size to use with LARGE_READ/LARGE_WRITE.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Specs say up to 64k data bytes, but Windows traffic
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * uses 60k... no doubt for some good reason.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * (Probably to keep 4k block alignment.)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * XXX: Move to smb.h maybe?
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Default timeout values, all in seconds.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Make these tunable (only via mdb for now).
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic int smb_smb_read(struct smb_share *ssp, u_int16_t fid,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int *len, int *rresid, uio_t *uiop, struct smb_cred *scred, int timo);
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic int smb_smb_write(struct smb_share *ssp, u_int16_t fid,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int *len, int *rresid, uio_t *uiop, struct smb_cred *scred, int timo);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow const char *d_name;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow (sizeof (smb_dialects) / sizeof (struct smb_dialect) - 2)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Number of seconds between 1970 and 1601 year
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_time_local2server(struct timespec *tsp, int tzoff, long *seconds)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * XXX - what if we connected to the server when it was in
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * daylight savings/summer time and we've subsequently switched
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * to standard time, or vice versa, so that the time zone
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * offset we got from the server is now wrong?
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* - tz.tz_minuteswest * 60 - (wall_cmos_clock ? adjkerntz : 0) */
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_time_server2local(ulong_t seconds, int tzoff, struct timespec *tsp)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * XXX - what if we connected to the server when it was in
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * daylight savings/summer time and we've subsequently switched
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * to standard time, or vice versa, so that the time zone
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * offset we got from the server is now wrong?
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* + tz.tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0); */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Time from server comes as UTC, so no need to use tz
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*ARGSUSED*/
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_time_NT2local(u_int64_t nsec, int tzoff, struct timespec *tsp)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_time_server2local(nsec / 10000000 - DIFF1970TO1601, 0, tsp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*ARGSUSED*/
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_time_local2NT(struct timespec *tsp, int tzoff, u_int64_t *nsec)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *nsec = (((u_int64_t)(seconds) & ~1) + DIFF1970TO1601) *
4bff34e37def8a90f9194d81bc345c52ba20086athurlowextern int iconv_open(const char *to, const char *from, void **handle);
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_smb_negotiate(struct smb_vc *vcp, struct smb_cred *scred)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow vcp->vc_hflags = SMB_FLAGS_CASELESS; /* XXX on Unix? */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Make sure SMB_FLAGS2_UNICODE is "off" so mb_put_dstring
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * marshalls the dialect strings in plain ascii.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(VCTOCP(vcp), SMB_COM_NEGOTIATE, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This request should not wait for
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * connection state changes, etc.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow "Don't know how to talk with server %s (%d)\n",
4bff34e37def8a90f9194d81bc345c52ba20086athurlow "Server %s negotiated old dialect (%s)\n",
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMBSDEBUG("Dialect %s (%d, %d)\n", dp->d_name, dindex, wc);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow "packet signing, which we dont support: "
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * They don't do NT error codes.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * If we send requests with
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * SMB_FLAGS2_ERR_STATUS set in
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Flags2, Windows 98, at least,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * appears to send replies with that
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * bit set even though it sends back
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * DOS error codes. (They probably
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * just use the request header as
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * a template for the reply header,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * and don't bother clearing that bit.)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Therefore, we clear that bit in
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * our vc_hflags2 field.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 3 cases here:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 1) Extended security.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Read bc bytes below for security blob.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Note that we DON'T put the Caps flag in outtok.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * outtoklen = bc
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 2) No extended security, have challenge data and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * possibly a domain name (which might be zero
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * bytes long, meaning "missing").
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Copy challenge stuff to vcp->vc_ch (sblen bytes),
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * then copy Cap flags and domain name (bc-sblen
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * bytes) to outtok.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * outtoklen = bc-sblen+4, where the 4 is for the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Caps flag.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 3) No extended security, no challenge data, just
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * possibly a domain name.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Copy Capsflags and domain name (bc) to outtok.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * outtoklen = bc+4, where 4 is for the Caps flag
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Sanity check: make sure the challenge length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * isn't bigger than the byte count.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * For servers that don't support unicode
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * there are 2 things we could do:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 1) Pass the server Caps flags up to the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * user level so the logic up there will
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * know whether the domain name is unicode
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * (this is what I did).
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 2) Try to convert the non-unicode string
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * to unicode. This doubles the length of
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * the outtok buffer and would be guessing that
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * the string was single-byte ascii, and that
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * might be wrong. Why ask for trouble?
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Warning: NetApp may omit the GUID */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * No extended security.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Stick domain name, if present,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * and caps in outtok.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* first store server capability bits */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Then store the domain name if present;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * be sure to subtract 4 from the length
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * for the Caps flag.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Extended security.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Stick the rest of the buffer in outtok.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow vcp->vc_hflags2 &= ~(SMB_FLAGS2_EXT_SEC|SMB_FLAGS2_DFS|
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } else { /* an old CORE protocol */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } while (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error == 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Maximum outstanding requests.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Max VCs between server and client.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We only use one.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Maximum transfer size.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Sanity checks:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Spec. says lower limit is 1024. OK.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Let's be conservative about an upper limit here.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Win2k uses 16644 (and others) so 32k should be a
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * reasonable sanity limit for this value.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Note that this limit does NOT affect READX/WRITEX
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * with CAP_LARGE_xxx, which we nearly always use.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Max read/write sizes, WITHOUT overhead.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This is just the payload size, so we must
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * leave room for the SMB headers, etc.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * With CAP_LARGE_xxx, always use 60k.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Otherwise use the vc_txmax value, but
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * reduced and rounded down. Tricky bit:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Servers typically give us a value that's
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * some nice "round" number, i.e 0x4000 plus
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * some overhead, i.e. Win2k: 16644==0x4104
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Subtract for the SMB header (32) and the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * SMB command word and byte vectors (34?),
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * then round down to a 512 byte multiple.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * If the server supports Unicode, set up to use Unicode
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * when talking to them. Othewise, use code page 437.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * todo: if we can't determine the server's encoding, we
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * need to try a best-guess here.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = iconv_open(servercs, "utf-8", &servercshandle);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = iconv_open("utf-8", servercs, &localcshandle);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error != 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlowget_ascii_password(struct smb_vc *vcp, int upper, char *pbuf)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow strncpy(pbuf, smb_vc_getpass(vcp), SMB_MAXPASSWORDLEN);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*ARGSUSED*/
4bff34e37def8a90f9194d81bc345c52ba20086athurlowadd_name_to_blob(uchar_t *blobnames, struct smb_vc *vcp, const uchar_t *name,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow uninamelen = smb_strtouni(uninamebuf, namebuf, namelen,
4bff34e37def8a90f9194d81bc345c52ba20086athurlowmake_ntlmv2_blob(struct smb_vc *vcp, u_int64_t client_nonce, size_t *bloblen)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * XXX - the information at
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * http://davenport.sourceforge.net/ntlm.html#theNtlmv2Response
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * says that the "target information" comes from the Type 2 message,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * but, as we're not doing NTLMSSP, we don't have that.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Should we use the names from the NegProt response? Can we trust
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * the NegProt response? (I've seen captures where the primary
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * domain name has an extra byte in front of it.)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * For now, we don't trust it - we use vcp->vc_domain and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * vcp->vc_srvname, instead. We upper-case them and convert
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * them to Unicode, as that's what's supposed to be in the blob.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow + 3*sizeof (struct ntlmv2_namehdr) + 4 + 2*domainlen + 2*srvlen;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ASSERT(blob == (uchar_t *)((struct ntlmv2_blobhdr *)blob));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow blobnames = add_name_to_blob(blobnames, vcp, (uchar_t *)vcp->vc_domain,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow blobnames = add_name_to_blob(blobnames, vcp, (uchar_t *)vcp->vc_srvname,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow blobnames = add_name_to_blob(blobnames, vcp, NULL, 0, NAMETYPE_EOL, 0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * See radar 4134676. This define helps us avoid how a certain old server
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * grants limited Guest access when we try NTLMv2, but works fine with NTLM.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * The fingerprint we are looking for here is DOS error codes and no-Unicode.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Note XP grants Guest access but uses Unicode and NT error codes.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#define smb_antique(rqp) (!((rqp)->sr_rpflags2 & SMB_FLAGS2_ERR_STATUS) && \
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * When not doing Kerberos, we can try, in order:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * NTLM with the ASCII password not upper-cased
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * NTLM with the ASCII password upper-cased
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * if the server supports encrypted passwords, or
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * plain-text with the ASCII password not upper-cased
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * plain-text with the ASCII password upper-cased
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * if it doesn't.
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_smb_ssnsetup(struct smb_vc *vcp, struct smb_cred *scred)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow char *pp = NULL, *up = NULL, *ucup = NULL, *ucdp = NULL;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Most of the "capability" bits we offer should be copied
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * from those offered by the server, with a mask applied.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This is the mask of capabilies copied from the server.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Some others get special handling below.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* No unicode unless server supports and encryption on */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Try only plain text passwords.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow state = STATE_NOUCPW; /* try plain-text mixed-case first */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We're not doing extended security, which, for
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * now, means we're not doing Kerberos.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Fail if the minimum authentication level is
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Kerberos.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Server wants encrypted passwords.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We tried NTLMv2 in STATE_NTLMV2.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Shall we allow fallback? (to NTLM)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We tried NTLM in STATE_NOUCPW.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * No need to try it again.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Plain-text passwords.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Fail if the minimum authentication level is
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * LM or better.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(VCTOCP(vcp), SMB_COM_SESSION_SETUP_ANDX,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Domain name must be upper-case, as that's what's used
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * when computing LMv2 and NTLMv2 responses - and, for NTLMv2,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * the domain name in the request has to be upper-cased as well.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * (That appears not to be the case for the user name. Go
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * don't need to uppercase domain string. It's already uppercase UTF-8.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * In the share security mode password will be used
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * only in the tree authentication
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbuf = kmem_alloc(SMB_MAXPASSWORDLEN + 1, KM_SLEEP);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Compute the LMv2 and NTLMv2 responses,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * derived from the challenge, the user name,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * the domain/workgroup into which we're
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * logging, and the Unicode password.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Construct the client nonce by getting
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * a bunch of random data.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Convert the user name to upper-case, as
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * that's what's used when computing LMv2
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * and NTLMv2 responses.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Compute the LMv2 response, derived
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * from the server challenge, the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * user name, the domain/workgroup
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * into which we're logging, the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * client nonce, and the NT hash.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Construct the blob.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Compute the NTLMv2 response, derived
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * from the server challenge, the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * user name, the domain/workgroup
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * into which we're logging, the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * blob, and the NT hash.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow sizeof (struct ntlmv2_blobhdr) +
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Compute the LM response, derived
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * from the challenge and the ASCII
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * password.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Compute the NTLM response, derived from
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * the challenge and the NT hash.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We try w/o uppercasing first so Samba mixed case
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * passwords work. If that fails, we come back and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * try uppercasing to satisfy OS/2 and Windows for
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Workgroups.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow get_ascii_password(vcp, (state == STATE_UCPW), pbuf);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * The uniplen is zeroed because Samba cannot deal
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * with this 2nd cleartext password. This Samba
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * "bug" is actually a workaround for problems in
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Microsoft clients.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * If userid is null we are attempting anonymous browse login
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * so passwords must be zero length.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_put_dstring(mbp, vcp, up, SMB_CS_NONE); /* user */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_put_dstring(mbp, vcp, ucdp, SMB_CS_NONE); /* domain */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_mem(mbp, pp, plen, MB_MSYSTEM); /* password */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_mem(mbp, (caddr_t)unipp, uniplen, MB_MSYSTEM);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_put_dstring(mbp, vcp, up, SMB_CS_NONE); /* user */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_put_dstring(mbp, vcp, ucdp, SMB_CS_NONE); /* dom */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_put_dstring(mbp, vcp, NativeOS, SMB_CS_NONE); /* OS */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_put_dstring(mbp, vcp, LanMan, SMB_CS_NONE); /* LAN Mgr */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This request should not wait for
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * connection state changes, etc.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (rqp->sr_errclass == ERRDOS && rqp->sr_serror == ERRnoaccess)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = md_get_mem(mdp, vcp->vc_outtok, bl, MB_MSYSTEM);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* server OS, LANMGR, & Domain here */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } while (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (vcp->vc_sopt.sv_sm & SMB_SM_USER && !vcp->vc_intok &&
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We're doing user-level authentication (so we are actually
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * sending authentication stuff over the wire), and we're
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * not doing extended security, and the stuff we tried
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * failed (or we we're trying to login a real user but
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * got granted guest access instead.)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Should we try the next type of authentication?
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Yes, we still have more to try.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMBERROR("we declined ntlmv2 guest access. errno will be %d\n",
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Restore things we changed and return */
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_smb_ssnclose(struct smb_vc *vcp, struct smb_cred *scred)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(VCTOCP(vcp), SMB_COM_LOGOFF_ANDX, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Run this with a relatively short timeout.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We don't really care about the result,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * as we're just trying to play nice and
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * "say goodbye" before we hangup.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * XXX: Add SMBLOGOFFTIMO somewhere?
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic char *
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_smb_treeconnect(struct smb_share *ssp, struct smb_cred *scred)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow const char *pw;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Make this a "VC-level" request, so it will have
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * rqp->sr_share == NULL, and smb_iod_sendrq()
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * will send it with TID = SMB_TID_UNKNOWN
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This also serves to bypass the wait for
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * share state changes, which this call is
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * trying to carry out.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * No longer need to set ssp->ss_tid
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * here, but it's harmless enough.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(VCTOCP(vcp), SMB_COM_TREE_CONNECT_ANDX,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow pbuf = kmem_alloc(SMB_MAXPASSWORDLEN + 1, KM_SLEEP);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We try w/o uppercasing first so Samba mixed case
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * passwords work. If that fails we come back and try
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * uppercasing to satisfy OS/2 and Windows for Workgroups.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We need to convert here to the server codeset.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Initially we will send the same stuff and see what happens
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * witout the conversion. REVISIT.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow iconv_convstr(vcp->vc_toserver, pbuf, pbuf, SMB_MAXPASSWORDLEN);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMBSDEBUG("error %d from mb_put_mem for pp\n", error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_put_dmem(mbp, vcp, pp, strlen(pp), caseopt, NULL);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMBSDEBUG("error %d from smb_put_dmem for srvname\n", error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMBSDEBUG("error %d from smb_put_dstring for ss_name\n", error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* The type name is always ASCII */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = mb_put_mem(mbp, pp, strlen(pp) + 1, MB_MSYSTEM);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMBSDEBUG("error %d from mb_put_mem for ss_type\n", error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Don't want to risk missing a successful
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * tree connect response.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Success! */
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_smb_treedisconnect(struct smb_share *ssp, struct smb_cred *scred)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Build this as a "VC-level" request, so it will
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * avoid testing the _GONE flag on the share,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * which has already been set at this point.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Add the share pointer "by hand" below, so
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * smb_iod_sendrq will plug in the TID.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(VCTOCP(vcp), SMB_COM_TREE_DISCONNECT, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Run this with a relatively short timeout. (5 sec.)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We don't really care about the result here, but we
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * do need to make sure we send this out, or we could
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * "leak" active tree IDs on interrupt or timeout.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * The NOINTR_SEND flag makes this request immune to
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * interrupt or timeout until the send is done.
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_smb_readx(struct smb_share *ssp, u_int16_t fid, int *len, int *rresid,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ((vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_READX) == 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Fall back to the old cmd. */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ((vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_FILES) == 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Have ReadX but not large files? */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(SSTOCP(ssp), SMB_COM_READ_ANDX, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_mem(mbp, (caddr_t)&fid, sizeof (fid), MB_MSYSTEM);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint32le(mbp, (u_int32_t)(uiop->uio_offset));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint16le(mbp, (u_int16_t)*len); /* MaxCount */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint16le(mbp, (u_int16_t)*len); /* MinCount */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* (only indicates blocking) */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint32le(mbp, (unsigned)*len >> 16); /* MaxCountHigh */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint16le(mbp, (u_int16_t)*len); /* Remaining ("obsolete") */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint32le(mbp, (u_int32_t)((uiop->uio_loffset) >> 32));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow md_get_uint16le(mdp, NULL); /* data compaction mode */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (resid == 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } while (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_smb_writex(struct smb_share *ssp, u_int16_t fid, int *len, int *rresid,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ((vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_WRITEX) == 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Fall back to the old cmd. */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ((vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_FILES) == 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Have WriteX but not large files? */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(SSTOCP(ssp), SMB_COM_WRITE_ANDX, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_mem(mbp, (caddr_t)&fid, sizeof (fid), MB_MSYSTEM);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint32le(mbp, (u_int32_t)(uiop->uio_offset));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint16le(mbp, (u_int16_t)((unsigned)*len >> 16));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint16le(mbp, 64); /* data offset from header start */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint32le(mbp, (u_int32_t)((uiop->uio_loffset) >> 32));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow md_get_uint16le(mdp, &resid); /* actually is # written */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * if LARGE_WRITEX then there's one more bit of # written
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if ((vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_WRITEX)) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } while (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_smb_read(struct smb_share *ssp, u_int16_t fid, int *len, int *rresid,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* This cmd is limited to 32-bit offsets. */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(SSTOCP(ssp), SMB_COM_READ, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_mem(mbp, (caddr_t)&fid, sizeof (fid), MB_MSYSTEM);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint16le(mbp, (u_int16_t)min(uiop->uio_resid, 0xffff));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (resid == 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } while (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_smb_write(struct smb_share *ssp, u_int16_t fid, int *len, int *rresid,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* This cmd is limited to 32-bit offsets. */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(SSTOCP(ssp), SMB_COM_WRITE, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_mem(mbp, (caddr_t)&fid, sizeof (fid), MB_MSYSTEM);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint16le(mbp, (u_int16_t)min(uiop->uio_resid, 0xffff));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow } while (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Common function for read/write with UIO.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Called by netsmb smb_usr_rw,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * smbfs_readvnode, smbfs_writevnode
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_rwuio(struct smb_share *ssp, u_int16_t fid, uio_rw_t rw,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow while (tsize > 0) {
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Lint: tsize may be 64-bits */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_smb_writex(ssp, fid, &len, &resid, uiop,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Errors can happen in copyin/copyout, the rpc, etc. so
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * they imply resid is unreliable. The only safe thing is
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * to pretend zero bytes made it. We needn't restore the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * iovs because callers don't depend on them in error
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * paths - uio_resid and uio_offset are what matter.
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_smb_echo(struct smb_vc *vcp, struct smb_cred *scred, int timo)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(VCTOCP(vcp), SMB_COM_ECHO, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Note: the IOD calls this, so
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * this request must not wait for
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * connection state changes, etc.
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_smb_checkdir(struct smb_share *ssp, void *dnp, char *name,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(SSTOCP(ssp), SMB_COM_CHECK_DIRECTORY, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * All we need to do is marshall the path: "\\"
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * (the root of the share) into this request.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * We essentially in-line smbfs_fullpath() here,
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * except no mb_put_padbyte (already aligned).
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_put_dstring(mbp, SSTOVC(ssp), "\\", SMB_CS_NONE);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#endif /* APPLE */