summaryrefslogtreecommitdiff
path: root/usr/src/lib/libsmbfs
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libsmbfs')
-rw-r--r--usr/src/lib/libsmbfs/Makefile.com5
-rw-r--r--usr/src/lib/libsmbfs/netsmb/nb_lib.h59
-rw-r--r--usr/src/lib/libsmbfs/netsmb/smb_lib.h136
-rw-r--r--usr/src/lib/libsmbfs/netsmb/smb_rap.h12
-rw-r--r--usr/src/lib/libsmbfs/smb/acl_api.c3
-rw-r--r--usr/src/lib/libsmbfs/smb/acl_conv.c77
-rw-r--r--usr/src/lib/libsmbfs/smb/charsets.c173
-rw-r--r--usr/src/lib/libsmbfs/smb/charsets.h5
-rw-r--r--usr/src/lib/libsmbfs/smb/ctx.c66
-rw-r--r--usr/src/lib/libsmbfs/smb/file.c265
-rw-r--r--usr/src/lib/libsmbfs/smb/mapfile-vers56
-rw-r--r--usr/src/lib/libsmbfs/smb/mbuf.c49
-rw-r--r--usr/src/lib/libsmbfs/smb/nb_name.c3
-rw-r--r--usr/src/lib/libsmbfs/smb/nb_net.c126
-rw-r--r--usr/src/lib/libsmbfs/smb/nbns_rq.c36
-rw-r--r--usr/src/lib/libsmbfs/smb/netshareenum.c68
-rw-r--r--usr/src/lib/libsmbfs/smb/print.c3
-rw-r--r--usr/src/lib/libsmbfs/smb/private.h154
-rw-r--r--usr/src/lib/libsmbfs/smb/rap.c50
-rw-r--r--usr/src/lib/libsmbfs/smb/rcfile.c18
-rw-r--r--usr/src/lib/libsmbfs/smb/rq.c11
-rw-r--r--usr/src/lib/libsmbfs/smb/subr.c83
-rw-r--r--usr/src/lib/libsmbfs/smb/utf_str.c207
23 files changed, 961 insertions, 704 deletions
diff --git a/usr/src/lib/libsmbfs/Makefile.com b/usr/src/lib/libsmbfs/Makefile.com
index 9ffc1634ef..a2232234de 100644
--- a/usr/src/lib/libsmbfs/Makefile.com
+++ b/usr/src/lib/libsmbfs/Makefile.com
@@ -22,8 +22,6 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
# lib/libsmbfs/Makefile.com
LIBRARY= libsmbfs.a
@@ -55,7 +53,8 @@ OBJECTS=\
spnego.o \
spnegoparse.o \
subr.o \
- ui-sun.o
+ ui-sun.o \
+ utf_str.o
include $(SRC)/lib/Makefile.lib
diff --git a/usr/src/lib/libsmbfs/netsmb/nb_lib.h b/usr/src/lib/libsmbfs/netsmb/nb_lib.h
index 1c4100e17a..d2403edf75 100644
--- a/usr/src/lib/libsmbfs/netsmb/nb_lib.h
+++ b/usr/src/lib/libsmbfs/netsmb/nb_lib.h
@@ -32,11 +32,14 @@
* $Id: nb_lib.h,v 1.4 2004/12/11 05:23:58 lindak Exp $
*/
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
#ifndef _NETSMB_NB_LIB_H_
#define _NETSMB_NB_LIB_H_
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Error codes
*/
@@ -98,69 +101,17 @@ typedef struct nbns_nr nbns_nr_t;
#define NBNS_GROUPFLG 0x8000
-/*
- * nbns request
- */
-struct nbns_rq {
- int nr_opcode;
- int nr_nmflags;
- int nr_rcode;
- int nr_qdcount;
- int nr_ancount;
- int nr_nscount;
- int nr_arcount;
- struct nb_name *nr_qdname;
- uint16_t nr_qdtype;
- uint16_t nr_qdclass;
- struct in_addr nr_dest; /* receiver of query */
- struct sockaddr_in nr_sender; /* sender of response */
- int nr_rpnmflags;
- int nr_rprcode;
- uint16_t nr_rpancount;
- uint16_t nr_rpnscount;
- uint16_t nr_rparcount;
- uint16_t nr_trnid;
- struct nb_ctx *nr_nbd;
- struct mbdata nr_rq;
- struct mbdata nr_rp;
- struct nb_ifdesc *nr_if;
- int nr_flags;
- int nr_fd;
- int nr_maxretry;
-};
-typedef struct nbns_rq nbns_rq_t;
-
-struct nb_ifdesc {
- int id_flags;
- struct in_addr id_addr;
- struct in_addr id_mask;
- char id_name[16]; /* actually IFNAMSIZ */
- struct nb_ifdesc *id_next;
-};
-typedef struct nb_ifdesc nb_ifdesc_t;
-
struct sockaddr;
#ifdef __cplusplus
extern "C" {
#endif
-int nb_name_len(struct nb_name *);
-/* new flag UCflag. 1=uppercase,0=don't */
-int nb_name_encode(struct nb_name *, uchar_t *);
-int nb_encname_len(const uchar_t *);
-
-int nb_snballoc(int namelen, struct sockaddr_nb **);
-void nb_snbfree(struct sockaddr *);
-int nb_sockaddr(struct sockaddr *, struct nb_name *, struct sockaddr_nb **);
-
int nb_resolvehost_in(const char *, struct sockaddr **);
int nbns_resolvename(const char *, struct nb_ctx *, struct sockaddr **);
int nbns_getnodestatus(struct sockaddr *targethost,
struct nb_ctx *ctx, char *system, char *workgroup);
int nb_getlocalname(char *name, size_t maxlen);
-int nb_enum_if(struct nb_ifdesc **);
-
const char *nb_strerror(int error);
int nb_ctx_create(struct nb_ctx **);
diff --git a/usr/src/lib/libsmbfs/netsmb/smb_lib.h b/usr/src/lib/libsmbfs/netsmb/smb_lib.h
index 7756ce2638..bec4a1c0b5 100644
--- a/usr/src/lib/libsmbfs/netsmb/smb_lib.h
+++ b/usr/src/lib/libsmbfs/netsmb/smb_lib.h
@@ -32,11 +32,14 @@
* $Id: smb_lib.h,v 1.21.82.2 2005/06/02 00:55:39 lindak Exp $
*/
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
#ifndef _NETSMB_SMB_LIB_H_
#define _NETSMB_SMB_LIB_H_
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -65,47 +68,6 @@
#define SMB_NB_ERROR 0x20000
/*
- * These get/set macros do not handle mis-aligned data.
- * The data are all supposed to be aligned, but that's
- * up to the server. If we ever encounter a server that
- * doesn't obey this rule, a "strict alignment" client
- * (i.e. SPARC) may get an alignment trap in one of these.
- * If that ever happens, make these macros into functions
- * that can handle mis-aligned data. (Or catch traps.)
- */
-#define getb(buf, ofs) (((const uint8_t *)(buf))[ofs])
-#define setb(buf, ofs, val) (((uint8_t *)(buf))[ofs]) = val
-#define getbw(buf, ofs) ((uint16_t)(getb(buf, ofs)))
-#define getw(buf, ofs) (*((uint16_t *)(&((uint8_t *)(buf))[ofs])))
-#define getdw(buf, ofs) (*((uint32_t *)(&((uint8_t *)(buf))[ofs])))
-
-#ifdef _LITTLE_ENDIAN
-
-#define getwle(buf, ofs) (*((uint16_t *)(&((uint8_t *)(buf))[ofs])))
-#define getdle(buf, ofs) (*((uint32_t *)(&((uint8_t *)(buf))[ofs])))
-#define getwbe(buf, ofs) (ntohs(getwle(buf, ofs)))
-#define getdbe(buf, ofs) (ntohl(getdle(buf, ofs)))
-
-#define setwle(buf, ofs, val) getwle(buf, ofs) = val
-#define setwbe(buf, ofs, val) getwle(buf, ofs) = htons(val)
-#define setdle(buf, ofs, val) getdle(buf, ofs) = val
-#define setdbe(buf, ofs, val) getdle(buf, ofs) = htonl(val)
-
-#else /* _LITTLE_ENDIAN */
-
-#define getwbe(buf, ofs) (*((uint16_t *)(&((uint8_t *)(buf))[ofs])))
-#define getdbe(buf, ofs) (*((uint32_t *)(&((uint8_t *)(buf))[ofs])))
-#define getwle(buf, ofs) (BSWAP_16(getwbe(buf, ofs)))
-#define getdle(buf, ofs) (BSWAP_32(getdbe(buf, ofs)))
-
-#define setwbe(buf, ofs, val) getwbe(buf, ofs) = val
-#define setwle(buf, ofs, val) getwbe(buf, ofs) = BSWAP_16(val)
-#define setdbe(buf, ofs, val) getdbe(buf, ofs) = val
-#define setdle(buf, ofs, val) getdbe(buf, ofs) = BSWAP_32(val)
-
-#endif /* _LITTLE_ENDIAN */
-
-/*
* SMB work context. Used to store all values which are necessary
* to establish connection to an SMB server.
*/
@@ -124,11 +86,6 @@ struct smb_ctx {
struct smbioc_oshare ct_sh;
char *ct_origshare;
char *ct_home;
-#ifdef APPLE
- /* temporary automount hack */
- char **ct_xxx;
- int ct_maxxxx; /* max # to mount (-x arg) */
-#endif
void *ct_secblob;
int ct_secbloblen;
/* krb5 stuff: all anonymous struct pointers here. */
@@ -181,18 +138,6 @@ typedef struct smb_ctx smb_ctx_t;
#define SMB_ST_MAX STYPE_UNKNOWN
#define SMB_ST_NONE 0xff /* not a part of protocol */
-
-/*
- * request handling structures
- */
-struct mbuf {
- int m_len;
- int m_maxlen;
- char *m_data;
- struct mbuf *m_next;
-};
-typedef struct mbuf mbuf_t;
-
struct mbdata {
struct mbuf *mb_top;
struct mbuf *mb_cur;
@@ -201,24 +146,6 @@ struct mbdata {
};
typedef struct mbdata mbdata_t;
-#define M_ALIGNFACTOR (sizeof (long))
-#define M_ALIGN(len) (((len) + M_ALIGNFACTOR - 1) & ~(M_ALIGNFACTOR - 1))
-#define M_BASESIZE (sizeof (struct mbuf))
-#define M_MINSIZE (256 - M_BASESIZE)
-#define M_TOP(m) ((char *)(m) + M_BASESIZE)
-#define M_TRAILINGSPACE(m) ((m)->m_maxlen - (m)->m_len)
-#define mtod(m, t) ((t)(m)->m_data)
-
-struct smb_rq {
- uchar_t rq_cmd;
- struct mbdata rq_rq;
- struct mbdata rq_rp;
- struct smb_ctx *rq_ctx;
- int rq_wcount;
- int rq_bcount;
-};
-typedef struct smb_rq smb_rq_t;
-
struct smb_bitname {
uint_t bn_bit;
char *bn_name;
@@ -232,8 +159,6 @@ extern struct rcfile *smb_rc;
extern "C" {
#endif
-struct sockaddr;
-
int smb_lib_init(void);
int smb_open_driver(void);
int smb_open_rcfile(struct smb_ctx *ctx);
@@ -269,18 +194,14 @@ int smb_ctx_flags2(struct smb_ctx *);
int smb_smb_open_print_file(struct smb_ctx *, int, int, const char *, smbfh*);
int smb_smb_close_print_file(struct smb_ctx *, smbfh);
-int smb_read(struct smb_ctx *, smbfh, off_t, size_t, char *);
-int smb_write(struct smb_ctx *, smbfh, off_t, size_t, const char *);
-
-#define smb_rq_getrequest(rqp) (&(rqp)->rq_rq)
-#define smb_rq_getreply(rqp) (&(rqp)->rq_rp)
-
-int smb_rq_init(struct smb_ctx *, uchar_t, size_t, struct smb_rq **);
-void smb_rq_done(struct smb_rq *);
-void smb_rq_wend(struct smb_rq *);
-int smb_rq_simple(struct smb_rq *);
-int smb_rq_dmem(struct mbdata *, const char *, size_t);
-int smb_rq_dstring(struct mbdata *, const char *);
+typedef void (*smb_ctx_close_hook_t)(struct smb_ctx *);
+void smb_ctx_set_close_hook(smb_ctx_close_hook_t);
+int smb_fh_close(struct smb_ctx *ctx, smbfh fh);
+int smb_fh_open(struct smb_ctx *ctx, const char *, int, smbfh *);
+int smb_fh_read(struct smb_ctx *, smbfh, off_t, size_t, char *);
+int smb_fh_write(struct smb_ctx *, smbfh, off_t, size_t, const char *);
+int smb_fh_xactnp(struct smb_ctx *, smbfh, int, const char *,
+ int *, char *, int *);
int smb_t2_request(struct smb_ctx *, int, uint16_t *, const char *,
int, void *, int, void *, int *, void *, int *, void *, int *);
@@ -288,37 +209,6 @@ int smb_t2_request(struct smb_ctx *, int, uint16_t *, const char *,
void smb_simplecrypt(char *dst, const char *src);
int smb_simpledecrypt(char *dst, const char *src);
-int m_getm(struct mbuf *, size_t, struct mbuf **);
-int m_lineup(struct mbuf *, struct mbuf **);
-int mb_init(struct mbdata *, size_t);
-int mb_initm(struct mbdata *, struct mbuf *);
-int mb_done(struct mbdata *);
-int mb_fit(struct mbdata *mbp, size_t size, char **pp);
-int mb_put_uint8(struct mbdata *, uint8_t);
-int mb_put_uint16be(struct mbdata *, uint16_t);
-int mb_put_uint16le(struct mbdata *, uint16_t);
-int mb_put_uint32be(struct mbdata *, uint32_t);
-int mb_put_uint32le(struct mbdata *, uint32_t);
-int mb_put_uint64be(struct mbdata *, uint64_t);
-int mb_put_uint64le(struct mbdata *, uint64_t);
-int mb_put_mem(struct mbdata *, const char *, size_t);
-int mb_put_pstring(struct mbdata *mbp, const char *s);
-int mb_put_mbuf(struct mbdata *, struct mbuf *);
-
-int mb_get_uint8(struct mbdata *, uint8_t *);
-int mb_get_uint16(struct mbdata *, uint16_t *);
-int mb_get_uint16le(struct mbdata *, uint16_t *);
-int mb_get_uint16be(struct mbdata *, uint16_t *);
-int mb_get_uint32(struct mbdata *, uint32_t *);
-int mb_get_uint32be(struct mbdata *, uint32_t *);
-int mb_get_uint32le(struct mbdata *, uint32_t *);
-int mb_get_uint64(struct mbdata *, uint64_t *);
-int mb_get_uint64be(struct mbdata *, uint64_t *);
-int mb_get_uint64le(struct mbdata *, uint64_t *);
-int mb_get_mem(struct mbdata *, char *, size_t);
-
-extern uchar_t nls_lower[256], nls_upper[256];
-
int nls_setrecode(const char *, const char *);
int nls_setlocale(const char *);
char *nls_str_toext(char *, const char *);
diff --git a/usr/src/lib/libsmbfs/netsmb/smb_rap.h b/usr/src/lib/libsmbfs/netsmb/smb_rap.h
index 118861f633..bb85ef0f17 100644
--- a/usr/src/lib/libsmbfs/netsmb/smb_rap.h
+++ b/usr/src/lib/libsmbfs/netsmb/smb_rap.h
@@ -35,8 +35,6 @@
#ifndef _NETSMB_SMB_RAP_H_
#define _NETSMB_SMB_RAP_H_
-#pragma ident "%Z%%M% %I% %E% SMI"
-
struct smb_rap {
char *r_sparam;
char *r_nparam;
@@ -54,13 +52,6 @@ struct smb_rap {
int r_entries;
};
-struct smb_share_info_1 {
- char shi1_netname[13];
- char shi1_pad;
- uint16_t shi1_type;
- uint32_t shi1_remark; /* char * */
-};
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -70,10 +61,9 @@ void smb_rap_done(struct smb_rap *);
int smb_rap_request(struct smb_rap *, struct smb_ctx *);
int smb_rap_setNparam(struct smb_rap *, int);
int smb_rap_setPparam(struct smb_rap *, void *);
+int smb_rap_getNparam(struct smb_rap *, long *);
int smb_rap_error(struct smb_rap *, int);
-int smb_rap_NetShareEnum(struct smb_ctx *, int, void *, int *, int *, int *);
-
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/libsmbfs/smb/acl_api.c b/usr/src/lib/libsmbfs/smb/acl_api.c
index 2dc024e086..6c8552e75a 100644
--- a/usr/src/lib/libsmbfs/smb/acl_api.c
+++ b/usr/src/lib/libsmbfs/smb/acl_api.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* ACL API for smbfs
*/
@@ -54,6 +52,7 @@
#include <netsmb/smb_lib.h>
#include <netsmb/smbfs_acl.h>
#include <netsmb/smbfs_isec.h>
+#include "private.h"
/* Sanity check SD sizes */
#define MAX_RAW_SD_SIZE 32768
diff --git a/usr/src/lib/libsmbfs/smb/acl_conv.c b/usr/src/lib/libsmbfs/smb/acl_conv.c
index 2073bf47f5..ec77c8f3c5 100644
--- a/usr/src/lib/libsmbfs/smb/acl_conv.c
+++ b/usr/src/lib/libsmbfs/smb/acl_conv.c
@@ -24,8 +24,6 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* ACL support for smbfs
*
@@ -59,6 +57,8 @@
#include <netsmb/smb_lib.h>
#include <netsmb/smbfs_acl.h>
#include <netsmb/smbfs_isec.h>
+#include <netsmb/mchain.h>
+#include "private.h"
#ifdef _KERNEL
#define MALLOC(size) kmem_alloc(size, KM_SLEEP)
@@ -179,6 +179,7 @@ ifree_ace(i_ntace_t *ace)
static int
mb_get_ace(mbdata_t *mbp, i_ntace_t **acep)
{
+ mbdata_t tmp_mb;
i_ntace_t *ace = NULL;
uint16_t ace_len;
int error;
@@ -187,13 +188,28 @@ mb_get_ace(mbdata_t *mbp, i_ntace_t **acep)
return (ENOMEM);
bzero(ace, sizeof (*ace));
- ERRCHK(mb_get_uint8(mbp, &ace->ace_type));
- ERRCHK(mb_get_uint8(mbp, &ace->ace_flags));
- ERRCHK(mb_get_uint16le(mbp, &ace_len));
- ERRCHK(mb_get_uint32le(mbp, &ace->ace_rights));
+ /*
+ * The ACE is realy variable length,
+ * with format determined by the type.
+ * XXX: This only decodes types 0-7
+ *
+ * There may also be padding after it, so
+ * decode the using a copy of the mbdata,
+ * and then consume the specified length.
+ */
+ tmp_mb = *mbp;
+
+ /* Fixed-size header */
+ ERRCHK(mb_get_uint8(&tmp_mb, &ace->ace_type));
+ ERRCHK(mb_get_uint8(&tmp_mb, &ace->ace_flags));
+ ERRCHK(mb_get_uint16le(&tmp_mb, &ace_len));
- ERRCHK(mb_get_sid(mbp, &ace->ace_sid));
- /* XXX: consume any ace_len not used? */
+ /* Variable-size body */
+ ERRCHK(mb_get_uint32le(&tmp_mb, &ace->ace_rights));
+ ERRCHK(mb_get_sid(&tmp_mb, &ace->ace_sid));
+
+ /* Now actually consume ace_len */
+ ERRCHK(mb_get_mem(mbp, NULL, ace_len));
/* Success! */
*acep = ace;
@@ -208,8 +224,7 @@ static int
mb_put_ace(mbdata_t *mbp, i_ntace_t *ace)
{
int cnt0, error;
- char *ace_len_p;
- uint16_t ace_len;
+ uint16_t ace_len, *ace_len_p;
if (ace == NULL)
return (EINVAL);
@@ -218,14 +233,13 @@ mb_put_ace(mbdata_t *mbp, i_ntace_t *ace)
ERRCHK(mb_put_uint8(mbp, ace->ace_type));
ERRCHK(mb_put_uint8(mbp, ace->ace_flags));
- ERRCHK(mb_fit(mbp, 2, &ace_len_p));
+ ERRCHK(mb_fit(mbp, 2, (char **)&ace_len_p));
ERRCHK(mb_put_uint32le(mbp, ace->ace_rights));
ERRCHK(mb_put_sid(mbp, ace->ace_sid));
ace_len = mbp->mb_count - cnt0;
- /* LINTED */
- setwle(ace_len_p, 0, ace_len);
+ *ace_len_p = htoles(ace_len);
/* Success! */
return (0);
@@ -295,7 +309,10 @@ mb_get_acl(mbdata_t *mbp, i_ntacl_t **aclp)
ERRCHK(mb_get_ace(mbp, acep));
acep++;
}
- /* XXX: consume any acl_len not used? */
+ /*
+ * There may be more data here, but
+ * the caller takes care of that.
+ */
/* Success! */
*aclp = acl;
@@ -311,8 +328,7 @@ mb_put_acl(mbdata_t *mbp, i_ntacl_t *acl)
{
i_ntace_t **acep;
uint8_t revision;
- char *acl_len_p;
- uint16_t acl_len;
+ uint16_t acl_len, *acl_len_p;
uint32_t *subauthp;
size_t aclsz;
int i, cnt0, error;
@@ -321,7 +337,7 @@ mb_put_acl(mbdata_t *mbp, i_ntacl_t *acl)
ERRCHK(mb_put_uint8(mbp, acl->acl_revision));
ERRCHK(mb_put_uint8(mbp, 0)); /* pad1 */
- ERRCHK(mb_fit(mbp, 2, &acl_len_p));
+ ERRCHK(mb_fit(mbp, 2, (char **)&acl_len_p));
ERRCHK(mb_put_uint16le(mbp, acl->acl_acecount));
ERRCHK(mb_put_uint16le(mbp, 0)); /* pad2 */
@@ -333,8 +349,7 @@ mb_put_acl(mbdata_t *mbp, i_ntacl_t *acl)
/* Fill in acl_len_p */
acl_len = mbp->mb_count - cnt0;
- /* LINTED */
- setwle(acl_len_p, 0, acl_len);
+ *acl_len_p = htoles(acl_len);
/* Success! */
return (0);
@@ -441,7 +456,7 @@ errout:
int
mb_put_ntsd(mbdata_t *mbp, i_ntsd_t *sd)
{
- char *owneroffp, *groupoffp, *sacloffp, *dacloffp;
+ uint32_t *owneroffp, *groupoffp, *sacloffp, *dacloffp;
uint32_t owneroff, groupoff, sacloff, dacloff;
int cnt0, error;
@@ -451,10 +466,10 @@ mb_put_ntsd(mbdata_t *mbp, i_ntsd_t *sd)
ERRCHK(mb_put_uint8(mbp, sd->sd_revision));
ERRCHK(mb_put_uint8(mbp, 0)); /* pad1 */
ERRCHK(mb_put_uint16le(mbp, sd->sd_flags));
- ERRCHK(mb_fit(mbp, 4, &owneroffp));
- ERRCHK(mb_fit(mbp, 4, &groupoffp));
- ERRCHK(mb_fit(mbp, 4, &sacloffp));
- ERRCHK(mb_fit(mbp, 4, &dacloffp));
+ ERRCHK(mb_fit(mbp, 4, (char **)&owneroffp));
+ ERRCHK(mb_fit(mbp, 4, (char **)&groupoffp));
+ ERRCHK(mb_fit(mbp, 4, (char **)&sacloffp));
+ ERRCHK(mb_fit(mbp, 4, (char **)&dacloffp));
/*
* These could be marshalled in any order, but
@@ -478,14 +493,10 @@ mb_put_ntsd(mbdata_t *mbp, i_ntsd_t *sd)
}
/* Fill in the offsets */
- /* LINTED */
- setdle(owneroffp, 0, owneroff);
- /* LINTED */
- setdle(groupoffp, 0, groupoff);
- /* LINTED */
- setdle(sacloffp, 0, sacloff);
- /* LINTED */
- setdle(dacloffp, 0, dacloff);
+ *owneroffp = htolel(owneroff);
+ *groupoffp = htolel(groupoff);
+ *sacloffp = htolel(sacloff);
+ *dacloffp = htolel(dacloff);
/* Success! */
return (0);
@@ -816,7 +827,7 @@ smbfs_acl_sd2zfs(
idms = I_GetMappings(idmap_gh);
if (idms != IDMAP_SUCCESS) {
#ifdef DEBUG
- printf("idmap_get_mappings: rc=%d\n", rc);
+ printf("idmap_get_mappings: rc=%d\n", idms);
#endif
/* creative error choice */
error = EIDRM;
diff --git a/usr/src/lib/libsmbfs/smb/charsets.c b/usr/src/lib/libsmbfs/smb/charsets.c
index 7000be5416..81075a3a2f 100644
--- a/usr/src/lib/libsmbfs/smb/charsets.c
+++ b/usr/src/lib/libsmbfs/smb/charsets.c
@@ -21,7 +21,9 @@
*
* @APPLE_LICENSE_HEADER_END@
*/
-/* @(#)charsets.c *
+/* CSTYLED */
+/*
+ * @(#)charsets.c *
* (c) 2004 Apple Computer, Inc. All Rights Reserved
*
*
@@ -33,32 +35,20 @@
* 28-Nov-2004 Guy Harris New today
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
+#include <errno.h>
#include <iconv.h>
#include <langinfo.h>
#include <strings.h>
-#ifdef NOTPORTED
-#include <CoreFoundation/CoreFoundation.h>
-#include <CoreFoundation/CFStringDefaultEncoding.h>
-#include <CoreFoundation/CFStringEncodingConverter.h>
-#include <sys/mchain.h>
-#endif /* NOTPORTED */
-
#include <netsmb/smb_lib.h>
#include <netsmb/mchain.h>
#include "charsets.h"
-#ifdef NOTPORTED
-extern uid_t real_uid,eff_uid;
-#endif /* NOTPORTED */
-
/*
* On Solaris, we will need to do some rewriting to use our iconv
* routines for the conversions. For now, we're effectively
@@ -69,43 +59,47 @@ extern uid_t real_uid,eff_uid;
static unsigned
xtoi(char u)
{
- if (isdigit(u))
- return (u - '0');
- else if (islower(u))
- return (10 + u - 'a');
- else if (isupper(u))
- return (10 + u - 'A');
- return (16);
+ if (isdigit(u))
+ return (u - '0');
+ else if (islower(u))
+ return (10 + u - 'a');
+ else if (isupper(u))
+ return (10 + u - 'A');
+ return (16);
}
-/* Removes the "%" escape sequences from a URL component.
+/*
+ * Removes the "%" escape sequences from a URL component.
* See IETF RFC 2396.
*/
char *
-unpercent(char * component)
+unpercent(char *component)
{
- char c, *s;
- unsigned hi, lo;
+ char c, *s;
+ unsigned hi, lo;
- if (component)
- for (s = component; (c = *s) != 0; s++) {
- if (c != '%')
- continue;
- if ((hi = xtoi(s[1])) > 15 || (lo = xtoi(s[2])) > 15)
- continue; /* ignore invalid escapes */
- s[0] = hi*16 + lo;
- /*
- * This was strcpy(s + 1, s + 3);
- * But nowadays leftward overlapping copies are
- * officially undefined in C. Ours seems to
- * work or not depending upon alignment.
- */
- memmove(s+1, s+3, strlen(s+3) + 1);
- }
- return (component);
+ if (component == NULL)
+ return (component);
+
+ for (s = component; (c = *s) != 0; s++) {
+ if (c != '%')
+ continue;
+ if ((hi = xtoi(s[1])) > 15 || (lo = xtoi(s[2])) > 15)
+ continue; /* ignore invalid escapes */
+ s[0] = hi*16 + lo;
+ /*
+ * This was strcpy(s + 1, s + 3);
+ * But nowadays leftward overlapping copies are
+ * officially undefined in C. Ours seems to
+ * work or not depending upon alignment.
+ */
+ memmove(s+1, s+3, strlen(s+3) + 1);
+ }
+ return (component);
}
+/* BEGIN CSTYLED */
#ifdef NOTPORTED
static CFStringEncoding
get_windows_encoding_equivalent( void )
@@ -247,7 +241,7 @@ convert_wincs_to_utf8(const char *windows_string)
CFRelease(s);
return result;
#else /* NOTPORTED */
- return ((char*)windows_string);
+ return (strdup((char*)windows_string));
#endif /* NOTPORTED */
}
@@ -290,96 +284,15 @@ convert_utf8_to_wincs(const char *utf8_string)
CFRelease(s);
return result;
#else /* NOTPORTED */
- return ((char*)utf8_string);
+ return (strdup((char*)utf8_string));
#endif /* NOTPORTED */
}
+/* END CSTYLED */
/*
- * Convert little-endian Unicode string to UTF-8.
- * Converts the Unicode string to host byte order in place.
- */
-char *
-convert_leunicode_to_utf8(unsigned short *unicode_string)
-{
- unsigned short *unicode_charp, unicode_char;
- int len = 0;
-
- for (unicode_charp = unicode_string;
- (unicode_char = *unicode_charp) != 0;
- unicode_charp++) {
- *unicode_charp = letohs(unicode_char);
- len = len + 2;
- }
- return (convert_unicode_to_utf8(unicode_string, len));
-}
-
-char *
-convert_unicode_to_utf8(unsigned short *unicode_string, int len)
-{
- iconv_t cd;
- char from[BUFSIZ], to[BUFSIZ];
- char *tptr = NULL;
- const char *fptr;
- size_t ileft, oleft, ret;
-
- cd = iconv_open("UTF-8", "UTF-16");
- if (cd != (iconv_t)-1) {
- ileft = len;
- bcopy((char *)unicode_string, from, ileft);
- fptr = from;
- oleft = BUFSIZ;
- tptr = to;
- ret = iconv(cd, &fptr, &ileft, &tptr, &oleft);
- if (ret != (size_t)-1) {
- to[BUFSIZ-oleft] = '\0';
- tptr = to;
- } else {
- tptr = NULL;
- }
- (void) iconv_close(cd);
- }
- return (tptr);
-}
-
-/*
- * Convert UTF-8 string to little-endian Unicode.
+ * We replaced these routines for Solaris:
+ * convert_leunicode_to_utf8
+ * convert_unicode_to_utf8
+ * convert_utf8_to_leunicode
+ * with new code in: utf_str.c
*/
-unsigned short *
-convert_utf8_to_leunicode(const char *utf8_string)
-{
-#ifdef NOTPORTED
- CFStringRef s;
- CFIndex maxlen;
- unsigned short *result;
- CFRange range;
- int i;
-
- s = CFStringCreateWithCString(NULL, utf8_string,
- kCFStringEncodingUTF8);
- if (s == NULL) {
- smb_error("CFStringCreateWithCString for UTF-8 failed on \"%s\"", -1,
- utf8_string);
- return NULL;
- }
-
- maxlen = CFStringGetLength(s);
- result = malloc(2*(maxlen + 1));
- if (result == NULL) {
- smb_error("Couldn't allocate buffer for Unicode string for \"%s\" - skipping", -1,
- utf8_string);
- CFRelease(s);
- return NULL;
- }
- range.location = 0;
- range.length = maxlen;
- CFStringGetCharacters(s, range, result);
- for (i = 0; i < maxlen; i++)
- result[i] = CFSwapInt16HostToLittle(result[i]);
- result[maxlen] = 0;
- CFRelease(s);
- return result;
-#else /* NOTPORTED */
- /* LINTED */ /* XXX Really need to fix this! */
- return ((ushort_t *)utf8_string); /* XXX */
-#endif /* NOTPORTED */
-}
diff --git a/usr/src/lib/libsmbfs/smb/charsets.h b/usr/src/lib/libsmbfs/smb/charsets.h
index 5518afc783..c754425f37 100644
--- a/usr/src/lib/libsmbfs/smb/charsets.h
+++ b/usr/src/lib/libsmbfs/smb/charsets.h
@@ -34,15 +34,14 @@
* 28-Nov-2004 Guy Harris New today
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifndef __CHARSETS_H__
#define __CHARSETS_H__
extern char *convert_wincs_to_utf8(const char *windows_string);
extern char *convert_utf8_to_wincs(const char *utf8_string);
extern char *convert_leunicode_to_utf8(unsigned short *windows_string);
-extern char *convert_unicode_to_utf8(unsigned short *windows_string, int len);
+extern char *convert_unicode_to_utf8(unsigned short *windows_string);
extern unsigned short *convert_utf8_to_leunicode(const char *utf8_string);
+extern size_t unicode_strlen(const uint16_t *unicode_string);
#endif /* __CHARSETS_H__ */
diff --git a/usr/src/lib/libsmbfs/smb/ctx.c b/usr/src/lib/libsmbfs/smb/ctx.c
index ae79686869..dfc86bd191 100644
--- a/usr/src/lib/libsmbfs/smb/ctx.c
+++ b/usr/src/lib/libsmbfs/smb/ctx.c
@@ -32,7 +32,10 @@
* $Id: ctx.c,v 1.32.70.2 2005/06/02 00:55:40 lindak Exp $
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
#include <sys/param.h>
#include <sys/ioctl.h>
@@ -58,10 +61,6 @@
#include <kerberosv5/krb5.h>
#include <kerberosv5/com_err.h>
-extern uid_t real_uid, eff_uid;
-
-#define NB_NEEDRESOLVER
-
#include <netsmb/smb_lib.h>
#include <netsmb/netbios.h>
#include <netsmb/nb_lib.h>
@@ -71,6 +70,7 @@ extern uid_t real_uid, eff_uid;
#include <spnego.h>
#include "derparse.h"
+#include "private.h"
extern MECH_OID g_stcMechOIDList [];
@@ -80,20 +80,23 @@ extern MECH_OID g_stcMechOIDList [];
int smb_debug, smb_verbose;
/*
- * This used to call the DCE/RPC code.
- * We want more strict layering than this.
- * The redirector should simply export a
- * remote pipe API, comsumed by dce rpc.
- * Make it a no-op for now.
+ * Give the RPC library a callback hook that will be
+ * called whenever we destroy or reinit an smb_ctx_t.
+ * The name rpc_cleanup_smbctx() is legacy, and was
+ * originally a direct call into the RPC code.
*/
-#if 0
-#include <rpc_cleanup.h>
-#else
+static smb_ctx_close_hook_t close_hook;
static void
rpc_cleanup_smbctx(struct smb_ctx *ctx)
{
+ if (close_hook)
+ (*close_hook)(ctx);
+}
+void
+smb_ctx_set_close_hook(smb_ctx_close_hook_t hook)
+{
+ close_hook = hook;
}
-#endif
void
dump_ctx_flags(int flags)
@@ -229,7 +232,9 @@ smb_ctx_init(struct smb_ctx *ctx, int argc, char *argv[],
ctx->ct_minlevel = minlevel;
ctx->ct_maxlevel = maxlevel;
+ /* Fill in defaults */
ctx->ct_ssn.ioc_opt = SMBVOPT_CREATE | SMBVOPT_MINAUTH_NTLM;
+
ctx->ct_ssn.ioc_timeout = 15;
ctx->ct_ssn.ioc_retrycount = 4;
ctx->ct_ssn.ioc_owner = SMBM_ANY_OWNER;
@@ -1230,7 +1235,6 @@ smb_ctx_ioctl(struct smb_ctx *ctx, int inum, struct smbioc_lookup *rqp)
/* Note: No longer put length in outtok[0] */
/* *((int *)rqp->ioc_ssn.ioc_outtok) = (int)siz; */
- seteuid(eff_uid); /* restore setuid root briefly */
if (ioctl(ctx->ct_fd, inum, rqp) == -1) {
rc = errno;
goto out;
@@ -1255,7 +1259,6 @@ smb_ctx_ioctl(struct smb_ctx *ctx, int inum, struct smbioc_lookup *rqp)
if (ioctl(ctx->ct_fd, inum, rqp) == -1)
rc = errno;
out:
- seteuid(real_uid); /* and back to real user */
return (rc);
}
@@ -1890,7 +1893,6 @@ smb_ctx_lookup(struct smb_ctx *ctx, int level, int flags)
/*
* Otherwise we're doing plain old NTLM
*/
- seteuid(eff_uid); /* restore setuid root briefly */
if ((ctx->ct_flags & SMBCF_SSNACTIVE) == 0) {
/*
* This is the magic that tells the driver to
@@ -1915,7 +1917,6 @@ smb_ctx_lookup(struct smb_ctx *ctx, int level, int flags)
}
out:
- seteuid(real_uid); /* and back to real user */
if (failure) {
error = errno;
smb_error(dgettext(TEXT_DOMAIN,
@@ -1937,7 +1938,6 @@ smb_ctx_flags2(struct smb_ctx *ctx)
"can't get flags2 for a session"), errno);
return (-1);
}
- printf(dgettext(TEXT_DOMAIN, "Flags2 value is %d\n"), flags2);
return (flags2);
}
@@ -2030,6 +2030,34 @@ smb_ctx_readrcsection(struct smb_ctx *ctx, const char *sname, int level)
}
}
+ rc_getstringptr(smb_rc, sname, "signing", &p);
+ if (p) {
+ /*
+ * "signing" was set in this section; override
+ * the current signing settings.
+ */
+ ctx->ct_ssn.ioc_opt &= ~SMBVOPT_SIGNING_MASK;
+ if (strcmp(p, "disabled") == 0) {
+ /* leave flags zero (expr for lint) */
+ (void) ctx->ct_ssn.ioc_opt;
+ } else if (strcmp(p, "enabled") == 0) {
+ ctx->ct_ssn.ioc_opt |=
+ SMBVOPT_SIGNING_ENABLED;
+ } else if (strcmp(p, "required") == 0) {
+ ctx->ct_ssn.ioc_opt |=
+ SMBVOPT_SIGNING_ENABLED |
+ SMBVOPT_SIGNING_REQUIRED;
+ } else {
+ /*
+ * Unknown "signing" value.
+ */
+ smb_error(dgettext(TEXT_DOMAIN,
+"invalid signing policy \"%s\" specified in the section %s"),
+ 0, p, sname);
+ return (EINVAL);
+ }
+ }
+
/*
* Domain name. Allow both keywords:
* "workgroup", "domain"
diff --git a/usr/src/lib/libsmbfs/smb/file.c b/usr/src/lib/libsmbfs/smb/file.c
index dd738e8d97..e7a02e77df 100644
--- a/usr/src/lib/libsmbfs/smb/file.c
+++ b/usr/src/lib/libsmbfs/smb/file.c
@@ -32,7 +32,10 @@
* $Id: file.c,v 1.4 2004/12/13 00:25:21 lindak Exp $
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
#include <sys/param.h>
#include <sys/ioctl.h>
@@ -48,15 +51,230 @@
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
+#include <libintl.h>
#include <sys/types.h>
-extern uid_t real_uid, eff_uid;
+#include <sys/file.h>
#include <netsmb/smb_lib.h>
#include <cflib.h>
+#include "charsets.h"
+#include "private.h"
+
int
-smb_read(struct smb_ctx *ctx, smbfh fh, off_t offset, size_t count, char *dst)
+smb_fh_close(struct smb_ctx *ctx, smbfh fh)
+{
+ struct smb_rq *rqp;
+ struct mbdata *mbp;
+ int serr;
+
+ serr = smb_rq_init(ctx, SMB_COM_CLOSE, 0, &rqp);
+ if (serr != 0)
+ return (serr);
+ mbp = smb_rq_getrequest(rqp);
+ mb_put_uint16le(mbp, fh);
+ mb_put_uint32le(mbp, 0); /* time stamp */
+ smb_rq_wend(rqp);
+ serr = smb_rq_simple(rqp);
+ if (serr != 0) {
+ smb_rq_done(rqp);
+ return (serr);
+ }
+ mbp = smb_rq_getreply(rqp);
+ smb_rq_done(rqp);
+
+ return (serr);
+}
+
+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,
+ smbfh *fhp, uint32_t *action_taken)
+{
+ struct smb_rq *rqp;
+ struct mbdata *mbp;
+ uint8_t wc;
+ size_t pathlen, pathsize;
+ int error, flags2;
+ uint16_t *upath = NULL;
+
+ flags2 = smb_ctx_flags2(ctx);
+ if (flags2 == -1)
+ return (EIO);
+
+ error = smb_rq_init(ctx, SMB_COM_NT_CREATE_ANDX, 42, &rqp);
+ if (error != 0)
+ return (error);
+
+ if (flags2 & SMB_FLAGS2_UNICODE) {
+ upath = convert_utf8_to_leunicode(path);
+ if (upath == NULL) {
+ smb_error(dgettext(TEXT_DOMAIN,
+ "%s: failed converting to UCS-2"), 0, path);
+ error = EINVAL;
+ goto out;
+ }
+ pathlen = unicode_strlen(upath);
+ pathsize = (pathlen + 1) * 2;
+ } else {
+ pathlen = strlen(path);
+ pathsize = pathlen + 1;
+ }
+
+ mbp = smb_rq_getrequest(rqp);
+ mb_put_uint8(mbp, 0xff); /* secondary command */
+ mb_put_uint8(mbp, 0); /* MBZ */
+ mb_put_uint16le(mbp, 0); /* offset to next command (none) */
+ mb_put_uint8(mbp, 0); /* MBZ */
+ mb_put_uint16le(mbp, pathsize); /* path size (bytes) */
+ mb_put_uint32le(mbp, 0); /* 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, NTCREATEX_IMPERSONATION_IMPERSONATION); /* (?) */
+ mb_put_uint8(mbp, 0); /* security flags (?) */
+ smb_rq_wend(rqp);
+
+ /* XXX: Need a "put string" function. */
+ if (flags2 & SMB_FLAGS2_UNICODE) {
+ mb_put_uint8(mbp, 0); /* pad byte - align(2) for Unicode */
+ mb_put_mem(mbp, (char *)upath, pathsize);
+ } else
+ mb_put_mem(mbp, path, pathsize);
+
+ 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
+ */
+ wc = rqp->rq_wcount;
+ if (wc < 26) {
+ smb_error(dgettext(TEXT_DOMAIN,
+ "%s: open failed, bad word count"), 0, path);
+ error = EBADRPC;
+ goto out;
+ }
+ mb_get_uint8(mbp, NULL); /* secondary cmd */
+ mb_get_uint8(mbp, NULL); /* mbz */
+ mb_get_uint16le(mbp, NULL); /* andxoffset */
+ mb_get_uint8(mbp, NULL); /* oplock lvl granted */
+ mb_get_uint16le(mbp, fhp); /* FID */
+ mb_get_uint32le(mbp, action_taken);
+#if 0 /* skip decoding the rest */
+ mb_get_uint64le(mbp, NULL); /* creation time */
+ mb_get_uint64le(mbp, NULL); /* access time */
+ mb_get_uint64le(mbp, NULL); /* write time */
+ mb_get_uint64le(mbp, NULL); /* change time */
+ mb_get_uint32le(mbp, NULL); /* attributes */
+ mb_get_uint64le(mbp, NULL); /* allocation size */
+ mb_get_uint64le(mbp, NULL); /* EOF */
+ mb_get_uint16le(mbp, NULL); /* file type */
+ mb_get_uint16le(mbp, NULL); /* device state */
+ mb_get_uint8(mbp, NULL); /* directory (boolean) */
+#endif /* skip decoding */
+
+out:
+ if (upath)
+ free(upath);
+ smb_rq_done(rqp);
+
+ return (0);
+}
+
+/*
+ * Conveinence wrapper for smb_fh_ntcreate
+ * Converts Unix-style open call to NTCreate.
+ */
+int
+smb_fh_open(struct smb_ctx *ctx, const char *path, int oflag, smbfh *fhp)
+{
+ int error, mode, open_disp, req_acc, share_acc;
+ char *p, *ntpath = NULL;
+
+ /*
+ * Map O_RDONLY, O_WRONLY, O_RDWR
+ * to FREAD, FWRITE
+ */
+ mode = (oflag & 3) + 1;
+
+ /*
+ * Compute requested access, share access.
+ */
+ req_acc = (
+ STD_RIGHT_READ_CONTROL_ACCESS |
+ STD_RIGHT_SYNCHRONIZE_ACCESS);
+ share_acc = NTCREATEX_SHARE_ACCESS_NONE;
+ if (mode & FREAD) {
+ req_acc |= (
+ SA_RIGHT_FILE_READ_DATA |
+ SA_RIGHT_FILE_READ_EA |
+ SA_RIGHT_FILE_READ_ATTRIBUTES);
+ share_acc |= NTCREATEX_SHARE_ACCESS_READ;
+ }
+ if (mode & FWRITE) {
+ req_acc |= (
+ SA_RIGHT_FILE_WRITE_DATA |
+ SA_RIGHT_FILE_APPEND_DATA |
+ SA_RIGHT_FILE_WRITE_EA |
+ SA_RIGHT_FILE_WRITE_ATTRIBUTES);
+ share_acc |= NTCREATEX_SHARE_ACCESS_WRITE;
+ }
+
+ /*
+ * Compute open disposition
+ */
+ if (oflag & FCREAT) {
+ /* Creat if necessary. */
+ if (oflag & FEXCL) {
+ /* exclusive */
+ open_disp = NTCREATEX_DISP_CREATE;
+ } else if (oflag & FTRUNC)
+ open_disp = NTCREATEX_DISP_OVERWRITE_IF;
+ else
+ open_disp = NTCREATEX_DISP_OPEN_IF;
+ } else {
+ /* Not creating. */
+ if (oflag & FTRUNC)
+ open_disp = NTCREATEX_DISP_OVERWRITE;
+ else
+ 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 */
+ req_acc, SMB_EFA_NORMAL, share_acc, open_disp,
+ NTCREATEX_OPTIONS_NON_DIRECTORY_FILE,
+ NTCREATEX_IMPERSONATION_IMPERSONATION,
+ fhp, NULL);
+ free(ntpath);
+
+ return (error);
+}
+
+int
+smb_fh_read(struct smb_ctx *ctx, smbfh fh, off_t offset, size_t count,
+ char *dst)
{
struct smbioc_rw rwrq;
@@ -65,17 +283,14 @@ smb_read(struct smb_ctx *ctx, smbfh fh, off_t offset, size_t count, char *dst)
rwrq.ioc_base = dst;
rwrq.ioc_cnt = count;
rwrq.ioc_offset = offset;
- seteuid(eff_uid);
if (ioctl(ctx->ct_fd, SMBIOC_READ, &rwrq) == -1) {
- seteuid(real_uid); /* and back to real user */
return (-1);
}
- seteuid(real_uid); /* and back to real user */
return (rwrq.ioc_cnt);
}
int
-smb_write(struct smb_ctx *ctx, smbfh fh, off_t offset, size_t count,
+smb_fh_write(struct smb_ctx *ctx, smbfh fh, off_t offset, size_t count,
const char *src)
{
struct smbioc_rw rwrq;
@@ -85,11 +300,41 @@ smb_write(struct smb_ctx *ctx, smbfh fh, off_t offset, size_t count,
rwrq.ioc_base = (char *)src;
rwrq.ioc_cnt = count;
rwrq.ioc_offset = offset;
- seteuid(eff_uid);
if (ioctl(ctx->ct_fd, SMBIOC_WRITE, &rwrq) == -1) {
- seteuid(real_uid); /* and back to real user */
return (-1);
}
- seteuid(real_uid); /* and back to real user */
return (rwrq.ioc_cnt);
}
+
+/*
+ * Do a TRANSACT_NAMED_PIPE, which is basically just a
+ * pipe write and pipe read, all in one round trip.
+ *
+ * tdlen, tdata describe the data to send.
+ * rdlen, rdata on input describe the receive buffer,
+ * and on output *rdlen is the received length.
+ */
+int
+smb_fh_xactnp(struct smb_ctx *ctx, smbfh fh,
+ int tdlen, const char *tdata, /* transmit */
+ int *rdlen, char *rdata, /* receive */
+ int *more)
+{
+ int err, rparamcnt;
+ uint16_t setup[2];
+
+ setup[0] = TRANS_TRANSACT_NAMED_PIPE;
+ setup[1] = fh;
+ rparamcnt = 0;
+
+ err = smb_t2_request(ctx, 2, setup, "\\PIPE\\",
+ 0, NULL, /* TX paramcnt, params */
+ tdlen, (void *)tdata,
+ &rparamcnt, NULL, /* no RX params */
+ rdlen, rdata, more);
+
+ if (err)
+ *rdlen = 0;
+
+ return (err);
+}
diff --git a/usr/src/lib/libsmbfs/smb/mapfile-vers b/usr/src/lib/libsmbfs/smb/mapfile-vers
index f8f38ba6b0..b23d706b35 100644
--- a/usr/src/lib/libsmbfs/smb/mapfile-vers
+++ b/usr/src/lib/libsmbfs/smb/mapfile-vers
@@ -21,23 +21,32 @@
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
SUNWprivate_1.0 {
global:
- dropsuid;
+ convert_leunicode_to_utf8;
+ convert_unicode_to_utf8;
+ convert_utf8_to_leunicode;
+ convert_utf8_to_unicode;
+ convert_utf8_to_wincs;
+ convert_wincs_to_utf8;
+
nb_ctx_create;
nb_ctx_done;
nb_ctx_readrcsection;
nb_ctx_resolve;
nb_ctx_setns;
nb_resolvehost_in;
+ nb_strerror;
nbns_getnodestatus;
nbns_resolvename;
+
+ nls_str_toloc;
nls_str_upper;
+
rc_close;
rc_open;
+
smb_ctx_done;
smb_ctx_flags2;
smb_ctx_init;
@@ -45,21 +54,48 @@ SUNWprivate_1.0 {
smb_ctx_opt;
smb_ctx_readrc;
smb_ctx_resolve;
+ smb_ctx_set_close_hook;
+
+ smb_ctx_setfullserver;
+ smb_ctx_setpassword;
+ smb_ctx_setserver;
smb_ctx_setshare;
+ smb_ctx_setsrvaddr;
+ smb_ctx_setuser;
+ smb_ctx_setworkgroup;
+
smb_ctx_tdis;
- smb_debug;
+ smb_debug = NODIRECT; # data
smb_error;
+#
+# Functions to support named pipes
+ smb_fh_close;
+ smb_fh_open;
+ smb_fh_read;
+ smb_fh_write;
+ smb_fh_xactnp;
+#
smb_getprogname;
smb_lib_init;
- smb_netshareenum;
+ smb_netshareenum; # will move to libnetapi
smb_open_rcfile;
smb_simplecrypt;
smb_simpledecrypt;
smb_strerror;
- smb_rc; # data
- smb_read;
- smb_write;
- smb_verbose;
+ smb_rc = NODIRECT; # data
+#
+# Functions to support the Remote Access Protocol (RAP)
+ smb_rap_create;
+ smb_rap_done;
+ smb_rap_error;
+ smb_rap_getNparam;
+ smb_rap_request;
+ smb_rap_setNparam;
+ smb_rap_setPparam;
+#
+ smb_verbose = NODIRECT; # data
+#
+# Functions to support Access Control Lists (ACLs)
smbfs_acl_free_sd;
smbfs_acl_get;
smbfs_acl_getsd;
@@ -68,12 +104,14 @@ SUNWprivate_1.0 {
smbfs_acl_set;
smbfs_acl_setsd;
smbfs_acl_zfs2sd;
+#
smbfs_default_dom_usr;
smbfs_keychain_add;
smbfs_keychain_chk;
smbfs_keychain_del;
smbfs_keychain_del_everyone;
smbfs_keychain_del_owner;
+
unpercent;
local:
*;
diff --git a/usr/src/lib/libsmbfs/smb/mbuf.c b/usr/src/lib/libsmbfs/smb/mbuf.c
index 6f08ce1def..2e995dad50 100644
--- a/usr/src/lib/libsmbfs/smb/mbuf.c
+++ b/usr/src/lib/libsmbfs/smb/mbuf.c
@@ -32,7 +32,10 @@
* $Id: mbuf.c,v 1.3 2004/12/13 00:25:22 lindak Exp $
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
#include <sys/types.h>
#include <ctype.h>
@@ -48,6 +51,8 @@
#include <netsmb/smb_lib.h>
#include <netsmb/mchain.h>
+#include "private.h"
+
#ifdef APPLE
#define __func__ ""
#define MBERROR(format, args...) \
@@ -190,9 +195,6 @@ out:
/*
* Routines to put data in a buffer
*/
-#define MB_PUT(t) int error; t *p; \
- if ((error = mb_fit(mbp, sizeof (t), (char **)&p)) != 0) \
- return (error)
/*
* Check if object of size 'size' fit to the current position and
@@ -223,61 +225,50 @@ mb_fit(struct mbdata *mbp, size_t size, char **pp)
int
mb_put_uint8(struct mbdata *mbp, uint8_t x)
{
- MB_PUT(uint8_t);
- *p = x;
- return (0);
+ uint8_t y = x;
+ return (mb_put_mem(mbp, (char *)&y, sizeof (y)));
}
int
mb_put_uint16be(struct mbdata *mbp, uint16_t x)
{
- MB_PUT(uint16_t);
- /* LINTED */
- setwbe(p, 0, x);
- return (0);
+ uint16_t y = htobes(x);
+ return (mb_put_mem(mbp, (char *)&y, sizeof (y)));
}
int
mb_put_uint16le(struct mbdata *mbp, uint16_t x)
{
- MB_PUT(uint16_t);
- /* LINTED */
- setwle(p, 0, x);
- return (0);
+ uint16_t y = htoles(x);
+ return (mb_put_mem(mbp, (char *)&y, sizeof (y)));
}
int
mb_put_uint32be(struct mbdata *mbp, uint32_t x)
{
- MB_PUT(uint32_t);
- /* LINTED */
- setdbe(p, 0, x);
- return (0);
+ uint32_t y = htobel(x);
+ return (mb_put_mem(mbp, (char *)&y, sizeof (y)));
}
int
mb_put_uint32le(struct mbdata *mbp, uint32_t x)
{
- MB_PUT(uint32_t);
- /* LINTED */
- setdle(p, 0, x);
- return (0);
+ uint32_t y = htolel(x);
+ return (mb_put_mem(mbp, (char *)&y, sizeof (y)));
}
int
mb_put_uint64be(struct mbdata *mbp, uint64_t x)
{
- MB_PUT(uint64_t);
- *p = htobeq(x);
- return (0);
+ uint64_t y = htobeq(x);
+ return (mb_put_mem(mbp, (char *)&y, sizeof (y)));
}
int
mb_put_uint64le(struct mbdata *mbp, uint64_t x)
{
- MB_PUT(uint64_t);
- *p = htoleq(x);
- return (0);
+ uint64_t y = htoleq(x);
+ return (mb_put_mem(mbp, (char *)&y, sizeof (y)));
}
int
diff --git a/usr/src/lib/libsmbfs/smb/nb_name.c b/usr/src/lib/libsmbfs/smb/nb_name.c
index 1c631d73d1..af13efa7b4 100644
--- a/usr/src/lib/libsmbfs/smb/nb_name.c
+++ b/usr/src/lib/libsmbfs/smb/nb_name.c
@@ -32,8 +32,6 @@
* $Id: nb_name.c,v 1.11 2004/12/11 05:23:59 lindak Exp $
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/socket.h>
#include <ctype.h>
@@ -49,6 +47,7 @@
#include <netsmb/smb_lib.h>
#include <netsmb/nb_lib.h>
#include <netsmb/mchain.h>
+#include "private.h"
int
nb_snballoc(int namelen, struct sockaddr_nb **dst)
diff --git a/usr/src/lib/libsmbfs/smb/nb_net.c b/usr/src/lib/libsmbfs/smb/nb_net.c
index 7398cff0e0..29109c3093 100644
--- a/usr/src/lib/libsmbfs/smb/nb_net.c
+++ b/usr/src/lib/libsmbfs/smb/nb_net.c
@@ -32,8 +32,6 @@
* $Id: nb_net.c,v 1.8 2004/03/19 01:49:47 lindak Exp $
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
@@ -53,6 +51,12 @@
#include <netsmb/netbios.h>
#include <netsmb/smb_lib.h>
#include <netsmb/nb_lib.h>
+#include "private.h"
+
+/*
+ * General networking stuff, in spite of the names
+ * that imply they're specific to NetBIOS.
+ */
int
nb_getlocalname(char *name, size_t maxlen)
@@ -114,121 +118,3 @@ nb_resolvehost_in(const char *name, struct sockaddr **dest)
*dest = (struct sockaddr *)sinp;
return (0);
}
-
-#ifdef NOT_DEFINED
-int
-nb_enum_if(struct nb_ifdesc **iflist) {
- struct lifconf ifc;
- struct lifreq *ifrqp;
- struct nb_ifdesc *ifd;
- struct in_addr iaddr, imask;
- struct lifnum ifn;
- char *ifrdata, *iname;
- int s, rdlen, ifcnt, error, iflags, i;
-
- *iflist = NULL;
- s = socket(AF_INET, SOCK_DGRAM, 0);
- if (s == -1)
- return (errno);
-
- /* Get number of interfaces. */
- ifn.lifn_family = AF_INET;
- ifn.lifn_flags = 0;
- ifn.lifn_count = 0;
- if (ioctl(s, SIOCGLIFNUM, &ifn) != 0) {
- error = errno;
- goto bad;
- }
-
- rdlen = ifn.lifn_count * sizeof (struct lifreq);
- ifrdata = malloc(rdlen);
- if (ifrdata == NULL) {
- error = ENOMEM;
- goto bad;
- }
- ifc.lifc_flags = 0;
- ifc.lifc_family = AF_INET;
- ifc.lifc_len = rdlen;
- ifc.lifc_buf = ifrdata;
- if (ioctl(s, SIOCGLIFCONF, &ifc) != 0) {
- error = errno;
- goto bad;
- }
- ifrqp = ifc.lifc_req;
- ifcnt = ifc.lifc_len / sizeof (struct lifreq);
- error = 0;
- for (i = 0; i < ifcnt; i++, ifrqp++) {
- /* XXX for now, avoid IP6 broadcast performance costs */
- if (ifrqp->lifr_addr.ss_family != AF_INET)
- continue;
- if (ioctl(s, SIOCGLIFFLAGS, ifrqp) != 0)
- continue;
- iflags = ifrqp->lifr_flags;
- if ((iflags & IFF_UP) == 0 || (iflags & IFF_BROADCAST) == 0)
- continue;
-
- if (ioctl(s, SIOCGLIFADDR, ifrqp) != 0 ||
- ifrqp->lifr_addr.ss_family != AF_INET) {
- continue;
- }
- iname = ifrqp->lifr_name;
- if (strlen(iname) >= sizeof (ifd->id_name))
- continue;
- iaddr = (*(struct sockaddr_in *)&ifrqp->lifr_addr).sin_addr;
-
- if (ioctl(s, SIOCGLIFNETMASK, ifrqp) != 0)
- continue;
- imask = ((struct sockaddr_in *)&ifrqp->lifr_addr)->sin_addr;
-
- ifd = malloc(sizeof (struct nb_ifdesc));
- if (ifd == NULL)
- return (ENOMEM);
- bzero(ifd, sizeof (struct nb_ifdesc));
- strcpy(ifd->id_name, iname);
- ifd->id_flags = iflags;
- ifd->id_addr = iaddr;
- ifd->id_mask = imask;
- ifd->id_next = *iflist;
- *iflist = ifd;
- }
-bad:
- free(ifrdata);
- close(s);
- return (error);
-}
-
-/*ARGSUSED*/
-int
-nbns_resolvename(const char *name, struct sockaddr **dest)
-{
- printf("NetBIOS name resolver is not included in this distribution.\n");
- printf("Please use '-I' option to specify an IP address of server.\n");
- return (EHOSTUNREACH);
-}
-
-int
-nb_hostlookup(struct nb_name *np, const char *server, const char *hint,
- struct sockaddr_nb **dst)
-{
- struct sockaddr_nb *snb;
- int error;
-
- error = nb_sockaddr(NULL, np, &snb);
- if (error)
- return (error);
- do {
- if (hint) {
- error = nb_resolvehost_in(host, snb);
- if (error)
- break;
- } else {
- error = nb_resolvename(server);
- }
- } while (0);
- if (!error) {
- *dst = snb;
- } else
- nb_snbfree(snb);
- return (error);
-}
-#endif
diff --git a/usr/src/lib/libsmbfs/smb/nbns_rq.c b/usr/src/lib/libsmbfs/smb/nbns_rq.c
index 17de0a103a..773466b7fa 100644
--- a/usr/src/lib/libsmbfs/smb/nbns_rq.c
+++ b/usr/src/lib/libsmbfs/smb/nbns_rq.c
@@ -32,8 +32,6 @@
* $Id: nbns_rq.c,v 1.9 2005/02/24 02:04:38 lindak Exp $
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/time.h>
@@ -57,6 +55,40 @@
#include <netsmb/nb_lib.h>
#include <netsmb/mchain.h>
+#include "private.h"
+
+/*
+ * nbns request
+ */
+struct nbns_rq {
+ int nr_opcode;
+ int nr_nmflags;
+ int nr_rcode;
+ int nr_qdcount;
+ int nr_ancount;
+ int nr_nscount;
+ int nr_arcount;
+ struct nb_name *nr_qdname;
+ uint16_t nr_qdtype;
+ uint16_t nr_qdclass;
+ struct in_addr nr_dest; /* receiver of query */
+ struct sockaddr_in nr_sender; /* sender of response */
+ int nr_rpnmflags;
+ int nr_rprcode;
+ uint16_t nr_rpancount;
+ uint16_t nr_rpnscount;
+ uint16_t nr_rparcount;
+ uint16_t nr_trnid;
+ struct nb_ctx *nr_nbd;
+ struct mbdata nr_rq;
+ struct mbdata nr_rp;
+ struct nb_ifdesc *nr_if;
+ int nr_flags;
+ int nr_fd;
+ int nr_maxretry;
+};
+typedef struct nbns_rq nbns_rq_t;
+
static int nbns_rq_create(int opcode, struct nb_ctx *ctx,
struct nbns_rq **rqpp);
static void nbns_rq_done(struct nbns_rq *rqp);
diff --git a/usr/src/lib/libsmbfs/smb/netshareenum.c b/usr/src/lib/libsmbfs/smb/netshareenum.c
index 4da5fd17a2..2d7f9c2c3a 100644
--- a/usr/src/lib/libsmbfs/smb/netshareenum.c
+++ b/usr/src/lib/libsmbfs/smb/netshareenum.c
@@ -36,7 +36,10 @@
*/
/* END CSTYLED */
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
#include <stdlib.h>
#include <string.h>
@@ -47,11 +50,11 @@
#include <netsmb/smb_lib.h>
#include <netsmb/smb_rap.h>
#include <netsmb/smb_netshareenum.h>
-#include "charsets.h"
+#include <smb/charsets.h>
#if 0 /* XXX see below */
#include <dce/exc_handling.h>
-#include <attrb.h>
+#include <rpc/attrb.h>
#include "srvsvc.h"
#endif
@@ -102,6 +105,7 @@ rpc_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
return (EINVAL);
}
rpc_binding_from_string_binding(binding, &binding_h, &status);
+ rpc_string_free(&binding, (unsigned32 *)&free_status);
if (binding_status != rpc_s_ok) {
smb_error(dgettext(TEXT_DOMAIN,
"rpc_binding_from_string_binding failed with %d"), 0,
@@ -130,14 +134,12 @@ rpc_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
}
strcpy(srvnamestr, "\\\\");
strcat(srvnamestr, addrstr);
-#ifdef NOTYETDEFINED
usrvnamestr = convert_utf8_to_leunicode(srvnamestr);
-#endif
- usrvnamestr = srvnamestr;
if (usrvnamestr == NULL) {
smb_error(dgettext(TEXT_DOMAIN,
"can't convert string for server address to Unicode"), 0);
rpc_binding_free(&binding_h, &free_status);
+ free(srvnamestr);
return (EINVAL);
}
if (!exceptions_initialized) {
@@ -200,16 +202,10 @@ rpc_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
for (share = shares, elp = entry_list, i = 0; i < entries;
i++, share++) {
elp->type = share->shi1_type;
-#ifdef NOTYETDEFINED
elp->netname = convert_unicode_to_utf8(share->shi1_share);
-#endif
- elp->netname = share->shi1_share;
if (elp->netname == NULL)
goto fail;
-#ifdef NOTYETDEFINED
elp->remark = convert_unicode_to_utf8(share->shi1_remark);
-#endif
- elp->remark = share->shi1_remark;
if (elp->remark == NULL)
goto fail;
elp++;
@@ -261,6 +257,46 @@ cleanup_and_return:
}
#endif /* XXX */
+/*
+ * Enumerate shares using RAP
+ */
+
+struct smb_share_info_1 {
+ char shi1_netname[13];
+ char shi1_pad;
+ uint16_t shi1_type;
+ uint32_t shi1_remark; /* char * */
+};
+
+static int
+smb_rap_NetShareEnum(struct smb_ctx *ctx, int sLevel, void *pbBuffer,
+ int *cbBuffer, int *pcEntriesRead, int *pcTotalAvail)
+{
+ struct smb_rap *rap;
+ long lval = -1;
+ int error;
+ char *pass;
+ int i;
+
+ error = smb_rap_create(0, "WrLeh", "B13BWz", &rap);
+ if (error)
+ return (error);
+ smb_rap_setNparam(rap, sLevel); /* W - sLevel */
+ smb_rap_setPparam(rap, pbBuffer); /* r - pbBuffer */
+ smb_rap_setNparam(rap, *cbBuffer); /* L - cbBuffer */
+ error = smb_rap_request(rap, ctx);
+ if (error == 0) {
+ *pcEntriesRead = rap->r_entries;
+ error = smb_rap_getNparam(rap, &lval);
+ *pcTotalAvail = lval;
+ /* Copy the data length into the IN/OUT variable. */
+ *cbBuffer = rap->r_rcvbuflen;
+ }
+ error = smb_rap_error(rap, error);
+ smb_rap_done(rap);
+ return (error);
+}
+
static int
rap_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
struct share_info **entries_listp)
@@ -294,10 +330,7 @@ rap_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
i++, ep++) {
elp->type = letohs(ep->shi1_type);
ep->shi1_pad = '\0'; /* ensure null termination */
- elp->netname = strdup(ep->shi1_netname);
-#ifdef NOTYETDEFINED
elp->netname = convert_wincs_to_utf8(ep->shi1_netname);
-#endif
if (elp->netname == NULL)
continue; /* punt on this entry */
/*
@@ -305,10 +338,7 @@ rap_netshareenum(struct smb_ctx *ctx, int *entriesp, int *totalp,
*/
if (ep->shi1_remark >= lbound && ep->shi1_remark < rbound) {
cp = (char *)rpbuf + ep->shi1_remark;
- elp->remark = cp;
-#ifdef NOTYETDEFINED
- elp->remark = nls_str_toloc(cp, cp);
-#endif
+ elp->remark = convert_wincs_to_utf8(cp);
} else
elp->remark = NULL;
elp++;
diff --git a/usr/src/lib/libsmbfs/smb/print.c b/usr/src/lib/libsmbfs/smb/print.c
index 7b87c06e41..e0b18e8c40 100644
--- a/usr/src/lib/libsmbfs/smb/print.c
+++ b/usr/src/lib/libsmbfs/smb/print.c
@@ -32,8 +32,6 @@
* $Id: print.c,v 1.1.1.3 2001/07/06 22:38:43 conrad Exp $
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/time.h>
@@ -50,6 +48,7 @@
#include <netsmb/smb_lib.h>
#include <cflib.h>
+#include "private.h"
int
smb_smb_open_print_file(struct smb_ctx *ctx, int setuplen, int mode,
diff --git a/usr/src/lib/libsmbfs/smb/private.h b/usr/src/lib/libsmbfs/smb/private.h
new file mode 100644
index 0000000000..6630ed160a
--- /dev/null
+++ b/usr/src/lib/libsmbfs/smb/private.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2000-2001 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
+ * documentation and/or other materials provided with the distribution.
+ * 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.
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _PRIVATE_H
+#define _PRIVATE_H
+
+/*
+ * Private declarations for this library.
+ * Moved from smb_lib.h
+ */
+
+#include <inttypes.h>
+
+/*
+ * BSD-style mbuf simulation
+ */
+struct mbuf {
+ int m_len;
+ int m_maxlen;
+ char *m_data;
+ struct mbuf *m_next;
+};
+typedef struct mbuf mbuf_t;
+
+#if 0 /* in smb_lib.h */
+struct mbdata {
+ struct mbuf *mb_top;
+ struct mbuf *mb_cur;
+ char *mb_pos;
+ int mb_count;
+};
+typedef struct mbdata mbdata_t;
+#endif
+
+#define M_ALIGNFACTOR (sizeof (long))
+#define M_ALIGN(len) (((len) + M_ALIGNFACTOR - 1) & ~(M_ALIGNFACTOR - 1))
+#define M_BASESIZE (sizeof (struct mbuf))
+#define M_MINSIZE (256 - M_BASESIZE)
+#define M_TOP(m) ((char *)(m) + M_BASESIZE)
+#define M_TRAILINGSPACE(m) ((m)->m_maxlen - (m)->m_len)
+#define mtod(m, t) ((t)(m)->m_data)
+
+/*
+ * request handling structures
+ */
+struct smb_rq {
+ uchar_t rq_cmd;
+ struct mbdata rq_rq;
+ struct mbdata rq_rp;
+ struct smb_ctx *rq_ctx;
+ int rq_wcount;
+ int rq_bcount;
+};
+typedef struct smb_rq smb_rq_t;
+
+#define smb_rq_getrequest(rqp) (&(rqp)->rq_rq)
+#define smb_rq_getreply(rqp) (&(rqp)->rq_rp)
+
+int smb_rq_init(struct smb_ctx *, uchar_t, size_t, struct smb_rq **);
+void smb_rq_done(struct smb_rq *);
+void smb_rq_wend(struct smb_rq *);
+int smb_rq_simple(struct smb_rq *);
+int smb_rq_dmem(struct mbdata *, const char *, size_t);
+int smb_rq_dstring(struct mbdata *, const char *);
+
+
+/*
+ * Message compose/parse
+ */
+
+int m_getm(struct mbuf *, size_t, struct mbuf **);
+int m_lineup(struct mbuf *, struct mbuf **);
+int mb_init(struct mbdata *, size_t);
+int mb_initm(struct mbdata *, struct mbuf *);
+int mb_done(struct mbdata *);
+int mb_fit(struct mbdata *mbp, size_t size, char **pp);
+int mb_put_uint8(struct mbdata *, uint8_t);
+int mb_put_uint16be(struct mbdata *, uint16_t);
+int mb_put_uint16le(struct mbdata *, uint16_t);
+int mb_put_uint32be(struct mbdata *, uint32_t);
+int mb_put_uint32le(struct mbdata *, uint32_t);
+int mb_put_uint64be(struct mbdata *, uint64_t);
+int mb_put_uint64le(struct mbdata *, uint64_t);
+int mb_put_mem(struct mbdata *, const char *, size_t);
+int mb_put_pstring(struct mbdata *mbp, const char *s);
+int mb_put_mbuf(struct mbdata *, struct mbuf *);
+
+int mb_get_uint8(struct mbdata *, uint8_t *);
+int mb_get_uint16(struct mbdata *, uint16_t *);
+int mb_get_uint16le(struct mbdata *, uint16_t *);
+int mb_get_uint16be(struct mbdata *, uint16_t *);
+int mb_get_uint32(struct mbdata *, uint32_t *);
+int mb_get_uint32be(struct mbdata *, uint32_t *);
+int mb_get_uint32le(struct mbdata *, uint32_t *);
+int mb_get_uint64(struct mbdata *, uint64_t *);
+int mb_get_uint64be(struct mbdata *, uint64_t *);
+int mb_get_uint64le(struct mbdata *, uint64_t *);
+int mb_get_mem(struct mbdata *, char *, size_t);
+
+/*
+ * Network stuff (NetBIOS and otherwise)
+ */
+
+int nb_name_len(struct nb_name *);
+/* new flag UCflag. 1=uppercase,0=don't */
+int nb_name_encode(struct nb_name *, uchar_t *);
+int nb_encname_len(const uchar_t *);
+
+int nb_snballoc(int namelen, struct sockaddr_nb **);
+void nb_snbfree(struct sockaddr *);
+int nb_sockaddr(struct sockaddr *, struct nb_name *, struct sockaddr_nb **);
+
+int nbns_resolvename(const char *, struct nb_ctx *, struct sockaddr **);
+int nbns_getnodestatus(struct sockaddr *targethost,
+ struct nb_ctx *ctx, char *system, char *workgroup);
+int nb_getlocalname(char *name, size_t maxlen);
+
+extern uchar_t nls_lower[256], nls_upper[256];
+
+#endif /* _PRIVATE_H */
diff --git a/usr/src/lib/libsmbfs/smb/rap.c b/usr/src/lib/libsmbfs/smb/rap.c
index 00ccbd54a2..3a9e785191 100644
--- a/usr/src/lib/libsmbfs/smb/rap.c
+++ b/usr/src/lib/libsmbfs/smb/rap.c
@@ -34,8 +34,6 @@
* This is very simple implementation of RAP protocol.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/param.h>
#include <sys/errno.h>
#include <sys/stat.h>
@@ -52,6 +50,7 @@
#include <netsmb/mchain.h>
#include <netsmb/smb_lib.h>
#include <netsmb/smb_rap.h>
+#include "private.h"
static int
smb_rap_parserqparam(const char *s, char **next, int *rlen)
@@ -166,23 +165,28 @@ smb_rap_rqparam_z(struct smb_rap *rap, const char *value)
static int
smb_rap_rqparam(struct smb_rap *rap, char ptype, char plen, int value)
{
- char *p = rap->r_npbuf;
int len = 0;
uint_t uv = (uint_t)value;
+ uint32_t *lp;
+ uint16_t *sp;
+ char *p;
switch (ptype) {
case 'L':
case 'W':
/* LINTED */
- setwle(p, 0, uv);
- len = 2;
+ sp = (uint16_t *)rap->r_npbuf;
+ *sp = htoles(uv);
+ len = sizeof (*sp);
break;
case 'D':
/* LINTED */
- setdle(p, 0, uv);
- len = 4;
+ lp = (uint32_t *)rap->r_npbuf;
+ *lp = htolel(uv);
+ len = sizeof (*lp);
break;
case 'b':
+ p = rap->r_npbuf;
memset(p, uv, plen);
len = plen;
default:
@@ -293,7 +297,7 @@ smb_rap_setPparam(struct smb_rap *rap, void *value)
return (0);
}
-static int
+int
smb_rap_getNparam(struct smb_rap *rap, long *value)
{
char *p = rap->r_nparam;
@@ -436,33 +440,3 @@ smb_rap_error(struct smb_rap *rap, int error)
return (0);
return (rap->r_result | SMB_RAP_ERROR);
}
-
-/* todo: move this function to libnetapi */
-int
-smb_rap_NetShareEnum(struct smb_ctx *ctx, int sLevel, void *pbBuffer,
- int *cbBuffer, int *pcEntriesRead, int *pcTotalAvail)
-{
- struct smb_rap *rap;
- long lval = -1;
- int error;
- char *pass;
- int i;
-
- error = smb_rap_create(0, "WrLeh", "B13BWz", &rap);
- if (error)
- return (error);
- smb_rap_setNparam(rap, sLevel); /* W - sLevel */
- smb_rap_setPparam(rap, pbBuffer); /* r - pbBuffer */
- smb_rap_setNparam(rap, *cbBuffer); /* L - cbBuffer */
- error = smb_rap_request(rap, ctx);
- if (error == 0) {
- *pcEntriesRead = rap->r_entries;
- error = smb_rap_getNparam(rap, &lval);
- *pcTotalAvail = lval;
- /* Copy the data length into the IN/OUT variable. */
- *cbBuffer = rap->r_rcvbuflen;
- }
- error = smb_rap_error(rap, error);
- smb_rap_done(rap);
- return (error);
-}
diff --git a/usr/src/lib/libsmbfs/smb/rcfile.c b/usr/src/lib/libsmbfs/smb/rcfile.c
index 498b91c0d8..3f5a87435d 100644
--- a/usr/src/lib/libsmbfs/smb/rcfile.c
+++ b/usr/src/lib/libsmbfs/smb/rcfile.c
@@ -32,8 +32,6 @@
* $Id: rcfile.c,v 1.1.1.2 2001/07/06 22:38:43 conrad Exp $
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <fcntl.h>
#include <sys/types.h>
#include <sys/queue.h>
@@ -51,6 +49,7 @@
#include <cflib.h>
#include "rcfile_priv.h"
+extern int smb_debug;
SLIST_HEAD(rcfile_head, rcfile);
static struct rcfile_head pf_head = {NULL};
@@ -312,15 +311,19 @@ set_value(struct rcfile *rcp, struct rcsection *rsp, struct rckey *rkp,
new = eval_minauth(ptr);
if (new >= now) {
#ifdef DEBUG
- printf("set_value: rejecting %s=%s from %s\n",
- rkp->rk_name, ptr, home_nsmbrc ? "user file" : "SMF");
+ if (smb_debug)
+ printf(
+ "set_value: rejecting %s=%s from %s\n",
+ rkp->rk_name, ptr, home_nsmbrc ?
+ "user file" : "SMF");
#endif
return;
}
}
#ifdef DEBUG
- printf("set_value: applying %s=%s from %s\n",
- rkp->rk_name, ptr, home_nsmbrc ? "user file" : "SMF");
+ if (smb_debug)
+ printf("set_value: applying %s=%s from %s\n",
+ rkp->rk_name, ptr, home_nsmbrc ? "user file" : "SMF");
#endif
rkp->rk_value = strdup(ptr);
}
@@ -393,7 +396,8 @@ rc_parse(struct rcfile *rcp)
if (home_nsmbrc &&
(strcmp(buf, "nbns") == 0 ||
strcmp(buf, "nbns_enable") == 0 ||
- strcmp(buf, "nbns_broadcast") == 0)) {
+ strcmp(buf, "nbns_broadcast") == 0 ||
+ strcmp(buf, "signing") == 0)) {
fprintf(stderr, dgettext(TEXT_DOMAIN,
"option %s may not be set "
"in user .nsmbrc file\n"), buf);
diff --git a/usr/src/lib/libsmbfs/smb/rq.c b/usr/src/lib/libsmbfs/smb/rq.c
index c31c271819..6390a3c157 100644
--- a/usr/src/lib/libsmbfs/smb/rq.c
+++ b/usr/src/lib/libsmbfs/smb/rq.c
@@ -32,8 +32,6 @@
* $Id: rq.c,v 1.4 2004/12/13 00:25:23 lindak Exp $
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
@@ -50,8 +48,7 @@
#include <libintl.h>
#include <netsmb/smb_lib.h>
-
-extern uid_t real_uid, eff_uid;
+#include "private.h"
int
@@ -149,15 +146,12 @@ smb_rq_simple(struct smb_rq *rqp)
mbp = smb_rq_getreply(rqp);
krq.ioc_rpbufsz = mbp->mb_top->m_maxlen;
krq.ioc_rpbuf = mtod(mbp->mb_top, char *);
- seteuid(eff_uid);
if (ioctl(rqp->rq_ctx->ct_fd, SMBIOC_REQUEST, &krq) == -1) {
- seteuid(real_uid); /* and back to real user */
return (errno);
}
mbp->mb_top->m_len = krq.ioc_rwc * 2 + krq.ioc_rbc;
rqp->rq_wcount = krq.ioc_rwc;
rqp->rq_bcount = krq.ioc_rbc;
- seteuid(real_uid); /* and back to real user */
return (0);
}
@@ -197,9 +191,7 @@ smb_t2_request(struct smb_ctx *ctx, int setupcount, uint16_t *setup,
krq->ioc_rparam = rparam;
krq->ioc_rdata = rdata;
- seteuid(eff_uid);
if (ioctl(ctx->ct_fd, SMBIOC_T2RQ, krq) == -1) {
- seteuid(real_uid); /* and back to real user */
return (errno);
}
@@ -207,7 +199,6 @@ smb_t2_request(struct smb_ctx *ctx, int setupcount, uint16_t *setup,
*rdatacnt = krq->ioc_rdatacnt;
*buffer_oflow = (krq->ioc_rpflags2 & SMB_FLAGS2_ERR_STATUS) &&
(krq->ioc_error == NT_STATUS_BUFFER_OVERFLOW);
- seteuid(real_uid); /* and back to real user */
free(krq);
return (0);
}
diff --git a/usr/src/lib/libsmbfs/smb/subr.c b/usr/src/lib/libsmbfs/smb/subr.c
index 46842d730f..36a3c30ed9 100644
--- a/usr/src/lib/libsmbfs/smb/subr.c
+++ b/usr/src/lib/libsmbfs/smb/subr.c
@@ -32,14 +32,9 @@
* $Id: subr.c,v 1.19 2005/02/09 00:23:45 lindak Exp $
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/param.h>
#include <sys/types.h>
#include <sys/errno.h>
-#include <sys/syscall.h>
-#include <sys/wait.h>
-#include <sys/debug.h>
+#include <sys/time.h>
#include <unistd.h>
#include <ctype.h>
@@ -224,7 +219,8 @@ smb_open_rcfile(struct smb_ctx *ctx)
fprintf(stderr, dgettext(TEXT_DOMAIN,
"Can't open %s: %s\n"), fn, smb_strerror(errno));
#ifdef DEBUG
- dump_props("after reading global repository");
+ if (smb_debug)
+ dump_props("after reading global repository");
#endif
home = getenv("HOME");
@@ -244,7 +240,8 @@ smb_open_rcfile(struct smb_ctx *ctx)
}
home_nsmbrc = 0;
#ifdef DEBUG
- dump_props("after reading user settings");
+ if (smb_debug)
+ dump_props("after reading user settings");
#endif
if (smb_rc == NULL) {
return (ENOENT);
@@ -306,76 +303,6 @@ smb_simpledecrypt(char *dst, const char *src)
return (0);
}
-
-static int
-safe_execv(char *args[])
-{
- int pid;
- int status;
-
- pid = fork();
- if (pid == 0) {
- (void) execv(args[0], args);
- /* Changed from errx() to fprintf(stderr) -Pavan */
- fprintf(stderr, dgettext(TEXT_DOMAIN,
- "%s: execv %s failed, %s\n"), __progname,
- args[0], smb_strerror(errno));
- }
- if (pid == -1) {
- fprintf(stderr, dgettext(TEXT_DOMAIN, "%s: fork failed, %s\n"),
- __progname, smb_strerror(errno));
- return (1);
- }
- if (wait4(pid, &status, 0, NULL) != pid) {
- fprintf(stderr, dgettext(TEXT_DOMAIN,
- "%s: BUG executing %s command\n"), __progname, args[0]);
- return (1);
- } else if (!WIFEXITED(status)) {
- fprintf(stderr, dgettext(TEXT_DOMAIN,
- "%s: %s command aborted by signal %d\n"),
- __progname, args[0], WTERMSIG(status));
- return (1);
- } else if (WEXITSTATUS(status)) {
- fprintf(stderr, dgettext(TEXT_DOMAIN,
- "%s: %s command failed, exit status %d: %s\n"),
- __progname, args[0], WEXITSTATUS(status),
- smb_strerror(WEXITSTATUS(status)));
- return (1);
- }
- return (0);
-}
-
-
-void
-dropsuid()
-{
- /* drop setuid root privs asap */
- eff_uid = geteuid();
- real_uid = getuid();
- seteuid(real_uid);
-}
-
-
-#define KEXTLOAD_COMMAND "/sbin/kextload"
-#define FS_KEXT_DIR "/System/Library/Extensions/smbfs.kext"
-#define FULL_KEXTNAME "com.apple.filesystems.smbfs"
-
-
-int
-loadsmbvfs()
-{
- char *kextargs[] = {KEXTLOAD_COMMAND, FS_KEXT_DIR, NULL};
- int error = 0;
-
- /*
- * temporarily revert to root (required for kextload)
- */
- seteuid(eff_uid);
- error = safe_execv(kextargs);
- seteuid(real_uid); /* and back to real user */
- return (error);
-}
-
#undef __progname
char *__progname = NULL;
diff --git a/usr/src/lib/libsmbfs/smb/utf_str.c b/usr/src/lib/libsmbfs/smb/utf_str.c
new file mode 100644
index 0000000000..e80b1180f2
--- /dev/null
+++ b/usr/src/lib/libsmbfs/smb/utf_str.c
@@ -0,0 +1,207 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Unicode conversions (yet more)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <iconv.h>
+#include <libintl.h>
+
+#include <sys/u8_textprep.h>
+
+#include <netsmb/smb_lib.h>
+#include "charsets.h"
+
+
+/*
+ * Number of unicode symbols in the string,
+ * not including the 2-byte null terminator.
+ * (multiply by two for storage size)
+ */
+size_t
+unicode_strlen(const uint16_t *us)
+{
+ size_t len = 0;
+ while (*us++)
+ len++;
+ return (len);
+}
+
+static char *convert_ucs2xx_to_utf8(iconv_t, const uint16_t *);
+
+/*
+ * Convert (native) Unicode string to UTF-8.
+ * Returns allocated memory.
+ */
+char *
+convert_unicode_to_utf8(uint16_t *us)
+{
+ static iconv_t cd1 = (iconv_t)-1;
+
+ /* Get conversion descriptor (to, from) */
+ if (cd1 == (iconv_t)-1)
+ cd1 = iconv_open("UTF-8", "UCS-2");
+
+ return (convert_ucs2xx_to_utf8(cd1, us));
+}
+
+/*
+ * Convert little-endian Unicode string to UTF-8.
+ * Returns allocated memory.
+ */
+char *
+convert_leunicode_to_utf8(unsigned short *us)
+{
+ static iconv_t cd2 = (iconv_t)-1;
+
+ /* Get conversion descriptor (to, from) */
+ if (cd2 == (iconv_t)-1)
+ cd2 = iconv_open("UTF-8", "UCS-2LE");
+
+ return (convert_ucs2xx_to_utf8(cd2, us));
+}
+
+static char *
+convert_ucs2xx_to_utf8(iconv_t cd, const uint16_t *us)
+{
+ char *obuf, *optr;
+ const char *iptr;
+ size_t ileft, obsize, oleft, ret;
+
+ if (cd == (iconv_t)-1) {
+ smb_error(dgettext(TEXT_DOMAIN,
+ "iconv_open(UTF-8/UCS-2)"), -1);
+ return (NULL);
+ }
+
+ iptr = (const char *)us;
+ ileft = unicode_strlen(us);
+ ileft *= 2; /* now bytes */
+
+ /* Worst-case output size is 2x input size. */
+ oleft = ileft * 2;
+ obsize = oleft + 2; /* room for null */
+ obuf = malloc(obsize);
+ if (!obuf)
+ return (NULL);
+ optr = obuf;
+
+ ret = iconv(cd, &iptr, &ileft, &optr, &oleft);
+ *optr = '\0';
+ if (ret == (size_t)-1) {
+ smb_error(dgettext(TEXT_DOMAIN,
+ "iconv(%s) failed"), errno, obuf);
+ }
+ if (ileft) {
+ smb_error(dgettext(TEXT_DOMAIN,
+ "iconv(%s) failed"), -1, obuf);
+ /*
+ * XXX: What's better? return NULL?
+ * The truncated string? << for now
+ */
+ }
+
+ return (obuf);
+}
+
+static uint16_t *convert_utf8_to_ucs2xx(iconv_t, const char *);
+
+/*
+ * Convert UTF-8 string to Unicode.
+ * Returns allocated memory.
+ */
+uint16_t *
+convert_utf8_to_unicode(const char *utf8_string)
+{
+ static iconv_t cd3 = (iconv_t)-1;
+
+ /* Get conversion descriptor (to, from) */
+ if (cd3 == (iconv_t)-1)
+ cd3 = iconv_open("UCS-2", "UTF-8");
+ return (convert_utf8_to_ucs2xx(cd3, utf8_string));
+}
+
+/*
+ * Convert UTF-8 string to little-endian Unicode.
+ * Returns allocated memory.
+ */
+uint16_t *
+convert_utf8_to_leunicode(const char *utf8_string)
+{
+ static iconv_t cd4 = (iconv_t)-1;
+
+ /* Get conversion descriptor (to, from) */
+ if (cd4 == (iconv_t)-1)
+ cd4 = iconv_open("UCS-2LE", "UTF-8");
+ return (convert_utf8_to_ucs2xx(cd4, utf8_string));
+}
+
+static uint16_t *
+convert_utf8_to_ucs2xx(iconv_t cd, const char *utf8_string)
+{
+ uint16_t *obuf, *optr;
+ const char *iptr;
+ size_t ileft, obsize, oleft, ret;
+
+ if (cd == (iconv_t)-1) {
+ smb_error(dgettext(TEXT_DOMAIN,
+ "iconv_open(UCS-2/UTF-8)"), -1);
+ return (NULL);
+ }
+
+ iptr = utf8_string;
+ ileft = strlen(iptr);
+
+ /* Worst-case output size is 2x input size. */
+ oleft = ileft * 2;
+ obsize = oleft + 2; /* room for null */
+ obuf = malloc(obsize);
+ if (!obuf)
+ return (NULL);
+ optr = obuf;
+
+ ret = iconv(cd, &iptr, &ileft, (char **)&optr, &oleft);
+ *optr = '\0';
+ if (ret == (size_t)-1) {
+ smb_error(dgettext(TEXT_DOMAIN,
+ "iconv(%s) failed"), errno, utf8_string);
+ }
+ if (ileft) {
+ smb_error(dgettext(TEXT_DOMAIN,
+ "iconv(%s) failed"), -1, utf8_string);
+ /*
+ * XXX: What's better? return NULL?
+ * The truncated string? << for now
+ */
+ }
+
+ return (obuf);
+}