/*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2000, Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: rq.c,v 1.4 2004/12/13 00:25:23 lindak Exp $
*/
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <stdlib.h>
#include <sysexits.h>
#include <libintl.h>
#include "private.h"
/*
* Create and initialize a request structure, for either an
* "internal" request (one that does not use the driver) or
* a regular "driver" request, that uses driver ioctls.
*
* The two kinds are built a little differently:
* Driver requests are composed starting with the
* first word of the "variable word vector" section.
* The driver prepends the SMB header and word count.
* The driver also needs an output buffer to receive
* the response, filled in via copyout in the ioctl.
*
* Internal requests are composed entirely in this library.
* Space for the SMB header is reserved here, and later
*/
int
{
goto errout;
/*
* Setup the request buffer.
* Do the reply buffer later.
*/
goto errout;
/* Space for the SMB header. (filled in later) */
/*
* Copy the ctx flags here, so the caller can
* update the req flags before the OTW call.
*/
return (0);
if (rqp) {
}
return (ENOMEM);
}
void
{
}
/*
* Reserve space for the word count, which is filled in later by
* smb_rq_wend(). Also initialize the counter that it uses
* to figure out what value to fill in.
*
* Note that the word count happens to be 8-bits,
* which can lead to confusion.
*/
void
{
}
/*
* Fill in the word count, in the space reserved by
* smb_rq_wstart().
*/
void
{
int wcnt;
DPRINT("no wcount ptr\n");
return;
}
if (wcnt > 0x1ff)
if (wcnt & 1)
DPRINT("odd word count\n");
wcnt >>= 1;
/*
* Fill in the word count (8-bits).
* Also store it in the rq, in case
* we're using the ioctl path.
*/
}
/*
* Reserve space for the byte count, which is filled in later by
* smb_rq_bend(). Also initialize the counter that it uses
* to figure out what value to fill in.
*
* Note that the byte count happens to be 16-bits,
* which can lead to confusion.
*/
void
{
}
/*
* Fill in the byte count, in the space reserved by
* smb_rq_bstart().
*/
void
{
int bcnt;
DPRINT("no bcount ptr\n");
return;
}
if (bcnt > 0xffff)
/*
* Fill in the byte count (16-bits).
* Also store it in the rq, in case
* we're using the ioctl path.
*
* The pointer is char * type due to
* typical off-by-one alignment.
*/
}
int
{
mbuf_t *m;
char *data;
int error;
/*
* Make the SMB request body contiguous,
* and fill in the ioctl request.
*/
if (error)
return (error);
/*
* _rq_init left space for the SMB header,
* which makes mb_count the offset from
* the beginning of the header (useful).
* However, in this code path the driver
* prepends the header, so we skip it.
*/
/*
* Setup a buffer to hold the reply,
* at least MIN_REPLY_SIZE, or larger
* if the caller increased rq_rpbufsz.
*/
if (rpbufsz < MIN_REPLY_SIZE)
return (error);
/*
* Call the driver
*/
return (errno);
/*
* Initialize returned mbdata.
* SMB header already parsed.
*/
return (0);
}
int
const char *name,
int *buffer_oflow)
{
int i;
/* Bogus setup count, or too many setup words */
return (EINVAL);
}
for (i = 0; i < setupcount; i++)
return (errno);
}
return (0);
}
/*
* Do an over-the-wire call without using the nsmb driver.
* This is all "internal" to this library, and used only
* for connection setup (negotiate protocol, etc.)
*/
int
{
/*
* Fill in the NBT and SMB headers
* Using mbtmp so we can rewind without
* affecting the passed request mbdata.
*/
/* Have to save and restore m_len */
/*
* rewind done; fill it in
*/
/* pid_hi(2), signature(8), reserved(2) */
/* Restore original m_len */
/*
* Sign the message, if flags2 indicates.
*/
}
/*
* Send it, wait for the reply.
*/
return (err);
return (err);
/*
* Should have an SMB header, at least.
*/
DPRINT("len < 32");
return (EBADRPC);
}
/*
* If the request was signed, validate the
* signature on the response.
*/
if (err) {
DPRINT("bad signature");
return (err);
}
}
/*
* Decode the SMB header.
*/
DPRINT("not SMB");
return (EBADRPC);
}
/* pid_hi(2), signature(8), reserved(2) */
/*
* Figure out the status return.
* Caller looks at rq_status.
*/
}
return (0);
}
/*
* Map old DOS errors (etc.) to NT status codes.
* We probably don't need this anymore, since
* the oldest server we talk to is NT. But if
* later find we do need this, add support here
* for the DOS errors we care about.
*/
static uint32_t
{
return (0);
return (NT_STATUS_UNSUCCESSFUL);
}