summaryrefslogtreecommitdiff
path: root/usr/src/lib/libsmbfs/smb/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libsmbfs/smb/file.c')
-rw-r--r--usr/src/lib/libsmbfs/smb/file.c211
1 files changed, 72 insertions, 139 deletions
diff --git a/usr/src/lib/libsmbfs/smb/file.c b/usr/src/lib/libsmbfs/smb/file.c
index 3c8184e8a1..1c09532d61 100644
--- a/usr/src/lib/libsmbfs/smb/file.c
+++ b/usr/src/lib/libsmbfs/smb/file.c
@@ -33,6 +33,7 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -62,133 +63,66 @@
#include "private.h"
int
-smb_fh_close(struct smb_ctx *ctx, int fh)
+smb_fh_close(int fd)
{
- struct smb_rq *rqp;
- struct mbdata *mbp;
- int error;
-
- error = smb_rq_init(ctx, SMB_COM_CLOSE, &rqp);
- if (error != 0)
- return (error);
- mbp = smb_rq_getrequest(rqp);
- smb_rq_wstart(rqp);
- mb_put_uint16le(mbp, (uint16_t)fh);
- mb_put_uint32le(mbp, 0); /* time stamp */
- smb_rq_wend(rqp);
- mb_put_uint16le(mbp, 0); /* byte count */
-
- error = smb_rq_simple(rqp);
- smb_rq_done(rqp);
-
- return (error);
+ return (close(fd));
}
int
smb_fh_ntcreate(
struct smb_ctx *ctx, char *path,
- int flags, int req_acc, int efattr,
- int share_acc, int open_disp,
- int create_opts, int impersonation,
- int *fhp, uint32_t *action_taken)
+ int req_acc, int efattr, int share_acc,
+ int open_disp, int create_opts)
{
- struct smb_rq *rqp;
- struct mbdata *mbp;
- char *pathsizep;
- int pathstart, pathsize;
- int error, flags2, uc;
- uint16_t fh;
- uint8_t wc;
-
- flags2 = smb_ctx_flags2(ctx);
- if (flags2 == -1)
- return (EIO);
- uc = flags2 & SMB_FLAGS2_UNICODE;
-
- error = smb_rq_init(ctx, SMB_COM_NT_CREATE_ANDX, &rqp);
- if (error != 0)
- return (error);
-
- mbp = smb_rq_getrequest(rqp);
- smb_rq_wstart(rqp);
- mb_put_uint16le(mbp, 0xff); /* secondary command */
- mb_put_uint16le(mbp, 0); /* offset to next command (none) */
- mb_put_uint8(mbp, 0); /* MBZ (pad?) */
- (void) mb_fit(mbp, 2, &pathsizep); /* path size - fill in below */
- mb_put_uint32le(mbp, flags); /* create flags (oplock) */
- mb_put_uint32le(mbp, 0); /* FID - basis for path if not root */
- mb_put_uint32le(mbp, req_acc);
- mb_put_uint64le(mbp, 0); /* initial alloc. size */
- mb_put_uint32le(mbp, efattr); /* ext. file attributes */
- mb_put_uint32le(mbp, share_acc); /* share access mode */
- mb_put_uint32le(mbp, open_disp); /* open disposition */
- mb_put_uint32le(mbp, create_opts); /* create_options */
- mb_put_uint32le(mbp, impersonation);
- mb_put_uint8(mbp, 0); /* security flags (?) */
- smb_rq_wend(rqp);
- smb_rq_bstart(rqp);
- if (uc) {
- /*
- * We're about to put a unicode string. We know
- * we're misaligned at this point, and need to
- * save the mb_count at the start of the string,
- * not at the alignment padding placed before it.
- * So add the algnment padding by hand here.
- */
- mb_put_uint8(mbp, 0);
+ smbioc_ntcreate_t ioc;
+ int err, nmlen;
+ int new_fd = -1;
+ int32_t from_fd;
+
+ nmlen = strlen(path);
+ if (nmlen >= SMBIOC_MAX_NAME) {
+ err = EINVAL;
+ goto errout;
}
- pathstart = mbp->mb_count;
- mb_put_string(mbp, path, uc);
- smb_rq_bend(rqp);
-
- /* Now go back and fill in pathsizep */
- pathsize = mbp->mb_count - pathstart;
- pathsizep[0] = pathsize & 0xFF;
- pathsizep[1] = (pathsize >> 8);
-
- error = smb_rq_simple(rqp);
- if (error)
- goto out;
- mbp = smb_rq_getreply(rqp);
/*
- * spec says 26 for word count, but 34 words are defined
- * and observed from win2000
+ * Will represent this SMB-level open as a new
+ * open device handle. Get one, then duplicate
+ * the driver session and tree bindings.
*/
- error = md_get_uint8(mbp, &wc);
- if (error || wc < 26) {
- smb_error(dgettext(TEXT_DOMAIN,
- "%s: open failed, bad word count"), 0, path);
- error = EBADRPC;
- goto out;
+ new_fd = smb_open_driver();
+ if (new_fd < 0) {
+ err = errno;
+ goto errout;
+ }
+ from_fd = ctx->ct_dev_fd;
+ if (ioctl(new_fd, SMBIOC_DUP_DEV, &from_fd) == -1) {
+ err = errno;
+ goto errout;
}
- md_get_uint8(mbp, NULL); /* secondary cmd */
- md_get_uint8(mbp, NULL); /* mbz */
- md_get_uint16le(mbp, NULL); /* andxoffset */
- md_get_uint8(mbp, NULL); /* oplock lvl granted */
- md_get_uint16le(mbp, &fh); /* FID */
- md_get_uint32le(mbp, action_taken);
-#if 0 /* skip decoding the rest */
- md_get_uint64le(mbp, NULL); /* creation time */
- md_get_uint64le(mbp, NULL); /* access time */
- md_get_uint64le(mbp, NULL); /* write time */
- md_get_uint64le(mbp, NULL); /* change time */
- md_get_uint32le(mbp, NULL); /* attributes */
- md_get_uint64le(mbp, NULL); /* allocation size */
- md_get_uint64le(mbp, NULL); /* EOF */
- md_get_uint16le(mbp, NULL); /* file type */
- md_get_uint16le(mbp, NULL); /* device state */
- md_get_uint8(mbp, NULL); /* directory (boolean) */
-#endif
- /* success! */
- *fhp = fh;
- error = 0;
+ /*
+ * Do the SMB-level open with the new dev handle.
+ */
+ bzero(&ioc, sizeof (ioc));
+ strlcpy(ioc.ioc_name, path, SMBIOC_MAX_NAME);
+ ioc.ioc_req_acc = req_acc;
+ ioc.ioc_efattr = efattr;
+ ioc.ioc_share_acc = share_acc;
+ ioc.ioc_open_disp = open_disp;
+ ioc.ioc_creat_opts = create_opts;
+ if (ioctl(new_fd, SMBIOC_NTCREATE, &ioc) == -1) {
+ err = errno;
+ goto errout;
+ }
-out:
- smb_rq_done(rqp);
+ return (new_fd);
- return (error);
+errout:
+ if (new_fd != -1)
+ close(new_fd);
+ errno = err;
+ return (-1);
}
/*
@@ -196,10 +130,21 @@ out:
* Converts Unix-style open call to NTCreate.
*/
int
-smb_fh_open(struct smb_ctx *ctx, const char *path, int oflag, int *fhp)
+smb_fh_open(struct smb_ctx *ctx, const char *path, int oflag)
{
- int error, mode, open_disp, req_acc, share_acc;
+ int mode, open_disp, req_acc, share_acc;
char *p, *ntpath = NULL;
+ int fd = -1;
+
+ /*
+ * Convert Unix path to NT (backslashes)
+ */
+ ntpath = strdup(path);
+ if (ntpath == NULL)
+ return (-1); /* errno was set */
+ for (p = ntpath; *p; p++)
+ if (*p == '/')
+ *p = '\\';
/*
* Map O_RDONLY, O_WRONLY, O_RDWR
@@ -250,55 +195,43 @@ smb_fh_open(struct smb_ctx *ctx, const char *path, int oflag, int *fhp)
open_disp = NTCREATEX_DISP_OPEN;
}
- /*
- * Convert Unix path to NT (backslashes)
- */
- ntpath = strdup(path);
- if (ntpath == NULL)
- return (ENOMEM);
- for (p = ntpath; *p; p++)
- if (*p == '/')
- *p = '\\';
-
- error = smb_fh_ntcreate(ctx, ntpath, 0, /* flags */
+ fd = smb_fh_ntcreate(ctx, ntpath,
req_acc, SMB_EFA_NORMAL, share_acc, open_disp,
- NTCREATEX_OPTIONS_NON_DIRECTORY_FILE,
- NTCREATEX_IMPERSONATION_IMPERSONATION,
- fhp, NULL);
- free(ntpath);
+ NTCREATEX_OPTIONS_NON_DIRECTORY_FILE);
- return (error);
+ free(ntpath);
+ return (fd);
}
int
-smb_fh_read(struct smb_ctx *ctx, int fh, off_t offset, size_t count,
+smb_fh_read(int fd, off_t offset, size_t count,
char *dst)
{
struct smbioc_rw rwrq;
bzero(&rwrq, sizeof (rwrq));
- rwrq.ioc_fh = fh;
+ rwrq.ioc_fh = -1; /* tell driver to supply this */
rwrq.ioc_base = dst;
rwrq.ioc_cnt = count;
rwrq.ioc_offset = offset;
- if (ioctl(ctx->ct_dev_fd, SMBIOC_READ, &rwrq) == -1) {
+ if (ioctl(fd, SMBIOC_READ, &rwrq) == -1) {
return (-1);
}
return (rwrq.ioc_cnt);
}
int
-smb_fh_write(struct smb_ctx *ctx, int fh, off_t offset, size_t count,
+smb_fh_write(int fd, off_t offset, size_t count,
const char *src)
{
struct smbioc_rw rwrq;
bzero(&rwrq, sizeof (rwrq));
- rwrq.ioc_fh = fh;
+ rwrq.ioc_fh = -1; /* tell driver to supply this */
rwrq.ioc_base = (char *)src;
rwrq.ioc_cnt = count;
rwrq.ioc_offset = offset;
- if (ioctl(ctx->ct_dev_fd, SMBIOC_WRITE, &rwrq) == -1) {
+ if (ioctl(fd, SMBIOC_WRITE, &rwrq) == -1) {
return (-1);
}
return (rwrq.ioc_cnt);
@@ -313,7 +246,7 @@ smb_fh_write(struct smb_ctx *ctx, int fh, off_t offset, size_t count,
* and on output *rdlen is the received length.
*/
int
-smb_fh_xactnp(struct smb_ctx *ctx, int fh,
+smb_fh_xactnp(int fd,
int tdlen, const char *tdata, /* transmit */
int *rdlen, char *rdata, /* receive */
int *more)
@@ -322,10 +255,10 @@ smb_fh_xactnp(struct smb_ctx *ctx, int fh,
uint16_t setup[2];
setup[0] = TRANS_TRANSACT_NAMED_PIPE;
- setup[1] = fh;
+ setup[1] = 0xFFFF; /* driver replaces this */
rparamcnt = 0;
- err = smb_t2_request(ctx, 2, setup, "\\PIPE\\",
+ err = smb_t2_request(fd, 2, setup, "\\PIPE\\",
0, NULL, /* TX paramcnt, params */
tdlen, (void *)tdata,
&rparamcnt, NULL, /* no RX params */