4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Copyright (c) 2000-2001 Boris Popov
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Redistribution and use in source and binary forms, with or without
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * modification, are permitted provided that the following conditions
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * are met:
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 *
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 *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * $Id: smb_smb.c,v 1.35.100.2 2005/06/02 00:55:39 lindak Exp $
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
39f633a09e54fab2b9cf8d9d3ddc2a043b3e7465Bayard Bell * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * various SMB requests. Most of the routines merely packs data into mbufs.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/param.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/systm.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/kmem.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/proc.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/lock.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/socket.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/uio.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/random.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/note.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <sys/cmn_err.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb_osdep.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb_conn.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb_rq.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb_subr.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb_tran.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross#define STYPE_LEN 8 /* share type strings */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
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 */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#define SMB_MAX_LARGE_RW_SIZE (60*1024)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Default timeout values, all in seconds.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Make these tunable (only via mdb for now).
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint smb_timo_notice = 15;
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint smb_timo_default = 30; /* was SMB_DEFRQTIMO */
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint smb_timo_open = 45;
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint smb_timo_read = 45;
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint smb_timo_write = 60; /* was SMBWRTTIMO */
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint smb_timo_append = 90;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Rossstatic int smb_smb_read(struct smb_share *ssp, uint16_t fid,
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint32_t *lenp, uio_t *uiop, smb_cred_t *scred, int timo);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Rossstatic int smb_smb_write(struct smb_share *ssp, uint16_t fid,
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint32_t *lenp, uio_t *uiop, smb_cred_t *scred, int timo);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Rossstatic int smb_smb_readx(struct smb_share *ssp, uint16_t fid,
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint32_t *lenp, uio_t *uiop, smb_cred_t *scred, int timo);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Rossstatic int smb_smb_writex(struct smb_share *ssp, uint16_t fid,
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint32_t *lenp, uio_t *uiop, smb_cred_t *scred, int timo);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross/*
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * Get the string representation of a share "use" type,
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * as needed for the "service" in tree connect.
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross */
430b4c467020edf2445feb0c21db01c88b86243aGordon Rossstatic const char *
430b4c467020edf2445feb0c21db01c88b86243aGordon Rosssmb_share_typename(uint32_t stype)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross{
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross const char *p;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross switch (stype) {
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross case STYPE_DISKTREE:
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross p = "A:";
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross break;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross case STYPE_PRINTQ:
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross p = "LPT1:";
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross break;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross case STYPE_DEVICE:
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross p = "COMM";
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross break;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross case STYPE_IPC:
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross p = "IPC";
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross break;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross case STYPE_UNKNOWN:
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross default:
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross p = "?????";
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross break;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross }
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross return (p);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross}
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross/*
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * Parse a share type name (inverse of above)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross */
430b4c467020edf2445feb0c21db01c88b86243aGordon Rossstatic uint32_t
430b4c467020edf2445feb0c21db01c88b86243aGordon Rosssmb_share_parsetype(char *name)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross{
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross int stype;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross switch (*name) {
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross case 'A': /* A: */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross stype = STYPE_DISKTREE;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross break;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross case 'C': /* COMM */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross stype = STYPE_DEVICE;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross break;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross case 'I': /* IPC */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross stype = STYPE_IPC;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross break;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross case 'L': /* LPT: */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross stype = STYPE_PRINTQ;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross break;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross default:
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross stype = STYPE_UNKNOWN;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross break;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross }
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross return (stype);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross}
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosssmb_smb_treeconnect(struct smb_share *ssp, struct smb_cred *scred)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_vc *vcp;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_rq *rqp = NULL;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct mbchain *mbp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct mdchain *mdp;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross const char *tname;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross char *pbuf, *unc_name = NULL;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross int error, tlen, plen, unc_len;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross uint16_t bcnt, options;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross uint8_t wc;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross char stype_str[STYPE_LEN];
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross vcp = SSTOVC(ssp);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Make this a "VC-level" request, so it will have
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * rqp->sr_share == NULL, and smb_iod_sendrq()
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * will send it with TID = SMB_TID_UNKNOWN
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * This also serves to bypass the wait for
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * share state changes, which this call is
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * trying to carry out.
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = smb_rq_alloc(VCTOCP(vcp), SMB_COM_TREE_CONNECT_ANDX,
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross scred, &rqp);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross if (error)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (error);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Build the UNC name, i.e. "//server/share"
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * but with backslashes of course.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * size math: three slashes, one null.
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross unc_len = 4 + strlen(vcp->vc_srvname) + strlen(ssp->ss_name);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross unc_name = kmem_alloc(unc_len, KM_SLEEP);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross (void) snprintf(unc_name, unc_len, "\\\\%s\\%s",
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross vcp->vc_srvname, ssp->ss_name);
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross SMBSDEBUG("unc_name: \"%s\"", unc_name);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross /*
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * Share-level password (pre-computed in user-space)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * MS-SMB 2.2.6 says this should be null terminated,
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * and the pw length includes the null.
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross pbuf = ssp->ss_pass;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross plen = strlen(pbuf) + 1;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Build the request.
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mbp = &rqp->sr_rq;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_wstart(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint8(mbp, 0xff);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint8(mbp, 0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint16le(mbp, 0);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross mb_put_uint16le(mbp, 0); /* Flags */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross mb_put_uint16le(mbp, plen);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_wend(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_bstart(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Tree connect password, if any */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = mb_put_mem(mbp, pbuf, plen, MB_MSYSTEM);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (error)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* UNC resource name */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = smb_put_dstring(mbp, vcp, unc_name, SMB_CS_NONE);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (error)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Put the type string (always ASCII),
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * including the null.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross tname = smb_share_typename(ssp->ss_use);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross tlen = strlen(tname) + 1;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = mb_put_mem(mbp, tname, tlen, MB_MSYSTEM);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_bend(rqp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Run the request.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Using NOINTR_RECV because we don't want to risk
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * missing a successful tree connect response,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * which would "leak" Tree IDs.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rqp->sr_flags |= SMBR_NOINTR_RECV;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_simple(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMBSDEBUG("%d\n", error);
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross if (error) {
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross /*
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross * If we get the server name wrong, i.e. due to
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross * mis-configured name services, this will be
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross * NT_STATUS_DUPLICATE_NAME. Log this error.
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross */
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross SMBERROR("(%s) failed, status=0x%x",
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross unc_name, rqp->sr_error);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Parse the TCON response
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_rq_getreply(rqp, &mdp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross md_get_uint8(mdp, &wc);
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross if (wc != 3 && wc != 7) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = EBADRPC;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, NULL); /* AndX cmd */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, NULL); /* AndX off */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, &options); /* option bits (DFS, search) */
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross if (wc == 7) {
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross md_get_uint32le(mdp, NULL); /* MaximalShareAccessRights */
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross md_get_uint32le(mdp, NULL); /* GuestMaximalShareAcc... */
ae3d7f90695ef456a6da4f7bdccd448ebe0b99e1Gordon Ross }
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = md_get_uint16le(mdp, &bcnt); /* byte count */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * Get the returned share type string, i.e. "IPC" or whatever.
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * (See smb_share_typename, smb_share_parsetype). If we get
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * an error reading the type, just say STYPE_UNKNOWN.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross tlen = STYPE_LEN;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross bzero(stype_str, tlen--);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (tlen > bcnt)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross tlen = bcnt;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross md_get_mem(mdp, stype_str, tlen, MB_MSYSTEM);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross stype_str[tlen] = '\0';
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross ssp->ss_type = smb_share_parsetype(stype_str);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /* Success! */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_SS_LOCK(ssp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ssp->ss_tid = rqp->sr_rptid;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ssp->ss_vcgenid = vcp->vc_genid;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ssp->ss_options = options;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ssp->ss_flags |= SMBS_CONNECTED;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMB_SS_UNLOCK(ssp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossout:
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (unc_name)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross kmem_free(unc_name, unc_len);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_done(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_smb_treedisconnect(struct smb_share *ssp, struct smb_cred *scred)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_vc *vcp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_rq *rqp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int error;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (ssp->ss_tid == SMB_TID_UNKNOWN)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (0);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
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 */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow vcp = SSTOVC(ssp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(VCTOCP(vcp), SMB_COM_TREE_DISCONNECT, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow rqp->sr_share = ssp; /* by hand */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_wstart(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_wend(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_bstart(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_bend(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
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.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Also, don't reconnect for this, of course!
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross rqp->sr_flags |= (SMBR_NOINTR_SEND | SMBR_NORECONNECT);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_simple_timed(rqp, 5);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMBSDEBUG("%d\n", error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_done(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow ssp->ss_tid = SMB_TID_UNKNOWN;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross/*
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * Modern create/open of file or directory.
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross */
430b4c467020edf2445feb0c21db01c88b86243aGordon Rossint
430b4c467020edf2445feb0c21db01c88b86243aGordon Rosssmb_smb_ntcreate(
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct smb_share *ssp,
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct mbchain *name_mb,
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint32_t cr_flags, /* create flags */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint32_t req_acc, /* requested access */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint32_t efa, /* ext. file attrs (DOS attr +) */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint32_t share_acc,
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint32_t open_disp, /* open disposition */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint32_t createopt, /* NTCREATEX_OPTIONS_ */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint32_t impersonate, /* NTCREATEX_IMPERSONATION_... */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct smb_cred *scrp,
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint16_t *fidp, /* returned FID */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint32_t *cr_act_p, /* optional create action */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct smbfattr *fap) /* optional attributes */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross{
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct smb_rq rq, *rqp = &rq;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct smb_vc *vcp = SSTOVC(ssp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct mbchain *mbp;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct mdchain *mdp;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct smbfattr fa;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint64_t llongint;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint32_t longint, createact;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint16_t fid;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint8_t wc;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross int error;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross bzero(&fa, sizeof (fa));
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_NT_CREATE_ANDX, scrp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (error)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross return (error);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_getrequest(rqp, &mbp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross /* Word parameters */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_wstart(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint8(mbp, 0xff); /* secondary command */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint8(mbp, 0); /* MBZ */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint16le(mbp, 0); /* offset to next command (none) */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint8(mbp, 0); /* MBZ */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint16le(mbp, name_mb->mb_count);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint32le(mbp, cr_flags); /* NTCREATEX_FLAGS_* */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint32le(mbp, 0); /* FID - basis for path if not root */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint32le(mbp, req_acc);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint64le(mbp, 0); /* "initial allocation size" */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint32le(mbp, efa);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint32le(mbp, share_acc);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint32le(mbp, open_disp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint32le(mbp, createopt);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint32le(mbp, impersonate);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint8(mbp, 0); /* security flags (?) */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_wend(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross /*
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * Byte parameters: Just the path name, aligned.
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * Note: mb_put_mbuf consumes mb_top, so clear it.
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_bstart(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (SMB_UNICODE_STRINGS(vcp))
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_padbyte(mbp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_mbuf(mbp, name_mb->mb_top);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross bzero(name_mb, sizeof (*name_mb));
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_bend(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross /*
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * Don't want to risk missing a successful
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * open response, or we could "leak" FIDs.
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross rqp->sr_flags |= SMBR_NOINTR_RECV;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = smb_rq_simple_timed(rqp, smb_timo_open);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (error)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross goto done;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_getreply(rqp, &mdp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross /*
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * spec says 26 for word count, but 34 words are defined
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * and observed from win2000
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = md_get_uint8(mdp, &wc);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (error)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross goto done;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (wc != 26 && wc < 34) {
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = EBADRPC;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross goto done;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross }
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross md_get_uint8(mdp, NULL); /* secondary cmd */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross md_get_uint8(mdp, NULL); /* mbz */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross md_get_uint16le(mdp, NULL); /* andxoffset */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross md_get_uint8(mdp, NULL); /* oplock lvl granted */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross md_get_uint16le(mdp, &fid); /* file ID */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross md_get_uint32le(mdp, &createact); /* create_action */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross md_get_uint64le(mdp, &llongint); /* creation time */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_time_NT2local(llongint, &fa.fa_createtime);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross md_get_uint64le(mdp, &llongint); /* access time */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_time_NT2local(llongint, &fa.fa_atime);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross md_get_uint64le(mdp, &llongint); /* write time */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_time_NT2local(llongint, &fa.fa_mtime);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross md_get_uint64le(mdp, &llongint); /* change time */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_time_NT2local(llongint, &fa.fa_ctime);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross md_get_uint32le(mdp, &longint); /* attributes */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross fa.fa_attr = longint;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross md_get_uint64le(mdp, &llongint); /* allocation size */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross fa.fa_allocsz = llongint;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross md_get_uint64le(mdp, &llongint); /* EOF position */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross fa.fa_size = llongint;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = md_get_uint16le(mdp, NULL); /* file type */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross /* other stuff we don't care about */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Rossdone:
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_done(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (error)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross return (error);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross *fidp = fid;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (cr_act_p)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross *cr_act_p = createact;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (fap)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross *fap = fa; /* struct copy */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross return (0);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross}
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Rossint
430b4c467020edf2445feb0c21db01c88b86243aGordon Rosssmb_smb_close(struct smb_share *ssp, uint16_t fid, struct timespec *mtime,
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct smb_cred *scrp)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross{
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct smb_rq rq, *rqp = &rq;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct mbchain *mbp;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross long time;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross int error;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_CLOSE, scrp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (error)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross return (error);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_getrequest(rqp, &mbp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_wstart(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint16le(mbp, fid);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (mtime) {
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross int sv_tz = SSTOVC(ssp)->vc_sopt.sv_tz;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_time_local2server(mtime, sv_tz, &time);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross } else {
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross time = 0;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross }
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint32le(mbp, time);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_wend(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_bstart(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_bend(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
39f633a09e54fab2b9cf8d9d3ddc2a043b3e7465Bayard Bell /* Make sure we send, but only if already connected */
39f633a09e54fab2b9cf8d9d3ddc2a043b3e7465Bayard Bell rqp->sr_flags |= (SMBR_NOINTR_SEND | SMBR_NORECONNECT);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = smb_rq_simple(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_done(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross return (error);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross}
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Rossint
430b4c467020edf2445feb0c21db01c88b86243aGordon Rosssmb_smb_open_prjob(
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct smb_share *ssp,
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross char *title,
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint16_t setuplen,
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint16_t mode,
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct smb_cred *scrp,
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint16_t *fidp)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross{
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct smb_rq rq, *rqp = &rq;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct smb_vc *vcp = SSTOVC(ssp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct mbchain *mbp;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct mdchain *mdp;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint16_t fid;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross uint8_t wc;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross int error;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = smb_rq_init(rqp, SSTOCP(ssp), SMB_COM_OPEN_PRINT_FILE, scrp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (error)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross return (error);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_getrequest(rqp, &mbp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross /* Word parameters */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_wstart(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint16le(mbp, setuplen);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint16le(mbp, mode);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_wend(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross /*
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * Byte parameters: Just the title
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_bstart(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint8(mbp, SMB_DT_ASCII);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = smb_put_dstring(mbp, vcp, title, SMB_CS_NONE);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_bend(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (error)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross goto done;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross /*
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * Don't want to risk missing a successful
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * open response, or we could "leak" FIDs.
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross rqp->sr_flags |= SMBR_NOINTR_RECV;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = smb_rq_simple_timed(rqp, smb_timo_open);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (error)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross goto done;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_getreply(rqp, &mdp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = md_get_uint8(mdp, &wc);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (error || wc < 1) {
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = EBADRPC;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross goto done;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross }
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = md_get_uint16le(mdp, &fid);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Rossdone:
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_done(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (error)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross return (error);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross *fidp = fid;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross return (0);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross}
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross/*
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * Like smb_smb_close, but for print shares.
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross */
430b4c467020edf2445feb0c21db01c88b86243aGordon Rossint
430b4c467020edf2445feb0c21db01c88b86243aGordon Rosssmb_smb_close_prjob(struct smb_share *ssp, uint16_t fid,
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct smb_cred *scrp)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross{
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct smb_rq rq, *rqp = &rq;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross struct mbchain *mbp;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross int error;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = smb_rq_init(rqp, SSTOCP(ssp),
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross SMB_COM_CLOSE_PRINT_FILE, scrp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (error)
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross return (error);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_getrequest(rqp, &mbp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_wstart(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross mb_put_uint16le(mbp, fid);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_wend(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_bstart(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_bend(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
39f633a09e54fab2b9cf8d9d3ddc2a043b3e7465Bayard Bell /* Make sure we send but only if already connected */
39f633a09e54fab2b9cf8d9d3ddc2a043b3e7465Bayard Bell rqp->sr_flags |= (SMBR_NOINTR_SEND | SMBR_NORECONNECT);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = smb_rq_simple(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross smb_rq_done(rqp);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross return (error);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross}
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross/*
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * Common function for read/write with UIO.
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * Called by netsmb smb_usr_rw,
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * smbfs_readvnode, smbfs_writevnode
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Rossint
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Rosssmb_rwuio(struct smb_share *ssp, uint16_t fid, uio_rw_t rw,
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uio_t *uiop, smb_cred_t *scred, int timo)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_vc *vcp = SSTOVC(ssp);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross ssize_t save_resid;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint32_t len, rlen, maxlen;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross int error = 0;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross int (*iofun)(struct smb_share *, uint16_t, uint32_t *,
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uio_t *, smb_cred_t *, int);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross /*
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * Determine which function to use,
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * and the transfer size per call.
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross if (SMB_DIALECT(vcp) >= SMB_DIALECT_NTLM0_12) {
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross /*
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * Using NT LM 0.12, so readx, writex.
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * Make sure we can represent the offset.
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross if ((vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_FILES) == 0 &&
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross (uiop->uio_loffset + uiop->uio_resid) > UINT32_MAX)
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross return (EFBIG);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross if (rw == UIO_READ) {
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross iofun = smb_smb_readx;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross if (vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_READX)
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross maxlen = SMB_MAX_LARGE_RW_SIZE;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross else
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross maxlen = vcp->vc_rxmax;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross } else { /* UIO_WRITE */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross iofun = smb_smb_writex;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross if (vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_WRITEX)
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross maxlen = SMB_MAX_LARGE_RW_SIZE;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross else
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross maxlen = vcp->vc_wxmax;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross }
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross } else {
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross /*
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * Using the old SMB_READ and SMB_WRITE so
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * we're limited to 32-bit offsets, etc.
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * XXX: Someday, punt the old dialects.
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross if ((uiop->uio_loffset + uiop->uio_resid) > UINT32_MAX)
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross return (EFBIG);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross if (rw == UIO_READ) {
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross iofun = smb_smb_read;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross maxlen = vcp->vc_rxmax;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross } else { /* UIO_WRITE */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross iofun = smb_smb_write;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross maxlen = vcp->vc_wxmax;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross }
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross }
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross save_resid = uiop->uio_resid;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross while (uiop->uio_resid > 0) {
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross /* Lint: uio_resid may be 64-bits */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross rlen = len = (uint32_t)min(maxlen, uiop->uio_resid);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross error = (*iofun)(ssp, fid, &rlen, uiop, scred, timo);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross /*
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * Note: the iofun called uio_update, so
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * not doing that here as one might expect.
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross *
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * Quit the loop either on error, or if we
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * transferred less then requested.
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross if (error || (rlen < len))
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross break;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross timo = 0; /* only first I/O should wait */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross }
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross if (error && (save_resid != uiop->uio_resid)) {
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross /*
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * Stopped on an error after having
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * successfully transferred data.
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross * Suppress this error.
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross SMBSDEBUG("error %d suppressed\n", error);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross error = 0;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross }
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross return (error);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross}
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Rossstatic int
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Rosssmb_smb_readx(struct smb_share *ssp, uint16_t fid, uint32_t *lenp,
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uio_t *uiop, smb_cred_t *scred, int timo)
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_rq *rqp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct mbchain *mbp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct mdchain *mdp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int error;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint32_t offlo, offhi, rlen;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint16_t lenhi, lenlo, off, doff;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint8_t wc;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross lenhi = (uint16_t)(*lenp >> 16);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross lenlo = (uint16_t)*lenp;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross offhi = (uint32_t)(uiop->uio_loffset >> 32);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross offlo = (uint32_t)uiop->uio_loffset;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(SSTOCP(ssp), SMB_COM_READ_ANDX, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_getrequest(rqp, &mbp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_wstart(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint8(mbp, 0xff); /* no secondary command */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint8(mbp, 0); /* MBZ */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint16le(mbp, 0); /* offset to secondary */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross mb_put_uint16le(mbp, fid);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint32le(mbp, offlo); /* offset (low part) */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint16le(mbp, lenlo); /* MaxCount */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint16le(mbp, 1); /* MinCount */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross /* (only indicates blocking) */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint32le(mbp, lenhi); /* MaxCountHigh */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint16le(mbp, lenlo); /* Remaining ("obsolete") */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint32le(mbp, offhi); /* offset (high part) */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_wend(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_bstart(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_bend(rqp);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (timo == 0)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross timo = smb_timo_read;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = smb_rq_simple_timed(rqp, timo);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross smb_rq_getreply(rqp, &mdp);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = md_get_uint8(mdp, &wc);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (wc != 12) {
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = EBADRPC;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross }
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint8(mdp, NULL);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint8(mdp, NULL);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, NULL);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, NULL);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, NULL); /* data compaction mode */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, NULL);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, &lenlo); /* data len ret. */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, &doff); /* data offset */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, &lenhi);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross rlen = (lenhi << 16) | lenlo;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_mem(mdp, NULL, 4 * 2, MB_MSYSTEM);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = md_get_uint16le(mdp, NULL); /* ByteCount */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross /*
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross * Does the data offset indicate padding?
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross * The current offset is a constant, found
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross * by counting the md_get_ calls above.
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross off = SMB_HDRLEN + 3 + (12 * 2); /* =59 */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (doff > off) /* pad byte(s)? */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_mem(mdp, NULL, doff - off, MB_MSYSTEM);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (rlen == 0) {
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross *lenp = rlen;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross }
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross /* paranoid */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (rlen > *lenp) {
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross SMBSDEBUG("bad server! rlen %d, len %d\n",
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross rlen, *lenp);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross rlen = *lenp;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross }
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = md_get_uio(mdp, uiop, rlen);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross /* Success */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross *lenp = rlen;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Rossout:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_done(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic int
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Rosssmb_smb_writex(struct smb_share *ssp, uint16_t fid, uint32_t *lenp,
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uio_t *uiop, smb_cred_t *scred, int timo)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_rq *rqp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct mbchain *mbp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct mdchain *mdp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int error;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint32_t offlo, offhi, rlen;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint16_t lenhi, lenlo;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint8_t wc;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross lenhi = (uint16_t)(*lenp >> 16);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross lenlo = (uint16_t)*lenp;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross offhi = (uint32_t)(uiop->uio_loffset >> 32);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross offlo = (uint32_t)uiop->uio_loffset;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(SSTOCP(ssp), SMB_COM_WRITE_ANDX, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_getrequest(rqp, &mbp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_wstart(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint8(mbp, 0xff); /* no secondary command */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint8(mbp, 0); /* MBZ */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint16le(mbp, 0); /* offset to secondary */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross mb_put_uint16le(mbp, fid);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint32le(mbp, offlo); /* offset (low part) */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint32le(mbp, 0); /* MBZ (timeout) */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint16le(mbp, 0); /* !write-thru */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint16le(mbp, 0);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint16le(mbp, lenhi);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint16le(mbp, lenlo);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint16le(mbp, 64); /* data offset from header start */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint32le(mbp, offhi); /* offset (high part) */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_wend(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_bstart(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross mb_put_uint8(mbp, 0); /* pad byte */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = mb_put_uio(mbp, uiop, *lenp);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross smb_rq_bend(rqp);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (timo == 0)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross timo = smb_timo_write;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = smb_rq_simple_timed(rqp, timo);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross smb_rq_getreply(rqp, &mdp);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = md_get_uint8(mdp, &wc);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (wc != 6) {
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = EBADRPC;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross }
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint8(mdp, NULL); /* andx cmd */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint8(mdp, NULL); /* reserved */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, NULL); /* andx offset */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, &lenlo); /* data len ret. */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, NULL); /* remaining */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = md_get_uint16le(mdp, &lenhi);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross /* Success */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross rlen = (lenhi << 16) | lenlo;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross *lenp = rlen;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Rossout:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_done(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic int
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Rosssmb_smb_read(struct smb_share *ssp, uint16_t fid, uint32_t *lenp,
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uio_t *uiop, smb_cred_t *scred, int timo)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_rq *rqp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct mbchain *mbp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct mdchain *mdp;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross int error;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint32_t off32;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint16_t bc, cnt, dlen, rcnt, todo;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint8_t wc;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross ASSERT(uiop->uio_loffset <= UINT32_MAX);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross off32 = (uint32_t)uiop->uio_loffset;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross ASSERT(*lenp <= UINT16_MAX);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross cnt = (uint16_t)*lenp;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross /* This next is an "estimate" of planned reads. */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross todo = (uint16_t)min(uiop->uio_resid, UINT16_MAX);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(SSTOCP(ssp), SMB_COM_READ, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_getrequest(rqp, &mbp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_wstart(rqp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross mb_put_uint16le(mbp, fid);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint16le(mbp, cnt);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint32le(mbp, off32);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint16le(mbp, todo);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_wend(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_bstart(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_bend(rqp);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (timo == 0)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross timo = smb_timo_read;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = smb_rq_simple_timed(rqp, timo);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross smb_rq_getreply(rqp, &mdp);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = md_get_uint8(mdp, &wc);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (wc != 5) {
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = EBADRPC;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross }
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, &rcnt); /* ret. count */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_mem(mdp, NULL, 4 * 2, MB_MSYSTEM); /* res. */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint16le(mdp, &bc); /* byte count */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross md_get_uint8(mdp, NULL); /* buffer format */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = md_get_uint16le(mdp, &dlen); /* data len */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (dlen < rcnt) {
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross SMBSDEBUG("oops: dlen=%d rcnt=%d\n",
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross (int)dlen, (int)rcnt);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross rcnt = dlen;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross }
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (rcnt == 0) {
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross *lenp = 0;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross }
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross /* paranoid */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (rcnt > cnt) {
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross SMBSDEBUG("bad server! rcnt %d, cnt %d\n",
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross (int)rcnt, (int)cnt);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross rcnt = cnt;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross }
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = md_get_uio(mdp, uiop, (int)rcnt);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross /* success */
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross *lenp = (int)rcnt;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Rossout:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_done(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic int
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Rosssmb_smb_write(struct smb_share *ssp, uint16_t fid, uint32_t *lenp,
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uio_t *uiop, smb_cred_t *scred, int timo)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_rq *rqp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct mbchain *mbp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct mdchain *mdp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int error;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint32_t off32;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint16_t cnt, rcnt, todo;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross uint8_t wc;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross ASSERT(uiop->uio_loffset <= UINT32_MAX);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross off32 = (uint32_t)uiop->uio_loffset;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross ASSERT(*lenp <= UINT16_MAX);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross cnt = (uint16_t)*lenp;
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross /* This next is an "estimate" of planned writes. */
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross todo = (uint16_t)min(uiop->uio_resid, UINT16_MAX);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(SSTOCP(ssp), SMB_COM_WRITE, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_getrequest(rqp, &mbp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_wstart(rqp);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross mb_put_uint16le(mbp, fid);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint16le(mbp, cnt);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint32le(mbp, off32);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint16le(mbp, todo);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_wend(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_bstart(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint8(mbp, SMB_DT_DATA);
9c9af2590af49bb395bc8d2eace0f2d4ea16d165Gordon Ross mb_put_uint16le(mbp, cnt);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = mb_put_uio(mbp, uiop, *lenp);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross smb_rq_bend(rqp);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (timo == 0)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross timo = smb_timo_write;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = smb_rq_simple_timed(rqp, timo);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross smb_rq_getreply(rqp, &mdp);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = md_get_uint8(mdp, &wc);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (wc != 1) {
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = EBADRPC;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross }
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross error = md_get_uint16le(mdp, &rcnt);
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross if (error)
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross goto out;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross *lenp = rcnt;
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Ross
02d09e03eb27f3a2dc299de704e45dae5173f43fGordon Rossout:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_done(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowstatic u_int32_t smbechoes = 0;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowint
4bff34e37def8a90f9194d81bc345c52ba20086athurlowsmb_smb_echo(struct smb_vc *vcp, struct smb_cred *scred, int timo)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct smb_rq *rqp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow struct mbchain *mbp;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow int error;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_alloc(VCTOCP(vcp), SMB_COM_ECHO, scred, &rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow if (error)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mbp = &rqp->sr_rq;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_wstart(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint16le(mbp, 1); /* echo count */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_wend(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_bstart(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow mb_put_uint32le(mbp, atomic_inc_32_nv(&smbechoes));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_bend(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow /*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Note: the IOD calls this, so
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * this request must not wait for
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * connection state changes, etc.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross rqp->sr_flags |= SMBR_NORECONNECT;
4bff34e37def8a90f9194d81bc345c52ba20086athurlow error = smb_rq_simple_timed(rqp, timo);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow SMBSDEBUG("%d\n", error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow smb_rq_done(rqp);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow return (error);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}