diff options
Diffstat (limited to 'usr/src/lib/libsmbfs')
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); +} |