diff options
Diffstat (limited to 'usr/src/uts/common/fs')
65 files changed, 948 insertions, 777 deletions
diff --git a/usr/src/uts/common/fs/smbsrv/smb_acl.c b/usr/src/uts/common/fs/smbsrv/smb_acl.c index 8577663acf..75e579a636 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_acl.c +++ b/usr/src/uts/common/fs/smbsrv/smb_acl.c @@ -19,20 +19,16 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)smb_acl.c 1.5 08/07/28 SMI" - #include <sys/acl.h> #include <acl/acl_common.h> #include <smbsrv/smb_sid.h> #include <smbsrv/smb_fsops.h> #include <smbsrv/smb_idmap.h> #include <smbsrv/smb_kproto.h> -#include <smbsrv/ntstatus.h> -#include <smbsrv/ntaccess.h> #define ACE_FD_INHERIT_ACE (ACE_FILE_INHERIT_ACE | ACE_DIRECTORY_INHERIT_ACE) diff --git a/usr/src/uts/common/fs/smbsrv/smb_alloc.c b/usr/src/uts/common/fs/smbsrv/smb_alloc.c index dccb93d10e..fc3a3c0b5f 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_alloc.c +++ b/usr/src/uts/common/fs/smbsrv/smb_alloc.c @@ -27,53 +27,43 @@ #include <sys/sunddi.h> #include <sys/kmem.h> #include <sys/sysmacros.h> -#include <sys/types.h> - +#include <smbsrv/smb_kproto.h> #include <smbsrv/alloc.h> #define MEM_HDR_SIZE 8 -static uint32_t mem_get_size(void *ptr); +static uint32_t smb_memsize(void *); void * -mem_malloc(uint32_t size) +smb_malloc(uint32_t size) { - uint8_t *p; + uint32_t *hdr; + uint8_t *p; size += MEM_HDR_SIZE; - p = kmem_alloc(size, KM_SLEEP); - /*LINTED E_BAD_PTR_CAST_ALIGN*/ - *(uint32_t *)p = size; - p += MEM_HDR_SIZE; - - return (p); -} - -void * -mem_zalloc(uint32_t size) -{ - uint8_t *p; + hdr = kmem_zalloc(size, KM_SLEEP); + *hdr = size; - p = mem_malloc(size); - (void) memset(p, 0, size); + p = (uint8_t *)hdr; + p += MEM_HDR_SIZE; return (p); } char * -mem_strdup(const char *ptr) +smb_strdup(const char *ptr) { - char *p; - size_t size; + char *p; + size_t size; size = strlen(ptr) + 1; - p = mem_malloc(size); + p = smb_malloc(size); (void) memcpy(p, ptr, size); return (p); } static uint32_t -mem_get_size(void *ptr) +smb_memsize(void *ptr) { - uint32_t *p; + uint32_t *p; /*LINTED E_BAD_PTR_CAST_ALIGN*/ p = (uint32_t *)((uint8_t *)ptr - MEM_HDR_SIZE); @@ -82,40 +72,120 @@ mem_get_size(void *ptr) } void * -mem_realloc(void *ptr, uint32_t size) +smb_realloc(void *ptr, uint32_t size) { - void *new_ptr; - uint32_t current_size; + void *new_ptr; + uint32_t current_size; if (ptr == NULL) - return (mem_malloc(size)); + return (smb_malloc(size)); if (size == 0) { - smb_mem_free(ptr); + smb_mfree(ptr); return (NULL); } - current_size = mem_get_size(ptr) - MEM_HDR_SIZE; + current_size = smb_memsize(ptr) - MEM_HDR_SIZE; if (size <= current_size) return (ptr); - new_ptr = mem_malloc(size); + new_ptr = smb_malloc(size); (void) memcpy(new_ptr, ptr, current_size); - smb_mem_free(ptr); + smb_mfree(ptr); return (new_ptr); } void -smb_mem_free(void *ptr) +smb_mfree(void *ptr) { - uint8_t *p; + uint8_t *p; - if (ptr == 0) + if (ptr == NULL) return; p = (uint8_t *)ptr - MEM_HDR_SIZE; /*LINTED E_BAD_PTR_CAST_ALIGN*/ kmem_free(p, *(uint32_t *)p); } + +/* + * Initialize the list for request-specific temporary storage. + */ +void +smb_srm_init(smb_request_t *sr) +{ + list_create(&sr->sr_storage, sizeof (smb_srm_t), + offsetof(smb_srm_t, srm_lnd)); +} + +/* + * Free everything on the request-specific temporary storage list + * and destroy the list. + */ +void +smb_srm_fini(smb_request_t *sr) +{ + smb_srm_t *srm; + + while ((srm = list_head(&sr->sr_storage)) != NULL) { + list_remove(&sr->sr_storage, srm); + smb_mfree(srm); + } + + list_destroy(&sr->sr_storage); +} + +/* + * Allocate memory and associate it with the specified request. + * Memory allocated here can only be used for the duration of + * this request; it will be freed automatically on completion + * of the request + */ +void * +smb_srm_alloc(smb_request_t *sr, size_t size) +{ + smb_srm_t *srm; + + size += sizeof (smb_srm_t); + srm = smb_malloc(size); + srm->srm_size = size; + srm->srm_sr = sr; + list_insert_tail(&sr->sr_storage, srm); + + /* + * The memory allocated for use be the caller is + * immediately after our storage context area. + */ + return (void *)(srm + 1); +} + +/* + * Allocate or resize memory previously allocated for the specified + * request. + */ +void * +smb_srm_realloc(smb_request_t *sr, void *p, size_t size) +{ + smb_srm_t *old_srm = (smb_srm_t *)p; + smb_srm_t *new_srm; + + if (old_srm == NULL) + return (smb_srm_alloc(sr, size)); + + old_srm--; + list_remove(&sr->sr_storage, old_srm); + + size += sizeof (smb_srm_t); + new_srm = smb_realloc(old_srm, size); + new_srm->srm_size = smb_memsize(new_srm); + new_srm->srm_sr = sr; + list_insert_tail(&sr->sr_storage, new_srm); + + /* + * The memory allocated for use be the caller is + * immediately after our storage context area. + */ + return (void *)(new_srm + 1); +} diff --git a/usr/src/uts/common/fs/smbsrv/smb_close.c b/usr/src/uts/common/fs/smbsrv/smb_close.c index d64c01586f..282411a6a3 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_close.c +++ b/usr/src/uts/common/fs/smbsrv/smb_close.c @@ -23,8 +23,7 @@ * Use is subject to license terms. */ -#include <smbsrv/smb_incl.h> - +#include <smbsrv/smb_kproto.h> /* * Close a file by fid. All locks or other resources held by the diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_open.c b/usr/src/uts/common/fs/smbsrv/smb_common_open.c index 74049d0c60..e63a7dca32 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_common_open.c +++ b/usr/src/uts/common/fs/smbsrv/smb_common_open.c @@ -28,13 +28,14 @@ * open and create SMB interface functions. */ -#include <smbsrv/smb_incl.h> -#include <smbsrv/smb_fsops.h> -#include <smbsrv/nterror.h> -#include <smbsrv/ntstatus.h> -#include <smbsrv/smbinfo.h> +#include <sys/types.h> +#include <sys/cmn_err.h> #include <sys/fcntl.h> #include <sys/nbmlock.h> +#include <smbsrv/string.h> +#include <smbsrv/smb_kproto.h> +#include <smbsrv/smb_fsops.h> +#include <smbsrv/smbinfo.h> volatile uint32_t smb_fids = 0; @@ -44,7 +45,7 @@ static void smb_delete_new_object(smb_request_t *); static int smb_set_open_timestamps(smb_request_t *, smb_ofile_t *, boolean_t); static char *smb_pathname_strdup(smb_request_t *, const char *); -static char *smb_pathname_strcat(char *, const char *); +static char *smb_pathname_strcat(smb_request_t *, char *, const char *); /* * smb_access_generic_to_file @@ -177,16 +178,22 @@ smb_ofun_to_crdisposition(uint16_t ofun) uint32_t smb_common_open(smb_request_t *sr) { - uint32_t status = NT_STATUS_SUCCESS; - int count; + open_param_t *parg; + uint32_t status = NT_STATUS_SUCCESS; + int count; + + parg = kmem_alloc(sizeof (*parg), KM_SLEEP); + bcopy(&sr->arg.open, parg, sizeof (*parg)); for (count = 0; count <= 4; count++) { - if (count) + if (count != 0) delay(MSEC_TO_TICK(400)); status = smb_open_subr(sr); if (status != NT_STATUS_SHARING_VIOLATION) break; + + bcopy(parg, &sr->arg.open, sizeof (*parg)); } if (status == NT_STATUS_SHARING_VIOLATION) { @@ -199,6 +206,8 @@ smb_common_open(smb_request_t *sr) ERRDOS, ERROR_FILE_NOT_FOUND); } + kmem_free(parg, sizeof (*parg)); + return (status); } @@ -951,7 +960,7 @@ smb_validate_object_name(smb_pathname_t *pn) { if (pn->pn_fname && strlen(pn->pn_fname) == 5 && - mts_isdigit(pn->pn_fname[3]) && + smb_isdigit(pn->pn_fname[3]) && pn->pn_fname[4] == ':') { return (NT_STATUS_OBJECT_NAME_INVALID); } @@ -991,8 +1000,8 @@ smb_delete_new_object(smb_request_t *sr) * smb_pathname_setup * Parse path: pname/fname:sname:stype * - * Elements of the smb_pathname_t structure are allocated using - * smbsr_malloc and will thus be free'd when the sr is destroyed. + * Elements of the smb_pathname_t structure are allocated using request + * specific storage and will be free'd when the sr is destroyed. * * Eliminate duplicate slashes in pn->pn_path. * Populate pn structure elements with the individual elements @@ -1048,10 +1057,10 @@ smb_pathname_setup(smb_request_t *sr, smb_pathname_t *pn) pn->pn_sname = smb_pathname_strdup(sr, sname); pn->pn_stype = strchr(pn->pn_sname + 1, ':'); if (pn->pn_stype) { - (void) utf8_strupr(pn->pn_stype); + (void) smb_strupr(pn->pn_stype); } else { len = strlen(pn->pn_sname); - pn->pn_sname = smb_pathname_strcat(pn->pn_sname, ":$DATA"); + pn->pn_sname = smb_pathname_strcat(sr, pn->pn_sname, ":$DATA"); pn->pn_stype = pn->pn_sname + len; } ++pn->pn_stype; @@ -1061,8 +1070,9 @@ smb_pathname_setup(smb_request_t *sr, smb_pathname_t *pn) * smb_pathname_strdup * * Duplicate NULL terminated string s. - * The new string buffer is allocated using smbsr_malloc and - * will thus be free'd when the sr is destroyed. + * + * The new string is allocated using request specific storage and will + * be free'd when the sr is destroyed. */ static char * smb_pathname_strdup(smb_request_t *sr, const char *s) @@ -1071,7 +1081,7 @@ smb_pathname_strdup(smb_request_t *sr, const char *s) size_t n; n = strlen(s) + 1; - s2 = (char *)smbsr_malloc(&sr->request_storage, n); + s2 = smb_srm_alloc(sr, n); (void) strlcpy(s2, s, n); return (s2); } @@ -1083,16 +1093,16 @@ smb_pathname_strdup(smb_request_t *sr, const char *s) * concatenating NULL terminated string s2. * Append s2 and return resulting NULL terminated string. * - * The string buffer is reallocated using smbsr_realloc - * and will thus be free'd when the sr is destroyed. + * The string buffer is reallocated using request specific + * storage and will be free'd when the sr is destroyed. */ static char * -smb_pathname_strcat(char *s1, const char *s2) +smb_pathname_strcat(smb_request_t *sr, char *s1, const char *s2) { size_t n; n = strlen(s1) + strlen(s2) + 1; - s1 = smbsr_realloc(s1, n); + s1 = smb_srm_realloc(sr, s1, n); (void) strlcat(s1, s2, n); return (s1); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_transact.c b/usr/src/uts/common/fs/smbsrv/smb_common_transact.c index 75358d2bc8..5b76e0397c 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_common_transact.c +++ b/usr/src/uts/common/fs/smbsrv/smb_common_transact.c @@ -23,14 +23,13 @@ * Use is subject to license terms. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> #include <smbsrv/smb_share.h> -#include <smbsrv/oem.h> +#include <smbsrv/string.h> #include <smbsrv/nmpipes.h> #include <smbsrv/mailslot.h> #include <smbsrv/lmerr.h> -#include <smbsrv/nterror.h> #define SMB_QUOTA_UNLIMITED 0xFFFFFFFFFFFFFFFF; @@ -105,8 +104,8 @@ smb_com_transaction(smb_request_t *sr) smb_xa_rele(sr->session, xa); return (SDRC_ERROR); } - xa->xa_smb_trans_name = MEM_STRDUP("smb", stn); + xa->xa_pipe_name = smb_strdup(stn); xa->smb_flags = flags; xa->smb_timeout = timeo; xa->req_disp_param = pscnt; @@ -460,6 +459,10 @@ smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa) smbsr_error(sr, 0, ERRSRV, ERRaccess); return (SDRC_ERROR); + case NT_TRANSACT_RENAME: + rc = smb_nt_transact_rename(sr, xa); + break; + default: smbsr_error(sr, 0, ERRSRV, ERRsmbcmd); return (SDRC_ERROR); @@ -1014,7 +1017,7 @@ smb_trans_net_share_getinfo(smb_request_t *sr, struct smb_xa *xa) &share, &level, &max_bytes) != 0) return (SDRC_NOT_IMPLEMENTED); - (void) utf8_strlwr(share); + (void) smb_strlwr(share); rc = smb_kshare_getinfo(sr->sr_server->sv_lmshrd, share, &si, NULL); if ((rc != NERR_Success) || (si.shr_flags & SMB_SHRF_LONGNAME)) { (void) smb_mbc_encodef(&xa->rep_param_mb, "www", @@ -1377,7 +1380,7 @@ smb_trans_net_server_enum2(struct smb_request *sr, struct smb_xa *xa) si = sr->sr_cfg; - if (utf8_strcasecmp(si->skc_nbdomain, (char *)domain) != 0) { + if (smb_strcasecmp(si->skc_nbdomain, (char *)domain, 0) != 0) { (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww", 0, 0, 0, 0); return (SDRC_SUCCESS); } @@ -1405,19 +1408,36 @@ smb_trans_net_server_enum2(struct smb_request *sr, struct smb_xa *xa) return (SDRC_SUCCESS); } +static boolean_t +is_supported_mailslot(const char *mailslot) +{ + static char *mailslots[] = { + PIPE_LANMAN, + MAILSLOT_LANMAN, + MAILSLOT_BROWSE, + MAILSLOT_MSBROWSE + }; + + int i; + + for (i = 0; i < sizeof (mailslots)/sizeof (mailslots[0]); ++i) + if (smb_strcasecmp(mailslot, mailslots[i], 0) == 0) + return (B_TRUE); + + return (B_FALSE); +} + /* - * is_supported_pipe - * - * Currently, just return 0 if the pipe is \\PIPE\repl otherwise - * return 1. + * Currently, just return false if the pipe is \\PIPE\repl. + * Otherwise, return true. */ -int -is_supported_pipe(char *pname) +static boolean_t +is_supported_pipe(const char *pname) { - if (utf8_strcasecmp(pname, PIPE_REPL) == 0) - return (0); + if (smb_strcasecmp(pname, PIPE_REPL, 0) == 0) + return (B_FALSE); - return (1); + return (B_TRUE); } static smb_sdrc_t @@ -1476,7 +1496,7 @@ smb_trans_dispatch(struct smb_request *sr, struct smb_xa *xa) break; case TRANS_WAIT_NMPIPE: - if (is_supported_pipe(xa->xa_smb_trans_name) == 0) { + if (!is_supported_pipe(xa->xa_pipe_name)) { smbsr_error(sr, 0, ERRDOS, ERRbadfile); return (SDRC_ERROR); } @@ -1487,14 +1507,7 @@ smb_trans_dispatch(struct smb_request *sr, struct smb_xa *xa) goto trans_err_not_supported; } } else { - if ((utf8_strcasecmp(xa->xa_smb_trans_name, - PIPE_LANMAN) != 0) && - (utf8_strcasecmp( - xa->xa_smb_trans_name, MAILSLOT_LANMAN) != 0) && - (utf8_strcasecmp( - xa->xa_smb_trans_name, MAILSLOT_BROWSE) != 0) && - (utf8_strcasecmp( - xa->xa_smb_trans_name, MAILSLOT_MSBROWSE) != 0)) + if (!is_supported_mailslot(xa->xa_pipe_name)) goto trans_err_not_supported; if ((rc = smb_mbc_decodef(&xa->req_param_mb, "%wss", sr, @@ -1839,7 +1852,7 @@ smb_xa_create( smb_xa_t *xa, *nxa; smb_llist_t *xlist; - xa = MEM_ZALLOC("xa", sizeof (smb_xa_t)); + xa = kmem_zalloc(sizeof (smb_xa_t), KM_SLEEP); xa->xa_refcnt = 1; xa->smb_com = sr->smb_com; xa->smb_flg = sr->smb_flg; @@ -1872,7 +1885,7 @@ smb_xa_create( !SMB_XA_CLOSED(nxa) && !(nxa->xa_flags & SMB_XA_FLAG_COMPLETE)) { smb_llist_exit(xlist); - MEM_FREE("xa", xa); + kmem_free(xa, sizeof (smb_xa_t)); return (NULL); } nxa = smb_llist_next(xlist, nxa); @@ -1888,8 +1901,8 @@ smb_xa_delete(smb_xa_t *xa) ASSERT(xa->xa_refcnt == 0); ASSERT(SMB_XA_CLOSED(xa)); - if (xa->xa_smb_trans_name) - MEM_FREE("smb", xa->xa_smb_trans_name); + if (xa->xa_pipe_name) + smb_mfree(xa->xa_pipe_name); if (xa->rep_setup_mb.chain != NULL) m_freem(xa->rep_setup_mb.chain); @@ -1899,7 +1912,7 @@ smb_xa_delete(smb_xa_t *xa) m_freem(xa->rep_data_mb.chain); xa->xa_magic = (uint32_t)~SMB_XA_MAGIC; - MEM_FREE("xa", xa); + kmem_free(xa, sizeof (smb_xa_t)); } smb_xa_t * diff --git a/usr/src/uts/common/fs/smbsrv/smb_create.c b/usr/src/uts/common/fs/smbsrv/smb_create.c index ddc8408248..066b66bb85 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_create.c +++ b/usr/src/uts/common/fs/smbsrv/smb_create.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #define SMB_CREATE_NAMEBUF_SZ 16 @@ -159,7 +159,7 @@ smb_com_create_temporary(smb_request_t *sr) bcc = 1; /* null terminator */ bcc += snprintf(name, SMB_CREATE_NAMEBUF_SZ, "tt%05d.tmp", tmp_id); - buf = smbsr_malloc(&sr->request_storage, MAXPATHLEN); + buf = smb_srm_alloc(sr, MAXPATHLEN); (void) snprintf(buf, MAXPATHLEN, "%s\\%s", op->fqi.fq_path.pn_path, name); op->fqi.fq_path.pn_path = buf; diff --git a/usr/src/uts/common/fs/smbsrv/smb_delete.c b/usr/src/uts/common/fs/smbsrv/smb_delete.c index 7c1481bfae..e6d357c378 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_delete.c +++ b/usr/src/uts/common/fs/smbsrv/smb_delete.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> #include <smbsrv/smbinfo.h> #include <sys/nbmlock.h> diff --git a/usr/src/uts/common/fs/smbsrv/smb_directory.c b/usr/src/uts/common/fs/smbsrv/smb_directory.c index 60d95d0198..e21742220a 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_directory.c +++ b/usr/src/uts/common/fs/smbsrv/smb_directory.c @@ -23,10 +23,8 @@ * Use is subject to license terms. */ -#include <smbsrv/nterror.h> -#include <smbsrv/ntstatus.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smbinfo.h> -#include <smbsrv/smb_incl.h> #include <smbsrv/smb_fsops.h> typedef struct smb_dirpath { @@ -259,13 +257,12 @@ smb_dirpath_new(smb_request_t *sr) char *xpath; smb_dirpath_t *spp; - /* Malloc from the request storage area. This is freed automatically */ - /* so we don't need to worry about freeing it later */ - spp = smbsr_malloc(&sr->request_storage, sizeof (smb_dirpath_t)); + /* Allocate using request specific memory. */ + spp = smb_srm_alloc(sr, sizeof (smb_dirpath_t)); spp->sp_path = sr->arg.dirop.fqi.fq_path.pn_path; pathLen = strlen(spp->sp_path); spp->sp_curp = spp->sp_path; - xpath = smbsr_malloc(&sr->request_storage, pathLen + 1); + xpath = smb_srm_alloc(sr, pathLen + 1); sr->arg.dirop.fqi.fq_path.pn_path = xpath; spp->sp_sr = sr; @@ -589,7 +586,7 @@ smb_dirpath_isvalid(const char *path) if (*path == '\0') return (B_TRUE); - cp = smb_kstrdup(path, MAXPATHLEN); + cp = smb_strdup(path); p = strcanon(cp, "\\"); p += strspn(p, "\\"); @@ -597,11 +594,11 @@ smb_dirpath_isvalid(const char *path) bad = &bad_paths[i]; if (strncmp(p, bad->name, bad->len) == 0) { - kmem_free(cp, MAXPATHLEN); + smb_mfree(cp); return (B_FALSE); } } - kmem_free(cp, MAXPATHLEN); + smb_mfree(cp); return (B_TRUE); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_dispatch.c b/usr/src/uts/common/fs/smbsrv/smb_dispatch.c index 75b42e37bb..296ef8f2c2 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_dispatch.c +++ b/usr/src/uts/common/fs/smbsrv/smb_dispatch.c @@ -135,7 +135,7 @@ * empty if an error. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_kstat.h> #include <sys/sdt.h> diff --git a/usr/src/uts/common/fs/smbsrv/smb_echo.c b/usr/src/uts/common/fs/smbsrv/smb_echo.c index d934ccafd4..d7c8c7c859 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_echo.c +++ b/usr/src/uts/common/fs/smbsrv/smb_echo.c @@ -19,13 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> /* * The echo request is used to test the connection to the server, @@ -62,7 +60,7 @@ smb_com_echo(struct smb_request *sr) return (SDRC_ERROR); nbytes = sr->smb_bcc; - data = smbsr_malloc(&sr->request_storage, nbytes); + data = smb_srm_alloc(sr, nbytes); if (smb_mbc_decodef(&sr->smb_data, "#c", nbytes, data)) return (SDRC_ERROR); diff --git a/usr/src/uts/common/fs/smbsrv/smb_fem.c b/usr/src/uts/common/fs/smbsrv/smb_fem.c index 3582ce4986..ee3a38851f 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_fem.c +++ b/usr/src/uts/common/fs/smbsrv/smb_fem.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> #include <sys/sdt.h> #include <sys/fcntl.h> diff --git a/usr/src/uts/common/fs/smbsrv/smb_find.c b/usr/src/uts/common/fs/smbsrv/smb_find.c index ec55d1e6ba..f556f683ac 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_find.c +++ b/usr/src/uts/common/fs/smbsrv/smb_find.c @@ -23,6 +23,7 @@ * Use is subject to license terms. */ +#include <smbsrv/smb_kproto.h> /* * smb_com_search @@ -194,8 +195,6 @@ * circuit to the consumer. */ -#include <smbsrv/smb_incl.h> - /* *** smb_com_search *** */ smb_sdrc_t @@ -329,7 +328,7 @@ smb_com_search(smb_request_t *sr) (void) strlcpy(name, fileinfo.fi_name, SMB_SHORTNAMELEN - 1); if (to_upper) - (void) utf8_strupr(name); + (void) smb_strupr(name); } else { (void) strlcpy(name, fileinfo.fi_shortname, SMB_SHORTNAMELEN - 1); diff --git a/usr/src/uts/common/fs/smbsrv/smb_flush.c b/usr/src/uts/common/fs/smbsrv/smb_flush.c index 5f86e42dee..5de347b6b5 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_flush.c +++ b/usr/src/uts/common/fs/smbsrv/smb_flush.c @@ -36,7 +36,7 @@ * draft-heizer-cifs-v1-spec-00.txt */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> diff --git a/usr/src/uts/common/fs/smbsrv/smb_fsops.c b/usr/src/uts/common/fs/smbsrv/smb_fsops.c index c427df5632..e78a5c1a8a 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_fsops.c +++ b/usr/src/uts/common/fs/smbsrv/smb_fsops.c @@ -27,9 +27,6 @@ #include <sys/nbmlock.h> #include <smbsrv/smb_fsops.h> #include <smbsrv/smb_kproto.h> -#include <smbsrv/ntstatus.h> -#include <smbsrv/ntaccess.h> -#include <smbsrv/smb_incl.h> #include <acl/acl_common.h> #include <sys/fcntl.h> #include <sys/flock.h> @@ -972,8 +969,8 @@ smb_fsop_getattr(smb_request_t *sr, cred_t *cr, smb_node_t *snode, * into this routine. */ int -smb_fsop_link(smb_request_t *sr, cred_t *cr, smb_node_t *to_dnode, - smb_node_t *from_fnode, char *to_name) +smb_fsop_link(smb_request_t *sr, cred_t *cr, smb_node_t *from_fnode, + smb_node_t *to_dnode, char *to_name) { char *longname = NULL; int flags = 0; @@ -1102,6 +1099,28 @@ smb_fsop_rename( (ACE_DELETE | ACE_ADD_FILE))) return (EACCES); + /* + * SMB checks access on open and retains an access granted + * mask for use while the file is open. ACL changes should + * not affect access to an open file. + * + * If the rename is being performed on an ofile: + * - Check the ofile's access granted mask to see if the + * rename is permitted - requires DELETE access. + * - If the file system does access checking, set the + * ATTR_NOACLCHECK flag to ensure that the file system + * does not check permissions on subsequent calls. + */ + if (sr && sr->fid_ofile) { + rc = smb_ofile_access(sr->fid_ofile, cr, DELETE); + if (rc != NT_STATUS_SUCCESS) + return (EACCES); + + if (smb_tree_has_feature(sr->tid_tree, + SMB_TREE_ACEMASKONACCESS)) + flags = ATTR_NOACLCHECK; + } + rc = smb_vop_rename(from_dnode->vp, from_name, to_dnode->vp, to_name, flags, cr); @@ -1648,6 +1667,13 @@ smb_fsop_lookup_name( * * Other smb_fsop_* routines will call SMB_TREE_CONTAINS_NODE() to prevent * operations on files not in the parent mount. + * + * Case sensitivity flags (SMB_IGNORE_CASE, SMB_CASE_SENSITIVE): + * if SMB_CASE_SENSITIVE is set, the SMB_IGNORE_CASE flag will NOT be set + * based on the tree's case sensitivity. However, if the SMB_IGNORE_CASE + * flag is set in the flags value passed as a parameter, a case insensitive + * lookup WILL be done (regardless of whether SMB_CASE_SENSITIVE is set + * or not). */ int smb_fsop_lookup( @@ -1678,8 +1704,10 @@ smb_fsop_lookup( if (SMB_TREE_CONTAINS_NODE(sr, dnode) == 0) return (EACCES); - if (SMB_TREE_IS_CASEINSENSITIVE(sr)) - flags |= SMB_IGNORE_CASE; + if (!(flags & SMB_CASE_SENSITIVE)) { + if (SMB_TREE_IS_CASEINSENSITIVE(sr)) + flags |= SMB_IGNORE_CASE; + } if (SMB_TREE_SUPPORTS_CATIA(sr)) flags |= SMB_CATIA; if (SMB_TREE_SUPPORTS_ABE(sr)) diff --git a/usr/src/uts/common/fs/smbsrv/smb_init.c b/usr/src/uts/common/fs/smbsrv/smb_init.c index 2059dd572b..a974bdbd30 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_init.c +++ b/usr/src/uts/common/fs/smbsrv/smb_init.c @@ -30,10 +30,9 @@ #include <sys/ioccom.h> #include <sys/policy.h> #include <sys/cmn_err.h> -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_door_svc.h> #include <smbsrv/smb_ioctl.h> -#include <smbsrv/smb_kproto.h> static int smb_drv_open(dev_t *, int, int, cred_t *); static int smb_drv_close(dev_t, int, int, cred_t *); diff --git a/usr/src/uts/common/fs/smbsrv/smb_lock.c b/usr/src/uts/common/fs/smbsrv/smb_lock.c index c7901ca7f2..d74aa0be32 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_lock.c +++ b/usr/src/uts/common/fs/smbsrv/smb_lock.c @@ -31,7 +31,7 @@ * error code. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> #include <sys/nbmlock.h> #include <sys/param.h> diff --git a/usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c b/usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c index bf74578aba..02ade5c43d 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c +++ b/usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c @@ -57,7 +57,7 @@ * should return failure to the client */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> smb_sdrc_t smb_pre_lock_byte_range(smb_request_t *sr) diff --git a/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c b/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c index dd765c0979..98906e97e2 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c +++ b/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c @@ -208,7 +208,7 @@ * ERRSRV/ERRbaduid */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> smb_sdrc_t smb_pre_locking_andx(smb_request_t *sr) diff --git a/usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c b/usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c index 6eedfe3d19..6e9a00d975 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c +++ b/usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c @@ -19,13 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> /* diff --git a/usr/src/uts/common/fs/smbsrv/smb_mangle_name.c b/usr/src/uts/common/fs/smbsrv/smb_mangle_name.c index 2d73bb38ac..860e82cc5a 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_mangle_name.c +++ b/usr/src/uts/common/fs/smbsrv/smb_mangle_name.c @@ -28,15 +28,10 @@ #include <sys/sunddi.h> #include <sys/errno.h> #include <smbsrv/string.h> -#include <smbsrv/ctype.h> -#include <smbsrv/smb_i18n.h> #include <smbsrv/smb_vops.h> -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> -#define SMB_NAME83_BASELEN 8 -#define SMB_NAME83_LEN 12 - /* * Characters we don't allow in DOS file names. * If a filename contains any of these chars, it should get mangled. @@ -138,7 +133,7 @@ smb_match_unknown(char *name, char *pattern) char *np, *pp; rc = 0; - if (utf8_isstrupr(pattern) <= 0) + if (smb_isstrupr(pattern) <= 0) return (rc); np = name; @@ -149,7 +144,7 @@ smb_match_unknown(char *name, char *pattern) if (nc == ' ') continue; - nc = mts_toupper(nc); + nc = smb_toupper(nc); if ((pc = *pp++) != nc) break; } @@ -157,7 +152,7 @@ smb_match_unknown(char *name, char *pattern) if ((pc == '~') && (pp != (pattern + 1)) && ((pc = *pp++) != 0)) { - while (mts_isdigit(pc)) + while (smb_isdigit(pc)) pc = *pp++; if (pc == '.') { @@ -167,7 +162,7 @@ smb_match_unknown(char *name, char *pattern) } while ((nc = *np++) != 0) { - nc = mts_toupper(nc); + nc = smb_toupper(nc); if ((pc = *pp++) != nc) break; } @@ -222,7 +217,7 @@ smb_is_reserved_dos_name(const char *name) int len; int i; - ch = mts_toupper(*name); + ch = smb_toupper(*name); switch (ch) { case 'A': @@ -246,7 +241,7 @@ smb_is_reserved_dos_name(const char *name) for (i = 0; i < n_reserved; ++i) { len = strlen(reserved[i]); - if (utf8_strncasecmp(reserved[i], name, len) == 0) { + if (smb_strcasecmp(reserved[i], name, len) == 0) { ch = *(name + len); if ((ch == '\0') || (ch == '.')) return (B_TRUE); @@ -329,7 +324,7 @@ smb_needs_mangle(char *name, char **dot_pos) } for (namep = name; *namep; namep++) { - if (!mts_isascii(*namep) || + if (!smb_isascii(*namep) || strchr(special_chars, *namep) || strchr(invalid_dos_chars, *namep)) return (1); @@ -391,7 +386,7 @@ smb_needs_shortname(char *name) if (len) { (void) snprintf(buf, len + 1, "%s", name); /* if the name contains both lower and upper cases */ - if (utf8_isstrupr(buf) == 0 && utf8_isstrlwr(buf) == 0) { + if (smb_isstrupr(buf) == 0 && smb_isstrlwr(buf) == 0) { /* create shortname */ create = 1; } else if (dot_pos) { @@ -401,7 +396,7 @@ smb_needs_shortname(char *name) * if the extension contains both lower and upper * cases */ - if (utf8_isstrupr(buf) == 0 && utf8_isstrlwr(buf) == 0) + if (smb_isstrupr(buf) == 0 && smb_isstrlwr(buf) == 0) /* create shortname */ create = 1; } @@ -430,7 +425,7 @@ smb_mangle_char(unsigned char ch) if (strchr(special_chars, ch)) return ('_'); - return (mts_toupper(ch)); + return (smb_toupper(ch)); } /* @@ -565,21 +560,21 @@ int smb_mangle_name( if (smb_needs_shortname(name)) { namep = (unsigned char *)name; while (*namep) - *out_short++ = mts_toupper(*namep++); + *out_short++ = smb_toupper(*namep++); *out_short = '\0'; } out_83 = (unsigned char *)name83; (void) strcpy((char *)out_83, " . "); while (*name && *name != '.') - *out_83++ = mts_toupper(*name++); + *out_83++ = smb_toupper(*name++); if (*name == '.') { /* copy extension */ name++; out_83 = (unsigned char *)name83 + 9; while (*name) - *out_83++ = mts_toupper(*name++); + *out_83++ = smb_toupper(*name++); } return (1); } @@ -723,10 +718,15 @@ smb_unmangle_name(smb_node_t *dnode, char *name, char *namebuf, namep = dp->d_name; } + /* skip non utf8 filename */ + if (u8_validate(namep, strlen(namep), NULL, + U8_VALIDATE_ENTIRE, &err) < 0) + continue; + (void) smb_mangle_name(ino, namep, shortname, name83, 1); - if (utf8_strcasecmp(name, shortname) == 0) { + if (smb_strcasecmp(name, shortname, 0) == 0) { (void) strlcpy(namebuf, namep, buflen); kmem_free(buf, SMB_UNMANGLE_BUFSIZE); return (0); diff --git a/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c b/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c index 3eb054e383..3d60f5fd77 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c +++ b/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c @@ -27,9 +27,7 @@ * SMB mbuf marshaling encode/decode. */ -#include <smbsrv/smb_incl.h> - -#include <sys/sunddi.h> +#include <smbsrv/smb_kproto.h> #define MALLOC_QUANTUM 80 @@ -58,10 +56,10 @@ static int mbc_marshal_get_long(mbuf_chain_t *mbc, uint32_t *data); static uint64_t qswap(uint64_t ll); static int mbc_marshal_get_odd_long_long(mbuf_chain_t *mbc, uint64_t *data); static int mbc_marshal_get_long_long(mbuf_chain_t *mbc, uint64_t *data); -static int mbc_marshal_get_ascii_string(struct smb_malloc_list *, - mbuf_chain_t *, uint8_t **ascii, int); -static int mbc_marshal_get_unicode_string(struct smb_malloc_list *, - mbuf_chain_t *, uint8_t **, int); +static int mbc_marshal_get_ascii_string(smb_request_t *, mbuf_chain_t *, + uint8_t **ascii, int); +static int mbc_marshal_get_unicode_string(smb_request_t *, mbuf_chain_t *, + uint8_t **, int); static int mbc_marshal_get_mbufs(mbuf_chain_t *, int32_t, mbuf_t **); static int mbc_marshal_get_mbuf_chain(mbuf_chain_t *, int32_t, mbuf_chain_t *); static int mbc_marshal_get_uio(mbuf_chain_t *, struct uio *); @@ -298,7 +296,7 @@ ascii_conversion: cvalpp = va_arg(ap, uint8_t **); if (repc <= 1) repc = 0; - if (mbc_marshal_get_ascii_string(&sr->request_storage, + if (mbc_marshal_get_ascii_string(sr, mbc, cvalpp, repc) != 0) return (-1); break; @@ -311,7 +309,7 @@ unicode_translation: repc = 0; if (mbc->chain_offset & 1) mbc->chain_offset++; - if (mbc_marshal_get_unicode_string(&sr->request_storage, + if (mbc_marshal_get_unicode_string(sr, mbc, cvalpp, repc) != 0) return (-1); break; @@ -909,11 +907,11 @@ mbc_marshal_put_long_long(mbuf_chain_t *mbc, uint64_t data) static int mbc_marshal_put_ascii_string(mbuf_chain_t *mbc, char *mbs, int repc) { - mts_wchar_t wide_char; + smb_wchar_t wide_char; int nbytes; int length; - if ((length = mts_sbequiv_strlen(mbs)) == -1) + if ((length = smb_sbequiv_strlen(mbs)) == -1) return (DECODE_NO_MORE_DATA); length += sizeof (char); @@ -927,7 +925,7 @@ mbc_marshal_put_ascii_string(mbuf_chain_t *mbc, char *mbs, int repc) /* * We should restore oem chars here. */ - nbytes = mts_mbtowc(&wide_char, mbs, MTS_MB_CHAR_MAX); + nbytes = smb_mbtowc(&wide_char, mbs, MTS_MB_CHAR_MAX); if (nbytes == -1) return (DECODE_NO_MORE_DATA); @@ -946,14 +944,14 @@ mbc_marshal_put_ascii_string(mbuf_chain_t *mbc, char *mbs, int repc) static int mbc_marshal_put_unicode_string(mbuf_chain_t *mbc, char *ascii, int repc) { - mts_wchar_t wchar; + smb_wchar_t wchar; int consumed; int length; - if ((length = mts_wcequiv_strlen(ascii)) == -1) + if ((length = smb_wcequiv_strlen(ascii)) == -1) return (DECODE_NO_MORE_DATA); - length += sizeof (mts_wchar_t); + length += sizeof (smb_wchar_t); if ((repc > 1) && (repc < length)) length = repc; @@ -961,7 +959,7 @@ mbc_marshal_put_unicode_string(mbuf_chain_t *mbc, char *ascii, int repc) if (mbc_marshal_make_room(mbc, length)) return (DECODE_NO_MORE_DATA); while (length > 0) { - consumed = mts_mbtowc(&wchar, ascii, MTS_MB_CHAR_MAX); + consumed = smb_mbtowc(&wchar, ascii, MTS_MB_CHAR_MAX); if (consumed == -1) break; /* Invalid sequence */ /* @@ -973,7 +971,7 @@ mbc_marshal_put_unicode_string(mbuf_chain_t *mbc, char *ascii, int repc) ascii += consumed; mbc_marshal_store_byte(mbc, wchar); mbc_marshal_store_byte(mbc, wchar >> 8); - length -= sizeof (mts_wchar_t); + length -= sizeof (smb_wchar_t); } return (0); } @@ -1215,10 +1213,10 @@ mbc_marshal_get_long_long(mbuf_chain_t *mbc, uint64_t *data) */ static int mbc_marshal_get_ascii_string( - struct smb_malloc_list *ml, - mbuf_chain_t *mbc, + smb_request_t *sr, + mbuf_chain_t *mbc, uint8_t **ascii, - int max_ascii) + int max_ascii) { char *rcvbuf; char *ch; @@ -1226,7 +1224,7 @@ mbc_marshal_get_ascii_string( int length = 0; max = MALLOC_QUANTUM; - rcvbuf = smbsr_malloc(ml, max); + rcvbuf = smb_srm_alloc(sr, max); if (max_ascii == 0) max_ascii = 0xffff; @@ -1247,7 +1245,7 @@ mbc_marshal_get_ascii_string( length++; } max += MALLOC_QUANTUM; - rcvbuf = smbsr_realloc(rcvbuf, max); + rcvbuf = smb_srm_realloc(sr, rcvbuf, max); ch = rcvbuf + length; } @@ -1256,13 +1254,13 @@ multibyte_encode: * UTF-8 encode the string for internal system use. */ length = strlen(rcvbuf) + 1; - *ascii = smbsr_malloc(ml, length * MTS_MB_CHAR_MAX); + *ascii = smb_srm_alloc(sr, length * MTS_MB_CHAR_MAX); return (mbc_marshal_cstou8("CP850", (char *)*ascii, (size_t)length * MTS_MB_CHAR_MAX, rcvbuf, (size_t)length)); } static int -mbc_marshal_get_unicode_string(struct smb_malloc_list *ml, +mbc_marshal_get_unicode_string(smb_request_t *sr, mbuf_chain_t *mbc, uint8_t **ascii, int max_unicode) { int max; @@ -1275,7 +1273,7 @@ mbc_marshal_get_unicode_string(struct smb_malloc_list *ml, max_unicode = 0xffff; max = MALLOC_QUANTUM; - *ascii = smbsr_malloc(ml, max); + *ascii = smb_srm_alloc(sr, max); ch = (char *)*ascii; for (;;) { @@ -1289,12 +1287,12 @@ mbc_marshal_get_unicode_string(struct smb_malloc_list *ml, if (wchar == 0) goto done; - emitted = mts_wctomb(ch, wchar); + emitted = smb_wctomb(ch, wchar); length += emitted; ch += emitted; } max += MALLOC_QUANTUM; - *ascii = smbsr_realloc(*ascii, max); + *ascii = smb_srm_realloc(sr, *ascii, max); ch = (char *)*ascii + length; } done: *ch = 0; diff --git a/usr/src/uts/common/fs/smbsrv/smb_mbuf_util.c b/usr/src/uts/common/fs/smbsrv/smb_mbuf_util.c index 8dcba3b111..76d468eebe 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_mbuf_util.c +++ b/usr/src/uts/common/fs/smbsrv/smb_mbuf_util.c @@ -57,8 +57,7 @@ * */ -#include <smbsrv/smb_incl.h> -#include <smbsrv/mbuf.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_kstat.h> static kmem_cache_t *smb_mbc_cache = NULL; diff --git a/usr/src/uts/common/fs/smbsrv/smb_memory_manager.c b/usr/src/uts/common/fs/smbsrv/smb_memory_manager.c deleted file mode 100644 index 61e1066388..0000000000 --- a/usr/src/uts/common/fs/smbsrv/smb_memory_manager.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Memory management functions. - */ - -#include <smbsrv/smb_incl.h> - -/* - * smbsr_malloc - * - * allocate a block of memory with the given size and - * add it to the given linked list. This function is - * used to allocate temporary memories which are needed - * during processing of a SMB request. These memories - * get freed when request processing is finished. - */ -void * -smbsr_malloc(smb_malloc_list *list, size_t size) -{ - smb_malloc_list *element; - - size += sizeof (smb_malloc_list); - element = MEM_MALLOC("smb", size); - element->forw = list->forw; - element->back = list; - list->forw->back = element; - list->forw = element; - return (void *)(element + 1); /* return address of data */ -} - -/* - * smbsr_realloc - * - * This function is used in conjunction with smbsr_malloc to - * resize an already allocated entity. - */ -void * -smbsr_realloc(void *mem, size_t size) -{ - smb_malloc_list *element = (smb_malloc_list *)mem; - smb_malloc_list *new_entry; - smb_malloc_list *list; - - element--; - list = element->back; - QUEUE_CLIP(element); - size += sizeof (smb_malloc_list); - - new_entry = MEM_REALLOC("smb", element, size); - new_entry->forw = list->forw; - new_entry->back = list; - list->forw->back = new_entry; - list->forw = new_entry; - return (void *)(new_entry + 1); /* return address of new data */ -} - -/* - * smbsr_free_malloc_list - * - * Frees all memory block in the given linked list. - */ -void -smbsr_free_malloc_list(smb_malloc_list *root) -{ - smb_malloc_list *element; - - /* - * we initialize smb_request structure in smb_nt_notify_change - * function, so we should check root->forw to make sure it's - * not NULL. - */ - while (root->forw && root->forw != root) { - element = root->forw; - - element->forw->back = element->back; - element->back->forw = element->forw; - - /* and release it... */ - MEM_FREE("smb", element); - } -} diff --git a/usr/src/uts/common/fs/smbsrv/smb_negotiate.c b/usr/src/uts/common/fs/smbsrv/smb_negotiate.c index acca9991c9..17975468cc 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_negotiate.c +++ b/usr/src/uts/common/fs/smbsrv/smb_negotiate.c @@ -175,7 +175,7 @@ * Connectionless clients must set Sid to 0 in the SMB request header. * * Capabilities allows the server to tell the client what it supports. - * The bit definitions defined in cifs.h. Bit 0x2000 used to be set in + * The bit definitions defined in smb.h. Bit 0x2000 used to be set in * the negotiate response capabilities but it caused problems with * Windows 2000. It is probably not valid, it doesn't appear in the * CIFS spec. @@ -191,9 +191,8 @@ #include <sys/socket.h> #include <sys/random.h> #include <netinet/in.h> -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smbinfo.h> -#include <smbsrv/smb_i18n.h> /* * Maximum buffer size for DOS: chosen to be the same as NT. @@ -400,8 +399,8 @@ smb_com_negotiate(smb_request_t *sr) * skc_nbdomain is not expected to be aligned. * Use temporary buffer to avoid alignment padding */ - buflen = mts_wcequiv_strlen(sr->sr_cfg->skc_nbdomain) + - sizeof (mts_wchar_t); + buflen = smb_wcequiv_strlen(sr->sr_cfg->skc_nbdomain) + + sizeof (smb_wchar_t); tmpbuf = kmem_zalloc(buflen, KM_SLEEP); smb_msgbuf_init(&mb, (uint8_t *)tmpbuf, buflen, SMB_MSGBUF_UNICODE); diff --git a/usr/src/uts/common/fs/smbsrv/smb_node.c b/usr/src/uts/common/fs/smbsrv/smb_node.c index bd97813765..ae578f0899 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_node.c +++ b/usr/src/uts/common/fs/smbsrv/smb_node.c @@ -128,7 +128,7 @@ * course the state of the node should be tested/updated under the * protection of the mutex). */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> #include <smbsrv/smb_kstat.h> #include <sys/pathname.h> @@ -1283,6 +1283,7 @@ smb_node_getattr(smb_request_t *sr, smb_node_t *node, smb_attr_t *attr) if (node->vp->v_type == VDIR) { attr->sa_vattr.va_size = 0; attr->sa_allocsz = 0; + attr->sa_vattr.va_nlink = 1; } if (node->readonly_creator) diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_cancel.c b/usr/src/uts/common/fs/smbsrv/smb_nt_cancel.c index b49705efb8..1e4d9df892 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_nt_cancel.c +++ b/usr/src/uts/common/fs/smbsrv/smb_nt_cancel.c @@ -41,7 +41,7 @@ * the original request. No other response is generated for this SMB. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> smb_sdrc_t smb_pre_nt_cancel(smb_request_t *sr) diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c b/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c index aa12b2c96b..c5222de5ab 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c +++ b/usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c @@ -28,7 +28,7 @@ */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> #include <smbsrv/smb_vops.h> @@ -220,6 +220,11 @@ void smb_post_nt_create_andx(smb_request_t *sr) { DTRACE_SMB_1(op__NtCreateX__done, smb_request_t *, sr); + + if (sr->arg.open.dir != NULL) { + smb_ofile_release(sr->arg.open.dir); + sr->arg.open.dir = NULL; + } } smb_sdrc_t @@ -260,16 +265,14 @@ smb_com_nt_create_andx(struct smb_request *sr) if (op->rootdirfid == 0) { op->fqi.fq_dnode = sr->tid_tree->t_snode; } else { - sr->smb_fid = (ushort_t)op->rootdirfid; - smbsr_lookup_file(sr); - if (sr->fid_ofile == NULL) { + op->dir = smb_ofile_lookup_by_fid(sr->tid_tree, + (uint16_t)op->rootdirfid); + if (op->dir == NULL) { smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid); return (SDRC_ERROR); } - - op->fqi.fq_dnode = sr->fid_ofile->f_node; - smbsr_release_file(sr); + op->fqi.fq_dnode = op->dir->f_node; } if (smb_common_open(sr) != NT_STATUS_SUCCESS) diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c index 80f2319a96..22786fe92d 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c +++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c @@ -35,11 +35,6 @@ #include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> -#include <smbsrv/ntstatus.h> -#include <smbsrv/ntaccess.h> -#include <smbsrv/nterror.h> -#include <smbsrv/cifs.h> -#include <smbsrv/doserror.h> /* * smb_nt_transact_create @@ -136,6 +131,9 @@ smb_post_nt_transact_create(smb_request_t *sr, smb_xa_t *xa) smb_sd_term(sd); kmem_free(sd, sizeof (smb_sd_t)); } + + if (sr->arg.open.dir != NULL) + smb_ofile_release(sr->arg.open.dir); } smb_sdrc_t @@ -176,16 +174,14 @@ smb_nt_transact_create(smb_request_t *sr, smb_xa_t *xa) if (op->rootdirfid == 0) { op->fqi.fq_dnode = sr->tid_tree->t_snode; } else { - sr->smb_fid = (ushort_t)op->rootdirfid; - smbsr_lookup_file(sr); - if (sr->fid_ofile == NULL) { + op->dir = smb_ofile_lookup_by_fid(sr->tid_tree, + (uint16_t)op->rootdirfid); + if (op->dir == NULL) { smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid); return (SDRC_ERROR); } - - op->fqi.fq_dnode = sr->fid_ofile->f_node; - smbsr_release_file(sr); + op->fqi.fq_dnode = op->dir->f_node; } status = smb_common_open(sr); diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c index d1290e5889..ac52576534 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c +++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c @@ -23,9 +23,8 @@ * Use is subject to license terms. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/winioctl.h> -#include <smbsrv/ntstatus.h> static uint32_t smb_nt_trans_ioctl_noop(smb_request_t *, smb_xa_t *); diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c index cfb82e5419..e806482f3a 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c +++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c @@ -109,7 +109,7 @@ * FILE_ACTION_MODIFIED_STREAM 0x00000008 */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <sys/sdt.h> static void smb_notify_change_daemon(smb_thread_t *, void *); diff --git a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c index de6b9b385f..e2ceeb9de5 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c +++ b/usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c @@ -24,10 +24,6 @@ */ #include <smbsrv/smb_kproto.h> -#include <smbsrv/ntstatus.h> -#include <smbsrv/nterror.h> -#include <smbsrv/doserror.h> -#include <smbsrv/cifs.h> static void smb_encode_sd(struct smb_xa *, smb_sd_t *, uint32_t); static void smb_encode_sacl(struct smb_xa *, smb_acl_t *); diff --git a/usr/src/uts/common/fs/smbsrv/smb_odir.c b/usr/src/uts/common/fs/smbsrv/smb_odir.c index c953aa05a5..c89bee8e98 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_odir.c +++ b/usr/src/uts/common/fs/smbsrv/smb_odir.c @@ -243,7 +243,6 @@ * See smb_search, smb_find, smb_find_unique, and smb_trans2_find for details */ -#include <smbsrv/smb_incl.h> #include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> #include <smbsrv/smb_share.h> @@ -573,7 +572,7 @@ int smb_odir_read_fileinfo(smb_request_t *sr, smb_odir_t *od, smb_fileinfo_t *fileinfo, boolean_t *eof) { - int rc; + int rc, errnum; smb_odirent_t *odirent; boolean_t ignore_case; @@ -612,6 +611,12 @@ smb_odir_read_fileinfo(smb_request_t *sr, smb_odir_t *od, if ((rc = smb_odir_next_odirent(od, odirent)) != 0) break; + /* skip non utf8 filename */ + if (u8_validate(odirent->od_name, + strlen(odirent->od_name), NULL, + U8_VALIDATE_ENTIRE, &errnum) < 0) + continue; + if (!smb_match_name(odirent->od_ino, odirent->od_name, od->d_pattern, ignore_case)) continue; diff --git a/usr/src/uts/common/fs/smbsrv/smb_ofile.c b/usr/src/uts/common/fs/smbsrv/smb_ofile.c index 8d7ec2f06d..fa0904040f 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_ofile.c +++ b/usr/src/uts/common/fs/smbsrv/smb_ofile.c @@ -160,7 +160,6 @@ * being queued in that list is NOT registered by incrementing the * reference count. */ -#include <smbsrv/smb_incl.h> #include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> @@ -616,7 +615,7 @@ smb_ofile_disallow_fclose(smb_ofile_t *of) case SMB_FTYPE_MESG_PIPE: ASSERT(of->f_pipe); - if (utf8_strcasecmp(of->f_pipe->p_name, "SRVSVC") == 0) + if (smb_strcasecmp(of->f_pipe->p_name, "SRVSVC", 0) == 0) return (B_TRUE); break; default: @@ -1282,7 +1281,7 @@ smb_ofile_netinfo_init(smb_ofile_t *of, smb_netfileinfo_t *fi) fi->fi_fid = of->f_fid; fi->fi_uniqid = of->f_uniqid; fi->fi_pathlen = strlen(buf) + 1; - fi->fi_path = smb_kstrdup(buf, fi->fi_pathlen); + fi->fi_path = smb_strdup(buf); kmem_free(buf, MAXPATHLEN); fi->fi_namelen = user->u_domain_len + user->u_name_len + 2; @@ -1299,7 +1298,7 @@ smb_ofile_netinfo_fini(smb_netfileinfo_t *fi) return; if (fi->fi_path) - kmem_free(fi->fi_path, fi->fi_pathlen); + smb_mfree(fi->fi_path); if (fi->fi_username) kmem_free(fi->fi_username, fi->fi_namelen); diff --git a/usr/src/uts/common/fs/smbsrv/smb_open_andx.c b/usr/src/uts/common/fs/smbsrv/smb_open_andx.c index f701f35c7b..ee67413338 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_open_andx.c +++ b/usr/src/uts/common/fs/smbsrv/smb_open_andx.c @@ -23,8 +23,8 @@ * Use is subject to license terms. */ +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_vops.h> -#include <smbsrv/smb_incl.h> int smb_open_dsize_check = 0; diff --git a/usr/src/uts/common/fs/smbsrv/smb_opipe.c b/usr/src/uts/common/fs/smbsrv/smb_opipe.c index a2917039c9..3048e034e7 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_opipe.c +++ b/usr/src/uts/common/fs/smbsrv/smb_opipe.c @@ -32,7 +32,7 @@ #include <sys/door_data.h> #include <sys/uio.h> #include <sys/ksynch.h> -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_xdr.h> #define SMB_OPIPE_ISOPEN(OPIPE) \ @@ -170,13 +170,13 @@ smb_opipe_lookup(const char *path) name = path; name += strspn(name, "\\"); - if (utf8_strncasecmp(name, "PIPE", 4) == 0) { + if (smb_strcasecmp(name, "PIPE", 4) == 0) { path += 4; name += strspn(name, "\\"); } for (i = 0; i < sizeof (named_pipes) / sizeof (named_pipes[0]); ++i) { - if (utf8_strcasecmp(name, named_pipes[i]) == 0) + if (smb_strcasecmp(name, named_pipes[i], 0) == 0) return (named_pipes[i]); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_oplock.c b/usr/src/uts/common/fs/smbsrv/smb_oplock.c index 20fdfd10dc..53685acdb0 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_oplock.c +++ b/usr/src/uts/common/fs/smbsrv/smb_oplock.c @@ -37,7 +37,7 @@ * that is not the case anymore. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> #include <inet/tcp.h> diff --git a/usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c b/usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c index cfc1956044..6537da627e 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c +++ b/usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> #include <sys/pathname.h> #include <sys/sdt.h> @@ -41,7 +41,7 @@ smb_is_executable(char *path) if ((len >= 4) && (path[len - 4] == '.')) { (void) strcpy(extension, &path[len - 3]); - (void) utf8_strupr(extension); + (void) smb_strupr(extension); if (strcmp(extension, "EXE") == 0) return (NODE_FLAGS_EXECUTABLE); diff --git a/usr/src/uts/common/fs/smbsrv/smb_print.c b/usr/src/uts/common/fs/smbsrv/smb_print.c index fb45b80339..4e21dfdd2b 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_print.c +++ b/usr/src/uts/common/fs/smbsrv/smb_print.c @@ -19,17 +19,15 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * SMB print interface. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> /* diff --git a/usr/src/uts/common/fs/smbsrv/smb_process_exit.c b/usr/src/uts/common/fs/smbsrv/smb_process_exit.c index 83c626bab8..f39b376ee1 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_process_exit.c +++ b/usr/src/uts/common/fs/smbsrv/smb_process_exit.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -51,7 +51,7 @@ * send this message at all. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> smb_sdrc_t smb_pre_process_exit(smb_request_t *sr) diff --git a/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c b/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c index 377baec57e..d87e3994b9 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c +++ b/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c @@ -23,8 +23,8 @@ * Use is subject to license terms. */ +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_vops.h> -#include <smbsrv/smb_incl.h> #include <smbsrv/smb_fsops.h> /* @@ -91,7 +91,8 @@ static int smb_query_encode_response(smb_request_t *, smb_xa_t *, uint16_t, smb_queryinfo_t *); static void smb_encode_stream_info(smb_request_t *, smb_xa_t *, smb_queryinfo_t *); -static int smb_all_info_filename(smb_tree_t *, smb_node_t *, char *, size_t); +static int smb_query_pathname(smb_tree_t *, smb_node_t *, boolean_t, + char *, size_t); uint32_t smb_pad_align(uint32_t offset, uint32_t align); @@ -500,7 +501,7 @@ smb_query_encode_response(smb_request_t *sr, smb_xa_t *xa, case SMB_FILE_ALT_NAME_INFORMATION: (void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0); (void) smb_mbc_encodef(&xa->rep_data_mb, "%lU", sr, - mts_wcequiv_strlen(qinfo->qi_shortname), + smb_wcequiv_strlen(qinfo->qi_shortname), qinfo->qi_shortname); break; @@ -688,19 +689,22 @@ smb_pad_align(uint32_t offset, uint32_t align) } /* - * smb_all_info_filename - * - * This format of filename is only used by the ALL_INFO levels. + * smb_query_pathname * * Determine the absolute pathname of 'node' within the share. + * For some levels (e.g. ALL_INFO) the pathname should include the + * sharename for others (e.g. NAME_INFO) the pathname should be + * relative to the share. * For example if the node represents file "test1.txt" in directory - * "dir1" on share "share1", the path would be: \share1\dir1\test1.txt + * "dir1" on share "share1" + * - if include_share is TRUE the pathname would be: \share1\dir1\test1.txt + * - if include_share is FALSE the pathname would be: \dir1\test1.txt * * If node represents a named stream, construct the pathname for the * associated unnamed stream then append the stream name. */ static int -smb_all_info_filename(smb_tree_t *tree, smb_node_t *node, +smb_query_pathname(smb_tree_t *tree, smb_node_t *node, boolean_t include_share, char *buf, size_t buflen) { char *sharename = tree->t_sharename; @@ -708,12 +712,14 @@ smb_all_info_filename(smb_tree_t *tree, smb_node_t *node, size_t len; vnode_t *vp; - len = snprintf(buf, buflen, "\\%s", sharename); - if (len == (buflen - 1)) - return (ENAMETOOLONG); + if (include_share) { + len = snprintf(buf, buflen, "\\%s", sharename); + if (len == (buflen - 1)) + return (ENAMETOOLONG); - buf += len; - buflen -= len; + buf += len; + buflen -= len; + } if (SMB_IS_STREAM(node)) vp = node->n_unode->vp; @@ -741,8 +747,8 @@ int smb_query_fileinfo(smb_request_t *sr, smb_node_t *node, uint16_t infolev, smb_queryinfo_t *qinfo) { - char *namep = node->od_name; int rc; + boolean_t include_sharename = B_FALSE; (void) bzero(qinfo, sizeof (smb_queryinfo_t)); @@ -768,31 +774,18 @@ smb_query_fileinfo(smb_request_t *sr, smb_node_t *node, uint16_t infolev, /* populate name, namelen and shortname */ - /* ALL_INFO levels are a special case for name field */ + /* ALL_INFO levels include the sharename in the name field */ if ((infolev == SMB_QUERY_FILE_ALL_INFO) || (infolev == SMB_FILE_ALL_INFORMATION)) { - rc = smb_all_info_filename(sr->tid_tree, node, - qinfo->qi_name, MAXPATHLEN); - if (rc != 0) { - smbsr_errno(sr, rc); - return (-1); - } - qinfo->qi_namelen = - smb_ascii_or_unicode_strlen(sr, qinfo->qi_name); - return (0); + include_sharename = B_TRUE; } - /* - * It looks like NT doesn't know what to do with the name "." - * so we convert it to "\\" to indicate the root directory. - * If the leading \ is missing, add it. - */ - if (strcmp(namep, ".") == 0) - (void) strlcpy(qinfo->qi_name, "\\", MAXNAMELEN); - else if (*namep != '\\') - (void) snprintf(qinfo->qi_name, MAXNAMELEN, "\\%s", namep); - else - (void) strlcpy(qinfo->qi_name, namep, MAXNAMELEN); + rc = smb_query_pathname(sr->tid_tree, node, include_sharename, + qinfo->qi_name, MAXPATHLEN); + if (rc != 0) { + smbsr_errno(sr, rc); + return (-1); + } qinfo->qi_namelen = smb_ascii_or_unicode_strlen(sr, qinfo->qi_name); @@ -809,14 +802,15 @@ smb_query_fileinfo(smb_request_t *sr, smb_node_t *node, uint16_t infolev, /* * If the shortname is generated by smb_mangle_name() * it will be returned as the alternative name. - * Otherwise, convert the original name to upper-case + * Otherwise, convert the original name to upper-case * and return it as the alternative name. */ (void) smb_mangle_name(qinfo->qi_attr.sa_vattr.va_nodeid, - namep, qinfo->qi_shortname, qinfo->qi_name83, 0); + node->od_name, qinfo->qi_shortname, qinfo->qi_name83, 0); if (*qinfo->qi_shortname == 0) { - (void) strlcpy(qinfo->qi_shortname, namep, SMB_SHORTNAMELEN); - (void) utf8_strupr(qinfo->qi_shortname); + (void) strlcpy(qinfo->qi_shortname, node->od_name, + SMB_SHORTNAMELEN); + (void) smb_strupr(qinfo->qi_shortname); } return (0); diff --git a/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c b/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c index 42831bb821..3053fa3a67 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c +++ b/usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * SMB: query_information_disk * @@ -64,7 +62,7 @@ * TotalUnit or FreeUnits (i.e. 0xFFFF) should be returned. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> smb_sdrc_t diff --git a/usr/src/uts/common/fs/smbsrv/smb_read.c b/usr/src/uts/common/fs/smbsrv/smb_read.c index 9593b18beb..e79a595b15 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_read.c +++ b/usr/src/uts/common/fs/smbsrv/smb_read.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> diff --git a/usr/src/uts/common/fs/smbsrv/smb_rename.c b/usr/src/uts/common/fs/smbsrv/smb_rename.c index 6da6809374..1a88f12700 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_rename.c +++ b/usr/src/uts/common/fs/smbsrv/smb_rename.c @@ -23,9 +23,8 @@ * Use is subject to license terms. */ -#include <smbsrv/nterror.h> #include <sys/synch.h> -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> #include <sys/nbmlock.h> @@ -42,11 +41,20 @@ #define SMB_NT_RENAME_RENAME_FILE 0x0104 #define SMB_NT_RENAME_MOVE_FILE 0x0105 -static int smb_do_rename(smb_request_t *, smb_fqi_t *, smb_fqi_t *); +/* + * SMB_TRANS2_SET_FILE/PATH_INFO (RENAME_INFORMATION level) flag + */ +#define SMB_RENAME_FLAG_OVERWRITE 0x001 + +static int smb_common_rename(smb_request_t *, smb_fqi_t *, smb_fqi_t *); static int smb_make_link(smb_request_t *, smb_fqi_t *, smb_fqi_t *); +static int smb_rename_check_stream(smb_fqi_t *, smb_fqi_t *); static int smb_rename_check_attr(smb_request_t *, smb_node_t *, uint16_t); static void smb_rename_set_error(smb_request_t *, int); +static int smb_rename_lookup_src(smb_request_t *); +static void smb_rename_release_src(smb_request_t *); + /* * smb_com_rename * @@ -62,8 +70,7 @@ static void smb_rename_set_error(smb_request_t *, int); * have. If SearchAttributes is zero then only normal files are renamed. * If the system file or hidden attributes are specified then the rename * is inclusive - both the specified type(s) of files and normal files are - * renamed. The encoding of SearchAttributes is described in section 3.10 - * - File Attribute Encoding. + * renamed. */ smb_sdrc_t smb_pre_rename(smb_request_t *sr) @@ -104,7 +111,7 @@ smb_com_rename(smb_request_t *sr) return (SDRC_ERROR); } - rc = smb_do_rename(sr, src_fqi, dst_fqi); + rc = smb_common_rename(sr, src_fqi, dst_fqi); if (rc != 0) { smb_rename_set_error(sr, rc); @@ -116,208 +123,17 @@ smb_com_rename(smb_request_t *sr) } /* - * smb_do_rename - * - * Common code for renaming a file. - * - * If the source and destination are identical, we go through all - * the checks but we don't actually do the rename. If the source - * and destination files differ only in case, we do a case-sensitive - * rename. Otherwise, we do a full case-insensitive rename. - * - * Returns errno values. - */ -static int -smb_do_rename(smb_request_t *sr, smb_fqi_t *src_fqi, smb_fqi_t *dst_fqi) -{ - smb_node_t *src_node, *tnode; - char *dstname; - DWORD status; - int rc; - int count; - char *path; - - tnode = sr->tid_tree->t_snode; - - /* Lookup the source node. It MUST exist. */ - path = src_fqi->fq_path.pn_path; - rc = smb_pathname_reduce(sr, sr->user_cr, path, tnode, tnode, - &src_fqi->fq_dnode, src_fqi->fq_last_comp); - if (rc != 0) - return (rc); - - rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS, tnode, - src_fqi->fq_dnode, src_fqi->fq_last_comp, &src_fqi->fq_fnode); - if (rc != 0) { - smb_node_release(src_fqi->fq_dnode); - return (rc); - } - - src_node = src_fqi->fq_fnode; - rc = smb_rename_check_attr(sr, src_node, src_fqi->fq_sattr); - if (rc != 0) { - smb_node_release(src_fqi->fq_fnode); - smb_node_release(src_fqi->fq_dnode); - return (rc); - } - - /* - * Break the oplock before access checks. If a client - * has a file open, this will force a flush or close, - * which may affect the outcome of any share checking. - */ - (void) smb_oplock_break(src_node, sr->session, B_FALSE); - - for (count = 0; count <= 3; count++) { - if (count) { - smb_node_end_crit(src_node); - delay(MSEC_TO_TICK(400)); - } - - smb_node_start_crit(src_node, RW_READER); - - status = smb_node_rename_check(src_node); - - if (status != NT_STATUS_SHARING_VIOLATION) - break; - } - - if (status == NT_STATUS_SHARING_VIOLATION) { - smb_node_end_crit(src_node); - smb_node_release(src_fqi->fq_fnode); - smb_node_release(src_fqi->fq_dnode); - return (EPIPE); /* = ERRbadshare */ - } - - status = smb_range_check(sr, src_node, 0, UINT64_MAX, B_TRUE); - - if (status != NT_STATUS_SUCCESS) { - smb_node_end_crit(src_node); - smb_node_release(src_fqi->fq_fnode); - smb_node_release(src_fqi->fq_dnode); - return (EACCES); - } - - /* Lookup destination node. */ - path = dst_fqi->fq_path.pn_path; - rc = smb_pathname_reduce(sr, sr->user_cr, path, tnode, tnode, - &dst_fqi->fq_dnode, dst_fqi->fq_last_comp); - if (rc != 0) { - smb_node_end_crit(src_node); - smb_node_release(src_fqi->fq_fnode); - smb_node_release(src_fqi->fq_dnode); - return (rc); - } - - rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS, tnode, - dst_fqi->fq_dnode, dst_fqi->fq_last_comp, &dst_fqi->fq_fnode); - if ((rc != 0) && (rc != ENOENT)) { - smb_node_end_crit(src_node); - smb_node_release(src_fqi->fq_fnode); - smb_node_release(src_fqi->fq_dnode); - smb_node_release(dst_fqi->fq_dnode); - return (rc); - } - - if (utf8_strcasecmp(src_fqi->fq_path.pn_path, - dst_fqi->fq_path.pn_path) == 0) { - - if (dst_fqi->fq_fnode) - smb_node_release(dst_fqi->fq_fnode); - - rc = strcmp(src_fqi->fq_fnode->od_name, dst_fqi->fq_last_comp); - if (rc == 0) { - smb_node_end_crit(src_node); - smb_node_release(src_fqi->fq_fnode); - smb_node_release(src_fqi->fq_dnode); - smb_node_release(dst_fqi->fq_dnode); - return (0); - } - - rc = smb_fsop_rename(sr, sr->user_cr, - src_fqi->fq_dnode, src_fqi->fq_fnode->od_name, - dst_fqi->fq_dnode, dst_fqi->fq_last_comp); - - smb_node_end_crit(src_node); - if (rc == 0) - smb_node_notify_change(dst_fqi->fq_dnode); - smb_node_release(src_fqi->fq_fnode); - smb_node_release(src_fqi->fq_dnode); - smb_node_release(dst_fqi->fq_dnode); - return (rc); - } - - /* dst node must not exist */ - if (dst_fqi->fq_fnode) { - smb_node_end_crit(src_node); - smb_node_release(src_fqi->fq_fnode); - smb_node_release(src_fqi->fq_dnode); - smb_node_release(dst_fqi->fq_fnode); - smb_node_release(dst_fqi->fq_dnode); - return (EEXIST); - } - - /* - * If the source name is mangled but the source and destination - * on-disk names are identical, we'll use the on-disk name. - */ - if ((smb_maybe_mangled_name(src_fqi->fq_last_comp)) && - (strcmp(src_fqi->fq_last_comp, dst_fqi->fq_last_comp) == 0)) { - dstname = src_fqi->fq_fnode->od_name; - } else { - dstname = dst_fqi->fq_last_comp; - } - - rc = smb_fsop_rename(sr, sr->user_cr, - src_fqi->fq_dnode, src_fqi->fq_fnode->od_name, - dst_fqi->fq_dnode, dstname); - - smb_node_end_crit(src_node); - if (rc == 0) - smb_node_notify_change(dst_fqi->fq_dnode); - smb_node_release(src_fqi->fq_fnode); - smb_node_release(src_fqi->fq_dnode); - smb_node_release(dst_fqi->fq_dnode); - return (rc); -} - -/* * smb_com_nt_rename * * Rename a file. Files OldFileName must exist and NewFileName must not. * Both pathnames must be relative to the Tid specified in the request. * Open files may be renamed. * - * Multiple files may be renamed in response to a single request as Rename - * File supports wildcards in the file name (last component of the path). - * NOTE: we don't support rename with wildcards. - * * SearchAttributes indicates the attributes that the target file(s) must * have. If SearchAttributes is zero then only normal files are renamed. * If the system file or hidden attributes are specified then the rename * is inclusive - both the specified type(s) of files and normal files are - * renamed. The encoding of SearchAttributes is described in section 3.10 - * - File Attribute Encoding. - * - * Client Request Description - * ================================= ================================== - * UCHAR WordCount; Count of parameter words = 4 - * USHORT SearchAttributes; - * USHORT InformationLevel; 0x0103 Create a hard link - * 0x0104 In-place rename - * 0x0105 Move (rename) a file - * ULONG ClusterCount Servers should ignore this value - * USHORT ByteCount; Count of data bytes; min = 4 - * UCHAR Buffer[]; Buffer containing: - * UCHAR BufferFormat1 0x04 - * UCHAR OldFileName[] OldFileName - * UCHAR BufferFormat1 0x04 - * UCHAR OldFileName[] NewFileName - * - * Server Response Description - * ================================= ================================== - * UCHAR WordCount; Count of parameter words = 0 - * UCHAR ByteCount; Count of data bytes = 0 + * renamed. */ smb_sdrc_t smb_pre_nt_rename(smb_request_t *sr) @@ -373,7 +189,7 @@ smb_com_nt_rename(smb_request_t *sr) break; case SMB_NT_RENAME_RENAME_FILE: case SMB_NT_RENAME_MOVE_FILE: - rc = smb_do_rename(sr, src_fqi, dst_fqi); + rc = smb_common_rename(sr, src_fqi, dst_fqi); break; case SMB_NT_RENAME_MOVE_CLUSTER_INFO: rc = EINVAL; @@ -393,43 +209,423 @@ smb_com_nt_rename(smb_request_t *sr) } /* + * smb_nt_transact_rename + * + * Windows servers return SUCCESS without renaming file. + * The only check required is to check that the handle (fid) is valid. + */ +smb_sdrc_t +smb_nt_transact_rename(smb_request_t *sr, smb_xa_t *xa) +{ + if (smb_mbc_decodef(&xa->req_param_mb, "w", &sr->smb_fid) != 0) + return (SDRC_ERROR); + + smbsr_lookup_file(sr); + if (sr->fid_ofile == NULL) { + smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid); + return (SDRC_ERROR); + } + smbsr_release_file(sr); + + return (SDRC_SUCCESS); +} + +/* + * smb_trans2_rename + * + * Implements SMB_FILE_RENAME_INFORMATION level of Trans2_Set_FileInfo + * and Trans2_Set_PathInfo. + * If the new filename (dst_fqi) already exists it may be overwritten + * if flags == 1. + */ +int +smb_trans2_rename(smb_request_t *sr, smb_node_t *node, char *fname, int flags) +{ + int rc; + smb_fqi_t *src_fqi = &sr->arg.dirop.fqi; + smb_fqi_t *dst_fqi = &sr->arg.dirop.dst_fqi; + + sr->arg.dirop.flags = flags ? SMB_RENAME_FLAG_OVERWRITE : 0; + sr->arg.dirop.info_level = SMB_NT_RENAME_RENAME_FILE; + + src_fqi->fq_sattr = SMB_SEARCH_ATTRIBUTES; + src_fqi->fq_fnode = node; + src_fqi->fq_dnode = node->n_dnode; + + dst_fqi->fq_path.pn_path = fname; + dst_fqi->fq_dnode = node->n_dnode; + (void) strlcpy(dst_fqi->fq_last_comp, fname, MAXNAMELEN); + + rc = smb_common_rename(sr, src_fqi, dst_fqi); + if (rc != 0) { + smb_rename_set_error(sr, rc); + return (-1); + } + + return (0); +} + +/* + * smb_common_rename + * + * Common code for renaming a file. + * + * If the source and destination are identical, we go through all + * the checks but we don't actually do the rename. If the source + * and destination files differ only in case, we do a case-sensitive + * rename. Otherwise, we do a full case-insensitive rename. + * + * Returns errno values. + */ +static int +smb_common_rename(smb_request_t *sr, smb_fqi_t *src_fqi, smb_fqi_t *dst_fqi) +{ + smb_node_t *src_fnode, *src_dnode, *dst_fnode, *dst_dnode; + smb_node_t *tnode; + int rc, count; + DWORD status; + char *new_name, *path; + + path = dst_fqi->fq_path.pn_path; + + /* Check if attempting to rename a stream - not yet supported */ + rc = smb_rename_check_stream(src_fqi, dst_fqi); + if (rc != 0) + return (rc); + + /* The source node may already have been provided */ + if (src_fqi->fq_fnode) { + smb_node_start_crit(src_fqi->fq_fnode, RW_READER); + smb_node_ref(src_fqi->fq_fnode); + smb_node_ref(src_fqi->fq_dnode); + } else { + /* lookup and validate src node */ + rc = smb_rename_lookup_src(sr); + if (rc != 0) + return (rc); + } + + src_fnode = src_fqi->fq_fnode; + src_dnode = src_fqi->fq_dnode; + + /* Find destination dnode and last_comp */ + if (dst_fqi->fq_dnode) { + smb_node_ref(dst_fqi->fq_dnode); + } else { + tnode = sr->tid_tree->t_snode; + rc = smb_pathname_reduce(sr, sr->user_cr, path, tnode, tnode, + &dst_fqi->fq_dnode, dst_fqi->fq_last_comp); + if (rc != 0) { + smb_rename_release_src(sr); + return (rc); + } + } + + dst_dnode = dst_fqi->fq_dnode; + new_name = dst_fqi->fq_last_comp; + + /* If exact name match in same directory, we're done */ + if ((src_dnode == dst_dnode) && + (strcmp(src_fnode->od_name, new_name) == 0)) { + smb_rename_release_src(sr); + smb_node_release(dst_dnode); + return (0); + } + + /* Lookup destination node */ + rc = smb_fsop_lookup(sr, sr->user_cr, 0, tnode, + dst_dnode, new_name, &dst_fqi->fq_fnode); + + /* + * Handle case where changing case of the same directory entry. + * + * If we found the dst node in the same directory as the src node, + * and their names differ only in case: + * + * If the tree is case sensitive (or mixed): + * Do case sensitive lookup to see if exact match exists. + * If the exact match is the same node as src_node we're done. + * + * If the tree is case insensitive: + * There is currently no way to tell if the case is different + * or not, so do the rename (unless the specified new name was + * mangled). + */ + if ((rc == 0) && + (src_dnode == dst_dnode) && + (smb_strcasecmp(src_fnode->od_name, + dst_fqi->fq_fnode->od_name, 0) == 0)) { + smb_node_release(dst_fqi->fq_fnode); + dst_fqi->fq_fnode = NULL; + + if (smb_tree_has_feature(sr->tid_tree, + SMB_TREE_NO_CASESENSITIVE)) { + if (smb_strcasecmp(src_fnode->od_name, + dst_fqi->fq_last_comp, 0) != 0) { + smb_rename_release_src(sr); + smb_node_release(dst_dnode); + return (0); + } + } else { + rc = smb_fsop_lookup(sr, sr->user_cr, + SMB_CASE_SENSITIVE, tnode, dst_dnode, new_name, + &dst_fqi->fq_fnode); + + if ((rc == 0) && + (dst_fqi->fq_fnode == src_fnode)) { + smb_rename_release_src(sr); + smb_node_release(dst_fqi->fq_fnode); + smb_node_release(dst_dnode); + return (0); + } + } + } + + if ((rc != 0) && (rc != ENOENT)) { + smb_rename_release_src(sr); + smb_node_release(dst_fqi->fq_dnode); + return (rc); + } + + if (dst_fqi->fq_fnode) { + dst_fnode = dst_fqi->fq_fnode; + + if (!(sr->arg.dirop.flags && SMB_RENAME_FLAG_OVERWRITE)) { + smb_rename_release_src(sr); + smb_node_release(dst_fnode); + smb_node_release(dst_dnode); + return (EEXIST); + } + + (void) smb_oplock_break(dst_fnode, sr->session, B_FALSE); + + for (count = 0; count <= 3; count++) { + if (count) { + smb_node_end_crit(dst_fnode); + delay(MSEC_TO_TICK(400)); + } + + smb_node_start_crit(dst_fnode, RW_READER); + status = smb_node_delete_check(dst_fnode); + + if (status != NT_STATUS_SHARING_VIOLATION) + break; + } + + if (status != NT_STATUS_SHARING_VIOLATION) + status = smb_range_check(sr, dst_fnode, + 0, UINT64_MAX, B_TRUE); + + if (status != NT_STATUS_SUCCESS) { + smb_rename_release_src(sr); + smb_node_end_crit(dst_fnode); + smb_node_release(dst_fnode); + smb_node_release(dst_dnode); + return (EACCES); + } + + if (smb_maybe_mangled_name(new_name)) { + (void) strlcpy(new_name, dst_fnode->od_name, + MAXNAMELEN); + } + } + + rc = smb_fsop_rename(sr, sr->user_cr, + src_dnode, src_fnode->od_name, + dst_dnode, new_name); + + smb_rename_release_src(sr); + + if (rc == 0) + smb_node_notify_change(dst_dnode); + + if (dst_fqi->fq_fnode) { + smb_node_end_crit(dst_fnode); + smb_node_release(dst_fnode); + } + smb_node_release(dst_dnode); + + return (rc); +} + +/* + * smb_rename_check_stream + * + * For a stream rename the dst path must begin with ':', or "\\:". + * We don't yet support stream rename, Return EACCES. + * + * If not a stream rename, in accordance with the above rule, + * it is not valid for either the src or dst to be a stream. + * Return EINVAL. + */ +static int +smb_rename_check_stream(smb_fqi_t *src_fqi, smb_fqi_t *dst_fqi) +{ + smb_node_t *src_fnode = src_fqi->fq_fnode; + char *src_path = src_fqi->fq_path.pn_path; + char *dst_path = dst_fqi->fq_path.pn_path; + + /* We do not yet support named stream rename - ACCESS DENIED */ + if ((dst_path[0] == ':') || + ((dst_path[0] == '\\') && (dst_path[1] == ':'))) { + return (EACCES); + } + + /* + * If not stream rename (above) neither src or dst can be + * a named stream. + */ + + if (smb_is_stream_name(dst_path)) + return (EINVAL); + + if (src_fqi->fq_fnode) { + if (SMB_IS_STREAM(src_fnode)) + return (EINVAL); + } else { + if (smb_is_stream_name(src_path)) + return (EINVAL); + } + + return (0); +} + + +/* * smb_make_link * - * Common code for creating a hard link (adding an additional name - * for a file. + * Creating a hard link (adding an additional name) for a file. * * If the source and destination are identical, we go through all * the checks but we don't create a link. * + * If the file is a symlink we create the hardlink on the target + * of the symlink (i.e. use SMB_FOLLOW_LINKS when looking up src). + * If the target of the symlink does not exist we fail with ENOENT. + * * Returns errno values. */ static int smb_make_link(smb_request_t *sr, smb_fqi_t *src_fqi, smb_fqi_t *dst_fqi) { - smb_node_t *src_fnode, *tnode; + smb_node_t *tnode; + char *path; + int rc; + + /* Cannnot create link on named stream */ + if (smb_is_stream_name(src_fqi->fq_path.pn_path) || + smb_is_stream_name(dst_fqi->fq_path.pn_path)) { + return (EINVAL); + } + + /* lookup and validate src node */ + rc = smb_rename_lookup_src(sr); + if (rc != 0) + return (rc); + + /* if src and dest paths match we're done */ + if (smb_strcasecmp(src_fqi->fq_path.pn_path, + dst_fqi->fq_path.pn_path, 0) == 0) { + smb_rename_release_src(sr); + return (0); + } + + /* find the destination dnode and last_comp */ + tnode = sr->tid_tree->t_snode; + path = dst_fqi->fq_path.pn_path; + rc = smb_pathname_reduce(sr, sr->user_cr, path, tnode, tnode, + &dst_fqi->fq_dnode, dst_fqi->fq_last_comp); + if (rc != 0) { + smb_rename_release_src(sr); + return (rc); + } + + /* If name match in same directory, we're done */ + if ((src_fqi->fq_dnode == dst_fqi->fq_dnode) && + (smb_strcasecmp(src_fqi->fq_fnode->od_name, + dst_fqi->fq_last_comp, 0) == 0)) { + smb_rename_release_src(sr); + smb_node_release(dst_fqi->fq_dnode); + return (0); + } + + /* Lookup the destination node. It MUST NOT exist. */ + rc = smb_fsop_lookup(sr, sr->user_cr, 0, tnode, + dst_fqi->fq_dnode, dst_fqi->fq_last_comp, &dst_fqi->fq_fnode); + if (rc == 0) { + smb_node_release(dst_fqi->fq_fnode); + rc = EEXIST; + } + if (rc != ENOENT) { + smb_rename_release_src(sr); + smb_node_release(dst_fqi->fq_dnode); + return (rc); + } + + rc = smb_fsop_link(sr, sr->user_cr, src_fqi->fq_fnode, + dst_fqi->fq_dnode, dst_fqi->fq_last_comp); + + smb_rename_release_src(sr); + if (rc == 0) + smb_node_notify_change(dst_fqi->fq_dnode); + smb_node_release(dst_fqi->fq_dnode); + return (rc); +} + +/* + * smb_rename_lookup_src + * + * Lookup the src node, checking for sharing violations and + * breaking any existing oplock. + * Populate sr->arg.dirop.fqi + * + * Upon success, the dnode and fnode will have holds and the + * fnode will be in a critical section. These should be + * released using smb_rename_release_src(). + * + * Returns errno values. + */ +static int +smb_rename_lookup_src(smb_request_t *sr) +{ + smb_node_t *src_node, *tnode; DWORD status; int rc; int count; char *path; - tnode = sr->tid_tree->t_snode; + struct dirop *dirop = &sr->arg.dirop; + smb_fqi_t *src_fqi = &sr->arg.dirop.fqi; + + if (smb_is_stream_name(src_fqi->fq_path.pn_path)) + return (EINVAL); - /* Lookup the source node. It MUST exist. */ + /* Lookup the source node */ + tnode = sr->tid_tree->t_snode; path = src_fqi->fq_path.pn_path; rc = smb_pathname_reduce(sr, sr->user_cr, path, tnode, tnode, &src_fqi->fq_dnode, src_fqi->fq_last_comp); if (rc != 0) return (rc); - rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS, tnode, + rc = smb_fsop_lookup(sr, sr->user_cr, 0, tnode, src_fqi->fq_dnode, src_fqi->fq_last_comp, &src_fqi->fq_fnode); if (rc != 0) { smb_node_release(src_fqi->fq_dnode); return (rc); } - src_fnode = src_fqi->fq_fnode; - rc = smb_rename_check_attr(sr, src_fnode, src_fqi->fq_sattr); + /* Not valid to create hardlink for directory */ + if ((dirop->info_level == SMB_NT_RENAME_SET_LINK_INFO) && + (smb_node_is_dir(src_fqi->fq_fnode))) { + smb_node_release(src_fqi->fq_fnode); + smb_node_release(src_fqi->fq_dnode); + return (EISDIR); + } + + src_node = src_fqi->fq_fnode; + + rc = smb_rename_check_attr(sr, src_node, src_fqi->fq_sattr); if (rc != 0) { smb_node_release(src_fqi->fq_fnode); smb_node_release(src_fqi->fq_dnode); @@ -441,81 +637,53 @@ smb_make_link(smb_request_t *sr, smb_fqi_t *src_fqi, smb_fqi_t *dst_fqi) * has a file open, this will force a flush or close, * which may affect the outcome of any share checking. */ - (void) smb_oplock_break(src_fnode, sr->session, B_FALSE); + (void) smb_oplock_break(src_node, sr->session, B_FALSE); for (count = 0; count <= 3; count++) { if (count) { - smb_node_end_crit(src_fnode); + smb_node_end_crit(src_node); delay(MSEC_TO_TICK(400)); } - smb_node_start_crit(src_fnode, RW_READER); - status = smb_node_rename_check(src_fnode); + smb_node_start_crit(src_node, RW_READER); + status = smb_node_rename_check(src_node); if (status != NT_STATUS_SHARING_VIOLATION) break; } if (status == NT_STATUS_SHARING_VIOLATION) { - smb_node_end_crit(src_fnode); + smb_node_end_crit(src_node); smb_node_release(src_fqi->fq_fnode); smb_node_release(src_fqi->fq_dnode); return (EPIPE); /* = ERRbadshare */ } - status = smb_range_check(sr, src_fnode, 0, UINT64_MAX, B_TRUE); + status = smb_range_check(sr, src_node, 0, UINT64_MAX, B_TRUE); if (status != NT_STATUS_SUCCESS) { - smb_node_end_crit(src_fnode); + smb_node_end_crit(src_node); smb_node_release(src_fqi->fq_fnode); smb_node_release(src_fqi->fq_dnode); return (EACCES); } - if (utf8_strcasecmp(src_fqi->fq_path.pn_path, - dst_fqi->fq_path.pn_path) == 0) { - smb_node_end_crit(src_fnode); - smb_node_release(src_fqi->fq_fnode); - smb_node_release(src_fqi->fq_dnode); - return (0); - } - - /* Lookup the destination node. It MUST NOT exist. */ - path = dst_fqi->fq_path.pn_path; - rc = smb_pathname_reduce(sr, sr->user_cr, path, tnode, tnode, - &dst_fqi->fq_dnode, dst_fqi->fq_last_comp); - if (rc != 0) { - smb_node_end_crit(src_fnode); - smb_node_release(src_fqi->fq_fnode); - smb_node_release(src_fqi->fq_dnode); - return (rc); - } - - rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS, tnode, - dst_fqi->fq_dnode, dst_fqi->fq_last_comp, &dst_fqi->fq_fnode); - if (rc == 0) { - smb_node_release(dst_fqi->fq_fnode); - rc = EEXIST; - } - if (rc != ENOENT) { - smb_node_end_crit(src_fnode); - smb_node_release(src_fqi->fq_fnode); - smb_node_release(src_fqi->fq_dnode); - smb_node_release(dst_fqi->fq_dnode); - return (rc); - } + return (0); +} - rc = smb_fsop_link(sr, sr->user_cr, dst_fqi->fq_dnode, src_fnode, - dst_fqi->fq_last_comp); +/* + * smb_rename_release_src + */ +static void +smb_rename_release_src(smb_request_t *sr) +{ + smb_fqi_t *src_fqi = &sr->arg.dirop.fqi; - smb_node_end_crit(src_fnode); - if (rc == 0) - smb_node_notify_change(dst_fqi->fq_dnode); + smb_node_end_crit(src_fqi->fq_fnode); smb_node_release(src_fqi->fq_fnode); smb_node_release(src_fqi->fq_dnode); - smb_node_release(dst_fqi->fq_dnode); - return (rc); } + static int smb_rename_check_attr(smb_request_t *sr, smb_node_t *node, uint16_t sattr) { @@ -558,6 +726,7 @@ smb_rename_set_error(smb_request_t *sr, int errnum) { ESRCH, ERROR_FILE_NOT_FOUND, NT_STATUS_NO_SUCH_FILE }, { EINVAL, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER }, { EACCES, ERROR_ACCESS_DENIED, NT_STATUS_ACCESS_DENIED }, + { EISDIR, ERROR_ACCESS_DENIED, NT_STATUS_FILE_IS_A_DIRECTORY }, { EIO, ERROR_INTERNAL_ERROR, NT_STATUS_INTERNAL_ERROR } }; diff --git a/usr/src/uts/common/fs/smbsrv/smb_sd.c b/usr/src/uts/common/fs/smbsrv/smb_sd.c index 6a9bc70418..b8d7fd3b7a 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_sd.c +++ b/usr/src/uts/common/fs/smbsrv/smb_sd.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,7 +30,6 @@ #include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> #include <smbsrv/smb_idmap.h> -#include <smbsrv/ntstatus.h> static void smb_sd_set_sacl(smb_sd_t *, smb_acl_t *, boolean_t, int); static void smb_sd_set_dacl(smb_sd_t *, smb_acl_t *, boolean_t, int); diff --git a/usr/src/uts/common/fs/smbsrv/smb_seek.c b/usr/src/uts/common/fs/smbsrv/smb_seek.c index d60a44d9e1..4e734063d9 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_seek.c +++ b/usr/src/uts/common/fs/smbsrv/smb_seek.c @@ -41,7 +41,7 @@ * file offset is beyond the 32-bit limit. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> /* diff --git a/usr/src/uts/common/fs/smbsrv/smb_server.c b/usr/src/uts/common/fs/smbsrv/smb_server.c index 98c7c17bbd..8da1310dc8 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_server.c +++ b/usr/src/uts/common/fs/smbsrv/smb_server.c @@ -215,10 +215,15 @@ #include <sys/priv.h> #include <sys/socketvar.h> #include <sys/zone.h> +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/ip.h> +#include <netinet/ip_icmp.h> +#include <netinet/ip_var.h> +#include <netinet/tcp.h> #include <smbsrv/smb_kproto.h> +#include <smbsrv/string.h> #include <smbsrv/netbios.h> -#include <smbsrv/smb_incl.h> -#include <smbsrv/cifs.h> #include <smbsrv/smb_fsops.h> #include <smbsrv/smb_share.h> #include <smbsrv/smb_door_svc.h> @@ -559,6 +564,7 @@ smb_server_start(smb_ioc_start_t *ioc) mutex_enter(&sv->sv_mutex); switch (sv->sv_state) { case SMB_SERVER_STATE_CONFIGURED: + smb_codepage_init(); sv->sv_thread_pool = taskq_create("smb_workers", sv->sv_cfg.skc_maxworkers, SMB_WORKER_PRIORITY, @@ -589,8 +595,6 @@ smb_server_start(smb_ioc_start_t *ioc) break; } - (void) oem_language_set("english"); - sv->sv_state = SMB_SERVER_STATE_RUNNING; mutex_exit(&sv->sv_mutex); smb_server_release(sv); diff --git a/usr/src/uts/common/fs/smbsrv/smb_session.c b/usr/src/uts/common/fs/smbsrv/smb_session.c index 68a597eeed..14971d067e 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_session.c +++ b/usr/src/uts/common/fs/smbsrv/smb_session.c @@ -30,8 +30,8 @@ #include <sys/socketvar.h> #include <sys/sdt.h> #include <smbsrv/netbios.h> -#include <smbsrv/smb_incl.h> -#include <smbsrv/smb_i18n.h> +#include <smbsrv/smb_kproto.h> +#include <smbsrv/string.h> #include <inet/tcp.h> static volatile uint64_t smb_kids; @@ -219,10 +219,9 @@ smb_session_request(struct smb_session *session) char client_name[NETBIOS_NAME_SZ]; struct mbuf_chain mbc; char *names = NULL; - mts_wchar_t *wbuf = NULL; + smb_wchar_t *wbuf = NULL; smb_xprt_t hdr; char *p; - unsigned int cpid = oem_get_smb_cpid(); int rc1, rc2; session->keep_alive = smb_keep_alive; @@ -283,10 +282,10 @@ smb_session_request(struct smb_session *session) * multi-byte format. We also need to strip off any * spaces added as part of the NetBIOS name encoding. */ - wbuf = kmem_alloc((SMB_PI_MAX_HOST * sizeof (mts_wchar_t)), KM_SLEEP); - (void) oemstounicodes(wbuf, client_name, SMB_PI_MAX_HOST, cpid); - (void) mts_wcstombs(session->workstation, wbuf, SMB_PI_MAX_HOST); - kmem_free(wbuf, (SMB_PI_MAX_HOST * sizeof (mts_wchar_t))); + wbuf = kmem_alloc((SMB_PI_MAX_HOST * sizeof (smb_wchar_t)), KM_SLEEP); + (void) oemtoucs(wbuf, client_name, SMB_PI_MAX_HOST, OEM_CPG_850); + (void) smb_wcstombs(session->workstation, wbuf, SMB_PI_MAX_HOST); + kmem_free(wbuf, (SMB_PI_MAX_HOST * sizeof (smb_wchar_t))); if ((p = strchr(session->workstation, ' ')) != 0) *p = '\0'; @@ -1039,8 +1038,8 @@ smb_session_lookup_user(smb_session_t *session, char *domain, char *name) user = smb_llist_head(ulist); while (user) { ASSERT(user->u_magic == SMB_USER_MAGIC); - if (!utf8_strcasecmp(user->u_name, name) && - !utf8_strcasecmp(user->u_domain, domain)) { + if (!smb_strcasecmp(user->u_name, name, 0) && + !smb_strcasecmp(user->u_domain, domain, 0)) { if (smb_user_hold(user)) break; } @@ -1123,14 +1122,14 @@ smb_session_isclient(smb_session_t *sn, const char *client) client += strspn(client, "\\"); - if (utf8_strcasecmp(client, sn->workstation) == 0) + if (smb_strcasecmp(client, sn->workstation, 0) == 0) return (B_TRUE); ipaddr = &sn->ipaddr; if (smb_inet_ntop(ipaddr, buf, SMB_IPSTRLEN(ipaddr->a_family)) == NULL) return (B_FALSE); - if (utf8_strcasecmp(client, buf) == 0) + if (smb_strcasecmp(client, buf, 0) == 0) return (B_TRUE); return (B_FALSE); @@ -1161,13 +1160,12 @@ smb_request_alloc(smb_session_t *session, int req_length) bzero(sr, sizeof (smb_request_t)); mutex_init(&sr->sr_mutex, NULL, MUTEX_DEFAULT, NULL); + smb_srm_init(sr); sr->session = session; sr->sr_server = session->s_server; sr->sr_gmtoff = session->s_server->si_gmtoff; sr->sr_cache = session->s_server->si_cache_request; sr->sr_cfg = &session->s_cfg; - sr->request_storage.forw = &sr->request_storage; - sr->request_storage.back = &sr->request_storage; sr->command.max_bytes = req_length; sr->reply.max_bytes = smb_maxbufsize; sr->sr_req_length = req_length; @@ -1204,8 +1202,7 @@ smb_request_free(smb_request_t *sr) sr->session = NULL; - /* Release any temp storage */ - smbsr_free_malloc_list(&sr->request_storage); + smb_srm_fini(sr); if (sr->sr_request_buf) kmem_free(sr->sr_request_buf, sr->sr_req_length); diff --git a/usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c b/usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c index 761706078f..7f2d86a1f9 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c +++ b/usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c @@ -222,7 +222,7 @@ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_token.h> #include <smbsrv/smb_door_svc.h> @@ -477,8 +477,7 @@ smb_authenticate(smb_request_t *sr, smb_sessionsetup_info_t *sinfo, boolean_t need_lookup = B_FALSE; uint32_t privileges; cred_t *cr; - char *buf; - size_t buflen = 0; + char *buf = NULL; char *p; bzero(&clnt_info, sizeof (netr_client_t)); @@ -500,8 +499,7 @@ smb_authenticate(smb_request_t *sr, smb_sessionsetup_info_t *sinfo, * for some forms of authentication. */ if (*sinfo->ssi_domain == '\0') { - buflen = strlen(sinfo->ssi_user) + 1; - buf = smb_kstrdup(sinfo->ssi_user, buflen); + buf = smb_strdup(sinfo->ssi_user); if ((p = strchr(buf, '@')) != NULL) { *p = '\0'; clnt_info.e_username = buf; @@ -531,8 +529,7 @@ smb_authenticate(smb_request_t *sr, smb_sessionsetup_info_t *sinfo, sr->smb_uid = user->u_uid; sr->uid_user = user; - if (buflen != 0) - kmem_free(buf, buflen); + smb_mfree(buf); return ((user->u_flags & SMB_USER_FLAG_GUEST) ? SMB_AUTH_GUEST : SMB_AUTH_USER); @@ -561,8 +558,7 @@ smb_authenticate(smb_request_t *sr, smb_sessionsetup_info_t *sinfo, usr_token = smb_get_token(&clnt_info); - if (buflen != 0) - kmem_free(buf, buflen); + smb_mfree(buf); if (usr_token == NULL) { smbsr_error(sr, 0, ERRSRV, ERRbadpw); diff --git a/usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.c b/usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.c index 2f9111516d..2c98d81c5e 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.c +++ b/usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.c @@ -33,8 +33,10 @@ * SMB_SET_FILE_END_OF_FILE_INFO * SMB_SET_FILE_ALLOCATION_INFO * - * Supported Passthrough levels: + * Handled Passthrough levels: * SMB_FILE_BASIC_INFORMATION + * SMB_FILE_RENAME_INFORMATION + * SMB_FILE_LINK_INFORMATION * SMB_FILE_DISPOSITION_INFORMATION * SMB_FILE_END_OF_FILE_INFORMATION * SMB_FILE_ALLOCATION_INFORMATION @@ -61,7 +63,7 @@ * attributes. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> typedef struct smb_setinfo { @@ -84,6 +86,7 @@ static int smb_set_basic_info(smb_request_t *, smb_setinfo_t *); static int smb_set_disposition_info(smb_request_t *, smb_setinfo_t *); static int smb_set_eof_info(smb_request_t *sr, smb_setinfo_t *); static int smb_set_alloc_info(smb_request_t *sr, smb_setinfo_t *); +static int smb_set_rename_info(smb_request_t *sr, smb_setinfo_t *); /* * smb_com_trans2_set_file_information @@ -285,7 +288,12 @@ smb_set_by_path(smb_request_t *sr, smb_xa_t *xa, kmem_free(name, MAXNAMELEN); if (rc != 0) { - smbsr_errno(sr, rc); + if (rc == ENOENT) { + smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND, + ERRDOS, ERROR_FILE_NOT_FOUND); + } else { + smbsr_errno(sr, rc); + } return (-1); } @@ -305,6 +313,9 @@ smb_set_by_path(smb_request_t *sr, smb_xa_t *xa, /* * smb_set_fileinfo + * + * For compatibility with windows servers, SMB_FILE_LINK_INFORMATION + * is handled by returning NT_STATUS_NOT_SUPPORTED. */ static int smb_set_fileinfo(smb_request_t *sr, smb_setinfo_t *sinfo) @@ -339,6 +350,13 @@ smb_set_fileinfo(smb_request_t *sr, smb_setinfo_t *sinfo) case SMB_FILE_ALLOCATION_INFORMATION: return (smb_set_alloc_info(sr, sinfo)); + case SMB_FILE_RENAME_INFORMATION: + return (smb_set_rename_info(sr, sinfo)); + + case SMB_FILE_LINK_INFORMATION: + smbsr_error(sr, NT_STATUS_NOT_SUPPORTED, + ERRDOS, ERROR_NOT_SUPPORTED); + return (-1); default: break; } @@ -681,3 +699,44 @@ smb_set_disposition_info(smb_request_t *sr, smb_setinfo_t *sinfo) } return (0); } + +/* + * smb_set_rename_info + * + * Explicity specified parameter validation rules: + * - If rootdir is not NULL respond with NT_STATUS_INVALID_PARAMETER. + * - If the filename contains a separator character respond with + * NT_STATUS_INVALID_PARAMETER. + */ +static int +smb_set_rename_info(smb_request_t *sr, smb_setinfo_t *sinfo) +{ + int rc; + uint32_t flags, rootdir, namelen; + char *fname; + + rc = smb_mbc_decodef(&sinfo->si_xa->req_data_mb, "lll", + &flags, &rootdir, &namelen); + if (rc == 0) { + rc = smb_mbc_decodef(&sinfo->si_xa->req_data_mb, "%#U", + sr, namelen, &fname); + } + if (rc != 0) + return (-1); + + if ((rootdir != 0) || (namelen == 0) || (namelen >= MAXNAMELEN)) { + smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, + ERRDOS, ERROR_INVALID_PARAMETER); + return (-1); + } + + if (strchr(fname, '\\') != NULL) { + smbsr_error(sr, NT_STATUS_NOT_SUPPORTED, + ERRDOS, ERROR_NOT_SUPPORTED); + return (-1); + } + + rc = smb_trans2_rename(sr, sinfo->si_node, fname, flags); + + return ((rc == 0) ? 0 : -1); +} diff --git a/usr/src/uts/common/fs/smbsrv/smb_signing.c b/usr/src/uts/common/fs/smbsrv/smb_signing.c index d587c21850..55c7e45b0b 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_signing.c +++ b/usr/src/uts/common/fs/smbsrv/smb_signing.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)smb_signing.c 1.4 08/07/08 SMI" - /* * These routines provide the SMB MAC signing for the SMB server. * The routines calculate the signature of a SMB message in an mbuf chain. @@ -42,10 +40,9 @@ */ #include <sys/uio.h> -#include <smbsrv/mbuf.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/msgbuf.h> #include <sys/crypto/api.h> -#include <smbsrv/smb_incl.h> #define SMBAUTH_SESSION_KEY_SZ 16 #define SMB_SIG_SIZE 8 diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c index e6a6ed1360..8f22111344 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c +++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c @@ -51,9 +51,7 @@ * occurred while setting EAs */ -#include <smbsrv/nterror.h> -#include <smbsrv/ntstatus.h> -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> /* diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_dfs.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_dfs.c index 67073b5871..166fc20179 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_trans2_dfs.c +++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_dfs.c @@ -19,13 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> /* diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c index f3aef8da99..11158d9d5c 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c +++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c @@ -202,7 +202,7 @@ * STRING FileName; Files full length name */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/msgbuf.h> #include <smbsrv/smb_fsops.h> @@ -686,7 +686,7 @@ smb_trans2_find_mbc_encode(smb_request_t *sr, smb_xa_t *xa, * Regardless of whether unicode or ascii, a single * termination byte is used. */ - buflen = namelen + sizeof (mts_wchar_t); + buflen = namelen + sizeof (smb_wchar_t); tmpbuf = kmem_zalloc(buflen, KM_SLEEP); smb_msgbuf_init(&mb, (uint8_t *)tmpbuf, buflen, mb_flags); if (smb_msgbuf_encode(&mb, "u", fileinfo->fi_name) < 0) { @@ -768,7 +768,7 @@ smb_trans2_find_mbc_encode(smb_request_t *sr, smb_xa_t *xa, smb_msgbuf_term(&mb); return (-1); } - shortlen = mts_wcequiv_strlen(fileinfo->fi_shortname); + shortlen = smb_wcequiv_strlen(fileinfo->fi_shortname); (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlllb.24cu", sr, diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c index 1d87b3dc6b..4d95fb3154 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c +++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c @@ -230,7 +230,7 @@ * ERRSRV/ERRinvdevice - resource identified by TID is not a file system */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> #include <smbsrv/smbinfo.h> @@ -315,7 +315,7 @@ smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa) case SMB_QUERY_FS_VOLUME_INFO: if ((sr->smb_flg2 & SMB_FLAGS2_UNICODE) || (sr->session->native_os == NATIVE_OS_WIN95)) { - length = mts_wcequiv_strlen(tree->t_volume); + length = smb_wcequiv_strlen(tree->t_volume); encode_str = "%qllb.U"; } else { length = strlen(tree->t_volume); @@ -364,7 +364,7 @@ smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa) (sr->session->native_os == NATIVE_OS_WIN2000) || (sr->session->native_os == NATIVE_OS_WIN95) || (sr->session->native_os == NATIVE_OS_MACOS)) { - length = mts_wcequiv_strlen(fsname); + length = smb_wcequiv_strlen(fsname); encode_str = "%lllU"; sr->smb_flg2 |= SMB_FLAGS2_UNICODE; } else { diff --git a/usr/src/uts/common/fs/smbsrv/smb_tree.c b/usr/src/uts/common/fs/smbsrv/smb_tree.c index ebe14f4cae..48e412345e 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_tree.c +++ b/usr/src/uts/common/fs/smbsrv/smb_tree.c @@ -170,7 +170,7 @@ #include <sys/stat.h> #include <sys/varargs.h> #include <sys/cred_impl.h> -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/lmerr.h> #include <smbsrv/smb_fsops.h> #include <smbsrv/smb_door_svc.h> @@ -215,7 +215,7 @@ smb_tree_connect(smb_request_t *sr) const char *name; int32_t stype; - (void) utf8_strlwr(unc_path); + (void) smb_strlwr(unc_path); if ((name = smb_tree_get_sharename(unc_path)) == NULL) { smbsr_error(sr, 0, ERRSRV, ERRinvnetname); @@ -1048,7 +1048,7 @@ smb_tree_get_flags(const smb_share_t *si, vfs_t *vfsp, smb_tree_t *tree) } (void) strlcpy(tree->t_typename, name, SMB_TYPENAMELEN); - (void) utf8_strupr((char *)tree->t_typename); + (void) smb_strupr((char *)tree->t_typename); if (vfs_has_feature(vfsp, VFSFT_XVATTR)) flags |= SMB_TREE_XVATTR; @@ -1339,7 +1339,7 @@ smb_tree_netinfo_init(smb_tree_t *tree, smb_netconnectinfo_t *info) info->ci_time = gethrestime_sec() - tree->t_connect_time; info->ci_sharelen = strlen(tree->t_sharename) + 1; - info->ci_share = smb_kstrdup(tree->t_sharename, info->ci_sharelen); + info->ci_share = smb_strdup(tree->t_sharename); user = tree->t_user; ASSERT(user); @@ -1359,7 +1359,7 @@ smb_tree_netinfo_fini(smb_netconnectinfo_t *info) if (info->ci_username) kmem_free(info->ci_username, info->ci_namelen); if (info->ci_share) - kmem_free(info->ci_share, info->ci_sharelen); + smb_mfree(info->ci_share); bzero(info, sizeof (smb_netconnectinfo_t)); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_tree_connect.c b/usr/src/uts/common/fs/smbsrv/smb_tree_connect.c index 5f3f4279b2..07ba7a7776 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_tree_connect.c +++ b/usr/src/uts/common/fs/smbsrv/smb_tree_connect.c @@ -23,7 +23,7 @@ * Use is subject to license terms. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> /* @@ -251,8 +251,7 @@ smb_pre_tree_connect_andx(smb_request_t *sr) &sr->arg.tcon.flags, &pwlen); if (rc == 0) { if (pwlen != 0) { - pwbuf = (uint8_t *)smbsr_malloc(&sr->request_storage, - pwlen); + pwbuf = smb_srm_alloc(sr, pwlen); bzero(pwbuf, pwlen); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c b/usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c index aab82acfff..5fc5654f4a 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c +++ b/usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c @@ -51,7 +51,7 @@ * USHORT ByteCount; Count of data bytes = 0 */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> smb_sdrc_t smb_pre_unlock_byte_range(smb_request_t *sr) diff --git a/usr/src/uts/common/fs/smbsrv/smb_user.c b/usr/src/uts/common/fs/smbsrv/smb_user.c index 0b92d8993e..3cd07490b9 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_user.c +++ b/usr/src/uts/common/fs/smbsrv/smb_user.c @@ -163,7 +163,7 @@ * being queued in that list is NOT registered by incrementing the * reference count. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_door_svc.h> @@ -230,8 +230,8 @@ smb_user_login( user->u_privileges = privileges; user->u_name_len = strlen(account_name) + 1; user->u_domain_len = strlen(domain_name) + 1; - user->u_name = smb_kstrdup(account_name, user->u_name_len); - user->u_domain = smb_kstrdup(domain_name, user->u_domain_len); + user->u_name = smb_strdup(account_name); + user->u_domain = smb_strdup(domain_name); user->u_cred = cr; user->u_privcred = smb_cred_create_privs(cr, privileges); user->u_audit_sid = audit_sid; @@ -254,8 +254,8 @@ smb_user_login( } smb_idpool_free(&session->s_uid_pool, user->u_uid); } - kmem_free(user->u_name, (size_t)user->u_name_len); - kmem_free(user->u_domain, (size_t)user->u_domain_len); + smb_mfree(user->u_name); + smb_mfree(user->u_domain); kmem_cache_free(session->s_server->si_cache_user, user); return (NULL); } @@ -582,7 +582,7 @@ smb_user_lookup_share( while (tree) { ASSERT(tree->t_magic == SMB_TREE_MAGIC); ASSERT(tree->t_user == user); - if (utf8_strcasecmp(tree->t_sharename, sharename) == 0) { + if (smb_strcasecmp(tree->t_sharename, sharename, 0) == 0) { if (smb_tree_hold(tree)) { smb_llist_exit(&user->u_tree_list); return (tree); @@ -625,7 +625,7 @@ smb_user_lookup_volume( ASSERT(tree->t_magic == SMB_TREE_MAGIC); ASSERT(tree->t_user == user); - if (utf8_strcasecmp(tree->t_volume, name) == 0) { + if (smb_strcasecmp(tree->t_volume, name, 0) == 0) { if (smb_tree_hold(tree)) { smb_llist_exit(&user->u_tree_list); return (tree); @@ -776,7 +776,7 @@ smb_user_namecmp(smb_user_t *user, const char *name) char *fq_name; boolean_t match; - if (utf8_strcasecmp(name, user->u_name) == 0) + if (smb_strcasecmp(name, user->u_name, 0) == 0) return (B_TRUE); fq_name = kmem_alloc(MAXNAMELEN, KM_SLEEP); @@ -784,12 +784,12 @@ smb_user_namecmp(smb_user_t *user, const char *name) (void) snprintf(fq_name, MAXNAMELEN, "%s\\%s", user->u_domain, user->u_name); - match = (utf8_strcasecmp(name, fq_name) == 0); + match = (smb_strcasecmp(name, fq_name, 0) == 0); if (!match) { (void) snprintf(fq_name, MAXNAMELEN, "%s@%s", user->u_name, user->u_domain); - match = (utf8_strcasecmp(name, fq_name) == 0); + match = (smb_strcasecmp(name, fq_name, 0) == 0); } kmem_free(fq_name, MAXNAMELEN); @@ -891,8 +891,8 @@ smb_user_delete( crfree(user->u_cred); if (user->u_privcred) crfree(user->u_privcred); - kmem_free(user->u_name, (size_t)user->u_name_len); - kmem_free(user->u_domain, (size_t)user->u_domain_len); + smb_mfree(user->u_name); + smb_mfree(user->u_domain); kmem_cache_free(user->u_server->si_cache_user, user); } @@ -1018,15 +1018,15 @@ smb_user_netinfo_init(smb_user_t *user, smb_netuserinfo_t *info) info->ui_flags = user->u_flags; info->ui_domain_len = user->u_domain_len; - info->ui_domain = smb_kstrdup(user->u_domain, info->ui_domain_len); + info->ui_domain = smb_strdup(user->u_domain); info->ui_account_len = user->u_name_len; - info->ui_account = smb_kstrdup(user->u_name, info->ui_account_len); + info->ui_account = smb_strdup(user->u_name); buf = kmem_alloc(MAXNAMELEN, KM_SLEEP); smb_session_getclient(session, buf, MAXNAMELEN); info->ui_workstation_len = strlen(buf) + 1; - info->ui_workstation = smb_kstrdup(buf, info->ui_workstation_len); + info->ui_workstation = smb_strdup(buf); kmem_free(buf, MAXNAMELEN); } @@ -1037,11 +1037,11 @@ smb_user_netinfo_fini(smb_netuserinfo_t *info) return; if (info->ui_domain) - kmem_free(info->ui_domain, info->ui_domain_len); + smb_mfree(info->ui_domain); if (info->ui_account) - kmem_free(info->ui_account, info->ui_account_len); + smb_mfree(info->ui_account); if (info->ui_workstation) - kmem_free(info->ui_workstation, info->ui_workstation_len); + smb_mfree(info->ui_workstation); bzero(info, sizeof (smb_netuserinfo_t)); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_util.c b/usr/src/uts/common/fs/smbsrv/smb_util.c index 870c68ae51..cfc1264fb4 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_util.c +++ b/usr/src/uts/common/fs/smbsrv/smb_util.c @@ -29,10 +29,9 @@ #include <sys/atomic.h> #include <sys/kidmap.h> #include <sys/time.h> -#include <smbsrv/smb_incl.h> +#include <sys/cpuvar.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> -#include <smbsrv/string.h> -#include <smbsrv/mbuf.h> #include <smbsrv/smbinfo.h> #include <smbsrv/smb_xdr.h> #include <smbsrv/smb_vops.h> @@ -41,9 +40,6 @@ #include <sys/sid.h> #include <sys/priv_names.h> -#define SMB_NAME83_BASELEN 8 -#define SMB_NAME83_EXTLEN 3 - static void smb_replace_wildcards(char *); static boolean_t @@ -77,7 +73,7 @@ int smb_ascii_or_unicode_strlen(struct smb_request *sr, char *str) { if (sr->smb_flg2 & SMB_FLAGS2_UNICODE) - return (mts_wcequiv_strlen(str)); + return (smb_wcequiv_strlen(str)); return (strlen(str)); } @@ -85,7 +81,7 @@ int smb_ascii_or_unicode_strlen_null(struct smb_request *sr, char *str) { if (sr->smb_flg2 & SMB_FLAGS2_UNICODE) - return (mts_wcequiv_strlen(str) + 2); + return (smb_wcequiv_strlen(str) + 2); return (strlen(str) + 1); } @@ -310,7 +306,7 @@ smb_stream_parse_name(char *path, char *filename, char *stream) if (stype == NULL) (void) strlcat(stream, ":$DATA", MAXNAMELEN); else - (void) utf8_strupr(stype); + (void) smb_strupr(stype); } /* @@ -1440,7 +1436,7 @@ smb_idmap_batch_destroy(smb_idmap_batch_t *sib) for (i = 0; i < sib->sib_nmap; i++) { domsid = sib->sib_maps[i].sim_domsid; if (domsid) - kmem_free(domsid, strlen(domsid) + 1); + smb_mfree(domsid); } } @@ -1474,7 +1470,7 @@ smb_idmap_batch_getid(idmap_get_handle_t *idmaph, smb_idmap_t *sim, smb_sid_tostr(sid, strsid); if (smb_sid_splitstr(strsid, &sim->sim_rid) != 0) return (IDMAP_ERR_SID); - sim->sim_domsid = smb_kstrdup(strsid, strlen(strsid) + 1); + sim->sim_domsid = smb_strdup(strsid); switch (idtype) { case SMB_IDMAP_USER: @@ -2036,23 +2032,6 @@ smb_cred_is_member(cred_t *cr, smb_sid_t *sid) } /* - * smb_kstrdup - * - * Duplicate the given string s. - */ -char * -smb_kstrdup(const char *s, size_t n) -{ - char *s2; - - ASSERT(s); - ASSERT(n); - s2 = kmem_alloc(n, KM_SLEEP); - (void) strlcpy(s2, s, n); - return (s2); -} - -/* * smb_cred_create_privs * * Creates a duplicate credential that contains system privileges for diff --git a/usr/src/uts/common/fs/smbsrv/smb_vfs.c b/usr/src/uts/common/fs/smbsrv/smb_vfs.c index 40d0497096..cbbd77c8a5 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_vfs.c +++ b/usr/src/uts/common/fs/smbsrv/smb_vfs.c @@ -19,19 +19,16 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "@(#)smb_vfs.c 1.3 08/08/07 SMI" - #include <sys/types.h> #include <sys/fsid.h> #include <sys/vfs.h> #include <sys/stat.h> #include <smbsrv/smb_ktypes.h> #include <smbsrv/smb_kproto.h> -#include <smbsrv/string.h> static smb_vfs_t *smb_vfs_lookup(smb_server_t *, vnode_t *); diff --git a/usr/src/uts/common/fs/smbsrv/smb_vops.c b/usr/src/uts/common/fs/smbsrv/smb_vops.c index 386e02af4b..93782f0b6d 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_vops.c +++ b/usr/src/uts/common/fs/smbsrv/smb_vops.c @@ -37,12 +37,10 @@ #include <sys/fcntl.h> #include <nfs/lm.h> -#include <smbsrv/smb_vops.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/string.h> - +#include <smbsrv/smb_vops.h> #include <smbsrv/smb_fsops.h> -#include <smbsrv/smb_kproto.h> -#include <smbsrv/smb_incl.h> /* * CATIA support @@ -110,7 +108,7 @@ typedef struct smb_catia_map { unsigned char unixchar; /* v4 */ - mts_wchar_t winchar; /* v5 */ + smb_wchar_t winchar; /* v5 */ } smb_catia_map_t; smb_catia_map_t catia_maps[SMB_CATIA_NUM_MAPS] = @@ -126,8 +124,8 @@ smb_catia_map_t catia_maps[SMB_CATIA_NUM_MAPS] = {'|', SMB_CATIA_WIN_BROKEN_BAR} }; -static mts_wchar_t smb_catia_v5_lookup[SMB_CATIA_V5_LOOKUP_MAX]; -static mts_wchar_t smb_catia_v4_lookup[SMB_CATIA_V4_LOOKUP_MAX]; +static smb_wchar_t smb_catia_v5_lookup[SMB_CATIA_V5_LOOKUP_MAX]; +static smb_wchar_t smb_catia_v4_lookup[SMB_CATIA_V4_LOOKUP_MAX]; static void smb_vop_setup_xvattr(smb_attr_t *smb_attr, xvattr_t *xvattr); static void smb_sa_to_va_mask(uint_t sa_mask, uint_t *va_maskp); @@ -1400,11 +1398,11 @@ smb_vop_catia_init_v4_lookup() int i, idx, offset = SMB_CATIA_V4_LOOKUP_LOW; for (i = 0; i < SMB_CATIA_V4_LOOKUP_MAX; i++) - smb_catia_v4_lookup[i] = (mts_wchar_t)(i + offset); + smb_catia_v4_lookup[i] = (smb_wchar_t)(i + offset); for (i = 0; i < SMB_CATIA_NUM_MAPS; i++) { idx = (int)catia_maps[i].winchar - offset; - smb_catia_v4_lookup[idx] = (mts_wchar_t)catia_maps[i].unixchar; + smb_catia_v4_lookup[idx] = (smb_wchar_t)catia_maps[i].unixchar; } } @@ -1420,7 +1418,7 @@ smb_vop_catia_init_v5_lookup() int i, idx; for (i = 0; i < SMB_CATIA_V5_LOOKUP_MAX; i++) - smb_catia_v5_lookup[i] = (mts_wchar_t)i; + smb_catia_v5_lookup[i] = (smb_wchar_t)i; for (i = 0; i < SMB_CATIA_NUM_MAPS; i++) { idx = (int)catia_maps[i].unixchar; @@ -1452,7 +1450,7 @@ smb_vop_catia_v5tov4(char *name, char *buf, int buflen) { int v4_idx, numbytes, inc; int space_left = buflen - 1; /* one byte reserved for null */ - mts_wchar_t wc; + smb_wchar_t wc; char mbstring[MTS_MB_CHAR_MAX]; char *p, *src = name, *dst = buf; @@ -1465,7 +1463,7 @@ smb_vop_catia_v5tov4(char *name, char *buf, int buflen) bzero(buf, buflen); while (*src) { - if ((numbytes = mts_mbtowc(&wc, src, MTS_MB_CHAR_MAX)) < 0) + if ((numbytes = smb_mbtowc(&wc, src, MTS_MB_CHAR_MAX)) < 0) return (name); if (wc < SMB_CATIA_V4_LOOKUP_LOW || @@ -1475,7 +1473,7 @@ smb_vop_catia_v5tov4(char *name, char *buf, int buflen) } else { /* Lookup required. */ v4_idx = (int)wc - SMB_CATIA_V4_LOOKUP_LOW; - inc = mts_wctomb(mbstring, smb_catia_v4_lookup[v4_idx]); + inc = smb_wctomb(mbstring, smb_catia_v4_lookup[v4_idx]); p = mbstring; } @@ -1509,7 +1507,7 @@ smb_vop_catia_v4tov5(char *name, char *buf, int buflen) { int v5_idx, numbytes; int space_left = buflen - 1; /* one byte reserved for null */ - mts_wchar_t wc; + smb_wchar_t wc; char mbstring[MTS_MB_CHAR_MAX]; char *src = name, *dst = buf; @@ -1521,16 +1519,16 @@ smb_vop_catia_v4tov5(char *name, char *buf, int buflen) (void) bzero(buf, buflen); while (*src) { - if (mts_isascii(*src)) { + if (smb_isascii(*src)) { /* Lookup required */ v5_idx = (int)*src++; - numbytes = mts_wctomb(mbstring, + numbytes = smb_wctomb(mbstring, smb_catia_v5_lookup[v5_idx]); if (space_left < numbytes) break; (void) strncpy(dst, mbstring, numbytes); } else { - if ((numbytes = mts_mbtowc(&wc, src, + if ((numbytes = smb_mbtowc(&wc, src, MTS_MB_CHAR_MAX)) < 0) break; if (space_left < numbytes) diff --git a/usr/src/uts/common/fs/smbsrv/smb_vss.c b/usr/src/uts/common/fs/smbsrv/smb_vss.c index 78300cf788..e70c292b38 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_vss.c +++ b/usr/src/uts/common/fs/smbsrv/smb_vss.c @@ -39,9 +39,9 @@ * in the snapshot. */ -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> +#include <smbsrv/string.h> #include <smbsrv/winioctl.h> -#include <smbsrv/ntstatus.h> #include <smbsrv/smb_door_svc.h> /* Size of the token on the wire due to encoding */ @@ -249,7 +249,7 @@ smb_vss_is_gmttoken(const char *s) while (*template) { if (*template == 'N') { - if (!mts_isdigit(*str)) + if (!smb_isdigit(*str)) return (B_FALSE); } else if (*template != *str) { return (B_FALSE); diff --git a/usr/src/uts/common/fs/smbsrv/smb_write.c b/usr/src/uts/common/fs/smbsrv/smb_write.c index c913770205..a07e555494 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_write.c +++ b/usr/src/uts/common/fs/smbsrv/smb_write.c @@ -24,9 +24,8 @@ */ #include <sys/sdt.h> -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> -#include <smbsrv/mbuf.h> #include <smbsrv/netbios.h> diff --git a/usr/src/uts/common/fs/smbsrv/smb_write_raw.c b/usr/src/uts/common/fs/smbsrv/smb_write_raw.c index a1d7948412..446b25bb23 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_write_raw.c +++ b/usr/src/uts/common/fs/smbsrv/smb_write_raw.c @@ -182,9 +182,8 @@ */ #include <sys/sdt.h> -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> #include <smbsrv/smb_fsops.h> -#include <smbsrv/mbuf.h> #include <smbsrv/netbios.h> extern uint32_t smb_keep_alive; diff --git a/usr/src/uts/common/fs/smbsrv/smb_xlate.c b/usr/src/uts/common/fs/smbsrv/smb_xlate.c index ffe1aa199d..c0f4f66391 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_xlate.c +++ b/usr/src/uts/common/fs/smbsrv/smb_xlate.c @@ -19,13 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <smbsrv/smb_incl.h> +#include <smbsrv/smb_kproto.h> struct xlate_table { int code; |