summaryrefslogtreecommitdiff
path: root/usr/src/uts
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts')
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_check_directory.c11
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_close.c12
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_common_open.c396
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_common_search.c24
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_common_transact.c92
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_common_tree.c32
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_create.c16
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_create_directory.c14
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_delete.c187
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_delete_directory.c10
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_dispatch.c241
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_find.c12
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_find_unique.c6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_flush.c4
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_fsops.c365
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_lock_byte_range.c6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_lock_svc.c251
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_locking_andx.c35
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c5
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_negotiate.c12
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_node.c257
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_create_andx.c13
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_transact_create.c11
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_transact_ioctl.c6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_transact_notify_change.c28
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_nt_transact_security.c37
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_ofile.c26
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_open_andx.c22
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_path_name_reduction.c6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_query_information.c6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_query_information2.c8
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_query_information_disk.c4
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_read.c25
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_rename.c110
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_rpc.c20
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_sd.c6
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_search.c11
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_seek.c36
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_session_setup_andx.c10
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_set_information.c8
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_set_information2.c10
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_create_directory.c14
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_find.c326
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c11
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_query_fs_information.c10
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c10
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c12
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c8
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c11
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c7
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_unlock_byte_range.c8
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_vops.c477
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_write.c76
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_write_raw.c15
-rw-r--r--usr/src/uts/common/smbsrv/cifs.h19
-rw-r--r--usr/src/uts/common/smbsrv/lmshare.h3
-rw-r--r--usr/src/uts/common/smbsrv/lmshare_door.h29
-rw-r--r--usr/src/uts/common/smbsrv/lsalib.h37
-rw-r--r--usr/src/uts/common/smbsrv/mlrpc.h54
-rw-r--r--usr/src/uts/common/smbsrv/mlsvc.h17
-rw-r--r--usr/src/uts/common/smbsrv/mlsvc_util.h101
-rw-r--r--usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl48
-rw-r--r--usr/src/uts/common/smbsrv/ndl/winreg.ndl202
-rw-r--r--usr/src/uts/common/smbsrv/samlib.h4
-rw-r--r--usr/src/uts/common/smbsrv/smb_door_svc.h18
-rw-r--r--usr/src/uts/common/smbsrv/smb_fsops.h14
-rw-r--r--usr/src/uts/common/smbsrv/smb_kproto.h49
-rw-r--r--usr/src/uts/common/smbsrv/smb_privilege.h5
-rw-r--r--usr/src/uts/common/smbsrv/smb_vops.h110
-rw-r--r--usr/src/uts/common/smbsrv/smbinfo.h24
-rw-r--r--usr/src/uts/common/smbsrv/smbvar.h12
71 files changed, 2270 insertions, 1852 deletions
diff --git a/usr/src/uts/common/fs/smbsrv/smb_check_directory.c b/usr/src/uts/common/fs/smbsrv/smb_check_directory.c
index d29e55eda6..9d6d0c202d 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_check_directory.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_check_directory.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -74,7 +74,7 @@ smb_com_check_directory(struct smb_request *sr)
struct smb_node *dnode;
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -88,7 +88,7 @@ smb_com_check_directory(struct smb_request *sr)
rc = smbd_fs_query(sr, &sr->arg.dirop.fqi, FQM_PATH_MUST_EXIST);
if (rc) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -104,7 +104,7 @@ smb_com_check_directory(struct smb_request *sr)
smb_node_release(dnode);
SMB_NULL_FQI_NODES(sr->arg.dirop.fqi);
- smbsr_raise_errno(sr, ENOTDIR);
+ smbsr_errno(sr, ENOTDIR);
/* NOTREACHED */
}
@@ -114,8 +114,7 @@ smb_com_check_directory(struct smb_request *sr)
SMB_NULL_FQI_NODES(sr->arg.dirop.fqi);
if (rc != 0) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_close.c b/usr/src/uts/common/fs/smbsrv/smb_close.c
index c4d129c2e4..f2d7faeb8d 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_close.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_close.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -53,14 +53,13 @@ smb_com_close(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
rc = smb_common_close(sr, last_wtime);
if (rc) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -86,8 +85,7 @@ smb_com_close_and_tree_disconnect(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -96,7 +94,7 @@ smb_com_close_and_tree_disconnect(struct smb_request *sr)
smb_tree_disconnect(sr->tid_tree);
if (rc) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
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 d3a462fbc5..5e0d94976b 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_common_open.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_open.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,22 +37,10 @@
#include <smbsrv/ntstatus.h>
#include <smbsrv/smbinfo.h>
#include <sys/fcntl.h>
+#include <sys/nbmlock.h>
extern uint32_t smb_is_executable(char *path);
-#define DENY_READ(share_access) ((share_access & FILE_SHARE_READ) == 0)
-
-#define DENY_WRITE(share_access) ((share_access & FILE_SHARE_WRITE) == 0)
-
-#define DENY_DELETE(share_access) ((share_access & FILE_SHARE_DELETE) == 0)
-
-#define DENY_RW(share_access) \
- ((share_access & (FILE_SHARE_READ | FILE_SHARE_WRITE)) == 0)
-
-#define DENY_ALL(share_access) (share_access == 0)
-
-#define DENY_NONE(share_access) (share_access == FILE_SHARE_ALL)
-
/*
* The default stability mode is to perform the write-through
* behaviour requested by the client.
@@ -219,130 +207,6 @@ smb_ofun_to_crdisposition(uint16_t ofun)
}
/*
- * smb_open_share_check
- *
- * check file sharing rules for current open request
- * against the given existing open.
- *
- * Returns NT_STATUS_SHARING_VIOLATION if there is any
- * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
- */
-uint32_t
-smb_open_share_check(struct smb_request *sr,
- struct smb_node *node,
- struct smb_ofile *open)
-{
- uint32_t desired_access;
- uint32_t share_access;
-
- desired_access = sr->arg.open.desired_access;
- share_access = sr->arg.open.share_access;
-
- /*
- * As far as I can tell share modes are not relevant to
- * directories. The check for exclusive access (Deny RW)
- * remains because I don't know whether or not it was here
- * for a reason.
- */
- if (node->attr.sa_vattr.va_type == VDIR) {
- if (DENY_RW(open->f_share_access) &&
- (node->n_orig_uid != crgetuid(sr->user_cr))) {
- return (NT_STATUS_SHARING_VIOLATION);
- }
-
- return (NT_STATUS_SUCCESS);
- }
-
- /* if it's just meta data */
- if ((open->f_granted_access & FILE_DATA_ALL) == 0)
- return (NT_STATUS_SUCCESS);
-
- /*
- * Check requested share access against the
- * open granted (desired) access
- */
- if (DENY_DELETE(share_access) && (open->f_granted_access & DELETE))
- return (NT_STATUS_SHARING_VIOLATION);
-
- if (DENY_READ(share_access) &&
- (open->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE)))
- return (NT_STATUS_SHARING_VIOLATION);
-
- if (DENY_WRITE(share_access) &&
- (open->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
- return (NT_STATUS_SHARING_VIOLATION);
-
- /* check requested desired access against the open share access */
- if (DENY_DELETE(open->f_share_access) && (desired_access & DELETE))
- return (NT_STATUS_SHARING_VIOLATION);
-
- if (DENY_READ(open->f_share_access) &&
- (desired_access & (FILE_READ_DATA | FILE_EXECUTE)))
- return (NT_STATUS_SHARING_VIOLATION);
-
- if (DENY_WRITE(open->f_share_access) &&
- (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
- return (NT_STATUS_SHARING_VIOLATION);
-
- return (NT_STATUS_SUCCESS);
-}
-
-/*
- * smb_file_share_check
- *
- * check file sharing rules for current open request
- * against all existing opens for a file.
- *
- * Returns NT_STATUS_SHARING_VIOLATION if there is any
- * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
- */
-uint32_t
-smb_file_share_check(struct smb_request *sr, struct smb_node *node)
-{
- struct smb_ofile *open;
- uint32_t status;
-
- if (node == 0 || node->n_refcnt <= 1)
- return (NT_STATUS_SUCCESS);
-
- /* if it's just meta data */
- if ((sr->arg.open.desired_access & FILE_DATA_ALL) == 0)
- return (NT_STATUS_SUCCESS);
-
- smb_llist_enter(&node->n_ofile_list, RW_READER);
- open = smb_llist_head(&node->n_ofile_list);
- while (open) {
- status = smb_open_share_check(sr, node, open);
- if (status == NT_STATUS_SHARING_VIOLATION) {
- smb_llist_exit(&node->n_ofile_list);
- return (status);
- }
- open = smb_llist_next(&node->n_ofile_list, open);
- }
- smb_llist_exit(&node->n_ofile_list);
-
- return (NT_STATUS_SUCCESS);
-}
-
-/*
- * smb_amask_to_amode
- * Converts specific read/write access rights of access mask to access
- * mode flags.
- */
-int
-smb_amask_to_amode(unsigned long amask)
-{
- if ((amask & FILE_READ_DATA) &&
- (amask & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
- return (O_RDWR);
-
- if (amask & (FILE_WRITE_DATA | FILE_APPEND_DATA))
- return (O_WRONLY);
-
- return (O_RDONLY);
-}
-
-/*
* smb_open_subr
*
* Notes on write-through behaviour. It looks like pre-LM0.12 versions
@@ -364,6 +228,7 @@ smb_amask_to_amode(unsigned long amask)
* in which case it won't return to the caller. Be careful how you
* handle things in here.
*/
+
uint32_t
smb_open_subr(struct smb_request *sr)
{
@@ -385,6 +250,8 @@ smb_open_subr(struct smb_request *sr)
int is_stream;
int lookup_flags = SMB_FOLLOW_LINKS;
uint32_t daccess;
+ uint32_t share_access = op->share_access;
+ uint32_t uniq_fid;
is_dir = (op->create_options & FILE_DIRECTORY_FILE) ? 1 : 0;
@@ -397,7 +264,7 @@ smb_open_subr(struct smb_request *sr)
if ((op->create_disposition != FILE_CREATE) &&
(op->create_disposition != FILE_OPEN_IF) &&
(op->create_disposition != FILE_OPEN)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_PARAMETER,
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_ACCESS);
/* invalid open mode */
/* NOTREACHED */
@@ -417,7 +284,7 @@ smb_open_subr(struct smb_request *sr)
sr->uid_user->u_name,
xlate_nt_status(NT_STATUS_TOO_MANY_OPENED_FILES));
- smbsr_raise_cifs_error(sr, NT_STATUS_TOO_MANY_OPENED_FILES,
+ smbsr_error(sr, NT_STATUS_TOO_MANY_OPENED_FILES,
ERRDOS, ERROR_TOO_MANY_OPEN_FILES);
/* NOTREACHED */
}
@@ -437,7 +304,7 @@ smb_open_subr(struct smb_request *sr)
* raise an exception or return success here.
*/
if ((rc = smb_rpc_open(sr)) != 0) {
- smbsr_raise_nt_error(sr, rc);
+ smbsr_error(sr, rc, 0, 0);
/* NOTREACHED */
} else {
return (NT_STATUS_SUCCESS);
@@ -445,13 +312,13 @@ smb_open_subr(struct smb_request *sr)
break;
default:
- smbsr_raise_error(sr, ERRSRV, ERRinvdevice);
+ smbsr_error(sr, 0, ERRSRV, ERRinvdevice);
/* NOTREACHED */
break;
}
if ((pathlen = strlen(op->fqi.path)) >= MAXPATHLEN) {
- smbsr_raise_error(sr, ERRSRV, ERRfilespecs);
+ smbsr_error(sr, 0, ERRSRV, ERRfilespecs);
/* NOTREACHED */
}
@@ -466,7 +333,7 @@ smb_open_subr(struct smb_request *sr)
op->fqi.srch_attr = op->fqi.srch_attr;
if ((status = smb_validate_object_name(op->fqi.path, is_dir)) != 0) {
- smbsr_raise_cifs_error(sr, status, ERRDOS, ERROR_INVALID_NAME);
+ smbsr_error(sr, status, ERRDOS, ERROR_INVALID_NAME);
/* NOTREACHED */
}
@@ -476,7 +343,7 @@ smb_open_subr(struct smb_request *sr)
if (rc = smb_pathname_reduce(sr, sr->user_cr, op->fqi.path,
sr->tid_tree->t_snode, cur_node, &op->fqi.dir_snode,
op->fqi.last_comp)) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -508,26 +375,41 @@ smb_open_subr(struct smb_request *sr)
} else {
smb_node_release(op->fqi.dir_snode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
+ /*
+ * The uniq_fid is a CIFS-server-wide unique identifier for an ofile
+ * which is used to uniquely identify open instances for the
+ * VFS share reservation mechanism (accessed via smb_fsop_shrlock()).
+ */
+
+ uniq_fid = SMB_UNIQ_FID();
+
if (op->fqi.last_comp_was_found) {
node = op->fqi.last_snode;
dnode = op->fqi.dir_snode;
/*
+ * Enter critical region for share reservations.
+ * (See comments above smb_fsop_shrlock().)
+ */
+
+ rw_enter(&node->n_share_lock, RW_WRITER);
+
+ /*
* Reject this request if the target is a directory
* and the client has specified that it must not be
* a directory (required by Lotus Notes).
*/
if ((op->create_options & FILE_NON_DIRECTORY_FILE) &&
(op->fqi.last_attr.sa_vattr.va_type == VDIR)) {
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr,
- NT_STATUS_FILE_IS_A_DIRECTORY,
+ smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -539,19 +421,20 @@ smb_open_subr(struct smb_request *sr)
* Directories cannot be opened
* with the above commands
*/
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr,
- NT_STATUS_FILE_IS_A_DIRECTORY,
+ smbsr_error(sr, NT_STATUS_FILE_IS_A_DIRECTORY,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
} else if (op->my_flags & MYF_MUST_BE_DIRECTORY) {
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr, NT_STATUS_NOT_A_DIRECTORY,
+ smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY,
ERRDOS, ERROR_DIRECTORY);
/* NOTREACHED */
}
@@ -561,10 +444,11 @@ smb_open_subr(struct smb_request *sr)
* flag is set.
*/
if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr, NT_STATUS_DELETE_PENDING,
+ smbsr_error(sr, NT_STATUS_DELETE_PENDING,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -573,12 +457,12 @@ smb_open_subr(struct smb_request *sr)
* Specified file already exists so the operation should fail.
*/
if (op->create_disposition == FILE_CREATE) {
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr,
- NT_STATUS_OBJECT_NAME_COLLISION, ERRDOS,
- ERROR_ALREADY_EXISTS);
+ smbsr_error(sr, NT_STATUS_OBJECT_NAME_COLLISION,
+ ERRDOS, ERROR_ALREADY_EXISTS);
/* NOTREACHED */
}
@@ -591,18 +475,42 @@ smb_open_subr(struct smb_request *sr)
if (node->attr.sa_vattr.va_type != VDIR) {
if (op->desired_access & (FILE_WRITE_DATA |
FILE_APPEND_DATA)) {
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_error(sr, ERRDOS,
- ERRnoaccess);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
+ ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
}
}
- status = smb_file_share_check(sr, node);
+ /*
+ * The following check removes the need to check share
+ * reservations again when a truncate is done.
+ */
+
+ if ((op->create_disposition == FILE_SUPERSEDE) ||
+ (op->create_disposition == FILE_OVERWRITE_IF) ||
+ (op->create_disposition == FILE_OVERWRITE)) {
+
+ if (!(op->desired_access &
+ (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
+ rw_exit(&node->n_share_lock);
+ smb_node_release(node);
+ smb_node_release(dnode);
+ SMB_NULL_FQI_NODES(op->fqi);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
+ ERRDOS, ERRnoaccess);
+ }
+ }
+
+ status = smb_fsop_shrlock(sr->user_cr, node, uniq_fid,
+ op->desired_access, share_access);
+
if (status == NT_STATUS_SHARING_VIOLATION) {
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
@@ -613,19 +521,19 @@ smb_open_subr(struct smb_request *sr)
op->desired_access);
if (status != NT_STATUS_SUCCESS) {
+ smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
+
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
+
if (status == NT_STATUS_PRIVILEGE_NOT_HELD) {
- smbsr_raise_cifs_error(sr,
- status,
- ERRDOS,
- ERROR_PRIVILEGE_NOT_HELD);
+ smbsr_error(sr, status,
+ ERRDOS, ERROR_PRIVILEGE_NOT_HELD);
} else {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_ACCESS_DENIED,
- ERRDOS,
- ERROR_ACCESS_DENIED);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
+ ERRDOS, ERROR_ACCESS_DENIED);
}
}
@@ -634,14 +542,16 @@ smb_open_subr(struct smb_request *sr)
* has the file open, this will force a flush or close,
* which may affect the outcome of any share checking.
*/
+
if (OPLOCKS_IN_FORCE(node)) {
status = smb_break_oplock(sr, node);
if (status != NT_STATUS_SUCCESS) {
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr, status,
+ smbsr_error(sr, status,
ERRDOS, ERROR_VC_DISCONNECTED);
/* NOTREACHED */
}
@@ -652,29 +562,37 @@ smb_open_subr(struct smb_request *sr)
case FILE_OVERWRITE_IF:
case FILE_OVERWRITE:
if (node->attr.sa_vattr.va_type == VDIR) {
+ smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr,
- NT_STATUS_ACCESS_DENIED, ERRDOS,
- ERROR_ACCESS_DENIED);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
+ ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
if (node->attr.sa_vattr.va_size != op->dsize) {
node->flags &= ~NODE_FLAGS_SET_SIZE;
+ bzero(&new_attr, sizeof (new_attr));
new_attr.sa_vattr.va_size = op->dsize;
new_attr.sa_mask = SMB_AT_SIZE;
- if ((rc = smb_fsop_setattr(sr, sr->user_cr,
- (&op->fqi)->last_snode, &new_attr,
- &op->fqi.last_attr)) != 0) {
+
+ rc = smb_fsop_setattr(sr, sr->user_cr,
+ node, &new_attr, &op->fqi.last_attr);
+
+ if (rc) {
+ smb_fsop_unshrlock(sr->user_cr,
+ node, uniq_fid);
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
+ op->dsize = op->fqi.last_attr.sa_vattr.va_size;
}
/*
@@ -712,11 +630,10 @@ smb_open_subr(struct smb_request *sr)
* fail with these two dispositions
*/
if (is_stream)
- smbsr_raise_cifs_error(sr,
- NT_STATUS_OBJECT_NAME_NOT_FOUND,
+ smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
ERRDOS, ERROR_FILE_NOT_FOUND);
else
- smbsr_raise_error(sr, ERRDOS, ERRbadfile);
+ smbsr_error(sr, 0, ERRDOS, ERRbadfile);
/* NOTREACHED */
}
@@ -731,32 +648,93 @@ smb_open_subr(struct smb_request *sr)
new_attr.sa_vattr.va_type = VREG;
new_attr.sa_vattr.va_mode = 0666;
new_attr.sa_mask = SMB_AT_TYPE | SMB_AT_MODE;
+
+ /*
+ * A problem with setting the readonly bit at
+ * create time is that this bit will prevent
+ * writes to the file from the same fid (which
+ * should be allowed).
+ *
+ * The solution is to set the bit at close time.
+ * Meanwhile, to prevent racing opens from being
+ * able to write to the file, the bit is set at
+ * create time until share reservations can be set
+ * to prevent write and delete access. At that point,
+ * the bit can be turned off until close (so as to
+ * allow writes from the same fid to the file).
+ */
+
+ if (op->dattr & SMB_FA_READONLY) {
+ new_attr.sa_dosattr = FILE_ATTRIBUTE_READONLY;
+ new_attr.sa_mask |= SMB_AT_DOSATTR;
+ }
+
rc = smb_fsop_create(sr, sr->user_cr, dnode,
op->fqi.last_comp, &new_attr,
&op->fqi.last_snode, &op->fqi.last_attr);
+
if (rc != 0) {
smb_rwx_rwexit(&dnode->n_lock);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
+ if (op->dattr & SMB_FA_READONLY) {
+ share_access &= ~(FILE_SHARE_WRITE |
+ FILE_SHARE_DELETE);
+ }
+
+ node = op->fqi.last_snode;
+
+ rw_enter(&node->n_share_lock, RW_WRITER);
+
+ status = smb_fsop_shrlock(sr->user_cr, node,
+ uniq_fid, op->desired_access,
+ share_access);
+
+ if (status == NT_STATUS_SHARING_VIOLATION) {
+ rw_exit(&node->n_share_lock);
+ smb_node_release(node);
+ smb_node_release(dnode);
+ SMB_NULL_FQI_NODES(op->fqi);
+ return (status);
+ }
+
+ new_attr = op->fqi.last_attr;
+ new_attr.sa_mask = 0;
+
+ if (op->dattr & SMB_FA_READONLY) {
+ new_attr.sa_dosattr &= ~FILE_ATTRIBUTE_READONLY;
+ new_attr.sa_mask |= SMB_AT_DOSATTR;
+ }
+
if (op->dsize) {
new_attr.sa_vattr.va_size = op->dsize;
- new_attr.sa_mask = SMB_AT_SIZE;
- rc = smb_fsop_setattr(sr, sr->user_cr,
- op->fqi.last_snode, &new_attr,
- &op->fqi.last_attr);
+ new_attr.sa_mask |= SMB_AT_SIZE;
+ }
+
+ if (new_attr.sa_mask) {
+ node->attr = new_attr;
+ node->what = new_attr.sa_mask;
+ rc = smb_sync_fsattr(sr, sr->user_cr, node);
+
if (rc != 0) {
- smb_node_release(op->fqi.last_snode);
+ smb_fsop_unshrlock(sr->user_cr, node,
+ uniq_fid);
+
+ rw_exit(&node->n_share_lock);
+ smb_node_release(node);
(void) smb_fsop_remove(sr, sr->user_cr,
dnode, op->fqi.last_comp, 0);
smb_rwx_rwexit(&dnode->n_lock);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
+ } else {
+ op->fqi.last_attr = node->attr;
}
}
@@ -772,30 +750,33 @@ smb_open_subr(struct smb_request *sr)
smb_rwx_rwexit(&dnode->n_lock);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
+
+ node = op->fqi.last_snode;
+ rw_enter(&node->n_share_lock, RW_WRITER);
}
created = 1;
op->action_taken = SMB_OACT_CREATED;
}
- if (node == 0) {
- node = op->fqi.last_snode;
- }
-
if ((op->fqi.last_attr.sa_vattr.va_type != VREG) &&
(op->fqi.last_attr.sa_vattr.va_type != VDIR) &&
(op->fqi.last_attr.sa_vattr.va_type != VLNK)) {
/* not allowed to do this */
+
+ smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
+
SMB_DEL_NEWOBJ(op->fqi);
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
if (created)
smb_rwx_rwexit(&dnode->n_lock);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_error(sr, ERRDOS, ERRnoaccess);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
@@ -811,17 +792,20 @@ smb_open_subr(struct smb_request *sr)
*/
of = smb_ofile_open(sr->tid_tree, node, sr->smb_pid, op->desired_access,
- op->create_options, op->share_access, SMB_FTYPE_DISK, NULL, 0,
- &err);
+ op->create_options, share_access, SMB_FTYPE_DISK, NULL, 0,
+ uniq_fid, &err);
if (of == NULL) {
+ smb_fsop_unshrlock(sr->user_cr, node, uniq_fid);
+
SMB_DEL_NEWOBJ(op->fqi);
+ rw_exit(&node->n_share_lock);
smb_node_release(node);
if (created)
smb_rwx_rwexit(&dnode->n_lock);
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr, err.status, err.errcls, err.errcode);
+ smbsr_error(sr, err.status, err.errcls, err.errcode);
/* NOTREACHED */
}
@@ -847,14 +831,20 @@ smb_open_subr(struct smb_request *sr)
op->my_flags &= ~MYF_OPLOCK_MASK;
if (status != NT_STATUS_SUCCESS) {
+ rw_exit(&node->n_share_lock);
+ /*
+ * smb_fsop_unshrlock() and smb_fsop_close()
+ * are called from smb_ofile_close()
+ */
(void) smb_ofile_close(of, 0);
smb_ofile_release(of);
if (created)
smb_rwx_rwexit(&dnode->n_lock);
+
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
- smbsr_raise_cifs_error(sr, status,
+ smbsr_error(sr, status,
ERRDOS, ERROR_SHARING_VIOLATION);
/* NOTREACHED */
}
@@ -868,11 +858,15 @@ smb_open_subr(struct smb_request *sr)
/*
* Clients may set the DOS readonly bit on create but they
* expect subsequent write operations on the open fid to
- * succeed. Thus the DOS readonly bit is not set until the
- * file is closed. The NODE_CREATED_READONLY flag will
- * inhibit other attempts to open the file with write access
- * and act as the indicator to set the DOS readonly bit on
+ * succeed. Thus the DOS readonly bit is not set permanently
+ * until the file is closed. The NODE_CREATED_READONLY flag
+ * will act as the indicator to set the DOS readonly bit on
* close.
+ * Above, the readonly bit is set on create, share
+ * reservations are set, and then the bit is unset.
+ * These actions allow writes to the open fid to succeed
+ * until the file is closed while preventing write access
+ * from other opens while this fid is active.
*/
if (op->dattr & SMB_FA_READONLY) {
node->flags |= NODE_CREATED_READONLY;
@@ -913,9 +907,11 @@ smb_open_subr(struct smb_request *sr)
sr->smb_fid = of->f_fid;
sr->fid_ofile = of;
- if (created) {
+ rw_exit(&node->n_share_lock);
+
+ if (created)
smb_rwx_rwexit(&dnode->n_lock);
- }
+
smb_node_release(dnode);
SMB_NULL_FQI_NODES(op->fqi);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_search.c b/usr/src/uts/common/fs/smbsrv/smb_common_search.c
index a17555669b..84d35fe9b0 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_common_search.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_search.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -41,7 +41,6 @@ smb_rdir_open(smb_request_t *sr, char *path, unsigned short sattr)
smb_odir_t *od;
smb_node_t *node;
char *last_component;
- smb_session_t *session = sr->session;
unsigned int rc;
int erc;
@@ -51,14 +50,14 @@ smb_rdir_open(smb_request_t *sr, char *path, unsigned short sattr)
sr->tid_tree->t_snode, sr->tid_tree->t_snode,
&node, last_component)) != 0) {
kmem_free(last_component, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
if ((node->vp)->v_type != VDIR) {
smb_node_release(node);
kmem_free(last_component, MAXNAMELEN);
- smbsr_raise_error(sr, ERRDOS, ERRbadpath);
+ smbsr_error(sr, 0, ERRDOS, ERRbadpath);
/* NOTREACHED */
}
@@ -67,18 +66,11 @@ smb_rdir_open(smb_request_t *sr, char *path, unsigned short sattr)
smb_node_release(node);
kmem_free(last_component, MAXNAMELEN);
if (sr->smb_com == SMB_COM_SEARCH) {
- if (session->capabilities & CAP_STATUS32) {
- smbsr_setup_nt_status(sr,
- ERROR_SEVERITY_WARNING,
- NT_STATUS_NO_MORE_FILES);
- return (SDRC_NORMAL_REPLY);
- } else {
- smbsr_raise_error(sr,
- ERRDOS, ERROR_NO_MORE_FILES);
- /* NOTREACHED */
- }
+ smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
+ ERRDOS, ERROR_NO_MORE_FILES);
+ return (SDRC_NORMAL_REPLY);
} else {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -89,7 +81,7 @@ smb_rdir_open(smb_request_t *sr, char *path, unsigned short sattr)
kmem_free(last_component, sizeof (od->d_pattern));
if (od == NULL) {
smb_node_release(node);
- smbsr_raise_error(sr, ERRDOS, ERROR_NO_MORE_FILES);
+ smbsr_error(sr, 0, ERRDOS, ERROR_NO_MORE_FILES);
/* NOTREACHED */
}
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 2558716c5e..dff0a689dd 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_common_transact.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_transact.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
*/
@@ -89,7 +89,7 @@ smb_com_transaction(struct smb_request *sr)
xa = smb_xa_create(sr->session, sr, tpscnt, tdscnt, mprcnt, mdrcnt,
msrcnt, suwcnt);
if (xa == NULL) {
- smbsr_raise_error(sr, ERRSRV, ERRnoroom);
+ smbsr_error(sr, 0, ERRSRV, ERRnoroom);
/* NOTREACHED */
}
@@ -114,17 +114,17 @@ smb_com_transaction(struct smb_request *sr)
if (MBC_SHADOW_CHAIN(&xa->req_setup_mb, &sr->smb_vwv,
sr->smb_vwv.chain_offset, suwcnt * 2)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
@@ -132,7 +132,7 @@ smb_com_transaction(struct smb_request *sr)
if (smb_xa_open(xa)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRsrverror);
+ smbsr_error(sr, 0, ERRDOS, ERRsrverror);
/* NOTREACHED */
}
sr->r_xa = xa;
@@ -144,7 +144,7 @@ smb_com_transaction(struct smb_request *sr)
if (!smb_xa_complete(xa)) {
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
@@ -161,13 +161,13 @@ smb_com_transaction_secondary(struct smb_request *sr)
int rc;
if ((xa = smbsr_lookup_xa(sr)) == 0) {
- smbsr_raise_error(sr, ERRSRV, ERRsrverror);
+ smbsr_error(sr, 0, ERRSRV, ERRsrverror);
/* NOTREACHED */
}
if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
@@ -194,13 +194,13 @@ smb_com_transaction_secondary(struct smb_request *sr)
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
mutex_exit(&xa->xa_mutex);
@@ -266,7 +266,7 @@ smb_com_transaction2(struct smb_request *sr)
xa = smb_xa_create(sr->session, sr, tpscnt, tdscnt, mprcnt, mdrcnt,
msrcnt, suwcnt);
if (xa == 0) {
- smbsr_raise_error(sr, ERRSRV, ERRnoroom);
+ smbsr_error(sr, 0, ERRSRV, ERRnoroom);
/* NOTREACHED */
}
@@ -278,17 +278,17 @@ smb_com_transaction2(struct smb_request *sr)
if (MBC_SHADOW_CHAIN(&xa->req_setup_mb, &sr->smb_vwv,
sr->smb_vwv.chain_offset, suwcnt*2)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
@@ -296,7 +296,7 @@ smb_com_transaction2(struct smb_request *sr)
if (smb_xa_open(xa)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRsrverror);
+ smbsr_error(sr, 0, ERRDOS, ERRsrverror);
/* NOTREACHED */
}
sr->r_xa = xa;
@@ -308,7 +308,7 @@ smb_com_transaction2(struct smb_request *sr)
if (!smb_xa_complete(xa)) {
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
@@ -325,13 +325,13 @@ smb_com_transaction2_secondary(struct smb_request *sr)
int rc;
if ((xa = smbsr_lookup_xa(sr)) == 0) {
- smbsr_raise_error(sr, ERRSRV, ERRsrverror);
+ smbsr_error(sr, 0, ERRSRV, ERRsrverror);
/* NOTREACHED */
}
if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
@@ -359,13 +359,13 @@ smb_com_transaction2_secondary(struct smb_request *sr)
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
mutex_exit(&xa->xa_mutex);
@@ -418,15 +418,15 @@ smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
case NT_TRANSACT_QUERY_QUOTA:
(void) smb_nt_transact_query_quota(sr, xa);
- smbsr_raise_error(sr, ERRSRV, ERRaccess);
+ smbsr_error(sr, 0, ERRSRV, ERRaccess);
/* NOTREACHED */
case NT_TRANSACT_SET_QUOTA:
- smbsr_raise_error(sr, ERRSRV, ERRaccess);
+ smbsr_error(sr, 0, ERRSRV, ERRaccess);
/* NOTREACHED */
default:
- smbsr_raise_error(sr, ERRSRV, ERRsmbcmd);
+ smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
/* NOTREACHED */
}
@@ -441,7 +441,7 @@ smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
case SDRC_UNIMPLEMENTED:
case SDRC_UNSUPPORTED:
- smbsr_raise_error(sr, ERRSRV, ERRsmbcmd);
+ smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
/* NOTREACHED */
default:
@@ -455,7 +455,7 @@ smb_nt_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
if (xa->smb_msrcnt < n_setup ||
xa->smb_mprcnt < n_param ||
xa->smb_mdrcnt < n_data) {
- smbsr_raise_error(sr, ERRSRV, ERRsmbcmd);
+ smbsr_error(sr, 0, ERRSRV, ERRsmbcmd);
/* NOTREACHED */
}
@@ -539,7 +539,7 @@ smb_com_nt_transact(struct smb_request *sr)
xa = smb_xa_create(sr->session, sr, TotalParameterCount, TotalDataCount,
MaxParameterCount, MaxDataCount, MaxSetupCount, SetupCount);
if (xa == 0) {
- smbsr_raise_error(sr, ERRSRV, ERRnoroom);
+ smbsr_error(sr, 0, ERRSRV, ERRnoroom);
/* NOTREACHED */
}
@@ -552,17 +552,17 @@ smb_com_nt_transact(struct smb_request *sr)
if (MBC_SHADOW_CHAIN(&xa->req_setup_mb, &sr->smb_vwv,
sr->smb_vwv.chain_offset, SetupCount * 2)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
@@ -570,7 +570,7 @@ smb_com_nt_transact(struct smb_request *sr)
if (smb_xa_open(xa)) {
smb_xa_rele(sr->session, xa);
- smbsr_raise_error(sr, ERRDOS, ERRsrverror);
+ smbsr_error(sr, 0, ERRDOS, ERRsrverror);
/* NOTREACHED */
}
sr->r_xa = xa;
@@ -582,7 +582,7 @@ smb_com_nt_transact(struct smb_request *sr)
if (!smb_xa_complete(xa)) {
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
@@ -599,13 +599,13 @@ smb_com_nt_transact_secondary(struct smb_request *sr)
int rc;
if ((xa = smbsr_lookup_xa(sr)) == 0) {
- smbsr_raise_error(sr, ERRSRV, ERRsrverror);
+ smbsr_error(sr, 0, ERRSRV, ERRsrverror);
/* NOTREACHED */
}
if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
if (smb_sign_check_secondary(sr, xa->reply_seqnum) != 0) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
@@ -633,13 +633,13 @@ smb_com_nt_transact_secondary(struct smb_request *sr)
if (MBC_SHADOW_CHAIN(&xa->req_param_mb, &sr->command, psoff, pscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
if (MBC_SHADOW_CHAIN(&xa->req_data_mb, &sr->command, dsoff, dscnt)) {
mutex_exit(&xa->xa_mutex);
smb_xa_close(xa);
- smbsr_raise_error(sr, ERRDOS, ERRbadformat);
+ smbsr_error(sr, 0, ERRDOS, ERRbadformat);
/* NOTREACHED */
}
mutex_exit(&xa->xa_mutex);
@@ -1926,8 +1926,7 @@ smb_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree,
sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -1942,7 +1941,7 @@ smb_trans_dispatch(struct smb_request *sr, struct smb_xa *xa)
case TRANS_WAIT_NMPIPE:
if (is_supported_pipe(xa->xa_smb_trans_name) == 0) {
- smbsr_raise_error(sr, ERRDOS, ERRbadfile);
+ smbsr_error(sr, 0, ERRDOS, ERRbadfile);
/* NOT REACHED */
}
rc = SDRC_NORMAL_REPLY;
@@ -2120,8 +2119,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
* data back to client.
*/
if (n_data == 0) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INFO_LENGTH_MISMATCH,
+ smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
/* NOT REACHED */
}
@@ -2134,8 +2132,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
* data back to client.
*/
if (n_data == 0) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INFO_LENGTH_MISMATCH,
+ smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
/* NOT REACHED */
}
@@ -2148,8 +2145,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
* data back to client.
*/
if (n_data == 0) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INFO_LENGTH_MISMATCH,
+ smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
/* NOT REACHED */
}
@@ -2162,8 +2158,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
* data back to client.
*/
if (n_data == 0) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INFO_LENGTH_MISMATCH,
+ smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
/* NOT REACHED */
}
@@ -2176,8 +2171,7 @@ smb_trans2_dispatch(struct smb_request *sr, struct smb_xa *xa)
* data back to client.
*/
if (n_data == 0) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INFO_LENGTH_MISMATCH,
+ smbsr_error(sr, NT_STATUS_INFO_LENGTH_MISMATCH,
ERRDOS, ERROR_BAD_LENGTH);
/* NOT REACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_common_tree.c b/usr/src/uts/common/fs/smbsrv/smb_common_tree.c
index 7906233a35..6947474f77 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_common_tree.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_common_tree.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -66,6 +66,7 @@ smbsr_connect_tree(struct smb_request *sr)
char *sharename;
char *access_msg;
int32_t stype;
+ DWORD status;
int rc;
errmsg[0] = '\0';
@@ -77,12 +78,12 @@ smbsr_connect_tree(struct smb_request *sr)
* Looks like a UNC path, make sure the format is correct.
*/
if (sharename[1] != '\\') {
- smbsr_raise_error(sr, ERRSRV, ERRinvnetname);
+ smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
/* NOTREACHED */
}
if ((sharename = strchr(sharename+2, '\\')) == 0) {
- smbsr_raise_error(sr, ERRSRV, ERRinvnetname);
+ smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
/* NOTREACHED */
}
@@ -91,12 +92,12 @@ smbsr_connect_tree(struct smb_request *sr)
/*
* This should be a sharename: no embedded '\' allowed.
*/
- smbsr_raise_error(sr, ERRSRV, ERRinvnetname);
+ smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
/* NOTREACHED */
}
if (smb_get_stype(sharename, sr->arg.tcon.service, &stype) != 0) {
- smbsr_raise_cifs_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
+ smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE,
ERRDOS, ERROR_BAD_DEV_TYPE);
/* NOTREACHED */
}
@@ -106,14 +107,11 @@ smbsr_connect_tree(struct smb_request *sr)
smbsr_share_report(sr, sharename, access_msg, errmsg);
/*
- * W2K sometimes tries to connect to user shares using an
- * anonymous IPC connection. NT returns access denied.
+ * Windows 2000 may try to connect to user shares using
+ * an anonymous IPC connection. NT returns access denied.
*/
- if (rc == ERRaccess)
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
- ERRSRV, ERRaccess);
- else
- smbsr_raise_error(sr, ERRSRV, rc);
+ status = (rc == ERRaccess) ? NT_STATUS_ACCESS_DENIED : 0;
+ smbsr_error(sr, status, ERRSRV, rc);
/* NOTREACHED */
}
@@ -167,11 +165,11 @@ smbsr_share_report(struct smb_request *sr, char *sharename,
/*
* smbsr_setup_share
*
- * This is where the real of setting up share is done. The main thing
- * to note is that we resolve ambiguities by assuming that a directory is
- * being requested. This function returns error codes, rather than calling
- * smbsr_raise_error. We return 0 on success or a non-zero error code if
- * there is a problem.
+ * This is where the real of setting up share is done.
+ * Note that ambiguities are resolved by assuming that a directory
+ * is being requested.
+ *
+ * Returns 0 on success or a non-zero error code on failure.
*/
int
smbsr_setup_share(struct smb_request *sr, char *sharename, int32_t stype,
diff --git a/usr/src/uts/common/fs/smbsrv/smb_create.c b/usr/src/uts/common/fs/smbsrv/smb_create.c
index 8fd289bb75..c38bbfd819 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_create.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_create.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -62,13 +62,13 @@ smb_com_create(struct smb_request *sr)
break;
case NT_STATUS_SHARING_VIOLATION:
- smbsr_raise_cifs_error(sr, NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
/* NOTREACHED */
break;
default:
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
break;
}
@@ -107,13 +107,13 @@ smb_com_create_new(struct smb_request *sr)
break;
case NT_STATUS_SHARING_VIOLATION:
- smbsr_raise_cifs_error(sr, NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
/* NOTREACHED */
break;
default:
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
break;
}
@@ -165,13 +165,13 @@ smb_com_create_temporary(struct smb_request *sr)
break;
case NT_STATUS_SHARING_VIOLATION:
- smbsr_raise_cifs_error(sr, NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
/* NOTREACHED */
break;
default:
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
break;
}
@@ -198,7 +198,7 @@ smb_common_create(struct smb_request *sr)
if ((op->desired_access == ((uint32_t)SMB_INVALID_AMASK)) ||
(op->share_access == ((uint32_t)SMB_INVALID_SHAREMODE))) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_PARAMETER,
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_create_directory.c b/usr/src/uts/common/fs/smbsrv/smb_create_directory.c
index e369f59b47..cb6e3f6e72 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_create_directory.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_create_directory.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -93,11 +93,7 @@ smb_com_create_directory(struct smb_request *sr)
}
if ((status = smb_validate_dirname(sr->arg.dirop.fqi.path)) != 0) {
- if (sr->session->capabilities & CAP_STATUS32)
- smbsr_raise_nt_error(sr, status);
- else
- smbsr_raise_error(sr, ERRDOS, ERROR_INVALID_NAME);
-
+ smbsr_error(sr, status, ERRDOS, ERROR_INVALID_NAME);
/* NOTREACHED */
}
@@ -110,12 +106,12 @@ smb_com_create_directory(struct smb_request *sr)
while (smbpath_next(spp)) {
rc = smb_common_create_directory(sr);
if (rc != 0 && rc != EEXIST)
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
}
/* We should have created one directory successfully! */
if (rc != 0)
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
smbsr_encode_empty_result(sr);
return (SDRC_NORMAL_REPLY);
@@ -164,7 +160,7 @@ smb_common_create_directory(struct smb_request *sr)
struct smb_node *node;
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_delete.c b/usr/src/uts/common/fs/smbsrv/smb_delete.c
index f35e3c4273..c3a4dad862 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_delete.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_delete.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -28,10 +28,10 @@
#include <smbsrv/smb_incl.h>
#include <smbsrv/smb_fsops.h>
#include <smbsrv/smbinfo.h>
+#include <sys/nbmlock.h>
-static DWORD smb_delete_check(struct smb_request *sr, struct smb_node *node,
- uint16_t dattr, smb_error_t *smberr);
-static DWORD smb_delete_share_check(struct smb_node *node);
+static uint32_t smb_delete_check(smb_request_t *sr, smb_node_t *node,
+ smb_error_t *smberr);
/*
* smb_com_delete
@@ -104,32 +104,22 @@ smb_com_delete(struct smb_request *sr)
int is_stream;
smb_odir_context_t *pc;
- pc = kmem_zalloc(sizeof (*pc), KM_SLEEP);
- fname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
- sname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
- name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
- fullname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
-
if (smbsr_decode_vwv(sr, "w", &sattr) != 0) {
- kmem_free(pc, sizeof (*pc));
- kmem_free(name, MAXNAMELEN);
- kmem_free(fname, MAXNAMELEN);
- kmem_free(sname, MAXNAMELEN);
- kmem_free(fullname, MAXPATHLEN);
smbsr_decode_error(sr);
/* NOTREACHED */
}
if (smbsr_decode_data(sr, "%S", sr, &path) != 0) {
- kmem_free(pc, sizeof (*pc));
- kmem_free(name, MAXNAMELEN);
- kmem_free(fname, MAXNAMELEN);
- kmem_free(sname, MAXNAMELEN);
- kmem_free(fullname, MAXPATHLEN);
smbsr_decode_error(sr);
/* NOTREACHED */
}
+ pc = kmem_zalloc(sizeof (*pc), KM_SLEEP);
+ fname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+ sname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+ name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
+ fullname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
+
is_stream = smb_stream_parse_name(path, fname, sname);
(void) smb_rdir_open(sr, path, sattr);
@@ -145,14 +135,50 @@ smb_com_delete(struct smb_request *sr)
while ((rc = smb_rdir_next(sr, &node, pc)) == 0) {
(void) strlcpy(name, pc->dc_name, MAXNAMELEN);
- if (smb_delete_check(sr, node, pc->dc_dattr, &smberr)
- != NT_STATUS_SUCCESS) {
+ if (pc->dc_dattr & SMB_FA_DIRECTORY) {
+ smberr.errcls = ERRDOS;
+ smberr.errcode = ERROR_ACCESS_DENIED;
+ smberr.status = NT_STATUS_FILE_IS_A_DIRECTORY;
smb_node_release(node);
goto delete_error;
}
- smb_node_release(node);
- node = NULL;
+ if ((pc->dc_dattr & SMB_FA_READONLY) ||
+ (node->flags & NODE_CREATED_READONLY)) {
+ smberr.errcls = ERRDOS;
+ smberr.errcode = ERROR_ACCESS_DENIED;
+ smberr.status = NT_STATUS_CANNOT_DELETE;
+ smb_node_release(node);
+ goto delete_error;
+ }
+
+ /*
+ * NT does not always close a file immediately, which
+ * can cause the share and access checking to fail
+ * (the node refcnt is greater than one), and the file
+ * doesn't get deleted. Breaking the oplock before
+ * share and access checking gives the client a chance
+ * to close the file.
+ */
+
+ if (OPLOCKS_IN_FORCE(node)) {
+ smberr.status = smb_break_oplock(sr, node);
+
+ if (smberr.status != NT_STATUS_SUCCESS) {
+ smberr.errcls = ERRDOS;
+ smberr.errcode = ERROR_VC_DISCONNECTED;
+ smb_node_release(node);
+ goto delete_error;
+ }
+ }
+
+ smb_node_start_crit(node, RW_READER);
+
+ if (smb_delete_check(sr, node, &smberr)) {
+ smb_node_end_crit(node);
+ smb_node_release(node);
+ goto delete_error;
+ }
if (is_stream) {
/*
@@ -177,6 +203,10 @@ smb_com_delete(struct smb_request *sr)
name, od);
}
+ smb_node_end_crit(node);
+ smb_node_release(node);
+ node = NULL;
+
if (rc != 0) {
if (rc != ENOENT) {
smb_rdir_close(sr);
@@ -185,7 +215,7 @@ smb_com_delete(struct smb_request *sr)
kmem_free(fname, MAXNAMELEN);
kmem_free(sname, MAXNAMELEN);
kmem_free(fullname, MAXPATHLEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
} else {
@@ -201,7 +231,7 @@ smb_com_delete(struct smb_request *sr)
kmem_free(fname, MAXNAMELEN);
kmem_free(sname, MAXNAMELEN);
kmem_free(fullname, MAXPATHLEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -231,57 +261,20 @@ delete_error:
kmem_free(fname, MAXNAMELEN);
kmem_free(sname, MAXNAMELEN);
kmem_free(fullname, MAXPATHLEN);
- smbsr_raise_cifs_error(sr,
- smberr.status, smberr.errcls, smberr.errcode);
+ smbsr_error(sr, smberr.status, smberr.errcls, smberr.errcode);
/* NOTREACHED */
return (SDRC_NORMAL_REPLY); /* compiler complains otherwise */
}
-static DWORD
-smb_delete_check(
- struct smb_request *sr,
- struct smb_node *node,
- uint16_t dattr,
- smb_error_t *smberr)
+uint32_t
+smb_delete_check(smb_request_t *sr, smb_node_t *node, smb_error_t *smberr)
{
- if (dattr & SMB_FA_DIRECTORY) {
- smberr->errcls = ERRDOS;
- smberr->errcode = ERROR_ACCESS_DENIED;
- smberr->status = NT_STATUS_FILE_IS_A_DIRECTORY;
- return (NT_STATUS_UNSUCCESSFUL);
- }
-
- if ((dattr & SMB_FA_READONLY) ||
- (node->flags & NODE_CREATED_READONLY)) {
- smberr->errcls = ERRDOS;
- smberr->errcode = ERROR_ACCESS_DENIED;
- smberr->status = NT_STATUS_CANNOT_DELETE;
- return (NT_STATUS_UNSUCCESSFUL);
- }
-
- /*
- * NT does not always close a file immediately, which
- * can cause the share and access checking to fail
- * (the node refcnt is greater than one), and the file
- * doesn't get deleted. Breaking the oplock before
- * share and access checking gives the client a chance
- * to close the file.
- */
- if (OPLOCKS_IN_FORCE(node)) {
- smberr->status = smb_break_oplock(sr, node);
+ smberr->status = smb_node_delete_check(node);
- if (smberr->status != NT_STATUS_SUCCESS) {
- smberr->errcls = ERRDOS;
- smberr->errcode = ERROR_VC_DISCONNECTED;
- return (NT_STATUS_UNSUCCESSFUL);
- }
- }
-
- smberr->status = smb_delete_share_check(node);
if (smberr->status == NT_STATUS_SHARING_VIOLATION) {
smberr->errcls = ERRDOS;
smberr->errcode = ERROR_SHARING_VIOLATION;
- return (NT_STATUS_UNSUCCESSFUL);
+ return (smberr->status);
}
/*
@@ -294,61 +287,15 @@ smb_delete_check(
* W2K rejects lock requests on open files which are opened
* with Metadata open modes. The error is STATUS_ACCESS_DENIED.
*/
- if (smb_lock_range_access(sr, node, 0, 0, FILE_WRITE_DATA) !=
- NT_STATUS_SUCCESS) {
+
+ smberr->status = smb_range_check(sr, sr->user_cr, node, 0,
+ UINT64_MAX, B_TRUE);
+
+ if (smberr->status != NT_STATUS_SUCCESS) {
smberr->errcls = ERRDOS;
smberr->errcode = ERROR_ACCESS_DENIED;
smberr->status = NT_STATUS_ACCESS_DENIED;
- return (NT_STATUS_UNSUCCESSFUL);
}
-
- return (NT_STATUS_SUCCESS);
-}
-
-/*
- * smb_delete_share_check
- *
- * An open file can be deleted only if opened for
- * accessing meta data. Share modes aren't important
- * in this case.
- *
- * NOTE: there is another mechanism for deleting an
- * open file that NT clients usually use this method.
- * That's setting "Delete on close" flag for an open
- * file, in this way the file will be deleted after
- * last close. This flag can be set by SmbTrans2SetFileInfo
- * with FILE_DISPOSITION_INFO information level.
- * For setting this flag file should be opened by
- * DELETE access in the FID that is passed in the Trans2
- * request.
- */
-static DWORD
-smb_delete_share_check(struct smb_node *node)
-{
- smb_ofile_t *file;
-
- if (node == 0 || node->n_refcnt <= 1)
- return (NT_STATUS_SUCCESS);
-
- if (node->attr.sa_vattr.va_type == VDIR)
- return (NT_STATUS_SUCCESS);
-
- smb_llist_enter(&node->n_ofile_list, RW_READER);
- file = smb_llist_head(&node->n_ofile_list);
- while (file) {
- ASSERT(file->f_magic == SMB_OFILE_MAGIC);
- if (file->f_granted_access &
- (FILE_READ_DATA |
- FILE_WRITE_DATA |
- FILE_APPEND_DATA |
- FILE_EXECUTE |
- DELETE)) {
- smb_llist_exit(&node->n_ofile_list);
- return (NT_STATUS_SHARING_VIOLATION);
- }
- file = smb_llist_next(&node->n_ofile_list, file);
- }
- smb_llist_exit(&node->n_ofile_list);
- return (NT_STATUS_SUCCESS);
+ return (smberr->status);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_delete_directory.c b/usr/src/uts/common/fs/smbsrv/smb_delete_directory.c
index e959b240b8..514551ad97 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_delete_directory.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_delete_directory.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -63,7 +63,7 @@ smb_com_delete_directory(struct smb_request *sr)
int rc;
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -77,7 +77,7 @@ smb_com_delete_directory(struct smb_request *sr)
rc = smbd_fs_query(sr, &sr->arg.dirop.fqi, FQM_PATH_MUST_EXIST);
if (rc) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -88,7 +88,7 @@ smb_com_delete_directory(struct smb_request *sr)
smb_node_release(sr->arg.dirop.fqi.dir_snode);
SMB_NULL_FQI_NODES(sr->arg.dirop.fqi);
- smbsr_raise_cifs_error(sr, NT_STATUS_CANNOT_DELETE,
+ smbsr_error(sr, NT_STATUS_CANNOT_DELETE,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -102,7 +102,7 @@ smb_com_delete_directory(struct smb_request *sr)
if (rc != 0) {
smb_node_release(dnode);
SMB_NULL_FQI_NODES(sr->arg.dirop.fqi);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_dispatch.c b/usr/src/uts/common/fs/smbsrv/smb_dispatch.c
index 96a23bb995..0cc54ae43e 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_dispatch.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_dispatch.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
*
@@ -145,7 +145,6 @@
#define SMB_ALL_DISPATCH_STAT_INCR(stat) atomic_inc_64(&stat);
-int smb_dispatch_diags = 0;
static kstat_t *smb_dispatch_ksp = NULL;
static kstat_named_t *smb_dispatch_kstat_data = NULL;
static int smb_dispatch_kstat_size = 0;
@@ -773,6 +772,7 @@ smb_dispatch_request(struct smb_request *sr)
{
int rc;
smb_dispatch_table_t *sdd;
+ smb_error_t err;
ASSERT(sr->tid_tree == 0);
ASSERT(sr->uid_user == 0);
@@ -834,20 +834,16 @@ smb_dispatch_request(struct smb_request *sr)
sr->first_smb_com = sr->smb_com;
/*
- * Verify SMB signature if signing is enabled,
- * dialiect is NT LM 0.12,
+ * Verify SMB signature if signing is enabled, dialect is NT LM 0.12,
* signing was negotiated and authentication has occurred.
*/
if (sr->session->signing.flags & SMB_SIGNING_ENABLED) {
if (smb_sign_check_request(sr) != 0) {
- /* Reply with ACCESS_DENIED */
- if (sr->session->capabilities & CAP_STATUS32)
- smbsr_setup_nt_status(sr, ERROR_SEVERITY_ERROR,
- NT_STATUS_ACCESS_DENIED);
- else {
- sr->smb_rcls = ERRDOS;
- sr->smb_err = ERRnoaccess;
- }
+ err.severity = ERROR_SEVERITY_ERROR;
+ err.status = NT_STATUS_ACCESS_DENIED;
+ err.errcls = ERRDOS;
+ err.errcode = ERROR_ACCESS_DENIED;
+ smbsr_set_error(sr, &err);
rc = -1;
smb_rwx_rwenter(&sr->session->s_lock, RW_READER);
goto reply_error;
@@ -956,15 +952,14 @@ andx_more:
sr->uid_user = smb_user_lookup_by_uid(sr->session,
&sr->user_cr, sr->smb_uid);
if (sr->uid_user == NULL) {
- smbsr_raise_error(sr, ERRSRV, ERRbaduid);
+ smbsr_error(sr, 0, ERRSRV, ERRbaduid);
/* NOTREACHED */
}
if (!(sdd->sdt_flags & SDDF_SUPPRESS_TID)) {
sr->tid_tree = smb_tree_lookup_by_tid(
sr->uid_user, sr->smb_tid);
if (sr->tid_tree == NULL) {
- smbsr_raise_error(sr, ERRSRV,
- ERRinvnid);
+ smbsr_error(sr, 0, ERRSRV, ERRinvnid);
/* NOTREACHED */
}
}
@@ -1274,78 +1269,15 @@ smbsr_encode_empty_result(struct smb_request *sr)
}
/*
- * cifs_raise_error
- *
- * Temporary workaround to the NT status versus Win32/SMB error codes
- * decision: just report them both here.
- */
-void
-smbsr_raise_cifs_error(struct smb_request *sr,
- DWORD status,
- int error_class,
- int error_code)
-{
- if (sr->session->capabilities & CAP_STATUS32)
- smbsr_raise_nt_error(sr, status);
- else
- smbsr_raise_error(sr, error_class, error_code);
-
- /* NOTREACHED */
-}
-
-void
-smbsr_raise_error(struct smb_request *sr, int errcls, int errcod)
-{
- sr->smb_rcls = (unsigned char)errcls;
- sr->smb_err = (uint16_t)errcod;
- longjmp(&sr->exjb);
-}
-
-/*
- * smbsr_setup_nt_status
- *
- * Set up an NT status in the smb_request but don't long jump or try
- * to do any error handling. There are times when we need a status set
- * up in the response to indicate that the request has either failed
- * or, at least, is only partially complete (possibly indicated by the
- * severity) but we also need to return some information to the client.
- */
-void
-smbsr_setup_nt_status(struct smb_request *sr,
- uint32_t severity,
- uint32_t nt_status)
-{
- nt_status |= severity;
- sr->smb_rcls = nt_status & 0xff;
- sr->smb_reh = (nt_status >> 8) & 0xff;
- sr->smb_err = nt_status >> 16;
- sr->smb_flg2 |= SMB_FLAGS2_NT_STATUS;
-}
-
-void
-smbsr_raise_nt_error(struct smb_request *sr, uint32_t errcod)
-{
- errcod |= 0xc0000000;
- sr->smb_rcls = errcod & 0xff;
- sr->smb_reh = (errcod >> 8) & 0xff;
- sr->smb_err = errcod >> 16;
- sr->smb_flg2 |= SMB_FLAGS2_NT_STATUS;
- longjmp(&sr->exjb);
-}
-
-
-/*
- * Attempt to map errno values to SMB and NT status values.
- * Note: ESRCH is used as special case to handle a lookup
- * failure on streams.
+ * Map errno values to SMB and NT status values.
+ * Note: ESRCH is a special case to handle a streams lookup failure.
*/
static struct {
- int unix_errno;
- int smb_error_class;
- int smb_error_value;
- DWORD nt_status;
-}
-smb_errno_map[] = {
+ int errnum;
+ int errcls;
+ int errcode;
+ DWORD status32;
+} smb_errno_map[] = {
{ ENOSPC, ERRDOS, ERROR_DISK_FULL, NT_STATUS_DISK_FULL },
{ EDQUOT, ERRDOS, ERROR_DISK_FULL, NT_STATUS_DISK_FULL },
{ EPERM, ERRSRV, ERRaccess, NT_STATUS_ACCESS_DENIED },
@@ -1375,74 +1307,115 @@ smb_errno_map[] = {
};
void
-smb_errmap_unix2smb(int en, smb_error_t *smberr)
+smbsr_map_errno(int errnum, smb_error_t *err)
{
int i;
- smberr->status = NT_STATUS_UNSUCCESSFUL;
- smberr->errcls = ERRDOS;
- smberr->errcode = ERROR_GEN_FAILURE;
-
for (i = 0; i < sizeof (smb_errno_map)/sizeof (smb_errno_map[0]); ++i) {
- if (smb_errno_map[i].unix_errno == en) {
- smberr->status = smb_errno_map[i].nt_status;
- smberr->errcls = smb_errno_map[i].smb_error_class;
- smberr->errcode = smb_errno_map[i].smb_error_value;
+ if (smb_errno_map[i].errnum == errnum) {
+ err->severity = ERROR_SEVERITY_ERROR;
+ err->status = smb_errno_map[i].status32;
+ err->errcls = smb_errno_map[i].errcls;
+ err->errcode = smb_errno_map[i].errcode;
return;
}
}
+
+ err->severity = ERROR_SEVERITY_ERROR;
+ err->status = NT_STATUS_INTERNAL_ERROR;
+ err->errcls = ERRDOS;
+ err->errcode = ERROR_INTERNAL_ERROR;
}
-int
-smbsr_set_errno(struct smb_request *sr, int en)
+void
+smbsr_errno(struct smb_request *sr, int errnum)
{
- int i;
+ smb_error_t err;
- ASSERT(en != -1);
+ smbsr_map_errno(errnum, &err);
+ smbsr_set_error(sr, &err);
+ longjmp(&sr->exjb);
+ /* NOTREACHED */
+}
- /*
- * If the client supports 32-bit NT status values, check for
- * an appropriate mapping and raise an NT error, control won't
- * return here due to the longjmp in smbsr_raise_nt_error.
- */
- if (sr->session->capabilities & CAP_STATUS32) {
- for (i = 0;
- i < sizeof (smb_errno_map)/sizeof (smb_errno_map[0]);
- ++i) {
- if (smb_errno_map[i].unix_errno == en) {
- smbsr_raise_nt_error(sr,
- smb_errno_map[i].nt_status);
- /* NOTREACHED */
- }
- }
- } else {
- for (i = 0;
- i < sizeof (smb_errno_map)/sizeof (smb_errno_map[0]);
- ++i) {
- if (smb_errno_map[i].unix_errno == en) {
- sr->smb_rcls = smb_errno_map[i].smb_error_class;
- sr->smb_err = smb_errno_map[i].smb_error_value;
- return (0);
- }
- }
- }
+/*
+ * Report a request processing warning.
+ */
+void
+smbsr_warn(smb_request_t *sr, DWORD status, uint16_t errcls, uint16_t errcode)
+{
+ smb_error_t err;
+
+ err.severity = ERROR_SEVERITY_WARNING;
+ err.status = status;
+ err.errcls = errcls;
+ err.errcode = errcode;
- sr->smb_rcls = ERRSRV;
- sr->smb_err = ERRerror;
- return (-1);
+ smbsr_set_error(sr, &err);
}
+/*
+ * Report a request processing error. This function will not return.
+ */
void
-smbsr_raise_errno(struct smb_request *sr, int en)
+smbsr_error(smb_request_t *sr, DWORD status, uint16_t errcls, uint16_t errcode)
{
- if (smbsr_set_errno(sr, en) != 0) {
- if (smb_dispatch_diags) {
- cmn_err(CE_NOTE, "SmbErrno: errno=%d", en);
- }
- }
+ smb_error_t err;
+ err.severity = ERROR_SEVERITY_ERROR;
+ err.status = status;
+ err.errcls = errcls;
+ err.errcode = errcode;
+
+ smbsr_set_error(sr, &err);
longjmp(&sr->exjb);
- /* no return */
+ /* NOTREACHED */
+}
+
+/*
+ * Setup a request processing error. This function can be used to
+ * report 32-bit status codes or DOS errors. Set the status code
+ * to 0 (NT_STATUS_SUCCESS) to explicitly report a DOS error,
+ * regardless of the client capabilities.
+ *
+ * If status is non-zero and the client supports 32-bit status
+ * codes, report the status. Otherwise, report the DOS error.
+ */
+void
+smbsr_set_error(smb_request_t *sr, smb_error_t *err)
+{
+ uint32_t status;
+ uint32_t severity;
+ uint32_t capabilities;
+
+ ASSERT(sr);
+ ASSERT(err);
+
+ status = err->status;
+ severity = (err->severity == 0) ? ERROR_SEVERITY_ERROR : err->severity;
+ capabilities = sr->session->capabilities;
+
+ if ((err->errcls == 0) && (err->errcode == 0)) {
+ capabilities |= CAP_STATUS32;
+ if (status == 0)
+ status = NT_STATUS_INTERNAL_ERROR;
+ }
+
+ if ((capabilities & CAP_STATUS32) && (status != 0)) {
+ status |= severity;
+ sr->smb_rcls = status & 0xff;
+ sr->smb_reh = (status >> 8) & 0xff;
+ sr->smb_err = status >> 16;
+ sr->smb_flg2 |= SMB_FLAGS2_NT_STATUS;
+ } else {
+ if ((err->errcls == 0) || (err->errcode == 0)) {
+ sr->smb_rcls = ERRSRV;
+ sr->smb_err = ERRerror;
+ } else {
+ sr->smb_rcls = (uint8_t)err->errcls;
+ sr->smb_err = (uint16_t)err->errcode;
+ }
+ }
}
smb_xa_t *
diff --git a/usr/src/uts/common/fs/smbsrv/smb_find.c b/usr/src/uts/common/fs/smbsrv/smb_find.c
index 1492219714..a45e5cab64 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_find.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_find.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -248,7 +248,7 @@ smb_com_find(struct smb_request *sr)
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree,
sr->smb_sid);
if (sr->sid_odir == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -286,13 +286,13 @@ smb_com_find(struct smb_request *sr)
if ((rc != 0) && (rc != ENOENT)) {
/* returned error by smb_rdir_next() */
smb_rdir_close(sr);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
if (count == 0) {
smb_rdir_close(sr);
- smbsr_raise_error(sr, ERRDOS, ERRnofiles);
+ smbsr_error(sr, 0, ERRDOS, ERRnofiles);
/* NOTREACHED */
}
@@ -408,7 +408,7 @@ smb_com_find_close(struct smb_request *sr)
}
if (key_len == 0) { /* begin search */
- smbsr_raise_error(sr, ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -423,7 +423,7 @@ smb_com_find_close(struct smb_request *sr)
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree,
sr->smb_sid);
if (sr->sid_odir == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_find_unique.c b/usr/src/uts/common/fs/smbsrv/smb_find_unique.c
index 59f9ba12b2..f9686297f0 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_find_unique.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_find_unique.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -264,13 +264,13 @@ smb_com_find_unique(struct smb_request *sr)
if ((rc != 0) && (rc != ENOENT)) {
/* returned error by smb_rdir_next() */
kmem_free(vdb, sizeof (struct vardata_block));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
if (count == 0) {
kmem_free(vdb, sizeof (struct vardata_block));
- smbsr_raise_error(sr, ERRDOS, ERRnofiles);
+ smbsr_error(sr, 0, ERRDOS, ERRnofiles);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_flush.c b/usr/src/uts/common/fs/smbsrv/smb_flush.c
index b9cfb8c349..c3da4a2352 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_flush.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_flush.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -93,7 +93,7 @@ smb_com_flush(smb_request_t *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree,
sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_fsops.c b/usr/src/uts/common/fs/smbsrv/smb_fsops.c
index 3d7292961e..561f640fd1 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_fsops.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_fsops.c
@@ -19,26 +19,31 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/sid.h>
+#include <sys/nbmlock.h>
#include <smbsrv/smb_fsops.h>
#include <smbsrv/smb_kproto.h>
#include <smbsrv/smbvar.h>
#include <smbsrv/ntstatus.h>
#include <smbsrv/ntaccess.h>
+#include <smbsrv/smb_incl.h>
#include <acl/acl_common.h>
-
-u_longlong_t smb_caller_id;
+#include <sys/fcntl.h>
+#include <sys/flock.h>
+#include <fs/fs_subr.h>
static int smb_fsop_amask_to_omode(uint32_t granted_access);
static int smb_fsop_sdinherit(smb_request_t *sr, smb_node_t *dnode,
smb_fssd_t *fs_sd);
+static callb_cpr_t *smb_fsop_frlock_callback(flk_cb_when_t when, void *error);
+
/*
* The smb_fsop_* functions have knowledge of CIFS semantics.
*
@@ -65,7 +70,8 @@ smb_fsop_start()
{
int error;
- smb_caller_id = fs_new_caller_id();
+ smb_vop_start();
+
error = smb_node_root_init();
if (error == 0)
@@ -85,32 +91,26 @@ smb_fsop_stop()
int
smb_fsop_open(smb_ofile_t *of)
{
- caller_context_t ct;
int mode;
mode = smb_fsop_amask_to_omode(of->f_granted_access);
- smb_get_caller_context(NULL, &ct);
-
/*
* Assuming that same vnode is returned as we had before
* (i.e. no special vnodes)
*/
- return (smb_vop_open(&of->f_node->vp, mode, of->f_cr, &ct));
+ return (smb_vop_open(&of->f_node->vp, mode, of->f_cr));
}
int
smb_fsop_close(smb_ofile_t *of)
{
- caller_context_t ct;
int mode;
mode = smb_fsop_amask_to_omode(of->f_granted_access);
- smb_get_caller_context(NULL, &ct);
-
- return (smb_vop_close(of->f_node->vp, mode, of->f_cr, &ct));
+ return (smb_vop_close(of->f_node->vp, mode, of->f_cr));
}
static int
@@ -141,7 +141,6 @@ smb_fsop_create_with_sd(
smb_attr_t *ret_attr,
smb_fssd_t *fs_sd)
{
- caller_context_t ct;
vsecattr_t *vsap;
vsecattr_t vsecattr;
acl_t *acl, *dacl, *sacl;
@@ -159,7 +158,6 @@ smb_fsop_create_with_sd(
flags = SMB_IGNORE_CASE;
ASSERT(cr);
- smb_get_caller_context(sr, &ct);
is_dir = ((fs_sd->sd_flags & SMB_FSSD_FLAGS_DIR) != 0);
@@ -191,10 +189,10 @@ smb_fsop_create_with_sd(
if (is_dir) {
rc = smb_vop_mkdir(snode->vp, name, attr, &vp, flags,
- cr, &ct, vsap);
+ cr, vsap);
} else {
rc = smb_vop_create(snode->vp, name, attr, &vp, flags,
- cr, &ct, vsap);
+ cr, vsap);
}
if (vsap != NULL)
@@ -226,7 +224,7 @@ smb_fsop_create_with_sd(
if (sr->tid_tree->t_flags & SMB_TREE_FLAG_UFS)
no_xvattr = B_TRUE;
rc = smb_vop_setattr(snode->vp, NULL, &set_attr,
- 0, kcred, no_xvattr, &ct);
+ 0, kcred, no_xvattr);
}
} else {
@@ -241,10 +239,10 @@ smb_fsop_create_with_sd(
if (is_dir) {
rc = smb_vop_mkdir(snode->vp, name, attr, &vp, flags,
- cr, &ct, NULL);
+ cr, NULL);
} else {
rc = smb_vop_create(snode->vp, name, attr, &vp, flags,
- cr, &ct, NULL);
+ cr, NULL);
}
if (rc != 0)
@@ -266,9 +264,9 @@ smb_fsop_create_with_sd(
if (rc != 0) {
if (is_dir) {
- (void) smb_vop_rmdir(snode->vp, name, flags, cr, &ct);
+ (void) smb_vop_rmdir(snode->vp, name, flags, cr);
} else {
- (void) smb_vop_remove(snode->vp, name, flags, cr, &ct);
+ (void) smb_vop_remove(snode->vp, name, flags, cr);
}
}
@@ -303,7 +301,6 @@ smb_fsop_create(
struct open_param *op = &sr->arg.open;
smb_node_t *fnode;
smb_attr_t file_attr;
- caller_context_t ct;
vnode_t *xattrdirvp;
vnode_t *vp;
char *longname = NULL;
@@ -397,10 +394,8 @@ smb_fsop_create(
return (rc);
}
- smb_get_caller_context(sr, &ct);
-
rc = smb_vop_stream_create(fnode->vp, sname, attr, &vp,
- &xattrdirvp, flags, cr, &ct);
+ &xattrdirvp, flags, cr);
if (rc != 0) {
smb_node_release(fnode);
@@ -457,9 +452,8 @@ smb_fsop_create(
* No incoming SD and filesystem is not ZFS
* let the filesystem handles the inheritance.
*/
- smb_get_caller_context(sr, &ct);
rc = smb_vop_create(dir_snode->vp, name, attr, &vp,
- flags, cr, &ct, NULL);
+ flags, cr, NULL);
if (rc == 0) {
*ret_snode = smb_node_lookup(sr, op, cr, vp,
@@ -503,7 +497,6 @@ smb_fsop_mkdir(
smb_attr_t *ret_attr)
{
struct open_param *op = &sr->arg.open;
- caller_context_t ct;
char *longname;
vnode_t *vp;
int flags = 0;
@@ -511,7 +504,6 @@ smb_fsop_mkdir(
uint32_t secinfo;
uint32_t status;
int rc;
-
ASSERT(cr);
ASSERT(dir_snode);
ASSERT(dir_snode->n_magic == SMB_NODE_MAGIC);
@@ -557,8 +549,6 @@ smb_fsop_mkdir(
if (SMB_TREE_CASE_INSENSITIVE(sr))
flags = SMB_IGNORE_CASE;
- smb_get_caller_context(sr, &ct);
-
if (op->sd) {
/*
* SD sent by client in Windows format. Needs to be
@@ -592,7 +582,7 @@ smb_fsop_mkdir(
} else {
rc = smb_vop_mkdir(dir_snode->vp, name, attr, &vp, flags, cr,
- &ct, NULL);
+ NULL);
if (rc == 0) {
*ret_snode = smb_node_lookup(sr, op, cr, vp, name,
@@ -632,7 +622,6 @@ smb_fsop_remove(
{
smb_node_t *fnode;
smb_attr_t file_attr;
- caller_context_t ct;
char *longname;
char *fname;
char *sname;
@@ -654,8 +643,6 @@ smb_fsop_remove(
if (SMB_TREE_IS_READ_ONLY(sr))
return (EROFS);
- smb_get_caller_context(sr, &ct);
-
fname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
sname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
@@ -687,7 +674,7 @@ smb_fsop_remove(
* Need to find out what permission is required by NTFS
* to remove a stream.
*/
- rc = smb_vop_stream_remove(fnode->vp, sname, flags, cr, &ct);
+ rc = smb_vop_stream_remove(fnode->vp, sname, flags, cr);
smb_node_release(fnode);
} else {
@@ -705,7 +692,7 @@ smb_fsop_remove(
if ((od == 0) && SMB_TREE_CASE_INSENSITIVE(sr))
flags = SMB_IGNORE_CASE;
- rc = smb_vop_remove(dir_snode->vp, name, flags, cr, &ct);
+ rc = smb_vop_remove(dir_snode->vp, name, flags, cr);
if (rc == ENOENT) {
if (smb_maybe_mangled_name(name) == 0) {
@@ -729,7 +716,7 @@ smb_fsop_remove(
*/
flags &= ~SMB_IGNORE_CASE;
rc = smb_vop_remove(dir_snode->vp, longname,
- flags, cr, &ct);
+ flags, cr);
}
kmem_free(longname, MAXNAMELEN);
@@ -754,7 +741,6 @@ smb_fsop_remove_streams(struct smb_request *sr, cred_t *cr,
smb_node_t *fnode)
{
struct fs_stream_info stream_info;
- caller_context_t ct;
uint32_t cookie = 0;
int flags = 0;
int rc;
@@ -773,17 +759,15 @@ smb_fsop_remove_streams(struct smb_request *sr, cred_t *cr,
if (SMB_TREE_CASE_INSENSITIVE(sr))
flags = SMB_IGNORE_CASE;
- smb_get_caller_context(sr, &ct);
-
for (;;) {
rc = smb_vop_stream_readdir(fnode->vp, &cookie, &stream_info,
- NULL, NULL, flags, cr, &ct);
+ NULL, NULL, flags, cr);
if ((rc != 0) || (cookie == SMB_EOF))
break;
(void) smb_vop_stream_remove(fnode->vp, stream_info.name, flags,
- cr, &ct);
+ cr);
}
return (rc);
}
@@ -809,7 +793,6 @@ smb_fsop_rmdir(
char *name,
int od)
{
- caller_context_t ct;
int rc;
int flags = 0;
char *longname;
@@ -843,9 +826,7 @@ smb_fsop_rmdir(
if ((od == 0) && SMB_TREE_CASE_INSENSITIVE(sr))
flags = SMB_IGNORE_CASE;
- smb_get_caller_context(sr, &ct);
-
- rc = smb_vop_rmdir(dir_snode->vp, name, flags, cr, &ct);
+ rc = smb_vop_rmdir(dir_snode->vp, name, flags, cr);
if (rc == ENOENT) {
if (smb_maybe_mangled_name(name) == 0)
@@ -867,8 +848,7 @@ smb_fsop_rmdir(
* a unique directory.
*/
flags &= ~SMB_IGNORE_CASE;
- rc = smb_vop_rmdir(dir_snode->vp, longname, flags, cr,
- &ct);
+ rc = smb_vop_rmdir(dir_snode->vp, longname, flags, cr);
}
kmem_free(longname, MAXNAMELEN);
@@ -893,10 +873,10 @@ smb_fsop_getattr(struct smb_request *sr, cred_t *cr, smb_node_t *snode,
{
smb_node_t *unnamed_node;
vnode_t *unnamed_vp = NULL;
- caller_context_t ct;
uint32_t status;
uint32_t access = 0;
int flags = 0;
+ int rc;
ASSERT(cr);
ASSERT(snode);
@@ -923,8 +903,6 @@ smb_fsop_getattr(struct smb_request *sr, cred_t *cr, smb_node_t *snode,
flags = ATTR_NOACLCHECK;
}
- smb_get_caller_context(sr, &ct);
-
unnamed_node = SMB_IS_STREAM(snode);
if (unnamed_node) {
@@ -933,7 +911,11 @@ smb_fsop_getattr(struct smb_request *sr, cred_t *cr, smb_node_t *snode,
unnamed_vp = unnamed_node->vp;
}
- return (smb_vop_getattr(snode->vp, unnamed_vp, attr, flags, cr, &ct));
+ rc = smb_vop_getattr(snode->vp, unnamed_vp, attr, flags, cr);
+ if (rc == 0)
+ snode->attr = *attr;
+
+ return (rc);
}
/*
@@ -959,7 +941,6 @@ smb_fsop_readdir(
smb_node_t **ret_snode,
smb_attr_t *ret_attr)
{
- caller_context_t ct;
smb_node_t *ret_snodep;
smb_node_t *fnode;
smb_attr_t tmp_attr;
@@ -986,13 +967,11 @@ smb_fsop_readdir(
if (SMB_TREE_CASE_INSENSITIVE(sr))
flags = SMB_IGNORE_CASE;
- smb_get_caller_context(sr, &ct);
-
od_name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
if (stream_info) {
rc = smb_vop_lookup(dir_snode->vp, name, &fvp, od_name,
- SMB_FOLLOW_LINKS, sr->tid_tree->t_snode->vp, cr, &ct);
+ SMB_FOLLOW_LINKS, sr->tid_tree->t_snode->vp, cr);
if (rc != 0) {
kmem_free(od_name, MAXNAMELEN);
@@ -1017,7 +996,7 @@ smb_fsop_readdir(
* Might have to use kcred.
*/
rc = smb_vop_stream_readdir(fvp, cookie, stream_info, &vp,
- &xattrdirvp, flags, cr, &ct);
+ &xattrdirvp, flags, cr);
if ((rc != 0) || (*cookie == SMB_EOF)) {
smb_node_release(fnode);
@@ -1047,7 +1026,7 @@ smb_fsop_readdir(
} else {
rc = smb_vop_readdir(dir_snode->vp, cookie, name, namelen,
- fileid, &vp, od_name, flags, cr, &ct);
+ fileid, &vp, od_name, flags, cr);
if (rc != 0) {
kmem_free(od_name, MAXNAMELEN);
@@ -1104,7 +1083,6 @@ smb_fsop_getdents(
char *args,
char *pattern)
{
- caller_context_t ct;
int flags = 0;
ASSERT(cr);
@@ -1118,10 +1096,8 @@ smb_fsop_getdents(
if (SMB_TREE_CASE_INSENSITIVE(sr))
flags = SMB_IGNORE_CASE;
- smb_get_caller_context(sr, &ct);
-
return (smb_vop_getdents(dir_snode, cookie, 0, maxcnt, args, pattern,
- flags, sr, cr, &ct));
+ flags, sr, cr));
}
/*
@@ -1145,7 +1121,6 @@ smb_fsop_rename(
char *to_name)
{
smb_node_t *from_snode;
- caller_context_t ct;
smb_attr_t tmp_attr;
vnode_t *from_vp;
int flags = 0;
@@ -1188,16 +1163,14 @@ smb_fsop_rename(
* XXX: Lock required through smb_node_release() below?
*/
- smb_get_caller_context(sr, &ct);
-
rc = smb_vop_lookup(from_dir_snode->vp, from_name, &from_vp, NULL, 0,
- NULL, cr, &ct);
+ NULL, cr);
if (rc != 0)
return (rc);
rc = smb_vop_rename(from_dir_snode->vp, from_name, to_dir_snode->vp,
- to_name, flags, cr, &ct);
+ to_name, flags, cr);
if (rc == 0) {
from_snode = smb_node_lookup(sr, NULL, cr, from_vp, from_name,
@@ -1242,7 +1215,6 @@ smb_fsop_setattr(
{
smb_node_t *unnamed_node;
vnode_t *unnamed_vp = NULL;
- caller_context_t ct;
uint32_t status;
uint32_t access = 0;
int rc = 0;
@@ -1278,8 +1250,6 @@ smb_fsop_setattr(
flags = ATTR_NOACLCHECK;
}
- smb_get_caller_context(sr, &ct);
-
unnamed_node = SMB_IS_STREAM(snode);
if (unnamed_node) {
@@ -1291,18 +1261,18 @@ smb_fsop_setattr(
if (sr->tid_tree->t_flags & SMB_TREE_FLAG_UFS)
no_xvattr = B_TRUE;
- rc = smb_vop_setattr(snode->vp, unnamed_vp,
- set_attr, flags, cr, no_xvattr, &ct);
+ rc = smb_vop_setattr(snode->vp, unnamed_vp, set_attr, flags, cr,
+ no_xvattr);
if ((rc == 0) && ret_attr) {
/*
- * This is an operation on behalf of CIFS service (to update
- * smb node's attr) not on behalf of the user so it's done
- * using kcred and the return value is intentionally ignored.
+ * Use kcred to update the node attr because this
+ * call is not being made on behalf of the user.
*/
ret_attr->sa_mask = SMB_AT_ALL;
- (void) smb_vop_getattr(snode->vp, unnamed_vp, ret_attr, 0,
- kcred, &ct);
+ rc = smb_vop_getattr(snode->vp, unnamed_vp, ret_attr, 0, kcred);
+ if (rc == 0)
+ snode->attr = *ret_attr;
}
return (rc);
@@ -1328,7 +1298,7 @@ smb_fsop_read(
{
smb_node_t *unnamed_node;
vnode_t *unnamed_vp = NULL;
- caller_context_t ct;
+ int svmand;
int rc;
ASSERT(cr);
@@ -1360,20 +1330,36 @@ smb_fsop_read(
cr = kcred;
}
- smb_get_caller_context(sr, &ct);
- rc = smb_vop_read(snode->vp, uio, cr, &ct);
+ smb_node_start_crit(snode, RW_READER);
+ rc = nbl_svmand(snode->vp, cr, &svmand);
+ if (rc) {
+ smb_node_end_crit(snode);
+ return (rc);
+ }
+
+ rc = nbl_lock_conflict(snode->vp, NBL_READ, uio->uio_loffset,
+ uio->uio_iov->iov_len, svmand, &smb_ct);
- if (rc == 0) {
+ if (rc) {
+ smb_node_end_crit(snode);
+ return (rc);
+ }
+ rc = smb_vop_read(snode->vp, uio, cr);
+
+ if (rc == 0 && ret_attr) {
/*
- * This is an operation on behalf of CIFS service (to update
- * smb node's attr) not on behalf of the user so it's done
- * using kcred and the return value is intentionally ignored.
+ * Use kcred to update the node attr because this
+ * call is not being made on behalf of the user.
*/
ret_attr->sa_mask = SMB_AT_ALL;
- (void) smb_vop_getattr(snode->vp, unnamed_vp, ret_attr, 0,
- kcred, &ct);
+ if (smb_vop_getattr(snode->vp, unnamed_vp, ret_attr, 0,
+ kcred) == 0) {
+ snode->attr = *ret_attr;
+ }
}
+ smb_node_end_crit(snode);
+
return (rc);
}
@@ -1396,7 +1382,7 @@ smb_fsop_write(
{
smb_node_t *unnamed_node;
vnode_t *unnamed_vp = NULL;
- caller_context_t ct;
+ int svmand;
int rc;
ASSERT(cr);
@@ -1410,15 +1396,13 @@ smb_fsop_write(
if (SMB_TREE_IS_READ_ONLY(sr))
return (EROFS);
- /*
- * XXX what if the file has been opened only with
- * FILE_APPEND_DATA?
- */
- rc = smb_ofile_access(sr->fid_ofile, cr, FILE_WRITE_DATA);
- if (rc != NT_STATUS_SUCCESS)
- return (EACCES);
- smb_get_caller_context(sr, &ct);
+ rc = smb_ofile_access(sr->fid_ofile, cr, FILE_WRITE_DATA);
+ if (rc != NT_STATUS_SUCCESS) {
+ rc = smb_ofile_access(sr->fid_ofile, cr, FILE_APPEND_DATA);
+ if (rc != NT_STATUS_SUCCESS)
+ return (EACCES);
+ }
unnamed_node = SMB_IS_STREAM(snode);
@@ -1435,19 +1419,35 @@ smb_fsop_write(
cr = kcred;
}
- rc = smb_vop_write(snode->vp, uio, flag, lcount, cr, &ct);
+ smb_node_start_crit(snode, RW_READER);
+ rc = nbl_svmand(snode->vp, cr, &svmand);
+ if (rc) {
+ smb_node_end_crit(snode);
+ return (rc);
+ }
+ rc = nbl_lock_conflict(snode->vp, NBL_WRITE, uio->uio_loffset,
+ uio->uio_iov->iov_len, svmand, &smb_ct);
- if (rc == 0) {
+ if (rc) {
+ smb_node_end_crit(snode);
+ return (rc);
+ }
+ rc = smb_vop_write(snode->vp, uio, flag, lcount, cr);
+
+ if (rc == 0 && ret_attr) {
/*
- * This is an operation on behalf of CIFS service (to update
- * smb node's attr) not on behalf of the user so it's done
- * using kcred and the return value is intentionally ignored.
+ * Use kcred to update the node attr because this
+ * call is not being made on behalf of the user.
*/
ret_attr->sa_mask = SMB_AT_ALL;
- (void) smb_vop_getattr(snode->vp, unnamed_vp, ret_attr, 0,
- kcred, &ct);
+ if (smb_vop_getattr(snode->vp, unnamed_vp, ret_attr, 0,
+ kcred) == 0) {
+ snode->attr = *ret_attr;
+ }
}
+ smb_node_end_crit(snode);
+
return (rc);
}
@@ -1577,7 +1577,6 @@ smb_fsop_lookup_name(
{
smb_node_t *fnode;
smb_attr_t file_attr;
- caller_context_t ct;
vnode_t *xattrdirvp;
vnode_t *vp;
char *od_name;
@@ -1627,7 +1626,7 @@ smb_fsop_lookup_name(
* What permissions NTFS requires for stream lookup if any?
*/
rc = smb_vop_stream_lookup(fnode->vp, sname, &vp, od_name,
- &xattrdirvp, flags, root_node->vp, cr, &ct);
+ &xattrdirvp, flags, root_node->vp, cr);
if (rc != 0) {
smb_node_release(fnode);
@@ -1707,7 +1706,6 @@ smb_fsop_lookup(
{
smb_node_t *lnk_target_node;
smb_node_t *lnk_dnode;
- caller_context_t ct;
char *longname;
char *od_name;
vnode_t *vp;
@@ -1727,12 +1725,10 @@ smb_fsop_lookup(
if (SMB_TREE_CASE_INSENSITIVE(sr))
flags |= SMB_IGNORE_CASE;
- smb_get_caller_context(sr, &ct);
-
od_name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
rc = smb_vop_lookup(dir_snode->vp, name, &vp, od_name, flags,
- root_node ? root_node->vp : NULL, cr, &ct);
+ root_node ? root_node->vp : NULL, cr);
if (rc != 0) {
if (smb_maybe_mangled_name(name) == 0) {
@@ -1764,7 +1760,7 @@ smb_fsop_lookup(
flags &= ~SMB_IGNORE_CASE;
rc = smb_vop_lookup(dir_snode->vp, longname, &vp, od_name,
- flags, root_node ? root_node->vp : NULL, cr, &ct);
+ flags, root_node ? root_node->vp : NULL, cr);
kmem_free(longname, MAXNAMELEN);
@@ -1871,7 +1867,6 @@ smb_fsop_stream_readdir(struct smb_request *sr, cred_t *cr, smb_node_t *fnode,
smb_node_t **ret_snode, smb_attr_t *ret_attr)
{
smb_node_t *ret_snodep = NULL;
- caller_context_t ct;
smb_attr_t tmp_attr;
vnode_t *xattrdirvp;
vnode_t *vp;
@@ -1889,10 +1884,8 @@ smb_fsop_stream_readdir(struct smb_request *sr, cred_t *cr, smb_node_t *fnode,
if (SMB_TREE_CASE_INSENSITIVE(sr))
flags = SMB_IGNORE_CASE;
- smb_get_caller_context(sr, &ct);
-
rc = smb_vop_stream_readdir(fnode->vp, cookiep, stream_info, &vp,
- &xattrdirvp, flags, cr, &ct);
+ &xattrdirvp, flags, cr);
if ((rc != 0) || *cookiep == SMB_EOF)
return (rc);
@@ -1922,8 +1915,6 @@ smb_fsop_stream_readdir(struct smb_request *sr, cred_t *cr, smb_node_t *fnode,
int /*ARGSUSED*/
smb_fsop_commit(smb_request_t *sr, cred_t *cr, smb_node_t *snode)
{
- caller_context_t ct;
-
ASSERT(cr);
ASSERT(snode);
ASSERT(snode->n_magic == SMB_NODE_MAGIC);
@@ -1934,9 +1925,7 @@ smb_fsop_commit(smb_request_t *sr, cred_t *cr, smb_node_t *snode)
if (SMB_TREE_IS_READ_ONLY(sr))
return (EROFS);
- smb_get_caller_context(sr, &ct);
-
- return (smb_vop_commit(snode->vp, cr, &ct));
+ return (smb_vop_commit(snode->vp, cr));
}
/*
@@ -1961,7 +1950,6 @@ smb_fsop_aclread(smb_request_t *sr, cred_t *cr, smb_node_t *snode,
int flags = 0;
int access = 0;
acl_t *acl;
- caller_context_t ct;
smb_node_t *unnamed_node;
ASSERT(cr);
@@ -1993,9 +1981,8 @@ smb_fsop_aclread(smb_request_t *sr, cred_t *cr, smb_node_t *snode,
if (sr->tid_tree->t_flags & SMB_TREE_FLAG_ACEMASKONACCESS)
flags = ATTR_NOACLCHECK;
- smb_get_caller_context(sr, &ct);
error = smb_vop_acl_read(snode->vp, &acl, flags,
- sr->tid_tree->t_acltype, cr, &ct);
+ sr->tid_tree->t_acltype, cr);
if (error != 0) {
return (error);
}
@@ -2025,7 +2012,6 @@ smb_fsop_aclwrite(smb_request_t *sr, cred_t *cr, smb_node_t *snode,
int error = 0;
int flags = 0;
int access = 0;
- caller_context_t ct;
acl_t *acl, *dacl, *sacl;
smb_node_t *unnamed_node;
@@ -2088,11 +2074,10 @@ smb_fsop_aclwrite(smb_request_t *sr, cred_t *cr, smb_node_t *snode,
error = acl_translate(acl, target_flavor, (snode->vp->v_type == VDIR),
fs_sd->sd_uid, fs_sd->sd_gid);
if (error == 0) {
- smb_get_caller_context(sr, &ct);
if (sr->tid_tree->t_flags & SMB_TREE_FLAG_ACEMASKONACCESS)
flags = ATTR_NOACLCHECK;
- error = smb_vop_acl_write(snode->vp, acl, flags, cr, &ct);
+ error = smb_vop_acl_write(snode->vp, acl, flags, cr);
}
if (dacl && sacl)
@@ -2474,11 +2459,131 @@ smb_fsop_eaccess(smb_request_t *sr, cred_t *cr, smb_node_t *snode,
FILE_WRITE_EA | FILE_APPEND_DATA | FILE_DELETE_CHILD;
}
-/*ARGSUSED*/
+/*
+ * smb_fsop_shrlock
+ *
+ * For the current open request, check file sharing rules
+ * against existing opens.
+ *
+ * Returns NT_STATUS_SHARING_VIOLATION if there is any
+ * sharing conflict. Returns NT_STATUS_SUCCESS otherwise.
+ *
+ * Full system-wide share reservation synchronization is available
+ * when the nbmand (non-blocking mandatory) mount option is set
+ * (i.e. nbl_need_crit() is true) and nbmand critical regions are used.
+ * This provides synchronization with NFS and local processes. The
+ * critical regions are entered in VOP_SHRLOCK()/fs_shrlock() (called
+ * from smb_open_subr()/smb_fsop_shrlock()/smb_vop_shrlock()) as well
+ * as the CIFS rename and delete paths.
+ *
+ * The CIFS server will also enter the nbl critical region in the open,
+ * rename, and delete paths when nbmand is not set. There is limited
+ * coordination with local and VFS share reservations in this case.
+ * Note that when the nbmand mount option is not set, the VFS layer
+ * only processes advisory reservations and the delete mode is not checked.
+ *
+ * Whether or not the nbmand mount option is set, intra-CIFS share
+ * checking is done in the open, delete, and rename paths using a CIFS
+ * critical region (node->n_share_lock).
+ */
+
+uint32_t
+smb_fsop_shrlock(cred_t *cr, struct smb_node *node, uint32_t uniq_fid,
+ uint32_t desired_access, uint32_t share_access)
+{
+ int rc;
+
+ if (node->attr.sa_vattr.va_type == VDIR)
+ return (NT_STATUS_SUCCESS);
+
+ /* Allow access if the request is just for meta data */
+ if ((desired_access & FILE_DATA_ALL) == 0)
+ return (NT_STATUS_SUCCESS);
+
+ rc = smb_node_open_check(node, cr, desired_access, share_access);
+ if (rc)
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ rc = smb_vop_shrlock(node->vp, uniq_fid, desired_access, share_access,
+ cr);
+ if (rc)
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ return (NT_STATUS_SUCCESS);
+}
+
void
-smb_get_caller_context(smb_request_t *sr, caller_context_t *ct)
+smb_fsop_unshrlock(cred_t *cr, smb_node_t *node, uint32_t uniq_fid)
+{
+ if (node->attr.sa_vattr.va_type == VDIR)
+ return;
+
+ (void) smb_vop_unshrlock(node->vp, uniq_fid, cr);
+}
+
+/*
+ * smb_fsop_frlock_callback
+ *
+ * smb wrapper function for fs_frlock
+ * this should never happen, as we are not attempting
+ * to set Mandatory Locks, cmd = F_SETLK_NBMAND
+ *
+ */
+
+static callb_cpr_t *
+/* ARGSUSED */
+smb_fsop_frlock_callback(flk_cb_when_t when, void *error)
{
- ct->cc_caller_id = smb_caller_id;
- ct->cc_pid = 0; /* TBD */
- ct->cc_sysid = 0; /* TBD */
+ return (0);
+}
+
+/*
+ * smb_fs_frlock
+ *
+ * smb wrapper function for fs_frlock
+ */
+
+int
+smb_fsop_frlock(smb_request_t *sr, smb_node_t *node, smb_lock_t *lock,
+ boolean_t unlock)
+{
+ vnode_t *vp;
+ flock64_t bf;
+ cred_t *cr;
+ caller_context_t *ct;
+ int cmd;
+ flk_callback_t flk_cb;
+ offset_t offset = 0;
+ int flag;
+ int error;
+ int i;
+
+ flk_init_callback(&flk_cb, smb_fsop_frlock_callback, &error);
+ cr = sr->user_cr;
+ ct = &smb_ct;
+ vp = node->vp;
+ cmd = F_SETLK;
+
+ if (unlock == B_TRUE) {
+ bf.l_type = F_UNLCK;
+ flag = 0;
+ } else if (lock->l_type == SMB_LOCK_TYPE_READONLY) {
+ bf.l_type = F_RDLCK;
+ flag = FREAD;
+ } else if (lock->l_type == SMB_LOCK_TYPE_READWRITE) {
+ bf.l_type = F_WRLCK;
+ flag = FWRITE;
+ }
+
+ bf.l_start = lock->l_start;
+ bf.l_len = lock->l_length;
+ bf.l_whence = 0; /* SEEK_SET */
+ bf.l_pid = lock->l_pid;
+ bf.l_sysid = 0;
+
+ for (i = 0; i < 4; i++)
+ bf.l_pad[i] = 0;
+
+ error = fs_frlock(vp, cmd, &bf, flag, offset, &flk_cb, cr, ct);
+ return (error);
}
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 cb5aa042ee..d9773cb50f 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
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -76,7 +76,7 @@ smb_com_lock_byte_range(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -90,7 +90,7 @@ smb_com_lock_byte_range(struct smb_request *sr)
result = smb_lock_range(sr, sr->fid_ofile,
(u_offset_t)off, (uint64_t)count, 0, SMB_LOCK_TYPE_READWRITE);
if (result != NT_STATUS_SUCCESS) {
- smb_lock_range_raise_error(sr, result);
+ smb_lock_range_error(sr, result);
/* NOT REACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_lock_svc.c b/usr/src/uts/common/fs/smbsrv/smb_lock_svc.c
index 7326d5a12c..b39188ebbd 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_lock_svc.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_lock_svc.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +34,17 @@
*/
#include <smbsrv/smb_incl.h>
+#include <smbsrv/smb_fsops.h>
+#include <sys/nbmlock.h>
+#include <sys/param.h>
+
+static void
+smb_unlock_to_posix_unlock(smb_request_t *sr, smb_node_t *node,
+ smb_lock_t *lock, boolean_t unlock);
+
+static boolean_t
+smb_is_range_unlocked(uint64_t start, uint64_t end, smb_llist_t *llist_head,
+ uint64_t *new_mark);
static int
smb_lock_range_overlap(struct smb_lock *lock, uint64_t start, uint64_t length);
@@ -367,6 +378,9 @@ smb_unlock_range(
}
smb_llist_remove(&node->n_lock_list, lock);
+
+ smb_unlock_to_posix_unlock(sr, node, lock, B_TRUE);
+
smb_llist_exit(&node->n_lock_list);
smb_lock_destroy(lock);
@@ -481,7 +495,14 @@ smb_lock_range(
smb_lock_free(lock);
} else {
- smb_llist_insert_tail(&node->n_lock_list, lock);
+ /*
+ * don't insert into the CIFS lock list unless the
+ * posix lock worked
+ */
+ if (smb_fsop_frlock(sr, node, lock, B_FALSE))
+ result = NT_STATUS_FILE_LOCK_CONFLICT;
+ else
+ smb_llist_insert_tail(&node->n_lock_list, lock);
}
smb_llist_exit(&node->n_lock_list);
@@ -506,15 +527,12 @@ smb_lock_range_access(
struct smb_node *node,
uint64_t start,
uint64_t length,
- uint32_t desired_access)
+ boolean_t will_write)
{
smb_lock_t *lock;
smb_llist_t *llist;
int status = NT_STATUS_SUCCESS;
- ASSERT((desired_access & ~(FILE_READ_DATA | FILE_WRITE_DATA)) == 0);
- ASSERT((desired_access & (FILE_READ_DATA | FILE_WRITE_DATA)) != 0);
-
llist = &node->n_lock_list;
smb_llist_enter(llist, RW_READER);
/* Search for any applicable lock */
@@ -526,8 +544,7 @@ smb_lock_range_access(
/* Lock does not overlap */
continue;
- if (lock->l_type == SMB_LOCK_TYPE_READONLY &&
- desired_access == FILE_READ_DATA)
+ if (lock->l_type == SMB_LOCK_TYPE_READONLY && !will_write)
continue;
if (lock->l_type == SMB_LOCK_TYPE_READWRITE &&
@@ -664,46 +681,196 @@ smb_node_destroy_lock_by_ofile(smb_node_t *node, smb_ofile_t *file)
}
void
-smb_lock_range_raise_error(smb_request_t *sr, uint32_t ntstatus)
+smb_lock_range_error(smb_request_t *sr, uint32_t status32)
{
- switch (ntstatus) {
- case NT_STATUS_CANCELLED:
- /*
- * XXX What is the proper error here?
- */
- smbsr_raise_error(sr, ERRDOS, ERRlock);
- /* NOTREACHED */
- case NT_STATUS_FILE_LOCK_CONFLICT:
- smbsr_raise_cifs_error(sr, NT_STATUS_FILE_LOCK_CONFLICT,
- ERRDOS, ERRlock);
- /* NOTREACHED */
- case NT_STATUS_LOCK_NOT_GRANTED:
- smbsr_raise_cifs_error(sr, NT_STATUS_LOCK_NOT_GRANTED,
- ERRDOS, ERRlock);
- /* NOTREACHED */
- case NT_STATUS_RANGE_NOT_LOCKED:
- smbsr_raise_cifs_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
- ERRDOS, ERRlock);
- /* NOTREACHED */
- default:
- ASSERT(0);
- smbsr_raise_error(sr, ERRDOS, ntstatus);
- /* NOTREACHED */
+ uint16_t errcode;
+
+ if (status32 == NT_STATUS_CANCELLED)
+ errcode = ERROR_OPERATION_ABORTED;
+ else
+ errcode = ERRlock;
+
+ smbsr_error(sr, status32, ERRDOS, errcode);
+ /* NOTREACHED */
+}
+
+/*
+ * smb_range_check()
+ *
+ * Perform range checking. First check for internal CIFS range conflicts
+ * and then check for external conflicts, for example, with NFS or local
+ * access.
+ *
+ * If nbmand is enabled, this function must be called from within an nbmand
+ * critical region
+ */
+
+DWORD
+smb_range_check(smb_request_t *sr, cred_t *cr, smb_node_t *node, uint64_t start,
+ uint64_t length, boolean_t will_write)
+{
+ smb_error_t smberr;
+ int svmand;
+ int nbl_op;
+ int rc;
+
+ ASSERT(node);
+ ASSERT(node->n_magic == SMB_NODE_MAGIC);
+ ASSERT(node->n_state == SMB_NODE_STATE_AVAILABLE);
+
+ ASSERT(smb_node_in_crit(node));
+
+ if (node->attr.sa_vattr.va_type == VDIR)
+ return (NT_STATUS_SUCCESS);
+
+ rc = smb_lock_range_access(sr, node, start, length, will_write);
+ if (rc)
+ return (NT_STATUS_UNSUCCESSFUL);
+
+ if ((rc = nbl_svmand(node->vp, cr, &svmand)) != 0) {
+ smbsr_map_errno(rc, &smberr);
+ return (smberr.status);
}
+
+ if (will_write)
+ nbl_op = NBL_WRITE;
+ else
+ nbl_op = NBL_READ;
+
+ if (nbl_lock_conflict(node->vp, nbl_op, start, length,
+ svmand, &smb_ct))
+ return (NT_STATUS_UNSUCCESSFUL);
+
+ return (NT_STATUS_SUCCESS);
}
+/*
+ * smb_unlock_to_posix_unlock
+ *
+ * checks if the current unlock request is in another lock
+ * and repeatedly calls smb_is_range_unlocked on a sliding basis to
+ * to unlock all bits of the lock that are not in other locks
+ *
+ */
void
-smb_unlock_range_raise_error(smb_request_t *sr, uint32_t ntstatus)
+smb_unlock_to_posix_unlock(smb_request_t *sr, smb_node_t *node,
+ smb_lock_t *lock, boolean_t unlock)
{
- switch (ntstatus) {
- case NT_STATUS_RANGE_NOT_LOCKED:
- smbsr_raise_cifs_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
- ERRDOS, ERRnotlocked);
- /* NOTREACHED */
- default:
- ASSERT(0);
- smbsr_raise_error(sr, ERRDOS, ntstatus);
- /* NOTREACHED */
+ uint64_t new_mark;
+ uint64_t unlock_start;
+ uint64_t unlock_end;
+ boolean_t unlocked;
+ smb_lock_t new_unlock;
+ smb_llist_t *llist_head;
+ int cnt = 1;
+
+ new_mark = 0;
+ unlock_start = lock->l_start;
+ unlock_end = unlock_start + lock->l_length;
+ llist_head = &node->n_lock_list;
+
+ while (cnt) {
+ if ((unlocked = smb_is_range_unlocked(unlock_start, unlock_end,
+ llist_head, &new_mark)) == B_TRUE) {
+ if (new_mark) {
+ new_unlock = *lock;
+ new_unlock.l_start = unlock_start;
+ new_unlock.l_length = new_mark - unlock_start;
+ (void) smb_fsop_frlock(sr, node,
+ &new_unlock, unlock);
+ unlock_start = new_mark;
+ } else {
+ new_unlock = *lock;
+ new_unlock.l_start = unlock_start;
+ new_unlock.l_length = unlock_end - unlock_start;
+ (void) smb_fsop_frlock(sr, node,
+ &new_unlock, unlock);
+ break;
+ }
+ } else if ((unlocked == B_FALSE) && new_mark) {
+ unlock_start = new_mark;
+ } else {
+ break;
+ }
+ }
+}
+
+/*
+ * smb_is_range_unlocked
+ *
+ * Checks if the current unlock byte range request overlaps another lock
+ * The return code and the value of new_mark must be interpreted as
+ * follows:
+ *
+ * B_TRUE and (new_mark == 0):
+ * This is the last or only lock left to be unlocked
+ *
+ * B_TRUE and (new_mark > 0):
+ * The range from start to new_mark can be unlocked
+ *
+ * B_FALSE and (new_mark == 0):
+ * The unlock can't be performed and we are done
+ *
+ * B_FALSE and (new_mark > 0),
+ * The range from start to new_mark can't be unlocked
+ * Start should be reset to new_mark for the next pass
+ */
+
+static boolean_t
+smb_is_range_unlocked(uint64_t start, uint64_t end, smb_llist_t *llist_head,
+ uint64_t *new_mark)
+{
+ struct smb_lock *lk = 0;
+ uint64_t low_water_mark = MAXOFFSET_T;
+ uint64_t lk_start;
+ uint64_t lk_end;
+
+ *new_mark = 0;
+ lk = smb_llist_head(llist_head);
+ while (lk) {
+
+ lk_end = lk->l_start + lk->l_length - 1;
+ lk_start = lk->l_start;
+
+ /*
+ * there is no overlap for the first 2 cases
+ * check next node
+ */
+ if (lk_end < start) {
+ lk = smb_llist_next(llist_head, lk);
+ continue;
+ }
+ if (lk_start > end) {
+ lk = smb_llist_next(llist_head, lk);
+ continue;
+ }
+
+ /* this range is completely locked */
+ if ((lk_start <= start) && (lk_end >= end)) {
+ return (B_FALSE);
+ }
+
+ /* the first part of this range is locked */
+ if ((start >= lk_start) && (start <= lk_end)) {
+ if (end > lk_end)
+ *new_mark = lk_end + 1;
+ return (B_FALSE);
+ }
+
+ /* this piece is unlocked */
+ if ((lk_start >= start) && (lk_start <= end)) {
+ if (low_water_mark > lk_start)
+ low_water_mark = lk_start;
+ }
+
+ lk = smb_llist_next(llist_head, lk);
+ }
+
+ if (low_water_mark != MAXOFFSET_T) {
+ *new_mark = low_water_mark;
+ return (B_TRUE);
}
+ /* the range is completely unlocked */
+ return (B_TRUE);
}
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 0acf7922c4..4aa585091e 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -239,8 +239,7 @@ smb_com_locking_andx(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -275,7 +274,7 @@ smb_com_locking_andx(struct smb_request *sr)
* implement this)
*/
if (lock_type & LOCKING_ANDX_CHANGE_LOCK_TYPE) {
- smbsr_raise_error(sr, ERRDOS, ERRnoatomiclocks);
+ smbsr_error(sr, 0, ERRDOS, ERRnoatomiclocks);
/* NOT REACHED */
}
@@ -283,8 +282,7 @@ smb_com_locking_andx(struct smb_request *sr)
* No support for cancel lock (smbtorture expects this)
*/
if (lock_type & LOCKING_ANDX_CANCEL_LOCK) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INVALID_PARAMETER,
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
/* NOT REACHED */
}
@@ -294,8 +292,7 @@ smb_com_locking_andx(struct smb_request *sr)
* negotiated protocol should be NT LM 0.12 or later
*/
if (sr->session->dialect < NT_LM_0_12) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INVALID_PARAMETER,
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
/* NOT REACHED */
}
@@ -305,17 +302,18 @@ smb_com_locking_andx(struct smb_request *sr)
&sr->smb_pid, &offset64, &length64);
if (rc) {
/*
- * This is the error returned by a W2K system
- * even when NT Status is negotiated.
+ * This is the error returned by Windows 2000
+ * even when STATUS32 has been negotiated.
*/
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOT REACHED */
}
result = smb_unlock_range(sr, sr->fid_ofile->f_node,
offset64, length64);
if (result != NT_STATUS_SUCCESS) {
- smb_unlock_range_raise_error(sr, result);
+ smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
+ ERRDOS, ERRnotlocked);
/* NOT REACHED */
}
}
@@ -324,14 +322,14 @@ smb_com_locking_andx(struct smb_request *sr)
rc = smb_decode_mbc(&sr->smb_data, "w2.QQ",
&sr->smb_pid, &offset64, &length64);
if (rc) {
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOT REACHED */
}
result = smb_lock_range(sr, sr->fid_ofile,
offset64, length64, timeout, ltype);
if (result != NT_STATUS_SUCCESS) {
- smb_lock_range_raise_error(sr, result);
+ smb_lock_range_error(sr, result);
/* NOT REACHED */
}
}
@@ -340,14 +338,15 @@ smb_com_locking_andx(struct smb_request *sr)
rc = smb_decode_mbc(&sr->smb_data, "wll", &sr->smb_pid,
&offset32, &length32);
if (rc) {
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOT REACHED */
}
result = smb_unlock_range(sr, sr->fid_ofile->f_node,
(uint64_t)offset32, (uint64_t)length32);
if (result != NT_STATUS_SUCCESS) {
- smb_unlock_range_raise_error(sr, result);
+ smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
+ ERRDOS, ERRnotlocked);
/* NOT REACHED */
}
}
@@ -356,7 +355,7 @@ smb_com_locking_andx(struct smb_request *sr)
rc = smb_decode_mbc(&sr->smb_data, "wll", &sr->smb_pid,
&offset32, &length32);
if (rc) {
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOT REACHED */
}
@@ -365,7 +364,7 @@ smb_com_locking_andx(struct smb_request *sr)
(uint64_t)length32,
timeout, ltype);
if (result != NT_STATUS_SUCCESS) {
- smb_lock_range_raise_error(sr, result);
+ smb_lock_range_error(sr, result);
/* NOT REACHED */
}
}
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 278916b8fd..4b56c61b73 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_logoff_andx.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -66,8 +66,7 @@ int
smb_com_logoff_andx(struct smb_request *sr)
{
if (sr->uid_user == NULL) {
- cmn_err(CE_WARN, "SmbLogoffAndX: bad uid");
- smbsr_raise_error(sr, ERRSRV, ERRbaduid);
+ smbsr_error(sr, 0, ERRSRV, ERRbaduid);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_negotiate.c b/usr/src/uts/common/fs/smbsrv/smb_negotiate.c
index 844e84a889..a14ae7d3a5 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_negotiate.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_negotiate.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -261,7 +261,7 @@ smb_com_negotiate(struct smb_request *sr)
if (sr->session->s_state != SMB_SESSION_STATE_ESTABLISHED) {
/* The protocol has already been negotiated. */
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOTREACHED */
}
@@ -269,7 +269,7 @@ smb_com_negotiate(struct smb_request *sr)
sr->smb_data.chain_offset < sr->smb_data.max_bytes;
pos++) {
if (smb_decode_mbc(&sr->smb_data, "%L", sr, &p) != 0) {
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOTREACHED */
}
@@ -284,7 +284,7 @@ smb_com_negotiate(struct smb_request *sr)
}
}
if (sel_pos < 0) {
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOTREACHED */
}
@@ -435,9 +435,7 @@ smb_com_negotiate(struct smb_request *sr)
break;
default:
- /* Just to make sure. */
- ASSERT(0);
- smbsr_raise_error(sr, ERRSRV, ERRerror);
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_node.c b/usr/src/uts/common/fs/smbsrv/smb_node.c
index 5ea8c5f1c3..13be0f3cf3 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_node.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_node.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -84,6 +84,7 @@
#include <smbsrv/smb_fsops.h>
#include <sys/pathname.h>
#include <sys/sdt.h>
+#include <sys/nbmlock.h>
uint32_t smb_is_executable(char *path);
static void smb_node_delete_on_close(smb_node_t *node);
@@ -138,7 +139,6 @@ smb_node_lookup(
fs_desc_t fsd;
int error;
krw_t lock_mode;
- caller_context_t ct;
vnode_t *unnamed_vp = NULL;
/*
@@ -154,9 +154,8 @@ smb_node_lookup(
* This getattr is performed on behalf of the server
* that's why kcred is used not the user's cred
*/
- smb_get_caller_context(sr, &ct);
attr->sa_mask = SMB_AT_ALL;
- error = smb_vop_getattr(vp, unnamed_vp, attr, 0, kcred, &ct);
+ error = smb_vop_getattr(vp, unnamed_vp, attr, 0, kcred);
if (error)
return (NULL);
@@ -208,6 +207,7 @@ smb_node_lookup(
smb_node_ref(dir_snode);
}
node->attr = *attr;
+ node->n_size = attr->sa_vattr.va_size;
smb_audit_node(node);
smb_rwx_xexit(&node->n_lock);
@@ -768,3 +768,252 @@ smb_node_reset_delete_on_close(smb_node_t *node)
}
smb_rwx_xexit(&node->n_lock);
}
+
+/*
+ * smb_node_share_check
+ *
+ * check file sharing rules for current open request
+ * against all existing opens for a file.
+ *
+ * Returns NT_STATUS_SHARING_VIOLATION if there is any
+ * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
+ */
+uint32_t
+smb_node_open_check(struct smb_node *node, cred_t *cr,
+ uint32_t desired_access, uint32_t share_access)
+{
+ smb_ofile_t *of;
+ uint32_t status;
+
+ ASSERT(node);
+ ASSERT(node->n_magic == SMB_NODE_MAGIC);
+ ASSERT(node->n_state == SMB_NODE_STATE_AVAILABLE);
+
+ smb_llist_enter(&node->n_ofile_list, RW_READER);
+ of = smb_llist_head(&node->n_ofile_list);
+ while (of) {
+ status = smb_node_share_check(node, cr, desired_access,
+ share_access, of);
+ if (status == NT_STATUS_SHARING_VIOLATION) {
+ smb_llist_exit(&node->n_ofile_list);
+ return (status);
+ }
+ of = smb_llist_next(&node->n_ofile_list, of);
+ }
+ smb_llist_exit(&node->n_ofile_list);
+
+ return (NT_STATUS_SUCCESS);
+}
+
+/*
+ * smb_open_share_check
+ *
+ * check file sharing rules for current open request
+ * against the given existing open.
+ *
+ * Returns NT_STATUS_SHARING_VIOLATION if there is any
+ * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
+ */
+uint32_t
+smb_node_share_check(
+ struct smb_node *node,
+ cred_t *cr,
+ uint32_t desired_access,
+ uint32_t share_access,
+ smb_ofile_t *of)
+{
+ /*
+ * It appears that share modes are not relevant to
+ * directories, but this check will remain as it is not
+ * clear whether it was originally put here for a reason.
+ */
+ if (node->attr.sa_vattr.va_type == VDIR) {
+ if (SMB_DENY_RW(of->f_share_access) &&
+ (node->n_orig_uid != crgetuid(cr))) {
+ return (NT_STATUS_SHARING_VIOLATION);
+ }
+
+ return (NT_STATUS_SUCCESS);
+ }
+
+ /* if it's just meta data */
+ if ((of->f_granted_access & FILE_DATA_ALL) == 0)
+ return (NT_STATUS_SUCCESS);
+
+ /*
+ * Check requested share access against the
+ * open granted (desired) access
+ */
+ if (SMB_DENY_DELETE(share_access) && (of->f_granted_access & DELETE))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ if (SMB_DENY_READ(share_access) &&
+ (of->f_granted_access & (FILE_READ_DATA | FILE_EXECUTE)))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ if (SMB_DENY_WRITE(share_access) &&
+ (of->f_granted_access & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ /* check requested desired access against the open share access */
+ if (SMB_DENY_DELETE(of->f_share_access) && (desired_access & DELETE))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ if (SMB_DENY_READ(of->f_share_access) &&
+ (desired_access & (FILE_READ_DATA | FILE_EXECUTE)))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ if (SMB_DENY_WRITE(of->f_share_access) &&
+ (desired_access & (FILE_WRITE_DATA | FILE_APPEND_DATA)))
+ return (NT_STATUS_SHARING_VIOLATION);
+
+ return (NT_STATUS_SUCCESS);
+}
+
+/*
+ * smb_rename_share_check
+ *
+ * An open file can be renamed if
+ *
+ * 1. isn't opened for data writing or deleting
+ *
+ * 2. Opened with "Deny Delete" share mode
+ * But not opened for data reading or executing
+ * (opened for accessing meta data)
+ */
+
+DWORD
+smb_node_rename_check(struct smb_node *node)
+{
+ struct smb_ofile *open;
+
+ ASSERT(node);
+ ASSERT(node->n_magic == SMB_NODE_MAGIC);
+ ASSERT(node->n_state == SMB_NODE_STATE_AVAILABLE);
+
+ /*
+ * Intra-CIFS check
+ */
+
+ smb_llist_enter(&node->n_ofile_list, RW_READER);
+ open = smb_llist_head(&node->n_ofile_list);
+ while (open) {
+ if (open->f_granted_access &
+ (FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE)) {
+ smb_llist_exit(&node->n_ofile_list);
+ return (NT_STATUS_SHARING_VIOLATION);
+ }
+
+ if ((open->f_share_access & FILE_SHARE_DELETE) == 0) {
+ if (open->f_granted_access &
+ (FILE_READ_DATA | FILE_EXECUTE)) {
+ smb_llist_exit(&node->n_ofile_list);
+ return (NT_STATUS_SHARING_VIOLATION);
+ }
+ }
+ open = smb_llist_next(&node->n_ofile_list, open);
+ }
+ smb_llist_exit(&node->n_ofile_list);
+
+ /*
+ * system-wide share check
+ */
+
+ if (nbl_share_conflict(node->vp, NBL_RENAME, NULL))
+ return (NT_STATUS_SHARING_VIOLATION);
+ else
+ return (NT_STATUS_SUCCESS);
+}
+
+/*
+ * smb_node_delete_check
+ *
+ * An open file can be deleted only if opened for
+ * accessing meta data. Share modes aren't important
+ * in this case.
+ *
+ * NOTE: there is another mechanism for deleting an
+ * open file that NT clients usually use.
+ * That's setting "Delete on close" flag for an open
+ * file. In this way the file will be deleted after
+ * last close. This flag can be set by SmbTrans2SetFileInfo
+ * with FILE_DISPOSITION_INFO information level.
+ * For setting this flag, the file should be opened by
+ * DELETE access in the FID that is passed in the Trans2
+ * request.
+ */
+DWORD
+smb_node_delete_check(smb_node_t *node)
+{
+ smb_ofile_t *file;
+
+ ASSERT(node);
+ ASSERT(node->n_magic == SMB_NODE_MAGIC);
+ ASSERT(node->n_state == SMB_NODE_STATE_AVAILABLE);
+
+ if (node->attr.sa_vattr.va_type == VDIR)
+ return (NT_STATUS_SUCCESS);
+
+ /*
+ * intra-CIFS check
+ */
+
+ smb_llist_enter(&node->n_ofile_list, RW_READER);
+ file = smb_llist_head(&node->n_ofile_list);
+ while (file) {
+ ASSERT(file->f_magic == SMB_OFILE_MAGIC);
+ if (file->f_granted_access &
+ (FILE_READ_DATA |
+ FILE_WRITE_DATA |
+ FILE_APPEND_DATA |
+ FILE_EXECUTE |
+ DELETE)) {
+ smb_llist_exit(&node->n_ofile_list);
+ return (NT_STATUS_SHARING_VIOLATION);
+ }
+ file = smb_llist_next(&node->n_ofile_list, file);
+ }
+ smb_llist_exit(&node->n_ofile_list);
+
+ /*
+ * system-wide share check
+ */
+
+ if (nbl_share_conflict(node->vp, NBL_REMOVE, NULL))
+ return (NT_STATUS_SHARING_VIOLATION);
+ else
+ return (NT_STATUS_SUCCESS);
+}
+
+/*
+ * smb_node_start_crit()
+ *
+ * Enter critical region for share reservations.
+ * See comments above smb_fsop_shrlock().
+ */
+
+void
+smb_node_start_crit(smb_node_t *node, krw_t mode)
+{
+ rw_enter(&node->n_share_lock, mode);
+ nbl_start_crit(node->vp, mode);
+}
+
+/*
+ * smb_node_end_crit()
+ *
+ * Exit critical region for share reservations.
+ */
+
+void
+smb_node_end_crit(smb_node_t *node)
+{
+ nbl_end_crit(node->vp);
+ rw_exit(&node->n_share_lock);
+}
+
+int
+smb_node_in_crit(smb_node_t *node)
+{
+ return (nbl_in_crit(node->vp) && RW_LOCK_HELD(&node->n_share_lock));
+}
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 36a3df5992..e7dbe26746 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
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -206,7 +206,7 @@ smb_com_nt_create_andx(struct smb_request *sr)
}
if (NameLength >= MAXPATHLEN) {
- smbsr_raise_nt_error(sr, NT_STATUS_OBJECT_PATH_NOT_FOUND);
+ smbsr_error(sr, NT_STATUS_OBJECT_PATH_NOT_FOUND, 0, 0);
/* NOTREACHED */
}
@@ -217,7 +217,7 @@ smb_com_nt_create_andx(struct smb_request *sr)
if ((op->create_options & FILE_DELETE_ON_CLOSE) &&
!(op->desired_access & DELETE)) {
- smbsr_raise_nt_error(sr, NT_STATUS_INVALID_PARAMETER);
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
/* NOTREACHED */
}
@@ -253,7 +253,7 @@ smb_com_nt_create_andx(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree,
sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -284,11 +284,10 @@ smb_com_nt_create_andx(struct smb_request *sr)
if (status != NT_STATUS_SUCCESS) {
if (status == NT_STATUS_SHARING_VIOLATION)
- smbsr_raise_cifs_error(sr,
- NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
else
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
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 00d648cc32..d844733b36 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
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -115,14 +115,14 @@ smb_nt_transact_create(struct smb_request *sr, struct smb_xa *xa)
if ((op->create_options & FILE_DELETE_ON_CLOSE) &&
!(op->desired_access & DELETE)) {
- smbsr_raise_nt_error(sr, NT_STATUS_INVALID_PARAMETER);
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
/* NOTREACHED */
}
if (sd_len) {
status = smb_decode_sd(xa, &sd);
if (status != NT_STATUS_SUCCESS) {
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
op->sd = &sd;
@@ -177,11 +177,10 @@ smb_nt_transact_create(struct smb_request *sr, struct smb_xa *xa)
if (status != NT_STATUS_SUCCESS) {
if (status == NT_STATUS_SHARING_VIOLATION)
- smbsr_raise_cifs_error(sr,
- NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
else
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
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 5725814a0f..16fbdbede8 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
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -90,7 +90,7 @@ smb_nt_transact_ioctl(struct smb_request *sr, struct smb_xa *xa)
&fid,
&is_fsctl,
&is_flags) != 0) {
- smbsr_raise_nt_error(sr, NT_STATUS_INVALID_PARAMETER);
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
}
for (i = 0;
@@ -103,7 +103,7 @@ smb_nt_transact_ioctl(struct smb_request *sr, struct smb_xa *xa)
}
if (status != NT_STATUS_SUCCESS)
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
(void) smb_encode_mbc(&xa->rep_param_mb, "l", 0);
return (SDRC_NORMAL_REPLY);
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 d70ddf4fc0..264a078a48 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
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -135,8 +135,7 @@ smb_nt_transact_notify_change(struct smb_request *sr, struct smb_xa *xa)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -144,10 +143,9 @@ smb_nt_transact_notify_change(struct smb_request *sr, struct smb_xa *xa)
if (node->attr.sa_vattr.va_type != VDIR) {
/*
- * notify change requests are only valid for
- * directories
+ * Notify change requests are only valid on directories.
*/
- smbsr_raise_nt_error(sr, NT_STATUS_NOT_A_DIRECTORY);
+ smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY, 0, 0);
/* NOTREACHED */
}
@@ -192,7 +190,7 @@ smb_nt_transact_notify_change(struct smb_request *sr, struct smb_xa *xa)
case SMB_REQ_STATE_CANCELED:
mutex_exit(&sr->sr_mutex);
- smbsr_raise_nt_error(sr, NT_STATUS_CANCELLED);
+ smbsr_error(sr, NT_STATUS_CANCELLED, 0, 0);
/* NOTREACHED */
default:
ASSERT(0);
@@ -211,13 +209,13 @@ smb_nt_transact_notify_change(struct smb_request *sr, struct smb_xa *xa)
* is sent in reply.
*/
int
-smb_reply_notify_change_request(
- smb_request_t *sr)
+smb_reply_notify_change_request(smb_request_t *sr)
{
smb_node_t *node;
int total_bytes, n_setup, n_param, n_data;
int param_off, param_pad, data_off, data_pad;
struct smb_xa *xa;
+ smb_error_t err;
xa = sr->r_xa;
node = sr->sr_ncr.nc_node;
@@ -273,12 +271,12 @@ smb_reply_notify_change_request(
break;
case SMB_REQ_STATE_CANCELED:
- /*
- * an STATUS should be sent,
- * we need an implementation of nt_raise_error
- * but without long jump.
- */
- smbsr_setup_nt_status(sr, 0xc0000000, NT_STATUS_CANCELLED);
+ err.severity = ERROR_SEVERITY_ERROR;
+ err.status = NT_STATUS_CANCELLED;
+ err.errcls = ERRDOS;
+ err.errcode = ERROR_OPERATION_ABORTED;
+ smbsr_set_error(sr, &err);
+
(void) smb_encode_mbc(&sr->reply, "bwbw",
(short)0, 0L, (short)0, 0L);
sr->smb_wct = 0;
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 fec95a2835..69ea40bdb3 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
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -74,25 +74,24 @@ smb_nt_transact_query_security_info(struct smb_request *sr, struct smb_xa *xa)
uint32_t secinfo;
uint32_t sdlen;
uint32_t status;
-
+ smb_error_t err;
if (smb_decode_mbc(&xa->req_param_mb, "w2.l",
&sr->smb_fid, &secinfo) != 0) {
- smbsr_raise_nt_error(sr, NT_STATUS_INVALID_PARAMETER);
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
/* NOTREACHED */
}
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
if ((sr->fid_ofile->f_node == NULL) ||
(sr->fid_ofile->f_ftype != SMB_FTYPE_DISK)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -107,14 +106,14 @@ smb_nt_transact_query_security_info(struct smb_request *sr, struct smb_xa *xa)
status = smb_sd_read(sr, &sd, secinfo);
if (status != NT_STATUS_SUCCESS) {
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
sdlen = smb_sd_len(&sd, secinfo);
if (sdlen == 0) {
smb_sd_term(&sd);
- smbsr_raise_nt_error(sr, NT_STATUS_INVALID_SECURITY_DESCR);
+ smbsr_error(sr, NT_STATUS_INVALID_SECURITY_DESCR, 0, 0);
/* NOTREACHED */
}
@@ -126,8 +125,11 @@ smb_nt_transact_query_security_info(struct smb_request *sr, struct smb_xa *xa)
* should provide a buffer size hint for the client.
*/
(void) smb_encode_mbc(&xa->rep_param_mb, "l", sdlen);
- smbsr_setup_nt_status(sr, ERROR_SEVERITY_ERROR,
- NT_STATUS_BUFFER_TOO_SMALL);
+ err.severity = ERROR_SEVERITY_ERROR;
+ err.status = NT_STATUS_BUFFER_TOO_SMALL;
+ err.errcls = ERRDOS;
+ err.errcode = ERROR_INSUFFICIENT_BUFFER;
+ smbsr_set_error(sr, &err);
smb_sd_term(&sd);
return (SDRC_NORMAL_REPLY);
}
@@ -166,25 +168,24 @@ smb_nt_transact_set_security_info(struct smb_request *sr, struct smb_xa *xa)
if (smb_decode_mbc(&xa->req_param_mb, "w2.l",
&sr->smb_fid, &secinfo) != 0) {
- smbsr_raise_nt_error(sr, NT_STATUS_INVALID_PARAMETER);
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
/* NOTREACHED */
}
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
if ((sr->fid_ofile->f_node == NULL) ||
(sr->fid_ofile->f_ftype != SMB_FTYPE_DISK)) {
- smbsr_raise_nt_error(sr, NT_STATUS_ACCESS_DENIED);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, 0, 0);
/* NOTREACHED */
}
if (sr->fid_ofile->f_node->flags & NODE_READ_ONLY) {
- smbsr_raise_nt_error(sr, NT_STATUS_MEDIA_WRITE_PROTECTED);
+ smbsr_error(sr, NT_STATUS_MEDIA_WRITE_PROTECTED, 0, 0);
/* NOTREACHED */
}
@@ -202,20 +203,20 @@ smb_nt_transact_set_security_info(struct smb_request *sr, struct smb_xa *xa)
status = smb_decode_sd(xa, &sd);
if (status != NT_STATUS_SUCCESS) {
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
if (((secinfo & SMB_OWNER_SECINFO) && (sd.sd_owner == NULL)) ||
((secinfo & SMB_GROUP_SECINFO) && (sd.sd_group == NULL))) {
- smbsr_raise_nt_error(sr, NT_STATUS_INVALID_PARAMETER);
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, 0, 0);
/* NOTREACHED */
}
status = smb_sd_write(sr, &sd, secinfo);
smb_sd_term(&sd);
if (status != NT_STATUS_SUCCESS) {
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_ofile.c b/usr/src/uts/common/fs/smbsrv/smb_ofile.c
index e8eb106291..fa9631336b 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_ofile.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_ofile.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -186,6 +186,7 @@ smb_ofile_open(
uint16_t ftype,
char *pipe_name,
uint32_t rpc_fid,
+ uint32_t uniqid,
smb_error_t *err)
{
smb_ofile_t *of;
@@ -203,6 +204,7 @@ smb_ofile_open(
of->f_magic = SMB_OFILE_MAGIC;
of->f_refcnt = 1;
of->f_fid = fid;
+ of->f_uniqid = uniqid;
of->f_opened_by_pid = pid;
of->f_granted_access = access_granted;
of->f_share_access = share_access;
@@ -271,7 +273,6 @@ smb_ofile_close(
{
int rc = 0;
-
ASSERT(of);
ASSERT(of->f_magic == SMB_OFILE_MAGIC);
@@ -286,9 +287,6 @@ smb_ofile_close(
if (of->f_ftype == SMB_FTYPE_MESG_PIPE) {
smb_rpc_close(of);
} else {
- if (of->f_node->vp->v_type == VREG)
- (void) smb_fsop_close(of);
-
if (of->f_node->flags & NODE_CREATED_READONLY) {
smb_node_set_dosattr(of->f_node,
of->f_node->attr.sa_dosattr |
@@ -300,12 +298,20 @@ smb_ofile_close(
rc = smb_sync_fsattr(NULL, of->f_cr, of->f_node);
smb_commit_delete_on_close(of);
smb_release_oplock(of, OPLOCK_RELEASE_FILE_CLOSED);
- smb_commit_delete_on_close(of);
+
+ /*
+ * Share reservations cannot be removed until the
+ * readonly bit has been set (if needed), above.
+ * See comments in smb_open_subr().
+ */
+ smb_fsop_unshrlock(of->f_cr, of->f_node, of->f_uniqid);
+
+ if (of->f_node->vp->v_type == VREG)
+ (void) smb_fsop_close(of);
+
/*
- * if there is any notify change request for
- * this file then see if any of them is related
- * to this open instance. If there is any then
- * cancel them.
+ * Cancel any notify change requests related
+ * to this open instance.
*/
if (of->f_node->flags & NODE_FLAGS_NOTIFY_CHANGE)
smb_process_file_notify_change_queue(of);
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 b195ed6353..486422d9c5 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_open_andx.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_open_andx.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -245,7 +245,7 @@ smb_com_open(struct smb_request *sr)
if ((op->desired_access == ((uint32_t)SMB_INVALID_AMASK)) ||
(op->share_access == ((uint32_t)SMB_INVALID_SHAREMODE))) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_PARAMETER,
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
/* NOTREACHED */
}
@@ -266,11 +266,10 @@ smb_com_open(struct smb_request *sr)
if ((status = smb_open_subr(sr)) != NT_STATUS_SUCCESS) {
if (status == NT_STATUS_SHARING_VIOLATION)
- smbsr_raise_cifs_error(sr,
- NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
else
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
@@ -281,7 +280,7 @@ smb_com_open(struct smb_request *sr)
}
if (op->dsize > UINT_MAX)
- smbsr_raise_error(sr, ERRDOS, ERRbadfunc);
+ smbsr_error(sr, 0, ERRDOS, ERRbadfunc);
file_attr = op->dattr & FILE_ATTRIBUTE_MASK;
@@ -330,7 +329,7 @@ smb_com_open_andx(struct smb_request *sr)
if ((op->desired_access == ((uint32_t)SMB_INVALID_AMASK)) ||
(op->share_access == ((uint32_t)SMB_INVALID_SHAREMODE))) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_PARAMETER,
+ smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
ERRDOS, ERROR_INVALID_PARAMETER);
/* NOTREACHED */
}
@@ -338,7 +337,7 @@ smb_com_open_andx(struct smb_request *sr)
op->dattr = file_attr;
op->create_disposition = smb_ofun_to_crdisposition(ofun);
if (op->create_disposition == ((uint32_t)SMB_INVALID_CRDISPOSITION)) {
- smbsr_raise_error(sr, ERRDOS, ERROR_INVALID_PARAMETER);
+ smbsr_error(sr, 0, ERRDOS, ERROR_INVALID_PARAMETER);
/* NOTREACHED */
}
@@ -376,17 +375,16 @@ smb_com_open_andx(struct smb_request *sr)
if (status != NT_STATUS_SUCCESS) {
if (status == NT_STATUS_SHARING_VIOLATION)
- smbsr_raise_cifs_error(sr,
- NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
else
- smbsr_raise_nt_error(sr, status);
+ smbsr_error(sr, status, 0, 0);
/* NOTREACHED */
}
if (op->dsize > UINT_MAX)
- smbsr_raise_error(sr, ERRDOS, ERRbadfunc);
+ smbsr_error(sr, 0, ERRDOS, ERRbadfunc);
if (MYF_OPLOCK_TYPE(op->my_flags) != MYF_OPLOCK_NONE) {
op->action_taken |= SMB_OACT_LOCK;
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 cc203a7315..c31c764bf4 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
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -59,10 +59,6 @@ smb_is_executable(char *path)
/*
* smbd_fs_query
*
- * This function has been changed to return errors instead of using
- * smbsr_raise_errno to longjmp round the calling code. This allows
- * the caller to release resources when an error occurs.
- *
* Upon success, the caller will need to call smb_node_release() on
* fqi.last_snode (if it isn't already set to NULL by this routine) and
* and fqi.dir_snode. These pointers will not be used after the caller
diff --git a/usr/src/uts/common/fs/smbsrv/smb_query_information.c b/usr/src/uts/common/fs/smbsrv/smb_query_information.c
index 8cb636aaa9..391c3f9c24 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_query_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_query_information.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -95,7 +95,7 @@ smb_com_query_information(struct smb_request *sr)
sr->tid_tree->t_snode, sr->tid_tree->t_snode, &dir_node, name))
!= 0) {
kmem_free(name, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -103,7 +103,7 @@ smb_com_query_information(struct smb_request *sr)
sr->tid_tree->t_snode, dir_node, name, &node, &attr, 0, 0)) != 0) {
smb_node_release(dir_node);
kmem_free(name, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_query_information2.c b/usr/src/uts/common/fs/smbsrv/smb_query_information2.c
index a1324aa74e..d6fa3d1f26 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_query_information2.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_query_information2.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -76,15 +76,13 @@ smb_com_query_information2(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
if (sr->fid_ofile->f_ftype != SMB_FTYPE_DISK) {
- cmn_err(CE_NOTE, "SmbQueryInfo2: access denied");
- smbsr_raise_error(sr, ERRDOS, ERRnoaccess);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
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 4c69d8516e..6e38758502 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,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -79,7 +79,7 @@ smb_com_query_information_disk(struct smb_request *sr)
if ((rc = smb_fsop_statfs(sr->user_cr, sr->tid_tree->t_snode, &df))
!= 0)
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
unit_size = 1;
block_size = df.f_frsize;
diff --git a/usr/src/uts/common/fs/smbsrv/smb_read.c b/usr/src/uts/common/fs/smbsrv/smb_read.c
index 8542a1a1f9..4e5ba4ec88 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_read.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_read.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -75,13 +75,12 @@ smb_com_read(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
if ((rc = smb_common_read(sr, &param)) != 0) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -123,7 +122,7 @@ smb_com_lock_and_read(struct smb_request *sr)
int rc;
if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
- smbsr_raise_error(sr, ERRDOS, ERRnoaccess);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
@@ -139,19 +138,18 @@ smb_com_lock_and_read(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
result = smb_lock_range(sr, sr->fid_ofile, param.r_offset,
(uint64_t)param.r_count, UINT_MAX, SMB_LOCK_TYPE_READWRITE);
if (result != NT_STATUS_SUCCESS) {
- smb_lock_range_raise_error(sr, result);
+ smb_lock_range_error(sr, result);
}
if ((rc = smb_common_read(sr, &param)) != 0) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -214,7 +212,7 @@ smb_com_read_raw(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree,
sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -301,13 +299,12 @@ smb_com_read_andx(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
if ((rc = smb_common_read(sr, &param)) != 0) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -379,7 +376,7 @@ smb_common_read(struct smb_request *sr, smb_read_param_t *param)
if (node->attr.sa_vattr.va_type != VDIR) {
rc = smb_lock_range_access(sr, node, param->r_offset,
- param->r_count, FILE_READ_DATA);
+ param->r_count, B_FALSE);
if (rc != NT_STATUS_SUCCESS) {
rc = ERANGE;
break;
diff --git a/usr/src/uts/common/fs/smbsrv/smb_rename.c b/usr/src/uts/common/fs/smbsrv/smb_rename.c
index f22e7187de..0239635663 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_rename.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_rename.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -29,12 +29,12 @@
#include <sys/synch.h>
#include <smbsrv/smb_incl.h>
#include <smbsrv/smb_fsops.h>
+#include <sys/nbmlock.h>
static int smb_do_rename(struct smb_request *sr,
struct smb_fqi *src_fqi,
struct smb_fqi *dst_fqi);
-
/*
* smb_com_rename
*
@@ -63,7 +63,7 @@ smb_com_rename(struct smb_request *sr)
int rc;
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -99,19 +99,18 @@ smb_com_rename(struct smb_request *sr)
* NT and W2K client behaviour.
*/
if (rc == EEXIST) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_OBJECT_NAME_COLLISION,
+ smbsr_error(sr, NT_STATUS_OBJECT_NAME_COLLISION,
ERRDOS, ERROR_ALREADY_EXISTS);
/* NOTREACHED */
}
if (rc == EPIPE) {
- smbsr_raise_cifs_error(sr, NT_STATUS_SHARING_VIOLATION,
+ smbsr_error(sr, NT_STATUS_SHARING_VIOLATION,
ERRDOS, ERROR_SHARING_VIOLATION);
/* NOTREACHED */
}
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -136,48 +135,6 @@ smb_com_rename(struct smb_request *sr)
}
/*
- * smb_rename_share_check
- *
- * An open file can be renamed if
- *
- * 1. isn't opened for data writing or deleting
- *
- * 2. Opened with "Deny Delete" share mode
- * But not opened for data reading or executing
- * (opened for accessing meta data)
- */
-DWORD
-smb_rename_share_check(struct smb_node *node)
-{
- struct smb_ofile *open;
-
- if (node == 0 || node->n_refcnt <= 1)
- return (NT_STATUS_SUCCESS);
-
- smb_llist_enter(&node->n_ofile_list, RW_READER);
- open = smb_llist_head(&node->n_ofile_list);
- while (open) {
- if (open->f_granted_access &
- (FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE)) {
- smb_llist_exit(&node->n_ofile_list);
- return (NT_STATUS_SHARING_VIOLATION);
- }
-
- if ((open->f_share_access & FILE_SHARE_DELETE) == 0) {
- if (open->f_granted_access &
- (FILE_READ_DATA | FILE_EXECUTE)) {
- smb_llist_exit(&node->n_ofile_list);
- return (NT_STATUS_SHARING_VIOLATION);
- }
- }
- open = smb_llist_next(&node->n_ofile_list, open);
- }
- smb_llist_exit(&node->n_ofile_list);
- return (NT_STATUS_SUCCESS);
-}
-
-
-/*
* smb_do_rename
*
* Backend to smb_com_rename to ensure that the rename operation is atomic.
@@ -228,28 +185,24 @@ smb_do_rename(
}
}
- status = smb_lock_range_access(sr, src_node, 0, 0, FILE_WRITE_DATA);
- if (status != NT_STATUS_SUCCESS) {
- smb_node_release(src_node);
- smb_node_release(src_fqi->dir_snode);
+ for (count = 0; count <= 3; count++) {
+ if (count) {
+ smb_node_end_crit(src_node);
+ delay(MSEC_TO_TICK(400));
+ }
- SMB_NULL_FQI_NODES(*src_fqi);
- SMB_NULL_FQI_NODES(*dst_fqi);
- return (EACCES);
- }
+ smb_node_start_crit(src_node, RW_READER);
+ status = smb_node_rename_check(src_node);
- for (count = 0; count <= 3; count++) {
- if (count)
- delay(MSEC_TO_TICK(400));
- status = smb_rename_share_check(src_node);
if (status != NT_STATUS_SHARING_VIOLATION)
break;
}
- smb_node_release(src_node);
-
if (status == NT_STATUS_SHARING_VIOLATION) {
+ smb_node_end_crit(src_node);
+
+ smb_node_release(src_node);
smb_node_release(src_fqi->dir_snode);
SMB_NULL_FQI_NODES(*src_fqi);
@@ -257,8 +210,25 @@ smb_do_rename(
return (EPIPE); /* = ERRbadshare */
}
+ status = smb_range_check(sr, sr->user_cr, src_node, 0, UINT64_MAX,
+ B_TRUE);
+
+ if (status != NT_STATUS_SUCCESS) {
+ smb_node_end_crit(src_node);
+
+ smb_node_release(src_node);
+ smb_node_release(src_fqi->dir_snode);
+
+ SMB_NULL_FQI_NODES(*src_fqi);
+ SMB_NULL_FQI_NODES(*dst_fqi);
+ return (EACCES);
+ }
+
if (utf8_strcasecmp(src_fqi->path, dst_fqi->path) == 0) {
if ((rc = smbd_fs_query(sr, dst_fqi, 0)) != 0) {
+ smb_node_end_crit(src_node);
+
+ smb_node_release(src_node);
smb_node_release(src_fqi->dir_snode);
SMB_NULL_FQI_NODES(*src_fqi);
@@ -276,6 +246,9 @@ smb_do_rename(
rc = strcmp(src_fqi->last_comp_od, dst_fqi->last_comp);
if (rc == 0) {
+ smb_node_end_crit(src_node);
+
+ smb_node_release(src_node);
smb_node_release(src_fqi->dir_snode);
smb_node_release(dst_fqi->dir_snode);
@@ -297,11 +270,18 @@ smb_do_rename(
SMB_NULL_FQI_NODES(*src_fqi);
SMB_NULL_FQI_NODES(*dst_fqi);
}
+
+ smb_node_end_crit(src_node);
+
+ smb_node_release(src_node);
return (rc);
}
rc = smbd_fs_query(sr, dst_fqi, FQM_PATH_MUST_NOT_EXIST);
if (rc != 0) {
+ smb_node_end_crit(src_node);
+
+ smb_node_release(src_node);
smb_node_release(src_fqi->dir_snode);
SMB_NULL_FQI_NODES(*src_fqi);
@@ -343,5 +323,9 @@ smb_do_rename(
SMB_NULL_FQI_NODES(*dst_fqi);
}
+ smb_node_end_crit(src_node);
+
+ smb_node_release(src_node);
+
return (rc);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_rpc.c b/usr/src/uts/common/fs/smbsrv/smb_rpc.c
index 5059c909b4..a270f442b1 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_rpc.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_rpc.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -205,7 +205,8 @@ smb_rpc_initialize(struct smb_request *sr, char *pipe_name)
op = &sr->arg.open;
of = smb_ofile_open(sr->tid_tree, NULL, sr->smb_pid,
op->desired_access, 0, op->share_access,
- SMB_FTYPE_MESG_PIPE, pipe_name, smb_rpc_fid(), &err);
+ SMB_FTYPE_MESG_PIPE, pipe_name, smb_rpc_fid(),
+ SMB_UNIQ_FID(), &err);
if (of == NULL)
return (err.status);
@@ -267,7 +268,7 @@ smb_rpc_transact(struct smb_request *sr, struct uio *uio)
if (pipe_info->fid == 0) {
smb_rpc_exit(pipe_info);
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERROR_INVALID_HANDLE);
/* NOTREACHED */
}
@@ -286,8 +287,8 @@ smb_rpc_transact(struct smb_request *sr, struct uio *uio)
if (rc != 0) {
smb_rpc_exit(pipe_info);
- smbsr_raise_nt_error(sr,
- NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID);
+ smbsr_error(sr, NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID,
+ 0, 0);
/* NOTREACHED */
}
@@ -310,13 +311,8 @@ smb_rpc_transact(struct smb_request *sr, struct uio *uio)
xa->rep_data_mb.max_bytes = mdrcnt;
MBC_ATTACH_MBUF(&xa->rep_data_mb, mhead);
- if (sr->session->capabilities & CAP_STATUS32)
- smbsr_setup_nt_status(sr, ERROR_SEVERITY_WARNING,
- NT_STATUS_BUFFER_OVERFLOW);
- else {
- sr->smb_rcls = ERRDOS;
- sr->smb_err = ERRmoredata;
- }
+ smbsr_warn(sr, NT_STATUS_BUFFER_OVERFLOW,
+ ERRDOS, ERROR_MORE_DATA);
} else {
/*
* The client has provided enough buffer space, all
diff --git a/usr/src/uts/common/fs/smbsrv/smb_sd.c b/usr/src/uts/common/fs/smbsrv/smb_sd.c
index fa2bf223d7..c26b70169a 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -145,7 +145,7 @@ smb_sd_read(smb_request_t *sr, smb_sd_t *sd, uint32_t secinfo)
error = smb_fsop_sdread(sr, sr->user_cr, node, &fs_sd);
if (error) {
- smb_errmap_unix2smb(error, &smb_err);
+ smbsr_map_errno(error, &smb_err);
return (smb_err.status);
}
@@ -186,7 +186,7 @@ smb_sd_write(smb_request_t *sr, smb_sd_t *sd, uint32_t secinfo)
smb_fssd_term(&fs_sd);
if (error) {
- smb_errmap_unix2smb(error, &smb_err);
+ smbsr_map_errno(error, &smb_err);
return (smb_err.status);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_search.c b/usr/src/uts/common/fs/smbsrv/smb_search.c
index 0700b8fd2d..d0411e1e58 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_search.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_search.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -162,7 +162,7 @@ smb_com_search(struct smb_request *sr)
}
if ((rc = fsd_getattr(&sr->tid_tree->t_fsd, &vol_attr)) != 0) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -212,8 +212,7 @@ smb_com_search(struct smb_request *sr)
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree,
sr->smb_sid);
if (sr->sid_odir == NULL) {
- smbsr_raise_cifs_error(sr,
- NT_STATUS_INVALID_HANDLE,
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -270,13 +269,13 @@ smb_com_search(struct smb_request *sr)
if ((rc != 0) && (rc != ENOENT)) {
/* returned error by smb_rdir_next() */
smb_rdir_close(sr);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
if (count == 0) {
smb_rdir_close(sr);
- smbsr_raise_error(sr, ERRDOS, ERRnofiles);
+ smbsr_error(sr, 0, ERRDOS, ERRnofiles);
/* NOTREACHED */
}
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_seek.c b/usr/src/uts/common/fs/smbsrv/smb_seek.c
index a120a26a9d..cffb9ce2d0 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_seek.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_seek.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -94,8 +94,7 @@ smb_com_seek(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -103,27 +102,16 @@ smb_com_seek(struct smb_request *sr)
(void) smb_set_file_size(sr);
}
- rc = smb_ofile_seek(sr->fid_ofile, mode, off, &off_ret);
- if (rc == 0) {
- smbsr_encode_result(sr, 2, 0, "blw", 2, off_ret, 0);
- return (SDRC_NORMAL_REPLY);
+ if ((rc = smb_ofile_seek(sr->fid_ofile, mode, off, &off_ret)) != 0) {
+ if (rc == EINVAL) {
+ smbsr_error(sr, 0, ERRDOS, ERRbadfunc);
+ /* NOTREACHED */
+ } else {
+ smbsr_error(sr, 0, ERRSRV, ERRerror);
+ /* NOTREACHED */
+ }
}
- if (rc == EINVAL) {
- smbsr_raise_error(sr, ERRDOS, ERRbadfunc);
- /* NOTREACHED */
- }
- if (rc == EOVERFLOW) {
- smbsr_raise_error(sr, ERRSRV, ERRerror);
- /* NOTREACHED */
- }
- ASSERT(0);
- smbsr_raise_error(sr, ERRSRV, ERRerror);
- /* NOTREACHED */
- /*
- * Although smbsr_raise_error() doesn't return and the compiler is
- * told so in smb_kproto.h it still has a problem if it doesn't
- * find here a return instruction with a value.
- */
- return (0);
+ smbsr_encode_result(sr, 2, 0, "blw", 2, off_ret, 0);
+ return (SDRC_NORMAL_REPLY);
}
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 b7217cf78b..887a0ca648 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
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -370,7 +370,7 @@ smb_com_session_setup_andx(struct smb_request *sr)
kmem_free(ci_password, ci_pwlen + 1);
if (cs_password)
kmem_free(cs_password, cs_pwlen + 1);
- smbsr_raise_error(sr, ERRSRV, ERRaccess);
+ smbsr_error(sr, 0, ERRSRV, ERRaccess);
/* NOTREACHED */
} else if (utf8_strcasecmp(primary_domain, hostname) == 0) {
/*
@@ -385,8 +385,6 @@ smb_com_session_setup_andx(struct smb_request *sr)
clnt_info.flags |= NETR_CFLG_LOCAL;
}
- (void) utf8_strupr(primary_domain);
-
/*
* If this is an additional setup for an existing user
* on this session, duplicate the authenticated user.
@@ -431,7 +429,7 @@ smb_com_session_setup_andx(struct smb_request *sr)
kmem_free(ci_password, ci_pwlen + 1);
if (cs_password)
kmem_free(cs_password, cs_pwlen + 1);
- smbsr_raise_error(sr, ERRSRV, ERRbadpw);
+ smbsr_error(sr, 0, ERRSRV, ERRbadpw);
/* NOTREACHED */
}
@@ -463,7 +461,7 @@ smb_com_session_setup_andx(struct smb_request *sr)
if (user == NULL) {
if (session_key)
kmem_free(session_key, sizeof (smb_session_key_t));
- smbsr_raise_error(sr, ERRDOS, ERROR_INVALID_HANDLE);
+ smbsr_error(sr, 0, ERRDOS, ERROR_INVALID_HANDLE);
/* no return */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_set_information.c b/usr/src/uts/common/fs/smbsrv/smb_set_information.c
index 728c86b8cd..e7b1237fa9 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_set_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_set_information.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -88,7 +88,7 @@ smb_com_set_information(struct smb_request *sr)
sr->tid_tree->t_snode, sr->tid_tree->t_snode, &dir_node, name))
!= 0) {
kmem_free(name, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -96,7 +96,7 @@ smb_com_set_information(struct smb_request *sr)
sr->tid_tree->t_snode, dir_node, name, &node, &attr, 0, 0)) != 0) {
smb_node_release(dir_node);
kmem_free(name, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -118,7 +118,7 @@ smb_com_set_information(struct smb_request *sr)
smb_node_release(node);
if (rc) {
kmem_free(name, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_set_information2.c b/usr/src/uts/common/fs/smbsrv/smb_set_information2.c
index 1510f7228a..8f00ff66d1 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_set_information2.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_set_information2.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -77,16 +77,14 @@ smb_com_set_information2(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
node = sr->fid_ofile->f_node;
if (node == 0 || sr->fid_ofile->f_ftype != SMB_FTYPE_DISK) {
- cmn_err(CE_NOTE, "SmbSetInfo2: access denied");
- smbsr_raise_error(sr, ERRDOS, ERRnoaccess);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
@@ -113,7 +111,7 @@ smb_com_set_information2(struct smb_request *sr)
smb_node_set_time(node, &crtime, &mtime, &atime, 0, what);
rc = smb_sync_fsattr(sr, sr->user_cr, node);
if (rc) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
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 6ef6691df3..dc85916d04 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
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -67,8 +67,8 @@ extern int smb_common_create_directory(struct smb_request *sr);
int
smb_com_trans2_create_directory(struct smb_request *sr, struct smb_xa *xa)
{
- int rc;
- DWORD status;
+ int rc;
+ DWORD status;
if (smb_decode_mbc(&xa->req_param_mb, "%4.s",
sr, &sr->arg.dirop.fqi.path) != 0) {
@@ -77,16 +77,12 @@ smb_com_trans2_create_directory(struct smb_request *sr, struct smb_xa *xa)
}
if ((status = smb_validate_dirname(sr->arg.dirop.fqi.path)) != 0) {
- if (sr->session->capabilities & CAP_STATUS32)
- smbsr_raise_nt_error(sr, status);
- else
- smbsr_raise_error(sr, ERRDOS, ERROR_INVALID_NAME);
-
+ smbsr_error(sr, status, ERRDOS, ERROR_INVALID_NAME);
/* NOTREACHED */
}
if ((rc = smb_common_create_directory(sr)) != 0) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
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 c92a248a93..57b3ba257c 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -176,36 +176,50 @@
#include <smbsrv/smbtrans.h>
#include <smbsrv/smb_fsops.h>
-int smb_trans2_find_get_maxdata(struct smb_request *, unsigned short,
- unsigned short);
+static int smb_trans2_find_get_maxdata(smb_request_t *, uint16_t, uint16_t);
-int smb_trans2_find_get_dents(struct smb_request *, struct smb_xa *,
- unsigned short, unsigned short, int, struct smb_node *,
- unsigned short, uint32_t, int, char *, uint32_t *, int *, int *);
+int smb_trans2_find_get_dents(smb_request_t *, smb_xa_t *,
+ uint16_t, uint16_t, int, smb_node_t *,
+ uint16_t, uint16_t, int, char *, uint32_t *, int *, int *);
int smb_gather_dents_info(char *, ino_t, int, char *, uint32_t, int32_t *,
- smb_attr_t *, struct smb_node *, char *, char *);
+ smb_attr_t *, smb_node_t *, char *, char *);
-int smb_trans2_find_process_ients(struct smb_request *, struct smb_xa *,
- smb_dent_info_hdr_t *, unsigned short, unsigned short, int,
- struct smb_node *, int *, uint32_t *);
+int smb_trans2_find_process_ients(smb_request_t *, smb_xa_t *,
+ smb_dent_info_hdr_t *, uint16_t, uint16_t, int,
+ smb_node_t *, int *, uint32_t *);
-int smb_trans2_find_mbc_encode(struct smb_request *, struct smb_xa *,
- smb_dent_info_t *, int, unsigned short, unsigned short,
- unsigned int, struct smb_node *, struct smb_node *);
+int smb_trans2_find_mbc_encode(smb_request_t *, smb_xa_t *,
+ smb_dent_info_t *, int, uint16_t, uint16_t,
+ uint32_t, smb_node_t *, smb_node_t *);
/*
- * Support for Catia Version 5 Deployment
+ * The UNIX characters below are considered illegal in Windows file names.
+ * The following character conversions are used to support sites in which
+ * Catia v4 is in use on UNIX and Catia v5 is in use on Windows.
+ *
+ * ---------------------------
+ * Unix-char | Windows-char
+ * ---------------------------
+ * " | (0x00a8) Diaeresis
+ * * | (0x00a4) Currency Sign
+ * : | (0x00f7) Division Sign
+ * < | (0x00ab) Left-Pointing Double Angle Quotation Mark
+ * > | (0x00bb) Right-Pointing Double Angle Quotation Mark
+ * ? | (0x00bf) Inverted Question mark
+ * \ | (0x00ff) Latin Small Letter Y with Diaeresis
+ * | | (0x00a6) Broken Bar
*/
-static int (*catia_callback)(unsigned char *, unsigned char *, int) = NULL;
+static int (*catia_callback)(uint8_t *, uint8_t *, int) = NULL;
void smb_register_catia_callback(
- int (*catia_v4tov5)(unsigned char *, unsigned char *, int));
+ int (*catia_v4tov5)(uint8_t *, uint8_t *, int));
void smb_unregister_catia_callback();
/*
- * Patchable parameter for find maximum count
+ * Tunable parameter to limit the maximum
+ * number of entries to be returned.
*/
-int max_find_count = 64;
+uint16_t smb_trans2_find_max = 128;
/*
* smb_register_catia_callback
@@ -216,7 +230,7 @@ int max_find_count = 64;
*/
void
smb_register_catia_callback(
- int (*catia_v4tov5)(unsigned char *, unsigned char *, int))
+ int (*catia_v4tov5)(uint8_t *, uint8_t *, int))
{
catia_callback = catia_v4tov5;
}
@@ -277,20 +291,21 @@ smb_unregister_catia_callback()
* found in the search
*/
int
-smb_com_trans2_find_first2(struct smb_request *sr, struct smb_xa *xa)
+smb_com_trans2_find_first2(smb_request_t *sr, smb_xa_t *xa)
{
int more = 0, rc;
- unsigned short sattr, fflag, infolev;
+ uint16_t sattr, fflag, infolev;
+ uint16_t maxcount = 0;
int maxdata;
- int count, maxcount = 0, wildcards;
+ int count, wildcards;
uint32_t cookie;
char *path;
- struct smb_node *dir_snode;
+ smb_node_t *dir_snode;
char *pattern;
- unsigned short sid;
+ uint16_t sid;
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -302,27 +317,36 @@ smb_com_trans2_find_first2(struct smb_request *sr, struct smb_xa *xa)
}
maxdata = smb_trans2_find_get_maxdata(sr, infolev, fflag);
-
if (maxdata == 0) {
- smbsr_raise_error(sr, ERRDOS, ERRunknownlevel);
+ smbsr_error(sr, NT_STATUS_INVALID_LEVEL,
+ ERRDOS, ERROR_INVALID_LEVEL);
/* NOTREACHED */
}
- /* Convert name to our form */
- if (sr->smb_flg2 & SMB_FLAGS2_UNICODE) {
+ /*
+ * When maxcount is zero Windows behaves as if it was 1.
+ */
+ if (maxcount == 0)
+ maxcount = 1;
+
+ if ((smb_trans2_find_max != 0) && (maxcount > smb_trans2_find_max))
+ maxcount = smb_trans2_find_max;
+
+ if (sr->smb_flg2 & SMB_FLAGS2_UNICODE)
(void) smb_convert_unicode_wildcards(path);
- }
+
(void) smb_rdir_open(sr, path, sattr);
/*
* Get a copy of information
*/
- pattern = kmem_alloc(MAXNAMELEN, KM_SLEEP);
dir_snode = sr->sid_odir->d_dir_snode;
+ pattern = kmem_alloc(MAXNAMELEN, KM_SLEEP);
(void) strcpy(pattern, sr->sid_odir->d_pattern);
- /* this is funky */
+
if (strcmp(pattern, "*.*") == 0)
(void) strncpy(pattern, "*", sizeof (pattern));
+
wildcards = sr->sid_odir->d_wildcards;
sattr = sr->sid_odir->d_sattr;
cookie = 0;
@@ -337,23 +361,22 @@ smb_com_trans2_find_first2(struct smb_request *sr, struct smb_xa *xa)
if (rc) {
smb_rdir_close(sr);
kmem_free(pattern, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
/*
- * Save the sid here because search might get closed
- * and sr->smb_sid becomes invalid.
- * This might not seem important because the search
- * is going to be finished anyways, but it's just for
- * the sake of compatibility with Windows.
+ * Save the sid here in case the search is closed below,
+ * which will invalidate sr->smb_sid. We return the
+ * sid, even though the search has been closed, to be
+ * compatible with Windows.
*/
sid = sr->smb_sid;
if (fflag & SMB_FIND_CLOSE_AFTER_REQUEST ||
- (!more && fflag & SMB_FIND_CLOSE_AT_EOS))
+ (!more && fflag & SMB_FIND_CLOSE_AT_EOS)) {
smb_rdir_close(sr);
- else {
+ } else {
mutex_enter(&sr->sid_odir->d_mutex);
sr->sid_odir->d_cookie = cookie;
mutex_exit(&sr->sid_odir->d_mutex);
@@ -366,8 +389,6 @@ smb_com_trans2_find_first2(struct smb_request *sr, struct smb_xa *xa)
return (SDRC_NORMAL_REPLY);
}
-
-
/*
* smb_com_trans2_find_next2
*
@@ -418,57 +439,61 @@ smb_com_trans2_find_first2(struct smb_request *sr, struct smb_xa *xa)
* matches found in the search
*/
int
-smb_com_trans2_find_next2(struct smb_request *sr, struct smb_xa *xa)
+smb_com_trans2_find_next2(smb_request_t *sr, smb_xa_t *xa)
{
- unsigned short fflag, infolev;
+ uint16_t fflag, infolev;
int maxdata, count, wildcards, more = 0, rc;
uint32_t cookie;
- uint32_t maxcount = 0;
- struct smb_node *dir_snode;
+ uint16_t maxcount = 0;
+ smb_node_t *dir_snode;
char *pattern;
- unsigned short sattr;
+ uint16_t sattr;
- pattern = kmem_alloc(MAXNAMELEN, KM_SLEEP);
/*
- * There is a path field as the last piece of input information:
+ * The last parameter in the request is a path, which is a
+ * null-terminated unicode string.
*
* smb_decode_mbc(&xa->req_param_mb, "%www lwu", sr,
- * &sr->smb_sid, &maxcount, &infolev, &cookie, &fflag, &path)
+ * &sr->smb_sid, &maxcount, &infolev, &cookie, &fflag, &path)
*
- * This feild has been removed because it's causing problem
- * with Mac OS 10 and it's not used anyways.
- * The problem is that code expects to see a 2-byte null
- * because the strings are supposed to be Unicode, but
- * Max OS 10 sends a 1-byte null which leads to decode error.
+ * We don't reference this parameter and it is not currently
+ * decoded because we a expect 2-byte null but Mac OS 10
+ * clients send a 1-byte null, which leads to a decode error.
*/
if (smb_decode_mbc(&xa->req_param_mb, "%www lw", sr,
&sr->smb_sid, &maxcount, &infolev, &cookie, &fflag) != 0) {
- kmem_free(pattern, MAXNAMELEN);
smbsr_decode_error(sr);
/* NOTREACHED */
}
- maxdata = smb_trans2_find_get_maxdata(sr, infolev, fflag);
-
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree, sr->smb_sid);
if (sr->sid_odir == NULL) {
- kmem_free(pattern, MAXNAMELEN);
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
+ maxdata = smb_trans2_find_get_maxdata(sr, infolev, fflag);
if (maxdata == 0) {
smb_rdir_close(sr);
- kmem_free(pattern, MAXNAMELEN);
- smbsr_raise_error(sr, ERRDOS, ERRunknownlevel);
+ smbsr_error(sr, NT_STATUS_INVALID_LEVEL,
+ ERRDOS, ERROR_INVALID_LEVEL);
/* NOTREACHED */
}
/*
+ * When maxcount is zero Windows behaves as if it was 1.
+ */
+ if (maxcount == 0)
+ maxcount = 1;
+
+ if ((smb_trans2_find_max != 0) && (maxcount > smb_trans2_find_max))
+ maxcount = smb_trans2_find_max;
+
+ /*
* Get a copy of information
*/
dir_snode = sr->sid_odir->d_dir_snode;
+ pattern = kmem_alloc(MAXNAMELEN, KM_SLEEP);
(void) strcpy(pattern, sr->sid_odir->d_pattern);
wildcards = sr->sid_odir->d_wildcards;
sattr = sr->sid_odir->d_sattr;
@@ -478,17 +503,6 @@ smb_com_trans2_find_next2(struct smb_request *sr, struct smb_xa *xa)
mutex_exit(&sr->sid_odir->d_mutex);
}
- /*
- * XXX this is an optimization made for SFS2 filesystem, it might
- * not be required for ZFS
- *
- * Break the count to smaller counts (less than the default 150)
- * to reduce the number of transaction failures
- * which may cause excessive delays and eventually a SMB staled
- * connection.
- */
- maxcount = (maxcount > max_find_count) ? max_find_count : maxcount;
-
rc = smb_trans2_find_get_dents(sr, xa, fflag, infolev, maxdata,
dir_snode, sattr, maxcount, wildcards, pattern, &cookie,
&more, &count);
@@ -496,7 +510,7 @@ smb_com_trans2_find_next2(struct smb_request *sr, struct smb_xa *xa)
if (rc) {
smb_rdir_close(sr);
kmem_free(pattern, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -516,21 +530,17 @@ smb_com_trans2_find_next2(struct smb_request *sr, struct smb_xa *xa)
return (SDRC_NORMAL_REPLY);
}
-
/*
* smb_trans2_find_get_maxdata
*
- * This function calculates the minimum space requirement for the
- * base on information level and fflag.
+ * Calculate the minimum response space required for the specified
+ * information level.
*
- * When success, minimum space requirement will be returned; otherwise,
- * 0 will be returned.
+ * A non-zero return value provides the minimum space required.
+ * A return value of zero indicates an unknown information level.
*/
-int
-smb_trans2_find_get_maxdata(
- struct smb_request *sr,
- unsigned short infolev,
- unsigned short fflag)
+static int
+smb_trans2_find_get_maxdata(smb_request_t *sr, uint16_t infolev, uint16_t fflag)
{
int maxdata;
@@ -573,8 +583,6 @@ smb_trans2_find_get_maxdata(
return (maxdata);
}
-
-
/*
* smb_trans2_find_get_dents
*
@@ -591,12 +599,12 @@ smb_trans2_find_get_maxdata(
int smb_trans2_find_get_dents(
smb_request_t *sr,
smb_xa_t *xa,
- unsigned short fflag,
- unsigned short infolev,
+ uint16_t fflag,
+ uint16_t infolev,
int maxdata,
smb_node_t *dir_snode,
- unsigned short sattr,
- uint32_t maxcount,
+ uint16_t sattr,
+ uint16_t maxcount,
int wildcards,
char *pattern,
uint32_t *cookie,
@@ -686,7 +694,7 @@ int smb_get_dents(
smb_request_t *sr,
uint32_t *cookie,
smb_node_t *dir_snode,
- unsigned int wildcards,
+ uint32_t wildcards,
smb_dent_info_hdr_t *ihdr,
int *more)
{
@@ -787,8 +795,8 @@ smb_gather_dents_info(
/*LINTED E_BAD_PTR_CAST_ALIGN*/
smb_dent_info_hdr_t *ihdr = (smb_dent_info_hdr_t *)args;
smb_dent_info_t *ient;
- unsigned char *v5_name = NULL;
- unsigned char *np = (unsigned char *)name;
+ uint8_t *v5_name = NULL;
+ uint8_t *np = (uint8_t *)name;
int reclen = sizeof (smb_dent_info_t) + namelen;
v5_name = kmem_alloc(MAXNAMELEN-1, KM_SLEEP);
@@ -805,28 +813,8 @@ smb_gather_dents_info(
return (0);
}
- /*
- * If StorEdge is configured to support Catia Version 5 deployments,
- * any directory entry whose name contains the special Unix character
- * that is considered to be illegal in Windows environement will be
- * translated based on the following
- * Special Character Translation Table.
- *
- * ---------------------------
- * Unix-char | Windows-char
- * ---------------------------
- * " | (0x00a8) Diaeresis
- * * | (0x00a4) Currency Sign
- * : | (0x00f7) Division Sign
- * < | (0x00ab) Left-Pointing Double Angle Quotation Mark
- * > | (0x00bb) Right-Pointing Double Angle Quotation Mark
- * ? | (0x00bf) Inverted Question mark
- * \ | (0x00ff) Latin Small Letter Y with Diaeresis
- * | | (0x00a6) Broken Bar
- */
if (catia_callback) {
- /* XXX 255 should be max name len or something */
- catia_callback(v5_name, (unsigned char *)name, 255);
+ catia_callback(v5_name, (uint8_t *)name, MAXNAMELEN-1);
np = v5_name;
reclen = sizeof (smb_dent_info_t) + strlen((char *)v5_name);
}
@@ -876,15 +864,15 @@ smb_gather_dents_info(
*/
int
smb_trans2_find_process_ients(
- struct smb_request *sr,
- struct smb_xa *xa,
- smb_dent_info_hdr_t *ihdr,
- unsigned short fflag,
- unsigned short infolev,
- int maxdata,
- struct smb_node *dir_snode,
- int *more,
- uint32_t *cookie)
+ smb_request_t *sr,
+ smb_xa_t *xa,
+ smb_dent_info_hdr_t *ihdr,
+ uint16_t fflag,
+ uint16_t infolev,
+ int maxdata,
+ smb_node_t *dir_snode,
+ int *more,
+ uint32_t *cookie)
{
int i, err = 0;
smb_dent_info_t *ient;
@@ -897,15 +885,15 @@ smb_trans2_find_process_ients(
break;
/*
- * FYI: Some observed differences between our response and
- * Windows response which hasn't caused problem yet!
+ * Observed differences between our response and Windows
+ * response, which hasn't caused a problem yet!
*
- * 1. The NextEntryOffset field for the last entry should be 0
- * This code always calculate the record length and put the
- * result in this field.
+ * 1. The NextEntryOffset field for the last entry should
+ * be 0. This code always calculate the record length
+ * and puts the result in the NextEntryOffset field.
*
- * 2. The FileIndex field is always 0. This code put the cookie
- * in this field.
+ * 2. The FileIndex field is always 0. This code puts
+ * the cookie in the FileIndex field.
*/
err = smb_trans2_find_mbc_encode(sr, xa, ient, maxdata, infolev,
fflag, mb_flags, dir_snode, NULL);
@@ -915,8 +903,8 @@ smb_trans2_find_process_ients(
}
/*
- * Not enough space to store all the entries returned; therefore,
- * update the more to 1.
+ * Not enough space to store all the entries returned,
+ * which is indicated by setting more.
*/
if (more && err < 0) {
*more = 1;
@@ -931,8 +919,6 @@ smb_trans2_find_process_ients(
return (i);
}
-
-
/*
* smb_trans2_find_mbc_encode
*
@@ -942,45 +928,45 @@ smb_trans2_find_process_ients(
* is reached. If the entry is valid and successful encoded, 0
* will be returned; otherwise, 1 will be returned.
*/
-int smb_trans2_find_mbc_encode(
- struct smb_request *sr,
- struct smb_xa *xa,
- smb_dent_info_t *ient,
- int maxdata,
- unsigned short infolev,
- unsigned short fflag,
- unsigned int mb_flags,
- struct smb_node *dir_snode, /*LINTED E_FUNC_ARG_UNUSED*/
- struct smb_node *sd_snode)
+int /*ARGSUSED*/
+smb_trans2_find_mbc_encode(
+ smb_request_t *sr,
+ smb_xa_t *xa,
+ smb_dent_info_t *ient,
+ int maxdata,
+ uint16_t infolev,
+ uint16_t fflag,
+ uint32_t mb_flags,
+ smb_node_t *dir_snode,
+ smb_node_t *sd_snode)
{
int uni_namelen;
- int sl, rl;
+ int shortlen;
+ uint32_t next_entry_offset;
char buf83[26];
smb_msgbuf_t mb;
uint32_t dattr = 0;
uint32_t size32 = 0;
uint64_t size64 = 0;
- struct smb_node *lnk_snode;
+ smb_node_t *lnk_snode;
smb_attr_t lnkattr;
int rc;
uni_namelen = smb_ascii_or_unicode_strlen(sr, ient->name);
-
if (uni_namelen == -1)
return (1);
+ next_entry_offset = maxdata + uni_namelen;
+
if (MBC_ROOM_FOR(&xa->rep_data_mb, (maxdata + uni_namelen)) == 0)
return (-1);
if (ient->attr.sa_vattr.va_type == VLNK) {
-
rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
sr->tid_tree->t_snode, dir_snode, ient->name, &lnk_snode,
&lnkattr, 0, 0);
/*
- * IR 104598
- *
* We normally want to resolve the object to which a symlink
* refers so that CIFS clients can access sub-directories and
* find the correct association for files. This causes a
@@ -990,7 +976,7 @@ int smb_trans2_find_mbc_encode(
* Some Windows applications (i.e. virus scanning) loop/hang
* trying to follow this recursive path and there is little
* we can do because the path is constructed on the client.
- * So we've added a flag that allows an end-user to disable
+ * skc_dirsymlink_enable allows an end-user to disable
* symlinks to directories. Symlinks to other object types
* should be unaffected.
*/
@@ -1012,10 +998,6 @@ int smb_trans2_find_mbc_encode(
dattr = smb_mode_to_dos_attributes(&ient->attr);
}
- /*
- * we don't send the '.stream' to client. User shouldn't
- * see this directory.
- */
switch (infolev) {
case SMB_INFO_STANDARD:
if (fflag & SMB_FIND_RETURN_RESUME_KEYS)
@@ -1036,8 +1018,8 @@ int smb_trans2_find_mbc_encode(
case SMB_INFO_QUERY_EA_SIZE:
if (fflag & SMB_FIND_RETURN_RESUME_KEYS)
- (void) smb_encode_mbc(&xa->rep_data_mb,
- "l", ient->cookie);
+ (void) smb_encode_mbc(&xa->rep_data_mb, "l",
+ ient->cookie);
(void) smb_encode_mbc(&xa->rep_data_mb, "%yyyllwlbu", sr,
ient->attr.sa_crtime.tv_sec ? ient->attr.sa_crtime.tv_sec :
@@ -1053,11 +1035,8 @@ int smb_trans2_find_mbc_encode(
break;
case SMB_FIND_FILE_DIRECTORY_INFO:
- /* Use maxdata instead */
- rl = maxdata + uni_namelen;
-
(void) smb_encode_mbc(&xa->rep_data_mb, "%llTTTTqqllu", sr,
- rl,
+ next_entry_offset,
ient->cookie,
ient->attr.sa_crtime.tv_sec ? &ient->attr.sa_crtime :
&ient->attr.sa_vattr.va_mtime,
@@ -1072,20 +1051,18 @@ int smb_trans2_find_mbc_encode(
break;
case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
- /* Use maxdata instead */
- rl = maxdata + uni_namelen;
bzero(buf83, sizeof (buf83));
- smb_msgbuf_init(&mb, (unsigned char *)buf83, sizeof (buf83),
+ smb_msgbuf_init(&mb, (uint8_t *)buf83, sizeof (buf83),
mb_flags);
if (smb_msgbuf_encode(&mb, "u", ient->shortname) < 0) {
smb_msgbuf_term(&mb);
return (-1);
}
- sl = smb_ascii_or_unicode_strlen(sr, ient->shortname);
+ shortlen = smb_ascii_or_unicode_strlen(sr, ient->shortname);
- (void) smb_encode_mbc(&xa->rep_data_mb,
- "%llTTTTqqlllb.24cu", sr,
- rl,
+ (void) smb_encode_mbc(&xa->rep_data_mb, "%llTTTTqqlllb.24cu",
+ sr,
+ next_entry_offset,
ient->cookie,
ient->attr.sa_crtime.tv_sec ? &ient->attr.sa_crtime :
&ient->attr.sa_vattr.va_mtime,
@@ -1097,7 +1074,7 @@ int smb_trans2_find_mbc_encode(
dattr,
uni_namelen,
0L,
- sl,
+ shortlen,
buf83,
ient->name);
@@ -1105,9 +1082,8 @@ int smb_trans2_find_mbc_encode(
break;
case SMB_FIND_FILE_NAMES_INFO:
- rl = maxdata + uni_namelen;
(void) smb_encode_mbc(&xa->rep_data_mb, "%lllu", sr,
- rl,
+ next_entry_offset,
ient->cookie,
uni_namelen,
ient->name);
@@ -1121,7 +1097,7 @@ int smb_trans2_find_mbc_encode(
* Close a search started by a Trans2FindFirst2 request.
*/
int
-smb_com_find_close2(struct smb_request *sr)
+smb_com_find_close2(smb_request_t *sr)
{
if (smbsr_decode_vwv(sr, "w", &sr->smb_sid) != 0) {
smbsr_decode_error(sr);
@@ -1130,13 +1106,11 @@ smb_com_find_close2(struct smb_request *sr)
sr->sid_odir = smb_odir_lookup_by_sid(sr->tid_tree, sr->smb_sid);
if (sr->sid_odir == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
smb_rdir_close(sr);
-
smbsr_encode_empty_result(sr);
return (SDRC_NORMAL_REPLY);
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c
index e6d4dbeccf..d4b5443cd9 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_file_info.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -105,8 +105,7 @@ smb_com_trans2_query_file_information(struct smb_request *sr, struct smb_xa *xa)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -176,7 +175,7 @@ smb_com_trans2_query_file_information(struct smb_request *sr, struct smb_xa *xa)
break;
default:
- smbsr_raise_error(sr, ERRDOS, ERRbadfile);
+ smbsr_error(sr, 0, ERRDOS, ERRbadfile);
/* NOTREACHED */
break;
}
@@ -359,7 +358,7 @@ smb_com_trans2_query_file_information(struct smb_request *sr, struct smb_xa *xa)
if (dir_snode == NULL) {
kmem_free(filebuf, MAXNAMELEN+1);
kmem_free(mangled_name, MAXNAMELEN);
- smbsr_raise_error(sr, ERRDOS, ERRbadfile);
+ smbsr_error(sr, 0, ERRDOS, ERRbadfile);
/* NOT REACHED */
}
(void) smb_encode_mbc(&xa->rep_param_mb, "w", 0);
@@ -386,7 +385,7 @@ smb_com_trans2_query_file_information(struct smb_request *sr, struct smb_xa *xa)
default:
kmem_free(filebuf, MAXNAMELEN+1);
kmem_free(mangled_name, MAXNAMELEN);
- smbsr_raise_error(sr, ERRDOS, ERRunknownlevel);
+ smbsr_error(sr, 0, ERRDOS, ERRunknownlevel);
/* NOTREACHED */
break;
}
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 509c4094f0..a1820b899e 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
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -283,14 +283,14 @@ smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa)
snode = sr->tid_tree->t_snode;
if (fsd_getattr(&sr->tid_tree->t_fsd, &vol_attr) != 0) {
- smbsr_raise_errno(sr, ESTALE);
+ smbsr_errno(sr, ESTALE);
/* NOTREACHED */
}
switch (infolev) {
case SMB_INFO_ALLOCATION:
if ((rc = smb_fsop_statfs(sr->user_cr, snode, &df)) != 0) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -365,7 +365,7 @@ smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa)
case SMB_QUERY_FS_SIZE_INFO:
if ((rc = smb_fsop_statfs(sr->user_cr, snode, &df)) != 0) {
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -425,7 +425,7 @@ smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa)
break;
default:
- smbsr_raise_error(sr, ERRDOS, ERRunknownlevel);
+ smbsr_error(sr, 0, ERRDOS, ERRunknownlevel);
/* NOTREACHED */
break;
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c
index 374a6de2bd..bea67e6545 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_query_path_info.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -341,7 +341,7 @@ smb_com_trans2_query_path_information(struct smb_request *sr, struct smb_xa *xa)
int len;
if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -382,7 +382,7 @@ smb_com_trans2_query_path_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(name, MAXNAMELEN);
kmem_free(short_name, MAXNAMELEN);
kmem_free(name83, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -393,7 +393,7 @@ smb_com_trans2_query_path_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(name, MAXNAMELEN);
kmem_free(short_name, MAXNAMELEN);
kmem_free(name83, MAXNAMELEN);
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
smb_node_release(dir_node);
@@ -576,7 +576,7 @@ smb_com_trans2_query_path_information(struct smb_request *sr, struct smb_xa *xa)
kmem_free(name, MAXNAMELEN);
kmem_free(short_name, MAXNAMELEN);
kmem_free(name83, MAXNAMELEN);
- smbsr_raise_error(sr, ERRDOS, ERRunknownlevel);
+ smbsr_error(sr, 0, ERRDOS, ERRunknownlevel);
/* NOTREACHED */
break;
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c
index 094032da1c..de71abb6d3 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_file_information.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -123,7 +123,7 @@ smb_com_trans2_set_file_information(struct smb_request *sr, struct smb_xa *xa)
if (!STYPE_ISDSK(sr->tid_tree->t_res_type) ||
SMB_TREE_IS_READ_ONLY(sr)) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -131,8 +131,7 @@ smb_com_trans2_set_file_information(struct smb_request *sr, struct smb_xa *xa)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -142,7 +141,7 @@ smb_com_trans2_set_file_information(struct smb_request *sr, struct smb_xa *xa)
!SMB_FTYPE_IS_DISK(sr->fid_ofile->f_ftype)) {
cmn_err(CE_NOTE, "SmbT2SetFileInfo: access denied");
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -154,8 +153,7 @@ smb_com_trans2_set_file_information(struct smb_request *sr, struct smb_xa *xa)
/* NOTREACHED */
} else if (status == NT_STATUS_UNSUCCESSFUL) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_cifs_error(sr, smberr.status,
- smberr.errcls, smberr.errcode);
+ smbsr_error(sr, smberr.status, smberr.errcls, smberr.errcode);
/* NOTREACHED */
}
kmem_free(info, sizeof (smb_trans2_setinfo_t));
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c
index 8c4368f93f..782e42f36d 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_information.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -228,7 +228,7 @@ smb_set_standard_info(
smb_node_set_time(node, &crtime, &mtime, &atime, 0, what);
rc = smb_sync_fsattr(sr, sr->user_cr, node);
if (rc) {
- smb_errmap_unix2smb(rc, smberr);
+ smbsr_map_errno(rc, smberr);
status = NT_STATUS_UNSUCCESSFUL;
}
@@ -295,7 +295,7 @@ smb_set_basic_info(
smb_node_set_time(node, &crtime, &mtime, &atime, &ctime, what);
rc = smb_sync_fsattr(sr, sr->user_cr, node);
if (rc) {
- smb_errmap_unix2smb(rc, smberr);
+ smbsr_map_errno(rc, smberr);
status = NT_STATUS_UNSUCCESSFUL;
}
@@ -339,7 +339,7 @@ smb_set_alloc_info(
* write requests without the inode ever being updated.
*/
if ((rc = smb_set_file_size(sr)) != 0) {
- smb_errmap_unix2smb(rc, smberr);
+ smbsr_map_errno(rc, smberr);
status = NT_STATUS_UNSUCCESSFUL;
}
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c
index 02be8c53cb..fd3c2d571f 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_set_path_information.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -134,7 +134,7 @@ smb_com_trans2_set_path_information(struct smb_request *sr, struct smb_xa *xa)
if (!STYPE_ISDSK(sr->tid_tree->t_res_type) ||
SMB_TREE_IS_READ_ONLY(sr)) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
ERRDOS, ERROR_ACCESS_DENIED);
/* NOTREACHED */
}
@@ -145,7 +145,7 @@ smb_com_trans2_set_path_information(struct smb_request *sr, struct smb_xa *xa)
if (rc != 0) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -157,7 +157,7 @@ smb_com_trans2_set_path_information(struct smb_request *sr, struct smb_xa *xa)
if (rc != 0) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
}
info->node = ret_snode;
@@ -170,8 +170,7 @@ smb_com_trans2_set_path_information(struct smb_request *sr, struct smb_xa *xa)
/* NOTREACHED */
} else if (status == NT_STATUS_UNSUCCESSFUL) {
kmem_free(info, sizeof (smb_trans2_setinfo_t));
- smbsr_raise_cifs_error(sr, smberr.status,
- smberr.errcls, smberr.errcode);
+ smbsr_error(sr, smberr.status, smberr.errcls, smberr.errcode);
/* NOTREACHED */
}
kmem_free(info, sizeof (smb_trans2_setinfo_t));
diff --git a/usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c b/usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c
index 9139930a4d..560c1d7b76 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_tree_disconnect.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -100,9 +100,10 @@ smb_com_tree_disconnect(struct smb_request *sr)
sr->smb_tid);
if (sr->uid_user == NULL || sr->tid_tree == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRinvnid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRinvnid);
+ /* NOTREACHED */
}
+
smbsr_rq_notify(sr, sr->session, sr->tid_tree);
smb_tree_disconnect(sr->tid_tree);
smbsr_encode_empty_result(sr);
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 fef432d9fc..8e75fadc36 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
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -69,15 +69,15 @@ smb_com_unlock_byte_range(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
result = smb_unlock_range(sr, sr->fid_ofile->f_node,
(u_offset_t)Offset, (uint64_t)Length);
if (result != NT_STATUS_SUCCESS) {
- smb_unlock_range_raise_error(sr, result);
+ smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
+ ERRDOS, ERRnotlocked);
/* NOT REACHED */
}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_vops.c b/usr/src/uts/common/fs/smbsrv/smb_vops.c
index 538c9cfc91..0e9bbe45f2 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_vops.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_vops.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +34,9 @@
#include <sys/pathname.h>
#include <sys/cred.h>
#include <sys/extdirent.h>
+#include <sys/nbmlock.h>
+#include <sys/share.h>
+#include <sys/fcntl.h>
#include <smbsrv/smb_vops.h>
#include <smbsrv/string.h>
@@ -43,21 +46,22 @@
#include <smbsrv/smb_kproto.h>
#include <smbsrv/smb_incl.h>
+void
+smb_vop_setup_xvattr(smb_attr_t *smb_attr, xvattr_t *xvattr);
static int
smb_vop_readdir_readpage(vnode_t *vp, void *buf, uint32_t offset, int *count,
- cred_t *cr, caller_context_t *ct, int flags);
+ cred_t *cr, int flags);
static int
smb_vop_readdir_entry(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
ino64_t *inop, vnode_t **vpp, char *od_name, int flags, cred_t *cr,
- caller_context_t *ct, char *dirbuf, int num_bytes);
+ char *dirbuf, int num_bytes);
static int
smb_vop_getdents_entries(smb_node_t *dir_snode, uint32_t *cookiep,
int32_t *dircountp, char *arg, uint32_t flags, struct smb_request *sr,
- cred_t *cr, caller_context_t *ct, char *dirbuf, int *maxentries,
- int num_bytes, char *);
+ cred_t *cr, char *dirbuf, int *maxentries, int num_bytes, char *);
extern int
smb_gather_dents_info(char *args, ino_t fileid, int namelen,
@@ -68,6 +72,8 @@ smb_gather_dents_info(char *args, ino_t fileid, int namelen,
static void
smb_sa_to_va_mask(uint_t sa_mask, uint_t *va_maskp);
+extern sysid_t lm_alloc_sysidt();
+
#define SMB_AT_MAX 16
static uint_t smb_attrmap[SMB_AT_MAX] = {
0,
@@ -88,16 +94,45 @@ static uint_t smb_attrmap[SMB_AT_MAX] = {
AT_SEQ
};
+/*
+ * The smb_ct will be used primarily for range locking.
+ * Since the CIFS server is mapping its locks to POSIX locks,
+ * only one pid is used for operations originating from the
+ * CIFS server (to represent CIFS in the VOP_FRLOCK routines).
+ */
+
+caller_context_t smb_ct;
+
+/*
+ * smb_vop_start()
+ *
+ * Initialize the smb caller context. This function must be called
+ * before any other smb_vop calls.
+ */
+
+void
+smb_vop_start(void)
+{
+ static boolean_t initialized = B_FALSE;
+
+ if (!initialized) {
+ smb_ct.cc_caller_id = fs_new_caller_id();
+ smb_ct.cc_pid = ttoproc(curthread)->p_pid;
+ smb_ct.cc_sysid = lm_alloc_sysidt();
+ initialized = B_TRUE;
+ }
+}
+
int
-smb_vop_open(vnode_t **vpp, int mode, cred_t *cred, caller_context_t *ct)
+smb_vop_open(vnode_t **vpp, int mode, cred_t *cred)
{
- return (VOP_OPEN(vpp, mode, cred, ct));
+ return (VOP_OPEN(vpp, mode, cred, &smb_ct));
}
int
-smb_vop_close(vnode_t *vp, int mode, cred_t *cred, caller_context_t *ct)
+smb_vop_close(vnode_t *vp, int mode, cred_t *cred)
{
- return (VOP_CLOSE(vp, mode, 1, (offset_t)0, cred, ct));
+ return (VOP_CLOSE(vp, mode, 1, (offset_t)0, cred, &smb_ct));
}
/*
@@ -115,19 +150,19 @@ smb_vop_close(vnode_t *vp, int mode, cred_t *cred, caller_context_t *ct)
*/
int
-smb_vop_read(vnode_t *vp, uio_t *uiop, cred_t *cr, caller_context_t *ct)
+smb_vop_read(vnode_t *vp, uio_t *uiop, cred_t *cr)
{
int error;
(void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
- error = VOP_READ(vp, uiop, 0, cr, ct);
+ error = VOP_READ(vp, uiop, 0, cr, &smb_ct);
VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
return (error);
}
int
smb_vop_write(vnode_t *vp, uio_t *uiop, uint32_t *flag, uint32_t *lcount,
- cred_t *cr, caller_context_t *ct)
+ cred_t *cr)
{
int error;
int ioflag = 0;
@@ -140,7 +175,7 @@ smb_vop_write(vnode_t *vp, uio_t *uiop, uint32_t *flag, uint32_t *lcount,
uiop->uio_llimit = MAXOFFSET_T;
(void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
- error = VOP_WRITE(vp, uiop, ioflag, cr, ct);
+ error = VOP_WRITE(vp, uiop, ioflag, cr, &smb_ct);
VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
*lcount -= uiop->uio_resid;
@@ -168,7 +203,7 @@ smb_vop_write(vnode_t *vp, uio_t *uiop, uint32_t *flag, uint32_t *lcount,
int
smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr,
- int flags, cred_t *cr, caller_context_t *ct)
+ int flags, cred_t *cr)
{
int error;
vnode_t *use_vp;
@@ -197,7 +232,7 @@ smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr,
XVA_SET_REQ(&tmp_xvattr, XAT_CREATETIME);
if ((error = VOP_GETATTR(use_vp, (vattr_t *)&tmp_xvattr, flags,
- cr, ct)) != 0)
+ cr, &smb_ct)) != 0)
return (error);
ret_attr->sa_vattr = tmp_xvattr.xva_vattr;
@@ -250,7 +285,7 @@ smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr,
tmp_xvattr.xva_vattr.va_mask = AT_SIZE;
if ((error = VOP_GETATTR(vp, (vattr_t *)&tmp_xvattr,
- flags, cr, ct)) != 0)
+ flags, cr, &smb_ct)) != 0)
return (error);
ret_attr->sa_vattr.va_size =
@@ -272,7 +307,7 @@ smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr,
smb_sa_to_va_mask(ret_attr->sa_mask,
&ret_attr->sa_vattr.va_mask);
- error = VOP_GETATTR(use_vp, &ret_attr->sa_vattr, flags, cr, ct);
+ error = VOP_GETATTR(use_vp, &ret_attr->sa_vattr, flags, cr, &smb_ct);
if (error != 0)
return (error);
@@ -297,7 +332,7 @@ smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr,
*/
tmp_attr.sa_vattr.va_mask = AT_SIZE;
- error = VOP_GETATTR(vp, &tmp_attr.sa_vattr, flags, cr, ct);
+ error = VOP_GETATTR(vp, &tmp_attr.sa_vattr, flags, cr, &smb_ct);
if (error != 0)
return (error);
@@ -326,14 +361,13 @@ smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *ret_attr,
int
smb_vop_setattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *set_attr,
- int flags, cred_t *cr, boolean_t no_xvattr, caller_context_t *ct)
+ int flags, cred_t *cr, boolean_t no_xvattr)
{
int error = 0;
int at_size = 0;
vnode_t *use_vp;
- xvattr_t tmp_xvattr;
- xoptattr_t *xoap = NULL;
- uint_t xva_mask;
+ xvattr_t xvattr;
+ vattr_t *vap;
if (unnamed_vp) {
use_vp = unnamed_vp;
@@ -354,116 +388,24 @@ smb_vop_setattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *set_attr,
if ((no_xvattr == B_FALSE) &&
vfs_has_feature(use_vp->v_vfsp, VFSFT_XVATTR)) {
- /*
- * Initialize xvattr, including bzero
- */
- xva_init(&tmp_xvattr);
- xoap = xva_getxoptattr(&tmp_xvattr);
-
- ASSERT(xoap);
-
- /*
- * Copy caller-specified classic attributes to tmp_xvattr.
- * First save tmp_xvattr's mask (set in xva_init()), which
- * contains AT_XVATTR. This is |'d in later if needed.
- */
-
- xva_mask = tmp_xvattr.xva_vattr.va_mask;
- tmp_xvattr.xva_vattr = set_attr->sa_vattr;
+ smb_vop_setup_xvattr(set_attr, &xvattr);
+ vap = (vattr_t *)&xvattr;
+ } else {
smb_sa_to_va_mask(set_attr->sa_mask,
- &tmp_xvattr.xva_vattr.va_mask);
-
- /*
- * Do not set ctime (only the file system can do it)
- */
-
- tmp_xvattr.xva_vattr.va_mask &= ~AT_CTIME;
-
- if (set_attr->sa_mask & SMB_AT_DOSATTR) {
-
- /*
- * "|" in the original xva_mask, which contains
- * AT_XVATTR
- */
-
- tmp_xvattr.xva_vattr.va_mask |= xva_mask;
-
- XVA_SET_REQ(&tmp_xvattr, XAT_ARCHIVE);
- XVA_SET_REQ(&tmp_xvattr, XAT_SYSTEM);
- XVA_SET_REQ(&tmp_xvattr, XAT_READONLY);
- XVA_SET_REQ(&tmp_xvattr, XAT_HIDDEN);
-
- /*
- * set_attr->sa_dosattr: If a given bit is not set,
- * that indicates that the corresponding field needs
- * to be updated with a "0" value. This is done
- * implicitly as the xoap->xoa_* fields were bzero'd.
- */
-
- if (set_attr->sa_dosattr & FILE_ATTRIBUTE_ARCHIVE)
- xoap->xoa_archive = 1;
-
- if (set_attr->sa_dosattr & FILE_ATTRIBUTE_SYSTEM)
- xoap->xoa_system = 1;
-
- if (set_attr->sa_dosattr & FILE_ATTRIBUTE_READONLY)
- xoap->xoa_readonly = 1;
-
- if (set_attr->sa_dosattr & FILE_ATTRIBUTE_HIDDEN)
- xoap->xoa_hidden = 1;
- }
-
- if (set_attr->sa_mask & SMB_AT_CRTIME) {
- /*
- * "|" in the original xva_mask, which contains
- * AT_XVATTR
- */
-
- tmp_xvattr.xva_vattr.va_mask |= xva_mask;
- XVA_SET_REQ(&tmp_xvattr, XAT_CREATETIME);
- xoap->xoa_createtime = set_attr->sa_crtime;
- }
-
- if ((error = VOP_SETATTR(use_vp, (vattr_t *)&tmp_xvattr, flags,
- cr, ct)) != 0)
- return (error);
-
- /*
- * If the size of the stream needs to be set, set it on
- * the stream file directly. (All other indicated attributes
- * are set on the stream's unnamed stream, above.)
- */
-
- if (at_size) {
- /*
- * set_attr->sa_vattr.va_size already contains the
- * size as set by the caller
- *
- * Note that vp is used here, and not use_vp.
- * Also, only AT_SIZE is needed.
- */
+ &set_attr->sa_vattr.va_mask);
+ vap = &set_attr->sa_vattr;
+ }
- set_attr->sa_vattr.va_mask = AT_SIZE;
- error = VOP_SETATTR(vp, &set_attr->sa_vattr, flags,
- cr, ct);
- }
+ if ((error = VOP_SETATTR(use_vp, vap, flags, cr, &smb_ct)) != 0)
return (error);
- }
- /*
- * Support for file systems without VFSFT_XVATTR or no_xvattr == B_TRUE
- */
- smb_sa_to_va_mask(set_attr->sa_mask, &set_attr->sa_vattr.va_mask);
+
/*
- * set_attr->sa_vattr already contains new values
- * as set by the caller
+ * If the size of the stream needs to be set, set it on
+ * the stream file directly. (All other indicated attributes
+ * are set on the stream's unnamed stream, above.)
*/
- error = VOP_SETATTR(use_vp, &set_attr->sa_vattr, flags, cr, ct);
-
- if (error != 0)
- return (error);
-
if (at_size) {
/*
* set_attr->sa_vattr.va_size already contains the
@@ -474,8 +416,10 @@ smb_vop_setattr(vnode_t *vp, vnode_t *unnamed_vp, smb_attr_t *set_attr,
*/
set_attr->sa_vattr.va_mask = AT_SIZE;
- error = VOP_SETATTR(vp, &set_attr->sa_vattr, flags, cr, ct);
+ error = VOP_SETATTR(vp, &set_attr->sa_vattr, flags, cr,
+ &smb_ct);
}
+
return (error);
}
@@ -531,7 +475,7 @@ smb_vop_access(vnode_t *vp, int mode, int flags, vnode_t *dir_vp, cred_t *cr)
int
smb_vop_lookup(vnode_t *dvp, char *name, vnode_t **vpp, char *od_name,
- int flags, vnode_t *rootvp, cred_t *cr, caller_context_t *ct)
+ int flags, vnode_t *rootvp, cred_t *cr)
{
int error = 0;
int option_flags = 0;
@@ -578,7 +522,7 @@ smb_vop_lookup(vnode_t *dvp, char *name, vnode_t **vpp, char *od_name,
pn_alloc(&rpn);
error = VOP_LOOKUP(dvp, name, vpp, NULL, option_flags, NULL, cr,
- ct, NULL, &rpn);
+ &smb_ct, NULL, &rpn);
if ((error == 0) && od_name) {
bzero(od_name, MAXNAMELEN);
@@ -594,25 +538,34 @@ smb_vop_lookup(vnode_t *dvp, char *name, vnode_t **vpp, char *od_name,
int
smb_vop_create(vnode_t *dvp, char *name, smb_attr_t *attr, vnode_t **vpp,
- int flags, cred_t *cr, caller_context_t *ct, vsecattr_t *vsap)
+ int flags, cred_t *cr, vsecattr_t *vsap)
{
int error;
int option_flags = 0;
+ xvattr_t xvattr;
+ vattr_t *vap;
if (flags & SMB_IGNORE_CASE)
option_flags = FIGNORECASE;
- smb_sa_to_va_mask(attr->sa_mask, &attr->sa_vattr.va_mask);
+ attr->sa_vattr.va_mask = 0;
+
+ if (vfs_has_feature(dvp->v_vfsp, VFSFT_XVATTR)) {
+ smb_vop_setup_xvattr(attr, &xvattr);
+ vap = (vattr_t *)&xvattr;
+ } else {
+ smb_sa_to_va_mask(attr->sa_mask, &attr->sa_vattr.va_mask);
+ vap = &attr->sa_vattr;
+ }
- error = VOP_CREATE(dvp, name, &attr->sa_vattr, EXCL,
- attr->sa_vattr.va_mode, vpp, cr, option_flags, ct, vsap);
+ error = VOP_CREATE(dvp, name, vap, EXCL, attr->sa_vattr.va_mode,
+ vpp, cr, option_flags, &smb_ct, vsap);
return (error);
}
int
-smb_vop_remove(vnode_t *dvp, char *name, int flags, cred_t *cr,
- caller_context_t *ct)
+smb_vop_remove(vnode_t *dvp, char *name, int flags, cred_t *cr)
{
int error;
int option_flags = 0;
@@ -620,7 +573,7 @@ smb_vop_remove(vnode_t *dvp, char *name, int flags, cred_t *cr,
if (flags & SMB_IGNORE_CASE)
option_flags = FIGNORECASE;
- error = VOP_REMOVE(dvp, name, cr, ct, option_flags);
+ error = VOP_REMOVE(dvp, name, cr, &smb_ct, option_flags);
return (error);
}
@@ -633,7 +586,7 @@ smb_vop_remove(vnode_t *dvp, char *name, int flags, cred_t *cr,
int
smb_vop_rename(vnode_t *from_dvp, char *from_name, vnode_t *to_dvp,
- char *to_name, int flags, cred_t *cr, caller_context_t *ct)
+ char *to_name, int flags, cred_t *cr)
{
int error;
int option_flags = 0;
@@ -643,14 +596,14 @@ smb_vop_rename(vnode_t *from_dvp, char *from_name, vnode_t *to_dvp,
option_flags = FIGNORECASE;
error = VOP_RENAME(from_dvp, from_name, to_dvp, to_name, cr,
- ct, option_flags);
+ &smb_ct, option_flags);
return (error);
}
int
smb_vop_mkdir(vnode_t *dvp, char *name, smb_attr_t *attr, vnode_t **vpp,
- int flags, cred_t *cr, caller_context_t *ct, vsecattr_t *vsap)
+ int flags, cred_t *cr, vsecattr_t *vsap)
{
int error;
int option_flags = 0;
@@ -662,7 +615,7 @@ smb_vop_mkdir(vnode_t *dvp, char *name, smb_attr_t *attr, vnode_t **vpp,
smb_sa_to_va_mask(attr->sa_mask, &attr->sa_vattr.va_mask);
- error = VOP_MKDIR(dvp, name, &attr->sa_vattr, vpp, cr, ct,
+ error = VOP_MKDIR(dvp, name, &attr->sa_vattr, vpp, cr, &smb_ct,
option_flags, vsap);
return (error);
@@ -677,8 +630,7 @@ smb_vop_mkdir(vnode_t *dvp, char *name, smb_attr_t *attr, vnode_t **vpp,
*/
int
-smb_vop_rmdir(vnode_t *dvp, char *name, int flags, cred_t *cr,
- caller_context_t *ct)
+smb_vop_rmdir(vnode_t *dvp, char *name, int flags, cred_t *cr)
{
int error;
int option_flags = 0;
@@ -698,16 +650,94 @@ smb_vop_rmdir(vnode_t *dvp, char *name, int flags, cred_t *cr,
* remove.
*/
- error = VOP_RMDIR(dvp, name, rootdir, cr, ct, option_flags);
+ error = VOP_RMDIR(dvp, name, rootdir, cr, &smb_ct, option_flags);
return (error);
}
int
-smb_vop_commit(vnode_t *vp, cred_t *cr, caller_context_t *ct)
+smb_vop_commit(vnode_t *vp, cred_t *cr)
+{
+ return (VOP_FSYNC(vp, 1, cr, &smb_ct));
+}
+
+void
+smb_vop_setup_xvattr(smb_attr_t *smb_attr, xvattr_t *xvattr)
{
- return (VOP_FSYNC(vp, 1, cr, ct));
+ xoptattr_t *xoap = NULL;
+ uint_t xva_mask;
+
+ /*
+ * Initialize xvattr, including bzero
+ */
+ xva_init(xvattr);
+ xoap = xva_getxoptattr(xvattr);
+
+ ASSERT(xoap);
+
+ /*
+ * Copy caller-specified classic attributes to xvattr.
+ * First save xvattr's mask (set in xva_init()), which
+ * contains AT_XVATTR. This is |'d in later if needed.
+ */
+
+ xva_mask = xvattr->xva_vattr.va_mask;
+ xvattr->xva_vattr = smb_attr->sa_vattr;
+
+ smb_sa_to_va_mask(smb_attr->sa_mask, &xvattr->xva_vattr.va_mask);
+
+ /*
+ * Do not set ctime (only the file system can do it)
+ */
+
+ xvattr->xva_vattr.va_mask &= ~AT_CTIME;
+
+ if (smb_attr->sa_mask & SMB_AT_DOSATTR) {
+
+ /*
+ * "|" in the original xva_mask, which contains
+ * AT_XVATTR
+ */
+
+ xvattr->xva_vattr.va_mask |= xva_mask;
+
+ XVA_SET_REQ(xvattr, XAT_ARCHIVE);
+ XVA_SET_REQ(xvattr, XAT_SYSTEM);
+ XVA_SET_REQ(xvattr, XAT_READONLY);
+ XVA_SET_REQ(xvattr, XAT_HIDDEN);
+
+ /*
+ * smb_attr->sa_dosattr: If a given bit is not set,
+ * that indicates that the corresponding field needs
+ * to be updated with a "0" value. This is done
+ * implicitly as the xoap->xoa_* fields were bzero'd.
+ */
+
+ if (smb_attr->sa_dosattr & FILE_ATTRIBUTE_ARCHIVE)
+ xoap->xoa_archive = 1;
+
+ if (smb_attr->sa_dosattr & FILE_ATTRIBUTE_SYSTEM)
+ xoap->xoa_system = 1;
+
+ if (smb_attr->sa_dosattr & FILE_ATTRIBUTE_READONLY)
+ xoap->xoa_readonly = 1;
+
+ if (smb_attr->sa_dosattr & FILE_ATTRIBUTE_HIDDEN)
+ xoap->xoa_hidden = 1;
+ }
+
+ if (smb_attr->sa_mask & SMB_AT_CRTIME) {
+ /*
+ * "|" in the original xva_mask, which contains
+ * AT_XVATTR
+ */
+
+ xvattr->xva_vattr.va_mask |= xva_mask;
+ XVA_SET_REQ(xvattr, XAT_CREATETIME);
+ xoap->xoa_createtime = smb_attr->sa_crtime;
+ }
}
+
/*
* smb_vop_readdir()
*
@@ -724,8 +754,7 @@ smb_vop_commit(vnode_t *vp, cred_t *cr, caller_context_t *ct)
int
smb_vop_readdir(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
- ino64_t *inop, vnode_t **vpp, char *od_name, int flags, cred_t *cr,
- caller_context_t *ct)
+ ino64_t *inop, vnode_t **vpp, char *od_name, int flags, cred_t *cr)
{
int num_bytes;
int error = 0;
@@ -737,7 +766,6 @@ smb_vop_readdir(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
ASSERT(namelen);
ASSERT(inop);
ASSERT(cr);
- ASSERT(ct);
if (dvp->v_type != VDIR) {
*namelen = 0;
@@ -759,7 +787,7 @@ smb_vop_readdir(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
*/
while ((error = smb_vop_readdir_readpage(dvp, dirbuf, *cookiep,
- &num_bytes, cr, ct, flags)) == 0) {
+ &num_bytes, cr, flags)) == 0) {
if (num_bytes <= 0)
break;
@@ -767,7 +795,7 @@ smb_vop_readdir(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
name[0] = '\0';
error = smb_vop_readdir_entry(dvp, cookiep, name, namelen,
- inop, vpp, od_name, flags, cr, ct, dirbuf,
+ inop, vpp, od_name, flags, cr, dirbuf,
num_bytes);
if (error)
@@ -815,7 +843,7 @@ smb_vop_readdir(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
static int
smb_vop_readdir_readpage(vnode_t *vp, void *buf, uint32_t offset, int *count,
- cred_t *cr, caller_context_t *ct, int flags)
+ cred_t *cr, int flags)
{
int error = 0;
int rdirent_flags = 0;
@@ -856,7 +884,7 @@ smb_vop_readdir_readpage(vnode_t *vp, void *buf, uint32_t offset, int *count,
auio.uio_fmode = 0;
(void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, NULL);
- error = VOP_READDIR(vp, &auio, cr, &sink, ct, rdirent_flags);
+ error = VOP_READDIR(vp, &auio, cr, &sink, &smb_ct, rdirent_flags);
VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, NULL);
if (error) {
@@ -900,7 +928,7 @@ smb_vop_readdir_readpage(vnode_t *vp, void *buf, uint32_t offset, int *count,
static int
smb_vop_readdir_entry(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
ino64_t *inop, vnode_t **vpp, char *od_name, int flags, cred_t *cr,
- caller_context_t *ct, char *dirbuf, int num_bytes)
+ char *dirbuf, int num_bytes)
{
uint32_t next_cookie;
int ebufsize;
@@ -969,7 +997,7 @@ smb_vop_readdir_entry(vnode_t *dvp, uint32_t *cookiep, char *name, int *namelen,
*/
error = smb_vop_lookup(dvp, edp->ed_name, vpp ? vpp : &vp,
- od_name, 0, NULL, cr, ct);
+ od_name, 0, NULL, cr);
if (error) {
if (error == ENOENT) {
@@ -1080,8 +1108,7 @@ smb_vop_getdents(
char *pattern,
uint32_t flags,
smb_request_t *sr,
- cred_t *cr,
- caller_context_t *ct)
+ cred_t *cr)
{
int error = 0;
int maxentries;
@@ -1107,13 +1134,13 @@ smb_vop_getdents(
num_bytes = SMB_MINLEN_RDDIR_BUF;
error = smb_vop_readdir_readpage(dvp, dirbuf, *cookiep,
- &num_bytes, cr, ct, flags);
+ &num_bytes, cr, flags);
if (error || (num_bytes <= 0))
break;
error = smb_vop_getdents_entries(dir_snode, cookiep, dircountp,
- arg, flags, sr, cr, ct, dirbuf, &maxentries, num_bytes,
+ arg, flags, sr, cr, dirbuf, &maxentries, num_bytes,
pattern);
if (error)
@@ -1158,7 +1185,6 @@ smb_vop_getdents_entries(
uint32_t flags,
struct smb_request *sr,
cred_t *cr,
- caller_context_t *ct,
char *dirbuf,
int *maxentries,
int num_bytes,
@@ -1219,7 +1245,7 @@ smb_vop_getdents_entries(
}
error = smb_vop_lookup(dvp, edp->ed_name, &fvp,
- NULL, 0, NULL, cr, ct);
+ NULL, 0, NULL, cr);
if (error) {
if (error == ENOENT) {
@@ -1335,14 +1361,14 @@ smb_vop_getdents_entries(
int
smb_vop_stream_lookup(vnode_t *fvp, char *stream_name, vnode_t **vpp,
char *od_name, vnode_t **xattrdirvpp, int flags, vnode_t *rootvp,
- cred_t *cr, caller_context_t *ct)
+ cred_t *cr)
{
char *solaris_stream_name;
char *name;
int error;
if ((error = smb_vop_lookup_xattrdir(fvp, xattrdirvpp,
- LOOKUP_XATTR | CREATE_XATTR_DIR, cr, ct)) != 0)
+ LOOKUP_XATTR | CREATE_XATTR_DIR, cr)) != 0)
return (error);
/*
@@ -1361,7 +1387,7 @@ smb_vop_stream_lookup(vnode_t *fvp, char *stream_name, vnode_t **vpp,
name = kmem_zalloc(MAXNAMELEN, KM_SLEEP);
if ((error = smb_vop_lookup(*xattrdirvpp, solaris_stream_name, vpp,
- name, flags, rootvp, cr, ct)) != 0) {
+ name, flags, rootvp, cr)) != 0) {
VN_RELE(*xattrdirvpp);
} else {
(void) strlcpy(od_name, &(name[SMB_STREAM_PREFIX_LEN]),
@@ -1376,14 +1402,13 @@ smb_vop_stream_lookup(vnode_t *fvp, char *stream_name, vnode_t **vpp,
int
smb_vop_stream_create(vnode_t *fvp, char *stream_name, smb_attr_t *attr,
- vnode_t **vpp, vnode_t **xattrdirvpp, int flags, cred_t *cr,
- caller_context_t *ct)
+ vnode_t **vpp, vnode_t **xattrdirvpp, int flags, cred_t *cr)
{
char *solaris_stream_name;
int error;
if ((error = smb_vop_lookup_xattrdir(fvp, xattrdirvpp,
- LOOKUP_XATTR | CREATE_XATTR_DIR, cr, ct)) != 0)
+ LOOKUP_XATTR | CREATE_XATTR_DIR, cr)) != 0)
return (error);
/*
@@ -1395,7 +1420,7 @@ smb_vop_stream_create(vnode_t *fvp, char *stream_name, smb_attr_t *attr,
stream_name);
if ((error = smb_vop_create(*xattrdirvpp, solaris_stream_name, attr,
- vpp, flags, cr, ct, NULL)) != 0)
+ vpp, flags, cr, NULL)) != 0)
VN_RELE(*xattrdirvpp);
kmem_free(solaris_stream_name, MAXNAMELEN);
@@ -1404,15 +1429,14 @@ smb_vop_stream_create(vnode_t *fvp, char *stream_name, smb_attr_t *attr,
}
int
-smb_vop_stream_remove(vnode_t *vp, char *stream_name, int flags, cred_t *cr,
- caller_context_t *ct)
+smb_vop_stream_remove(vnode_t *vp, char *stream_name, int flags, cred_t *cr)
{
char *solaris_stream_name;
vnode_t *xattrdirvp;
int error;
- if ((error = smb_vop_lookup_xattrdir(vp, &xattrdirvp, LOOKUP_XATTR, cr,
- ct)) != 0)
+ if ((error = smb_vop_lookup_xattrdir(vp, &xattrdirvp, LOOKUP_XATTR, cr))
+ != 0)
return (error);
/*
@@ -1424,7 +1448,7 @@ smb_vop_stream_remove(vnode_t *vp, char *stream_name, int flags, cred_t *cr,
stream_name);
/* XXX might have to use kcred */
- error = smb_vop_remove(xattrdirvp, solaris_stream_name, flags, cr, ct);
+ error = smb_vop_remove(xattrdirvp, solaris_stream_name, flags, cr);
kmem_free(solaris_stream_name, MAXNAMELEN);
@@ -1444,7 +1468,7 @@ smb_vop_stream_remove(vnode_t *vp, char *stream_name, int flags, cred_t *cr,
int
smb_vop_stream_readdir(vnode_t *fvp, uint32_t *cookiep,
struct fs_stream_info *stream_info, vnode_t **vpp, vnode_t **xattrdirvpp,
- int flags, cred_t *cr, caller_context_t *ct)
+ int flags, cred_t *cr)
{
int nsize = MAXNAMELEN-1;
int error = 0;
@@ -1454,7 +1478,7 @@ smb_vop_stream_readdir(vnode_t *fvp, uint32_t *cookiep,
vnode_t *vp;
if ((error = smb_vop_lookup_xattrdir(fvp, &xattrdirvp, LOOKUP_XATTR,
- cr, ct)) != 0)
+ cr)) != 0)
return (error);
bzero(stream_info->name, sizeof (stream_info->name));
@@ -1464,7 +1488,7 @@ smb_vop_stream_readdir(vnode_t *fvp, uint32_t *cookiep,
for (;;) {
error = smb_vop_readdir(xattrdirvp, cookiep, tmp_name, &nsize,
- &ino, &vp, NULL, flags | SMB_STREAM_RDDIR, cr, ct);
+ &ino, &vp, NULL, flags | SMB_STREAM_RDDIR, cr);
if (error || (*cookiep == SMB_EOF))
break;
@@ -1504,12 +1528,12 @@ smb_vop_stream_readdir(vnode_t *fvp, uint32_t *cookiep,
int
smb_vop_lookup_xattrdir(vnode_t *fvp, vnode_t **xattrdirvpp, int flags,
- cred_t *cr, caller_context_t *ct)
+ cred_t *cr)
{
int error;
- error = VOP_LOOKUP(fvp, "", xattrdirvpp, NULL, flags, NULL, cr, ct,
- NULL, NULL);
+ error = VOP_LOOKUP(fvp, "", xattrdirvpp, NULL, flags, NULL, cr,
+ &smb_ct, NULL, NULL);
return (error);
}
@@ -1560,7 +1584,7 @@ smb_vop_statfs(vnode_t *vp, struct statvfs64 *statp, cred_t *cr)
*/
int
smb_vop_acl_read(vnode_t *vp, acl_t **aclp, int flags, acl_type_t acl_type,
- cred_t *cr, caller_context_t *ct)
+ cred_t *cr)
{
int error;
vsecattr_t vsecattr;
@@ -1585,7 +1609,7 @@ smb_vop_acl_read(vnode_t *vp, acl_t **aclp, int flags, acl_type_t acl_type,
return (EINVAL);
}
- if (error = VOP_GETSECATTR(vp, &vsecattr, flags, cr, ct))
+ if (error = VOP_GETSECATTR(vp, &vsecattr, flags, cr, &smb_ct))
return (error);
*aclp = smb_fsacl_from_vsa(&vsecattr, acl_type);
@@ -1601,8 +1625,7 @@ smb_vop_acl_read(vnode_t *vp, acl_t **aclp, int flags, acl_type_t acl_type,
* Writes the given ACL in aclp for the specified file.
*/
int
-smb_vop_acl_write(vnode_t *vp, acl_t *aclp, int flags, cred_t *cr,
- caller_context_t *ct)
+smb_vop_acl_write(vnode_t *vp, acl_t *aclp, int flags, cred_t *cr)
{
int error;
vsecattr_t vsecattr;
@@ -1615,7 +1638,7 @@ smb_vop_acl_write(vnode_t *vp, acl_t *aclp, int flags, cred_t *cr,
if (error == 0) {
(void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL);
- error = VOP_SETSECATTR(vp, &vsecattr, flags, cr, ct);
+ error = VOP_SETSECATTR(vp, &vsecattr, flags, cr, &smb_ct);
VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL);
}
@@ -1713,3 +1736,93 @@ smb_vop_eaccess(vnode_t *vp, int *mode, int flags, vnode_t *dir_vp, cred_t *cr)
}
}
}
+
+/*
+ * smb_vop_shrlock()
+ *
+ * See comments for smb_fsop_shrlock()
+ */
+
+int
+smb_vop_shrlock(vnode_t *vp, uint32_t uniq_fid, uint32_t desired_access,
+ uint32_t share_access, cred_t *cr)
+{
+ struct shrlock shr;
+ struct shr_locowner shr_own;
+ short new_access = 0;
+ short deny = 0;
+ int flag = 0;
+ int cmd;
+
+ cmd = (nbl_need_check(vp)) ? F_SHARE_NBMAND : F_SHARE;
+
+ /*
+ * Check if this is a metadata access
+ */
+
+ if ((desired_access & FILE_DATA_ALL) == 0) {
+ new_access |= F_MDACC;
+ } else {
+ if (desired_access & (ACE_READ_DATA | ACE_EXECUTE)) {
+ new_access |= F_RDACC;
+ flag |= FREAD;
+ }
+
+ if (desired_access & (ACE_WRITE_DATA | ACE_APPEND_DATA |
+ ACE_ADD_FILE)) {
+ new_access |= F_WRACC;
+ flag |= FWRITE;
+ }
+
+ if (SMB_DENY_READ(share_access)) {
+ deny |= F_RDDNY;
+ }
+
+ if (SMB_DENY_WRITE(share_access)) {
+ deny |= F_WRDNY;
+ }
+
+ if (cmd == F_SHARE_NBMAND) {
+ if (desired_access & ACE_DELETE)
+ new_access |= F_RMACC;
+
+ if (SMB_DENY_DELETE(share_access)) {
+ deny |= F_RMDNY;
+ }
+ }
+ }
+
+ shr.s_access = new_access;
+ shr.s_deny = deny;
+ shr.s_sysid = smb_ct.cc_sysid;
+ shr.s_pid = uniq_fid;
+ shr.s_own_len = sizeof (shr_own);
+ shr.s_owner = (caddr_t)&shr_own;
+ shr_own.sl_id = shr.s_sysid;
+ shr_own.sl_pid = shr.s_pid;
+
+ return (VOP_SHRLOCK(vp, cmd, &shr, flag, cr, NULL));
+}
+
+int
+smb_vop_unshrlock(vnode_t *vp, uint32_t uniq_fid, cred_t *cr)
+{
+ struct shrlock shr;
+ struct shr_locowner shr_own;
+
+ /*
+ * For s_access and s_deny, we do not need to pass in the original
+ * values.
+ */
+
+ shr.s_access = 0;
+ shr.s_deny = 0;
+ shr.s_sysid = smb_ct.cc_sysid;
+ shr.s_pid = uniq_fid;
+ shr.s_own_len = sizeof (shr_own);
+ shr.s_owner = (caddr_t)&shr_own;
+ shr_own.sl_id = shr.s_sysid;
+ shr_own.sl_pid = shr.s_pid;
+
+ return (VOP_SHRLOCK(vp, F_UNSHARE, &shr, 0, cr, NULL));
+}
diff --git a/usr/src/uts/common/fs/smbsrv/smb_write.c b/usr/src/uts/common/fs/smbsrv/smb_write.c
index 93b9f6e758..79a0ed82ec 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_write.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_write.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -78,8 +78,7 @@ smb_com_write(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -104,7 +103,7 @@ smb_com_write(struct smb_request *sr)
if (rc != 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -151,8 +150,7 @@ smb_com_write_and_close(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -180,13 +178,13 @@ smb_com_write_and_close(struct smb_request *sr)
if (rc != 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
if ((rc = smb_common_close(sr, last_write)) != 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -219,7 +217,7 @@ smb_com_write_and_unlock(struct smb_request *sr)
int rc = 0;
if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
- smbsr_raise_error(sr, ERRDOS, ERRnoaccess);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
@@ -236,8 +234,7 @@ smb_com_write_and_unlock(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -259,7 +256,7 @@ smb_com_write_and_unlock(struct smb_request *sr)
if ((rc = smb_write_common(sr, param)) != 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
@@ -267,7 +264,8 @@ smb_com_write_and_unlock(struct smb_request *sr)
(uint64_t)param->w_count);
if (result != NT_STATUS_SUCCESS) {
kmem_free(param, sizeof (smb_write_param_t));
- smb_unlock_range_raise_error(sr, result);
+ smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
+ ERRDOS, ERRnotlocked);
/* NOTREACHED */
}
@@ -324,15 +322,14 @@ smb_com_write_andx(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
if (SMB_WRMODE_IS_STABLE(param->w_mode) &&
STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_error(sr, ERRSRV, ERRaccess);
+ smbsr_error(sr, 0, ERRSRV, ERRaccess);
/* NOTREACHED */
}
@@ -349,7 +346,7 @@ smb_com_write_andx(struct smb_request *sr)
if (param->w_count != 0) {
if ((rc = smb_write_common(sr, param)) != 0) {
kmem_free(param, sizeof (smb_write_param_t));
- smbsr_raise_errno(sr, rc);
+ smbsr_errno(sr, rc);
/* NOTREACHED */
}
}
@@ -381,10 +378,9 @@ smb_write_common(struct smb_request *sr, smb_write_param_t *param)
if (node->attr.sa_vattr.va_type != VDIR) {
rc = smb_lock_range_access(sr, node, param->w_offset,
- param->w_count, FILE_WRITE_DATA);
+ param->w_count, B_TRUE);
if (rc != NT_STATUS_SUCCESS) {
- smbsr_raise_cifs_error(sr, rc,
- ERRSRV, ERRaccess);
+ smbsr_error(sr, rc, ERRSRV, ERRaccess);
/* NOTREACHED */
}
}
@@ -444,35 +440,49 @@ smb_write_truncate(struct smb_request *sr, smb_write_param_t *param)
{
struct smb_ofile *ofile = sr->fid_ofile;
smb_node_t *node = ofile->f_node;
+ boolean_t append_only = B_FALSE;
int rc;
if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0)
return (0);
- if (node->attr.sa_vattr.va_type != VDIR) {
- rc = smb_lock_range_access(sr, node, param->w_offset,
- param->w_count, FILE_WRITE_DATA);
+ rc = smb_ofile_access(sr->fid_ofile, sr->user_cr, FILE_WRITE_DATA);
+ if (rc != NT_STATUS_SUCCESS) {
+ rc = smb_ofile_access(sr->fid_ofile, sr->user_cr,
+ FILE_APPEND_DATA);
if (rc != NT_STATUS_SUCCESS) {
- smbsr_raise_cifs_error(sr, rc,
- ERRSRV, ERRaccess);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
+ ERROR_ACCESS_DENIED);
/* NOTREACHED */
+ } else {
+ append_only = B_TRUE;
}
}
- /*
- * XXX what if the file has been opened only with
- * FILE_APPEND_DATA?
- */
- rc = smb_ofile_access(ofile, sr->user_cr, FILE_WRITE_DATA);
- if (rc != NT_STATUS_SUCCESS) {
- smbsr_raise_cifs_error(sr, NT_STATUS_ACCESS_DENIED,
- ERRDOS, ERROR_ACCESS_DENIED);
+ smb_rwx_xenter(&node->n_lock);
+
+ if (append_only && (param->w_offset < node->n_size)) {
+ smb_rwx_xexit(&node->n_lock);
+ smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
+ ERRDOS, ERRnoaccess);
/* NOTREACHED */
}
+ if (node->attr.sa_vattr.va_type != VDIR) {
+ rc = smb_lock_range_access(sr, node, param->w_offset,
+ param->w_count, B_TRUE);
+ if (rc != NT_STATUS_SUCCESS) {
+ smb_rwx_xexit(&node->n_lock);
+ smbsr_error(sr, rc, ERRSRV, ERRaccess);
+ /* NOTREACHED */
+ }
+ }
+
node->flags |= NODE_FLAGS_SET_SIZE;
node->n_size = param->w_offset;
+ smb_rwx_xexit(&node->n_lock);
+
if ((rc = smb_set_file_size(sr)) != 0)
return (rc);
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 5d02179cc2..4c7fcb6f81 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_write_raw.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_write_raw.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -216,6 +216,7 @@ smb_com_write_raw(struct smb_request *sr)
unsigned int stability;
struct mbuf_chain reply;
smb_node_t *fnode;
+ smb_error_t err;
if (sr->session->s_state != SMB_SESSION_STATE_WRITE_RAW_ACTIVE) {
return (SDRC_DROP_VC);
@@ -244,8 +245,7 @@ smb_com_write_raw(struct smb_request *sr)
sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid);
if (sr->fid_ofile == NULL) {
- smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE,
- ERRDOS, ERRbadfid);
+ smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
/* NOTREACHED */
}
@@ -260,10 +260,9 @@ smb_com_write_raw(struct smb_request *sr)
*/
if (fnode->attr.sa_vattr.va_type != VDIR) {
rc = smb_lock_range_access(sr, fnode, off,
- count, FILE_WRITE_DATA);
+ count, B_TRUE);
if (rc != NT_STATUS_SUCCESS) {
- smbsr_raise_cifs_error(sr, rc,
- ERRSRV, ERRaccess);
+ smbsr_error(sr, rc, ERRSRV, ERRaccess);
/* NOTREACHED */
}
}
@@ -440,8 +439,10 @@ notify_write_raw_complete:
* If we had an error fill in the appropriate error code
*/
if (rc != 0) {
- (void) smbsr_set_errno(sr, rc);
+ smbsr_map_errno(rc, &err);
+ smbsr_set_error(sr, &err);
}
+
/*
* Free raw write buffer if present (from smb_transfer_write_raw_data)
*/
diff --git a/usr/src/uts/common/smbsrv/cifs.h b/usr/src/uts/common/smbsrv/cifs.h
index 4533a21bb6..1f657a2d8c 100644
--- a/usr/src/uts/common/smbsrv/cifs.h
+++ b/usr/src/uts/common/smbsrv/cifs.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -421,6 +421,23 @@ extern "C" {
#define SMB_DA_WRITE_THROUGH 0x4000
/*
+ * Macros used for share reservation rule checking
+ */
+
+#define SMB_DENY_READ(share_access) ((share_access & FILE_SHARE_READ) == 0)
+
+#define SMB_DENY_WRITE(share_access) ((share_access & FILE_SHARE_WRITE) == 0)
+
+#define SMB_DENY_DELETE(share_access) ((share_access & FILE_SHARE_DELETE) == 0)
+
+#define SMB_DENY_RW(share_access) \
+ ((share_access & (FILE_SHARE_READ | FILE_SHARE_WRITE)) == 0)
+
+#define SMB_DENY_ALL(share_access) (share_access == 0)
+
+#define SMB_DENY_NONE(share_access) (share_access == FILE_SHARE_ALL)
+
+/*
* The SMB open function determines what action should be taken depending
* on the existence or lack thereof of files used in the operation. It
* has the following mapping:
diff --git a/usr/src/uts/common/smbsrv/lmshare.h b/usr/src/uts/common/smbsrv/lmshare.h
index db41a5bdee..218bb86df8 100644
--- a/usr/src/uts/common/smbsrv/lmshare.h
+++ b/usr/src/uts/common/smbsrv/lmshare.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -163,7 +163,6 @@ extern DWORD lmshrd_iterate(uint64_t iterator, lmshare_info_t *si);
extern DWORD lmshrd_list(int offset, lmshare_list_t *list);
extern DWORD lmshrd_list_transient(int offset, lmshare_list_t *list);
extern DWORD lmshrd_num_transient(void);
-extern int lmshrd_dump_hash(char *logfname);
#endif
extern int lmshrd_num_shares(void);
extern DWORD lmshrd_delete(char *share_name);
diff --git a/usr/src/uts/common/smbsrv/lmshare_door.h b/usr/src/uts/common/smbsrv/lmshare_door.h
index c1c6f2ba0c..4e4413bc9a 100644
--- a/usr/src/uts/common/smbsrv/lmshare_door.h
+++ b/usr/src/uts/common/smbsrv/lmshare_door.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -70,9 +70,9 @@ extern "C" {
#define SMB_GET_KCONFIG 17
-void smb_load_kconfig(smb_kmod_cfg_t *cfg);
-void smb_dr_get_kconfig(smb_dr_ctx_t *ctx, smb_kmod_cfg_t *cfg);
-void smb_dr_put_kconfig(smb_dr_ctx_t *ctx, smb_kmod_cfg_t *cfg);
+void smb_load_kconfig(smb_kmod_cfg_t *);
+void smb_dr_get_kconfig(smb_dr_ctx_t *, smb_kmod_cfg_t *);
+void smb_dr_put_kconfig(smb_dr_ctx_t *, smb_kmod_cfg_t *);
/*
* Door server status
@@ -97,17 +97,16 @@ void smb_dr_put_kconfig(smb_dr_ctx_t *ctx, smb_kmod_cfg_t *cfg);
* };
*/
-void smb_dr_get_lmshare(smb_dr_ctx_t *ctx, lmshare_info_t *si);
-void smb_dr_put_lmshare(smb_dr_ctx_t *ctx, lmshare_info_t *si);
-
-uint64_t smb_dr_get_lmshr_iterator(smb_dr_ctx_t *ctx);
-void smb_dr_put_lmshr_iterator(smb_dr_ctx_t *ctx,
- uint64_t lmshr_iter);
-void smb_dr_free_lmshr_iterator(smb_dr_ctx_t *ctx);
-void smb_dr_get_lmshr_list(smb_dr_ctx_t *ctx,
- lmshare_list_t *shrlist);
-void smb_dr_put_lmshr_list(smb_dr_ctx_t *ctx,
- lmshare_list_t *shrlist);
+void smb_dr_get_lmshare(smb_dr_ctx_t *, lmshare_info_t *);
+void smb_dr_put_lmshare(smb_dr_ctx_t *, lmshare_info_t *);
+
+uint64_t smb_dr_get_lmshr_iterator(smb_dr_ctx_t *);
+void smb_dr_put_lmshr_iterator(smb_dr_ctx_t *, uint64_t);
+void smb_dr_free_lmshr_iterator(smb_dr_ctx_t *);
+void smb_dr_get_lmshr_list(smb_dr_ctx_t *, lmshare_list_t *);
+void smb_dr_put_lmshr_list(smb_dr_ctx_t *, lmshare_list_t *);
+
+void lmshrd_door_close(void);
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/smbsrv/lsalib.h b/usr/src/uts/common/smbsrv/lsalib.h
index ae4076bf10..535fc9d62b 100644
--- a/usr/src/uts/common/smbsrv/lsalib.h
+++ b/usr/src/uts/common/smbsrv/lsalib.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -50,31 +50,8 @@ extern "C" {
/*
* lsalib.c
*/
-int lsa_lookup_builtin_name(char *account_name,
- smb_userinfo_t *user_info);
-
-int lsa_lookup_local_sam(char *domain,
- char *account_name,
- smb_userinfo_t *user_info);
-
-int lsa_lookup_local(char *name,
- smb_userinfo_t *user_info);
-
-int lsa_lookup_name(char *server,
- char *domain,
- char *account_name,
- smb_userinfo_t *user_info);
-
-DWORD lsa_lookup_name2(char *server,
- char *domain,
- char *account_name,
- smb_userinfo_t *user_info);
-
-int lsa_lookup_sid(nt_sid_t *sid,
- smb_userinfo_t *user_info);
-
-DWORD lsa_lookup_sid2(nt_sid_t *sid,
- smb_userinfo_t *user_info);
+uint32_t lsa_lookup_name(char *, char *, uint16_t, smb_userinfo_t *);
+uint32_t lsa_lookup_sid(nt_sid_t *, smb_userinfo_t *);
int lsa_lookup_privs(char *server,
char *account_name,
@@ -111,11 +88,11 @@ int lsar_query_security_desc(mlsvc_handle_t *lsa_handle);
DWORD lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass);
-int lsar_lookup_names(mlsvc_handle_t *lsa_handle,
+uint32_t lsar_lookup_names(mlsvc_handle_t *lsa_handle,
char *name,
smb_userinfo_t *user_info);
-int lsar_lookup_sids(mlsvc_handle_t *lsa_handle,
+uint32_t lsar_lookup_sids(mlsvc_handle_t *lsa_handle,
struct mslsa_sid *sid,
smb_userinfo_t *user_info);
@@ -145,11 +122,11 @@ DWORD lsar_lookup_priv_display_name(mlsvc_handle_t *lsa_handle,
char *display_name,
int display_len);
-DWORD lsar_lookup_sids2(mlsvc_handle_t *lsa_handle,
+uint32_t lsar_lookup_sids2(mlsvc_handle_t *lsa_handle,
struct mslsa_sid *sid,
smb_userinfo_t *user_info);
-DWORD lsar_lookup_names2(mlsvc_handle_t *lsa_handle,
+uint32_t lsar_lookup_names2(mlsvc_handle_t *lsa_handle,
char *name,
smb_userinfo_t *user_info);
diff --git a/usr/src/uts/common/smbsrv/mlrpc.h b/usr/src/uts/common/smbsrv/mlrpc.h
index 59ea5536fd..ff4d52254c 100644
--- a/usr/src/uts/common/smbsrv/mlrpc.h
+++ b/usr/src/uts/common/smbsrv/mlrpc.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -213,6 +213,21 @@ typedef struct mlrpc_service {
} mlrpc_service_t;
/*
+ * 20-byte opaque id used by various RPC services.
+ */
+typedef struct ndr_hdid {
+ uint32_t data[5];
+} ndr_hdid_t;
+
+typedef struct ndr_handle {
+ struct ndr_handle *nh_next;
+ ndr_hdid_t nh_id;
+ int nh_fid;
+ const mlrpc_service_t *nh_svc;
+ void *nh_data;
+} ndr_handle_t;
+
+/*
* The list of bindings is anchored at a connection. Nothing in the
* RPC mechanism allocates them. Binding elements which have service==0
* indicate free elements. When a connection is instantiated, at least
@@ -342,7 +357,8 @@ int mlrpc_heap_avail(mlrpc_heap_t *);
#define MLRPC_HEAP_STRSAVE(MXA, STR) \
mlrpc_heap_strsave((MXA)->heap, (STR))
-struct mlrpc_xaction {
+typedef struct mlrpc_xaction {
+ int fid;
unsigned short ptype; /* just handy, hi bits spcl */
unsigned short opnum; /* for requests */
struct mlndr_stream recv_mlnds;
@@ -353,7 +369,7 @@ struct mlrpc_xaction {
struct mlrpc_binding *binding_list; /* from connection */
mlrpc_heap_t *heap;
struct mlsvc_rpc_context *context;
-};
+} ndr_xa_t;
struct mlrpc_client {
int (*xa_init)(struct mlrpc_client *, struct mlrpc_xaction *,
@@ -371,16 +387,16 @@ struct mlrpc_client {
unsigned next_p_cont_id;
};
-/* mlndo.c */
+/* ndr_ops.c */
int mlnds_initialize(struct mlndr_stream *, unsigned, int, mlrpc_heap_t *);
void mlnds_destruct(struct mlndr_stream *);
-/* mlrpc_client.c */
+/* ndr_client.c */
int mlrpc_c_bind(struct mlrpc_client *, char *, struct mlrpc_binding **);
int mlrpc_c_call(struct mlrpc_binding *, int, void *, mlrpc_heapref_t *);
void mlrpc_c_free_heap(struct mlrpc_binding *, mlrpc_heapref_t *);
-/* mlrpc_encdec.c */
+/* ndr_marshal.c */
int mlrpc_encode_decode_common(struct mlrpc_xaction *, int, unsigned,
struct ndr_typeinfo *, void *);
int mlrpc_decode_call(struct mlrpc_xaction *, void *);
@@ -392,24 +408,30 @@ int mlrpc_encode_pdu_hdr(struct mlrpc_xaction *);
void mlrpc_decode_frag_hdr(struct mlndr_stream *, mlrpcconn_common_header_t *);
unsigned mlrpc_bind_ack_hdr_size(struct mlrpcconn_bind_ack_hdr *);
-/* mlrpc_server.c */
+/* ndr_server.c */
int mlrpc_generic_call_stub(struct mlrpc_xaction *);
-/* mlrpc_svc.c */
-struct mlrpc_stub_table *mlrpc_find_stub_in_svc(struct mlrpc_service *, int);
-struct mlrpc_service *mlrpc_find_service_by_name(const char *);
-struct mlrpc_service *mlrpc_find_service_by_uuids(mlrpc_uuid_t *, int,
- mlrpc_uuid_t *, int);
-int mlrpc_register_service(struct mlrpc_service *);
-void mlrpc_unregister_service(struct mlrpc_service *);
-void mlrpc_uuid_to_str(mlrpc_uuid_t *, char *);
-int mlrpc_str_to_uuid(char *, mlrpc_uuid_t *);
+/* ndr_svc.c */
+struct mlrpc_stub_table *mlrpc_find_stub_in_svc(mlrpc_service_t *, int);
+mlrpc_service_t *mlrpc_find_service_by_name(const char *);
+mlrpc_service_t *mlrpc_find_service_by_uuids(ndr_uuid_t *, int,
+ ndr_uuid_t *, int);
+int mlrpc_register_service(mlrpc_service_t *);
+void mlrpc_unregister_service(mlrpc_service_t *);
+void mlrpc_uuid_to_str(ndr_uuid_t *, char *);
+int mlrpc_str_to_uuid(char *, ndr_uuid_t *);
void mlrpc_binding_pool_initialize(struct mlrpc_binding **,
struct mlrpc_binding pool[], unsigned);
struct mlrpc_binding *mlrpc_find_binding(struct mlrpc_xaction *,
mlrpc_p_context_id_t);
struct mlrpc_binding *mlrpc_new_binding(struct mlrpc_xaction *);
+ndr_hdid_t *ndr_hdalloc(const ndr_xa_t *, const void *);
+void ndr_hdfree(const ndr_xa_t *, const ndr_hdid_t *);
+ndr_handle_t *ndr_hdlookup(const ndr_xa_t *, const ndr_hdid_t *);
+void ndr_hdclose(int fid);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/smbsrv/mlsvc.h b/usr/src/uts/common/smbsrv/mlsvc.h
index 6177d9fbaf..a85066fc9f 100644
--- a/usr/src/uts/common/smbsrv/mlsvc.h
+++ b/usr/src/uts/common/smbsrv/mlsvc.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -152,17 +152,10 @@ char *mlsvc_ipc_name(int ipc_type, char *username);
* the encrypted passwords.
*/
-int mlsvc_logon(char *domain_controller, char *domain_name,
- char *username);
-int mlsvc_echo(char *server);
-int mlsvc_open_pipe(char *hostname, char *domain, char *username,
- char *pipename);
-int mlsvc_close_pipe(int fid);
void mlsvc_nt_password_hash(char *result, char *password);
int mlsvc_encrypt_nt_password(char *password, char *key, int keylen, char *out,
int outmax);
DWORD mlsvc_join(char *server, char *domain, char *username, char *password);
-int mlsvc_locate_domain_controller(char *domain);
/*
* RPC request processing interface (mlsvc_server.c).
@@ -198,16 +191,8 @@ typedef struct mlsvc_pipe {
struct mlsvc_rpc_context *mlrpc_process(int, smb_dr_user_ctx_t *);
struct mlsvc_rpc_context *mlrpc_lookup(int fid);
void mlrpc_release(int);
-int mlsvc_session_native_values(int fid, int *remote_os, int *remote_lm,
- int *pdc_type);
void mlsvc_rpc_report_status(int opnum, DWORD status);
-/*
- * This is a temporary location for this NETLOGON stuff.
- */
-typedef int (*mlsvc_locate_pdc_t)(char *domain);
-void mlsvc_install_pdc_cb(mlsvc_locate_pdc_t locate_pdc_cb);
-
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/smbsrv/mlsvc_util.h b/usr/src/uts/common/smbsrv/mlsvc_util.h
index e9ababec15..24e6bdd1a9 100644
--- a/usr/src/uts/common/smbsrv/mlsvc_util.h
+++ b/usr/src/uts/common/smbsrv/mlsvc_util.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -48,72 +48,12 @@
extern "C" {
#endif
-/*
- * Predefined global RIDs.
- */
-#define MLSVC_DOMAIN_GROUP_RID_ADMINS 0x00000200L
-#define MLSVC_DOMAIN_GROUP_RID_USERS 0x00000201L
-#define MLSVC_DOMAIN_GROUP_RID_GUESTS 0x00000202L
-#define MLSVC_DOMAIN_GROUP_RID_COMPUTERS 0x00000203L
-#define MLSVC_DOMAIN_GROUP_RID_CONTROLLERS 0x00000204L
-#define MLSVC_DOMAIN_GROUP_RID_CERT_ADMINS 0x00000205L
-#define MLSVC_DOMAIN_GROUP_RID_SCHEMA_ADMINS 0x00000206L
-
-/*
- * Predefined local alias RIDs.
- */
-#define MLSVC_LOCAL_GROUP_RID_ADMINS 0x00000220L
-#define MLSVC_LOCAL_GROUP_RID_USERS 0x00000221L
-#define MLSVC_LOCAL_GROUP_RID_GUESTS 0x00000222L
-#define MLSVC_LOCAL_GROUP_RID_POWER_USERS 0x00000223L
-#define MLSVC_LOCAL_GROUP_RID_ACCOUNT_OPS 0x00000224L
-#define MLSVC_LOCAL_GROUP_RID_SERVER_OPS 0x00000225L
-#define MLSVC_LOCAL_GROUP_RID_PRINT_OPS 0x00000226L
-#define MLSVC_LOCAL_GROUP_RID_BACKUP_OPS 0x00000227L
-#define MLSVC_LOCAL_GROUP_RID_REPLICATOR 0x00000228L
-
-/*
- * All predefined local group RIDs belong
- * to a special domain called BUILTIN.
- */
-#define MLSVC_BUILTIN_DOMAIN_NAME "BUILTIN"
-#define MLSVC_BUILTIN_DOMAIN_SIDSTRLEN 8
-
-/*
- * Universal and NT well-known SIDs
- */
-#define MLSVC_NULL_SIDSTR "S-1-0-0"
-#define MSLVC_WORLD_SIDSTR "S-1-1-0"
-#define MSLVC_LOCAL_SIDSTR "S-1-2-0"
-#define MSLVC_CREATOR_OWNER_ID_SIDSTR "S-1-3-0"
-#define MSLVC_CREATOR_GROUP_ID_SIDSTR "S-1-3-1"
-#define MSLVC_CREATOR_OWNER_SERVER_ID_SIDSTR "S-1-3-2"
-#define MSLVC_CREATOR_GROUP_SERVER_ID_SIDSTR "S-1-3-3"
-#define MSLVC_NON_UNIQUE_IDS_SIDSTR "S-1-4"
-#define MLSVC_NT_AUTHORITY_SIDSTR "S-1-5"
-#define MLSVC_DIALUP_SIDSTR "S-1-5-1"
-#define MLSVC_NETWORK_SIDSTR "S-1-5-2"
-#define MLSVC_BATCH_SIDSTR "S-1-5-3"
-#define MLSVC_INTERACTIVE_SIDSTR "S-1-5-4"
-#define MLSVC_SERVICE_SIDSTR "S-1-5-6"
-#define MLSVC_ANONYMOUS_LOGON_SIDSTR "S-1-5-7"
-#define MLSVC_PROXY_SIDSTR "S-1-5-8"
-#define MLSVC_SERVER_LOGON_SIDSTR "S-1-5-9"
-#define MLSVC_SELF_SIDSTR "S-1-5-10"
-#define MLSVC_AUTHENTICATED_USER_SIDSTR "S-1-5-11"
-#define MLSVC_RESTRICTED_CODE_SIDSTR "S-1-5-12"
-#define MLSVC_NT_LOCAL_SYSTEM_SIDSTR "S-1-5-18"
-#define MLSVC_NT_NON_UNIQUE_SIDSTR "S-1-5-21"
-#define MLSVC_BUILTIN_DOMAIN_SIDSTR "S-1-5-32"
-
-int mlsvc_lookup_name(char *domain, char *name, nt_sid_t **sid);
-int mlsvc_lookup_sid(nt_sid_t *sid, char *buf, int bufsize);
-
smb_userinfo_t *mlsvc_alloc_user_info(void);
void mlsvc_free_user_info(smb_userinfo_t *user_info);
void mlsvc_release_user_info(smb_userinfo_t *user_info);
void mlsvc_setadmin_user_info(smb_userinfo_t *user_info);
char *mlsvc_sid_name_use(unsigned int snu_id);
+extern int mlsvc_is_local_domain(const char *);
/*
* The definition of a local unique id (LUID). This is an opaque id
@@ -148,38 +88,6 @@ typedef struct ms_handle {
} ms_handle_t;
/*
- * List of interface specifications: can be used to identify the
- * sub-system to which a handle is assigned. The handle management
- * library doesn't check or care about the ifspec value.
- */
-typedef enum ms_ifspec {
- MLSVC_IFSPEC_NULL,
- MLSVC_IFSPEC_LSAR,
- MLSVC_IFSPEC_SAMR,
- MLSVC_IFSPEC_WINREG,
- MLSVC_IFSPEC_SVCCTL,
- MLSVC_IFSPEC_SPOOLSS,
- MLSVC_IFSPEC_LOGR,
- MLSVC_IFSPEC_LLSR,
- MLSVC_NUM_IFSPECS
-} ms_ifspec_t;
-
-#define MLSVC_HANDLE_KEY_MAX 32
-
-typedef struct ms_handle_desc {
- struct ms_handle_desc *next;
- ms_handle_t handle;
- ms_ifspec_t ifspec;
- char key[MLSVC_HANDLE_KEY_MAX];
- DWORD discrim;
-} ms_handle_desc_t;
-
-ms_handle_t *mlsvc_get_handle(ms_ifspec_t ifspec, char *key, DWORD discrim);
-int mlsvc_put_handle(ms_handle_t *handle);
-int mlsvc_validate_handle(ms_handle_t *handle, char *key);
-ms_handle_desc_t *mlsvc_lookup_handle(ms_handle_t *handle);
-
-/*
* The mlsvc_rpc_context structure provides the connection binding context
* for client RPC calls. This space must be provided by the client library
* for use by the underlying RPC library. Note that we need two binding
@@ -217,11 +125,6 @@ struct mlsvc_rpc_context {
* The context contains a pointer to the top level handle for the
* interface, which is assigned during the bind. It's used when closing
* to detect when to free the context.
- *
- * I know this is really tacky but the elements in the descriptor are
- * arranged so that a handle can be overlaid directly onto a descriptor.
- * I probably won't do this but now you know - just in case you see it
- * in the code.
*/
typedef struct mlsvc_rpc_desc {
ms_handle_t handle;
diff --git a/usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl b/usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl
index fd42fcac1c..596329a521 100644
--- a/usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/rpcpdu.ndl
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -46,7 +46,7 @@
* UUID (Universal Unique IDentifier)
*/
/* (X/Open CAE Spec Appendix A) */
-struct mlrpc_uuid_dce {
+struct ndr_dce_uuid {
DWORD time_low;
WORD time_mid;
WORD time_hi_and_version;
@@ -55,13 +55,13 @@ struct mlrpc_uuid_dce {
BYTE node[6];
};
-struct mlrpc_uuid {
+struct ndr_uuid {
DWORD data1;
WORD data2;
WORD data3;
BYTE data4[8];
};
-typedef struct mlrpc_uuid mlrpc_uuid_t;
+typedef struct ndr_uuid ndr_uuid_t;
/*
* Representation label -- needed for RPC header
@@ -171,7 +171,7 @@ typedef WORD mlrpc_p_context_id_t;
_NO_REORDER_
struct mlrpc_p_syntax_id {
- mlrpc_uuid_t if_uuid;
+ ndr_uuid_t if_uuid;
DWORD if_version;
};
typedef struct mlrpc_p_syntax_id mlrpc_p_syntax_id_t;
@@ -182,7 +182,7 @@ struct mlrpc_p_cont_elem {
BYTE n_transfer_syn;
BYTE _reserved;
mlrpc_p_syntax_id_t abstract_syntax;
- /*SIZE_IS(n_transfer_syn)*/
+ /*SIZE_IS(n_transfer_syn)*/
mlrpc_p_syntax_id_t transfer_syntaxes[1];
};
typedef struct mlrpc_p_cont_elem mlrpc_p_cont_elem_t;
@@ -193,7 +193,7 @@ struct mlrpc_p_cont_list {
BYTE n_context_elem;
BYTE _reserved;
WORD _reserved2;
- /*SIZE_IS(n_context_elem)*/
+ /*SIZE_IS(n_context_elem)*/
mlrpc_p_cont_elem_t p_cont_elem[1];
};
typedef struct mlrpc_p_cont_list mlrpc_p_cont_list_t;
@@ -226,7 +226,7 @@ struct mlrpc_p_result_list {
BYTE n_results;
BYTE reserved;
WORD reserved2;
- /*SIZE_IS(n_results)*/
+ /*SIZE_IS(n_results)*/
mlrpc_p_result_t p_results[1];
};
typedef struct mlrpc_p_result_list mlrpc_p_result_list_t;
@@ -236,10 +236,10 @@ EXTERNTYPEINFO(mlrpc_p_result_list)
_NO_REORDER_
struct mlrpc_port_any {
WORD length; /* always 18 */
- /*SIZE_IS(length)*/
+ /*SIZE_IS(length)*/
BYTE port_spec[MLRPC_PORT_ANY_MAX_PORT_SPEC];
- /* \PIPE\ntsvcs */
- /* We cheat by using 18, and pad on the right with zeroes */
+ /* \PIPE\ntsvcs */
+ /* We cheat by using 18, and pad on the right with zeroes */
};
typedef struct mlrpc_port_any mlrpc_port_any_t;
EXTERNTYPEINFO(mlrpc_port_any)
@@ -377,15 +377,15 @@ _NO_REORDER_
struct mlrpcconn_request_hdr {
mlrpcconn_common_header_t common_hdr; /* 00:16 (see above) */
- /* needed for request, response, or fault */
+ /* needed for request, response, or fault */
DWORD alloc_hint; /* 16:04 allocation hint */
mlrpc_p_context_id_t
p_cont_id; /* 20:02 pres context, i.e. data rep */
WORD opnum; /* 22:02 op number w/i interface */
- /* optional field if PFC_OBJECT_UUID, not present */
- /* mlrpc_uuid_t object; */
+ /* optional field if PFC_OBJECT_UUID, not present */
+ /* ndr_uuid_t object; */
/* stub-data, 8-octet aligned */ /* 24:nn */
/* nn = frag_len - sizeof(common_header) - auth_len */
@@ -399,19 +399,19 @@ _NO_REORDER_
struct mlrpcconn_request_hdr_with_object {
mlrpcconn_common_header_t common_hdr; /* 00:16 (see above) */
- /* needed for request, response, or fault */
+ /* needed for request, response, or fault */
DWORD alloc_hint; /* 16:04 allocation hint */
mlrpc_p_context_id_t
p_cont_id; /* 20:02 pres context, i.e. data rep */
WORD opnum; /* 22:02 op number w/i interface */
- /* optional field if PFC_OBJECT_UUID, is present */
- mlrpc_uuid_t object; /* 24:16 object UUID, unknown purpose*/
+ /* optional field if PFC_OBJECT_UUID, is present */
+ ndr_uuid_t object; /* 24:16 object UUID, unknown purpose*/
/* stub-data, 8-octet aligned */ /* 28:nn */
/* nn = frag_len - sizeof(common_header) - auth_len */
- /* nn -= sizeof(mlrpc_uuid_t); */
+ /* nn -= sizeof(ndr_uuid_t); */
/* optional authentication verifier iff auth_length != 0 */
/* auth_verifier_co_t auth_verifier; */
@@ -435,12 +435,12 @@ _NO_REORDER_
struct mlrpcconn_response_hdr {
mlrpcconn_common_header_t common_hdr; /* 00:16 (see above) */
- /* needed for request, response, or fault */
+ /* needed for request, response, or fault */
DWORD alloc_hint; /* 16:04 allocation hint */
mlrpc_p_context_id_t
p_cont_id; /* 20:02 pres context, i.e. data rep */
- /* needed for response or fault */
+ /* needed for response or fault */
BYTE cancel_count; /* 22:01 cancel count */
BYTE reserved; /* 23:01 mbz */
@@ -467,17 +467,17 @@ struct mlrpcconn_fault_hdr {
mlrpc_p_context_id_t
p_cont_id; /* 20:02 pres context, i.e. data rep */
- /* needed for response or fault */
+ /* needed for response or fault */
BYTE cancel_count; /* 22:01 cancel count */
BYTE reserved; /* 23:01 mbz */
- /* fault code */
+ /* fault code */
DWORD status; /* 24:04 run-time fault code or 0 */
- /* pad to 8-byte alignment */
+ /* pad to 8-byte alignment */
BYTE reserved2[4]; /* 28:04 must-be-zero */
- /* stub-data here if status==0. We do not use this mode. */
+ /* stub-data here if status==0. We do not use this mode. */
/* optional authentication verifier iff auth_length != 0 */
/* auth_verifier_co_t auth_verifier; */
diff --git a/usr/src/uts/common/smbsrv/ndl/winreg.ndl b/usr/src/uts/common/smbsrv/ndl/winreg.ndl
index 2d3d1de28d..b1a02a858b 100644
--- a/usr/src/uts/common/smbsrv/ndl/winreg.ndl
+++ b/usr/src/uts/common/smbsrv/ndl/winreg.ndl
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,7 +34,10 @@
#include "ndrtypes.ndl"
+#define WINREG_OPNUM_OpenHKCR 0x00
+#define WINREG_OPNUM_OpenHKCU 0x01
#define WINREG_OPNUM_OpenHKLM 0x02
+#define WINREG_OPNUM_OpenHKPD 0x03
#define WINREG_OPNUM_OpenHKUsers 0x04
#define WINREG_OPNUM_Close 0x05
#define WINREG_OPNUM_CreateKey 0x06
@@ -44,34 +47,40 @@
#define WINREG_OPNUM_EnumValue 0x0a
#define WINREG_OPNUM_FlushKey 0x0b
#define WINREG_OPNUM_GetKeySec 0x0c
+#define WINREG_OPNUM_LoadKey 0x0d
+#define WINREG_OPNUM_NotifyChange 0x0e
#define WINREG_OPNUM_OpenKey 0x0f
#define WINREG_OPNUM_QueryKey 0x10
#define WINREG_OPNUM_QueryValue 0x11
+#define WINREG_OPNUM_ReplaceKey 0x12
+#define WINREG_OPNUM_RestoreKey 0x13
+#define WINREG_OPNUM_SaveKey 0x14
#define WINREG_OPNUM_SetKeySec 0x15
#define WINREG_OPNUM_CreateValue 0x16
+#define WINREG_OPNUM_UnloadKey 0x17
#define WINREG_OPNUM_Shutdown 0x18
+#define WINREG_OPNUM_AbortShutdown 0x19
#define WINREG_OPNUM_GetVersion 0x1a
-
-struct msreg_handle {
+struct winreg_handle {
DWORD hand1;
DWORD hand2;
WORD hand3[2];
BYTE hand4[8];
};
-typedef struct msreg_handle msreg_handle_t;
+typedef struct winreg_handle winreg_handle_t;
-struct msreg_string_desc {
+struct winreg_string_desc {
WORD length;
WORD allosize;
LPTSTR str;
};
-typedef struct msreg_string_desc msreg_string_t;
+typedef struct winreg_string_desc winreg_string_t;
/*
* Fake Varying/Conformant with a funny conformant.
*/
-struct msreg_value {
+struct winreg_value {
DWORD vc_first_is; /* 0 */
DWORD vc_length_is;
SIZE_IS(vc_length_is)
@@ -84,37 +93,59 @@ struct file_time {
};
typedef struct file_time file_time_t;
+OPERATION(WINREG_OPNUM_OpenHKCR)
+struct winreg_OpenHKCR {
+ IN DWORD *server;
+ IN DWORD access_mask;
+ OUT winreg_handle_t handle;
+ OUT DWORD status;
+};
+
+OPERATION(WINREG_OPNUM_OpenHKCU)
+struct winreg_OpenHKCU {
+ IN DWORD *server;
+ IN DWORD access_mask;
+ OUT winreg_handle_t handle;
+ OUT DWORD status;
+};
OPERATION(WINREG_OPNUM_OpenHKLM)
-struct msreg_OpenHKLM {
- IN BYTE whatever[8];
+struct winreg_OpenHKLM {
+ IN DWORD *server;
IN DWORD access_mask;
- OUT msreg_handle_t handle;
+ OUT winreg_handle_t handle;
OUT DWORD status;
};
+OPERATION(WINREG_OPNUM_OpenHKPD)
+struct winreg_OpenHKPD {
+ IN DWORD *server;
+ IN DWORD access_mask;
+ OUT winreg_handle_t handle;
+ OUT DWORD status;
+};
OPERATION(WINREG_OPNUM_OpenHKUsers)
-struct msreg_OpenHKUsers {
- IN BYTE whatever[8];
+struct winreg_OpenHKUsers {
+ IN DWORD *server;
IN DWORD access_mask;
- OUT msreg_handle_t handle;
+ OUT winreg_handle_t handle;
OUT DWORD status;
};
OPERATION(WINREG_OPNUM_Close)
-struct msreg_Close {
- IN msreg_handle_t handle;
- OUT msreg_handle_t result_handle;
+struct winreg_Close {
+ IN winreg_handle_t handle;
+ OUT winreg_handle_t result_handle;
OUT DWORD status;
};
OPERATION(WINREG_OPNUM_CreateKey)
-struct msreg_CreateKey {
- IN msreg_handle_t handle;
- IN msreg_string_t subkey;
+struct winreg_CreateKey {
+ IN winreg_handle_t handle;
+ IN winreg_string_t subkey;
/* IN ignore the remaining input data */
OUT DWORD status;
@@ -122,9 +153,9 @@ struct msreg_CreateKey {
OPERATION(WINREG_OPNUM_DeleteKey)
-struct msreg_DeleteKey {
- IN msreg_handle_t handle;
- IN msreg_string_t subkey;
+struct winreg_DeleteKey {
+ IN winreg_handle_t handle;
+ IN winreg_string_t subkey;
/* IN ignore the remaining input data */
OUT DWORD status;
@@ -132,9 +163,9 @@ struct msreg_DeleteKey {
OPERATION(WINREG_OPNUM_DeleteValue)
-struct msreg_DeleteValue {
- IN msreg_handle_t handle;
- IN msreg_string_t name;
+struct winreg_DeleteValue {
+ IN winreg_handle_t handle;
+ IN winreg_string_t name;
/* IN ignore the remaining input data */
OUT DWORD status;
@@ -146,27 +177,48 @@ struct msreg_DeleteValue {
* as IN parameters but we can ignore them.
*/
OPERATION(WINREG_OPNUM_EnumValue)
-struct msreg_EnumValue {
- IN msreg_handle_t handle;
- IN DWORD index;
+struct winreg_EnumValue {
+ IN winreg_handle_t handle;
+ IN DWORD index;
/* IN ignore the remaining input data */
- OUT msreg_string_t name;
+ OUT winreg_string_t name;
OUT DWORD *type;
- OUT struct msreg_value *value;
+ OUT struct winreg_value *value;
OUT DWORD *value_size;
OUT DWORD *value_size_total;
OUT DWORD status;
};
+OPERATION(WINREG_OPNUM_FlushKey)
+struct winreg_FlushKey {
+ IN winreg_handle_t handle;
+ OUT DWORD status;
+};
+
+OPERATION(WINREG_OPNUM_GetKeySec)
+struct winreg_GetKeySec {
+ IN winreg_handle_t handle;
+ IN DWORD sec_info;
+ OUT DWORD *sd;
+ OUT DWORD status;
+};
+
+OPERATION(WINREG_OPNUM_NotifyChange)
+struct winreg_NotifyChange {
+ IN winreg_handle_t handle;
+ IN DWORD watch_subtree;
+ IN DWORD notify_filter;
+ OUT DWORD status;
+};
OPERATION(WINREG_OPNUM_OpenKey)
-struct msreg_OpenKey {
- IN msreg_handle_t handle;
- IN msreg_string_t name;
+struct winreg_OpenKey {
+ IN winreg_handle_t handle;
+ IN winreg_string_t name;
IN DWORD unknown;
IN DWORD access_mask;
- OUT msreg_handle_t result_handle;
+ OUT winreg_handle_t result_handle;
OUT DWORD status;
};
@@ -183,14 +235,14 @@ struct msreg_OpenKey {
*/
OPERATION(WINREG_OPNUM_QueryKey)
-struct msreg_QueryKey {
- IN msreg_handle_t handle;
+struct winreg_QueryKey {
+ IN winreg_handle_t handle;
/*
* Ignore the remaining input data
- * (2 * DWORD, possibly msreg_string_t).
+ * (2 * DWORD, possibly winreg_string_t).
*/
- OUT msreg_string_t name;
+ OUT winreg_string_t name;
OUT DWORD unknown;
OUT DWORD sub_keys;
OUT DWORD max_subkey_len;
@@ -209,23 +261,31 @@ struct msreg_QueryKey {
* as IN parameters but we can ignore them.
*/
OPERATION(WINREG_OPNUM_QueryValue)
-struct msreg_QueryValue {
- IN msreg_handle_t handle;
- IN msreg_string_t value_name;
+struct winreg_QueryValue {
+ IN winreg_handle_t handle;
+ IN winreg_string_t value_name;
/* IN ignore the remaining input data */
OUT DWORD *type;
- OUT struct msreg_value *value;
+ OUT struct winreg_value *value;
OUT DWORD *value_size;
OUT DWORD *value_size_total;
OUT DWORD status;
};
+OPERATION(WINREG_OPNUM_SetKeySec)
+struct winreg_SetKeySec {
+ IN winreg_handle_t handle;
+ IN DWORD access_mask;
+ IN DWORD sd;
+ OUT DWORD status;
+};
+
OPERATION(WINREG_OPNUM_CreateValue)
-struct msreg_CreateValue {
- IN msreg_handle_t handle;
- IN msreg_string_t name;
+struct winreg_CreateValue {
+ IN winreg_handle_t handle;
+ IN winreg_string_t name;
/* IN ignore the remaining input data */
OUT DWORD status;
@@ -238,17 +298,17 @@ struct msreg_CreateValue {
* without anything appearing in the log, and return access denied.
*/
OPERATION(WINREG_OPNUM_Shutdown)
-struct msreg_Shutdown {
- IN DWORD ignored;
- OUT DWORD status;
+struct winreg_Shutdown {
+ IN DWORD ignored;
+ OUT DWORD status;
};
OPERATION(WINREG_OPNUM_GetVersion)
-struct msreg_GetVersion {
- IN msreg_handle_t handle;
- OUT DWORD version;
- OUT DWORD status;
+struct winreg_GetVersion {
+ IN winreg_handle_t handle;
+ OUT DWORD version;
+ OUT DWORD status;
};
@@ -257,30 +317,44 @@ struct msreg_GetVersion {
*/
INTERFACE(0)
union winreg_interface {
+ CASE(WINREG_OPNUM_OpenHKCR)
+ struct winreg_OpenHKCR OpenHKCR;
+ CASE(WINREG_OPNUM_OpenHKCU)
+ struct winreg_OpenHKCU OpenHKCU;
CASE(WINREG_OPNUM_OpenHKLM)
- struct msreg_OpenHKLM OpenHKLM;
+ struct winreg_OpenHKLM OpenHKLM;
+ CASE(WINREG_OPNUM_OpenHKPD)
+ struct winreg_OpenHKPD OpenHKPD;
CASE(WINREG_OPNUM_OpenHKUsers)
- struct msreg_OpenHKUsers OpenHKUsers;
+ struct winreg_OpenHKUsers OpenHKUsers;
CASE(WINREG_OPNUM_Close)
- struct msreg_Close Close;
+ struct winreg_Close Close;
CASE(WINREG_OPNUM_CreateKey)
- struct msreg_CreateKey CreateKey;
+ struct winreg_CreateKey CreateKey;
CASE(WINREG_OPNUM_DeleteKey)
- struct msreg_DeleteKey DeleteKey;
+ struct winreg_DeleteKey DeleteKey;
CASE(WINREG_OPNUM_DeleteValue)
- struct msreg_DeleteValue DeleteValue;
+ struct winreg_DeleteValue DeleteValue;
+ CASE(WINREG_OPNUM_FlushKey)
+ struct winreg_FlushKey FlushKey;
+ CASE(WINREG_OPNUM_GetKeySec)
+ struct winreg_GetKeySec GetKeySec;
+ CASE(WINREG_OPNUM_NotifyChange)
+ struct winreg_NotifyChange NotifyChange;
CASE(WINREG_OPNUM_OpenKey)
- struct msreg_OpenKey OpenKey;
+ struct winreg_OpenKey OpenKey;
CASE(WINREG_OPNUM_QueryKey)
- struct msreg_QueryKey QueryKey;
+ struct winreg_QueryKey QueryKey;
CASE(WINREG_OPNUM_QueryValue)
- struct msreg_QueryValue QueryValue;
+ struct winreg_QueryValue QueryValue;
+ CASE(WINREG_OPNUM_SetKeySec)
+ struct winreg_SetKeySec SetKeySec;
CASE(WINREG_OPNUM_CreateValue)
- struct msreg_CreateValue CreateValue;
+ struct winreg_CreateValue CreateValue;
CASE(WINREG_OPNUM_Shutdown)
- struct msreg_Shutdown Shutdown;
+ struct winreg_Shutdown Shutdown;
CASE(WINREG_OPNUM_GetVersion)
- struct msreg_GetVersion GetVersion;
+ struct winreg_GetVersion GetVersion;
};
typedef union winreg_interface winreg_interface_t;
EXTERNTYPEINFO(winreg_interface)
diff --git a/usr/src/uts/common/smbsrv/samlib.h b/usr/src/uts/common/smbsrv/samlib.h
index efec26a922..c38986d1d5 100644
--- a/usr/src/uts/common/smbsrv/samlib.h
+++ b/usr/src/uts/common/smbsrv/samlib.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -55,7 +55,7 @@ DWORD sam_create_trust_account(char *server, char *domain,
smb_auth_info_t *auth);
DWORD sam_create_account(char *server, char *domain_name, char *account_name,
- smb_auth_info_t *auth, DWORD account_flags, smb_userinfo_t *user_info);
+ smb_auth_info_t *auth, DWORD account_flags);
DWORD sam_remove_trust_account(char *server, char *domain);
diff --git a/usr/src/uts/common/smbsrv/smb_door_svc.h b/usr/src/uts/common/smbsrv/smb_door_svc.h
index be8898f42a..6b9b943a6a 100644
--- a/usr/src/uts/common/smbsrv/smb_door_svc.h
+++ b/usr/src/uts/common/smbsrv/smb_door_svc.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -82,20 +82,8 @@ enum smb_dr_opcode_t {
SMB_DR_USER_NONAUTH_LOGON,
SMB_DR_USER_AUTH_LOGOFF,
SMB_DR_USER_LIST,
- SMB_DR_GROUP_ADD,
- SMB_DR_GROUP_DELETE,
- SMB_DR_GROUP_MEMBER_ADD,
- SMB_DR_GROUP_MEMBER_REMOVE,
- SMB_DR_GROUP_COUNT,
- SMB_DR_GROUP_CACHE_SIZE,
- SMB_DR_GROUP_MODIFY,
- SMB_DR_GROUP_PRIV_NUM,
- SMB_DR_GROUP_PRIV_LIST,
- SMB_DR_GROUP_PRIV_GET,
- SMB_DR_GROUP_PRIV_SET,
- SMB_DR_GROUP_LIST,
- SMB_DR_GROUP_MEMBER_LIST,
- SMB_DR_GROUP_MEMBER_COUNT
+ SMB_DR_LOOKUP_SID,
+ SMB_DR_LOOKUP_NAME
};
enum smb_kdr_opcode_t {
diff --git a/usr/src/uts/common/smbsrv/smb_fsops.h b/usr/src/uts/common/smbsrv/smb_fsops.h
index afed8b6637..07e825c24d 100644
--- a/usr/src/uts/common/smbsrv/smb_fsops.h
+++ b/usr/src/uts/common/smbsrv/smb_fsops.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,11 +36,15 @@
#include <smbsrv/smbinfo.h>
#include <smbsrv/smb_vops.h>
#include <smbsrv/smbvar.h>
+#include <sys/callb.h>
+#include <sys/flock.h>
#ifdef __cplusplus
extern "C" {
#endif
+extern caller_context_t smb_ct;
+
int smb_fsop_open(smb_ofile_t *of);
int smb_fsop_close(smb_ofile_t *of);
@@ -119,7 +123,13 @@ int smb_fsop_sdread(smb_request_t *, cred_t *, smb_node_t *, smb_fssd_t *);
int smb_fsop_sdwrite(smb_request_t *, cred_t *, smb_node_t *, smb_fssd_t *,
int);
-void smb_get_caller_context(smb_request_t *sr, caller_context_t *ct);
+uint32_t smb_fsop_shrlock(cred_t *cr, smb_node_t *node, uint32_t uniq_fid,
+ uint32_t desired_access, uint32_t share_access);
+
+void smb_fsop_unshrlock(cred_t *cr, smb_node_t *node, uint32_t uniq_fid);
+
+int smb_fsop_frlock(smb_request_t *sr, smb_node_t *node, smb_lock_t *lock,
+ boolean_t unlock);
/*
* Lookup-related flags
diff --git a/usr/src/uts/common/smbsrv/smb_kproto.h b/usr/src/uts/common/smbsrv/smb_kproto.h
index 0b9442bed1..a23b42572c 100644
--- a/usr/src/uts/common/smbsrv/smb_kproto.h
+++ b/usr/src/uts/common/smbsrv/smb_kproto.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -101,10 +101,12 @@ void smb_release_oplock(struct smb_ofile *file, int reason);
uint32_t smb_unlock_range(struct smb_request *, struct smb_node *,
uint64_t, uint64_t);
-void smb_unlock_range_raise_error(smb_request_t *sr, uint32_t ntstatus);
uint32_t smb_lock_range(struct smb_request *, struct smb_ofile *,
uint64_t, uint64_t, uint32_t, uint32_t);
-void smb_lock_range_raise_error(smb_request_t *sr, uint32_t ntstatus);
+void smb_lock_range_error(smb_request_t *, uint32_t);
+
+DWORD smb_range_check(smb_request_t *, cred_t *, smb_node_t *,
+ uint64_t, uint64_t, boolean_t);
int smb_mangle_name(ino64_t fileid, char *name, char *shortname,
char *name83, int force);
@@ -149,31 +151,17 @@ void smbsr_decode_error(struct smb_request *);
void smbsr_encode_error(struct smb_request *);
void smbsr_encode_empty_result(struct smb_request *sr);
-#pragma does_not_return(smbsr_decode_error)
-#pragma does_not_return(smbsr_encode_error)
-
int smbsr_decode_vwv(struct smb_request *sr, char *fmt, ...);
int smbsr_decode_data(struct smb_request *sr, char *fmt, ...);
void smbsr_encode_result(struct smb_request *, int, int, char *, ...);
smb_xa_t *smbsr_lookup_xa(smb_request_t *sr);
void smbsr_send_reply(struct smb_request *);
-void smbsr_raise_cifs_error(struct smb_request *sr, DWORD status,
- int error_class, int error_code);
-
-int smbsr_set_errno(struct smb_request *, int);
-void smbsr_raise_errno(struct smb_request *, int);
-void smbsr_raise_error(struct smb_request *, int, int);
-void smbsr_raise_nt_error(struct smb_request *sr, uint32_t);
-
-#pragma does_not_return(smbsr_raise_cifs_error)
-#pragma does_not_return(smbsr_raise_error)
-#pragma does_not_return(smbsr_raise_nt_error)
-#pragma does_not_return(smbsr_raise_errno)
-
-void smbsr_setup_nt_status(struct smb_request *sr,
- uint32_t severity,
- uint32_t nt_status);
+void smbsr_map_errno(int, smb_error_t *);
+void smbsr_set_error(smb_request_t *, smb_error_t *);
+void smbsr_errno(struct smb_request *, int);
+void smbsr_warn(struct smb_request *, DWORD, uint16_t, uint16_t);
+void smbsr_error(struct smb_request *, DWORD, uint16_t, uint16_t);
int smb_mbc_encode(struct mbuf_chain *mbc, char *fmt, va_list ap);
int smb_mbc_decode(struct mbuf_chain *mbc, char *fmt, va_list ap);
@@ -202,7 +190,7 @@ int smb_component_match(struct smb_request *sr, ino64_t fileid,
struct smb_odir *od, smb_odir_context_t *pc);
int smb_lock_range_access(struct smb_request *, struct smb_node *,
- uint64_t, uint64_t, uint32_t desired_access);
+ uint64_t, uint64_t, boolean_t);
uint32_t smb_decode_sd(struct smb_xa *, smb_sd_t *);
@@ -247,6 +235,17 @@ void smb_node_root_fini();
void smb_node_add_lock(smb_node_t *node, smb_lock_t *lock);
void smb_node_destroy_lock(smb_node_t *node, smb_lock_t *lock);
void smb_node_destroy_lock_by_ofile(smb_node_t *node, smb_ofile_t *file);
+void smb_node_start_crit(smb_node_t *node, krw_t mode);
+void smb_node_end_crit(smb_node_t *node);
+int smb_node_in_crit(smb_node_t *node);
+
+uint32_t smb_node_open_check(smb_node_t *, cred_t *,
+ uint32_t, uint32_t);
+uint32_t smb_node_share_check(smb_node_t *, cred_t *,
+ uint32_t, uint32_t, smb_ofile_t *);
+DWORD smb_node_rename_check(smb_node_t *);
+DWORD smb_node_delete_check(smb_node_t *);
+
uint64_t smb_node_get_size(smb_node_t *node, smb_attr_t *attr);
void smb_node_set_time(struct smb_node *node, timestruc_t *crtime,
timestruc_t *mtime, timestruc_t *atime,
@@ -359,7 +358,6 @@ int smb_stream_parse_name(char *name, char *u_stream_name,
uint32_t smb_get_gmtoff(void);
void smb_set_gmtoff(uint32_t);
-void smb_errmap_unix2smb(int en, smb_error_t *smberr);
DWORD smb_trans2_set_information(struct smb_request *sr,
smb_trans2_setinfo_t *info,
smb_error_t *smberr);
@@ -398,7 +396,8 @@ void smb_session_disconnect_volume(fs_desc_t *);
smb_ofile_t *smb_ofile_lookup_by_fid(smb_tree_t *tree, uint16_t fid);
smb_ofile_t *smb_ofile_open(smb_tree_t *tree, smb_node_t *node, uint16_t pid,
uint32_t access_granted, uint32_t create_options, uint32_t share_access,
- uint16_t ftype, char *pipe_name, uint32_t rpc_fid, smb_error_t *err);
+ uint16_t ftype, char *pipe_name, uint32_t rpc_fid, uint32_t uniqid,
+ smb_error_t *err);
int smb_ofile_close(smb_ofile_t *ofile, uint32_t last_wtime);
uint32_t smb_ofile_access(smb_ofile_t *ofile, cred_t *cr, uint32_t access);
int smb_ofile_seek(smb_ofile_t *of, ushort_t mode, int32_t off,
diff --git a/usr/src/uts/common/smbsrv/smb_privilege.h b/usr/src/uts/common/smbsrv/smb_privilege.h
index c03455d469..9fad667938 100644
--- a/usr/src/uts/common/smbsrv/smb_privilege.h
+++ b/usr/src/uts/common/smbsrv/smb_privilege.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -98,6 +98,7 @@ extern "C" {
#define SE_CHANGE_NOTIFY_NAME "SeChangeNotifyPrivilege"
#define SE_REMOTE_SHUTDOWN_NAME "SeRemoteShutdownPrivilege"
+#define SE_MIN_LUID 2
#define SE_CREATE_TOKEN_LUID 2
#define SE_ASSIGNPRIMARYTOKEN_LUID 3
#define SE_LOCK_MEMORY_LUID 4
@@ -121,6 +122,7 @@ extern "C" {
#define SE_SYSTEM_ENVIRONMENT_LUID 22
#define SE_CHANGE_NOTIFY_LUID 23
#define SE_REMOTE_SHUTDOWN_LUID 24
+#define SE_MAX_LUID 24
/*
* Privilege attributes
@@ -181,6 +183,7 @@ int smb_privset_size();
void smb_privset_init(smb_privset_t *privset);
void smb_privset_free(smb_privset_t *privset);
void smb_privset_copy(smb_privset_t *dst, smb_privset_t *src);
+void smb_privset_merge(smb_privset_t *dst, smb_privset_t *src);
void smb_privset_enable(smb_privset_t *privset, uint32_t id);
int smb_privset_query(smb_privset_t *privset, uint32_t id);
void smb_privset_log(smb_privset_t *privset);
diff --git a/usr/src/uts/common/smbsrv/smb_vops.h b/usr/src/uts/common/smbsrv/smb_vops.h
index 3b09c99b63..0f98b41be5 100644
--- a/usr/src/uts/common/smbsrv/smb_vops.h
+++ b/usr/src/uts/common/smbsrv/smb_vops.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -318,67 +318,53 @@ struct fs_stream_info {
int fhopen(const struct smb_node *, int);
-extern int smb_vop_open(vnode_t **vpp, int mode, cred_t *cred,
- caller_context_t *ct);
-extern int smb_vop_close(vnode_t *vp, int flag, cred_t *cred,
- caller_context_t *ct);
-extern int smb_vop_read(vnode_t *vp, uio_t *uiop, cred_t *cr,
- caller_context_t *ct);
-extern int smb_vop_write(vnode_t *vp, uio_t *uiop, unsigned int *flag,
- uint32_t *lcount, cred_t *cr, caller_context_t *ct);
-extern int smb_vop_getattr(vnode_t *vp, vnode_t *unnamed_vp,
- smb_attr_t *ret_attr, int flags, cred_t *cr, caller_context_t *ct);
-extern int smb_vop_setattr(vnode_t *vp, vnode_t *unnamed_vp,
- smb_attr_t *set_attr, int flags, cred_t *cr, boolean_t no_xvattr,
- caller_context_t *ct);
-extern int smb_vop_access(vnode_t *vp, int mode, int flags, vnode_t *dir_vp,
- cred_t *cr);
-extern void smb_vop_eaccess(vnode_t *vp, int *mode, int flags, vnode_t *dir_vp,
- cred_t *cr);
-extern int smb_vop_lookup(vnode_t *dvp, char *name, vnode_t **vpp,
- char *od_name, int flags, vnode_t *rootvp, cred_t *cr,
- caller_context_t *ct);
-extern int smb_vop_create(vnode_t *dvp, char *name, smb_attr_t *attr,
- vnode_t **vpp, int flags, cred_t *cr, caller_context_t *ct,
- vsecattr_t *vsap);
-extern int smb_vop_remove(vnode_t *dvp, char *name, int flags, cred_t *cr,
- caller_context_t *ct);
-extern int smb_vop_rename(vnode_t *from_dvp, char *from_name, vnode_t *to_dvp,
- char *to_name, int flags, cred_t *cr, caller_context_t *ct);
-extern int smb_vop_mkdir(vnode_t *dvp, char *name, smb_attr_t *attr,
- vnode_t **vpp, int flags, cred_t *cr, caller_context_t *ct,
- vsecattr_t *vsap);
-extern int smb_vop_rmdir(vnode_t *dvp, char *name, int flags, cred_t *cr,
- caller_context_t *ct);
-extern int smb_vop_readdir(vnode_t *dvp, uint32_t *cookiep, char *name,
- int *namelen, ino64_t *inop, vnode_t **vpp, char *od_name, int flags,
- cred_t *cr, caller_context_t *ct);
-extern int smb_vop_commit(vnode_t *vp, cred_t *cr, caller_context_t *ct);
-extern int smb_vop_getdents(struct smb_node *dir_snode, uint32_t *cookiep,
- uint64_t *verifierp, int32_t *dircountp, char *arg, char *pattern,
- uint32_t flags, struct smb_request *sr, cred_t *cr,
- caller_context_t *ct);
-extern int smb_vop_statfs(vnode_t *vp, struct statvfs64 *statp, cred_t *cr);
-extern int smb_vop_stream_lookup(vnode_t *fvp, char *stream_name,
- vnode_t **vpp, char *name, vnode_t **xattrdirvpp, int flags,
- vnode_t *rootvp, cred_t *cr, caller_context_t *ct);
-extern int smb_vop_stream_create(vnode_t *fvp, char *stream_name,
- smb_attr_t *attr, vnode_t **vpp, vnode_t **xattrdirvpp, int flags,
- cred_t *cr, caller_context_t *ct);
-extern int smb_vop_stream_remove(vnode_t *vp, char *stream_name, int flags,
- cred_t *cr, caller_context_t *ct);
-extern int smb_vop_stream_readdir(vnode_t *fvp, uint32_t *cookiep,
- struct fs_stream_info *stream_info, vnode_t **vpp, vnode_t **xattrdirvp,
- int flags, cred_t *cr, caller_context_t *ct);
-extern int smb_vop_lookup_xattrdir(vnode_t *fvp, vnode_t **xattrdirvpp,
- int flags, cred_t *cr, caller_context_t *ct);
-extern int smb_vop_traverse_check(vnode_t **vpp);
-
-int smb_vop_acl_read(vnode_t *vp, acl_t **aclp, int flags, acl_type_t acl_type,
- cred_t *cr, caller_context_t *ct);
-int smb_vop_acl_write(vnode_t *vp, acl_t *aclp, int flags, cred_t *cr,
- caller_context_t *ct);
-acl_type_t smb_vop_acl_type(vnode_t *vp);
+extern void smb_vop_start(void);
+extern int smb_vop_open(vnode_t **, int, cred_t *);
+extern int smb_vop_close(vnode_t *, int, cred_t *);
+extern int smb_vop_read(vnode_t *, uio_t *, cred_t *);
+extern int smb_vop_write(vnode_t *, uio_t *, unsigned int *,
+ uint32_t *, cred_t *);
+extern int smb_vop_getattr(vnode_t *, vnode_t *,
+ smb_attr_t *, int, cred_t *);
+extern int smb_vop_setattr(vnode_t *, vnode_t *,
+ smb_attr_t *, int, cred_t *, boolean_t);
+extern int smb_vop_access(vnode_t *, int, int, vnode_t *,
+ cred_t *);
+extern void smb_vop_eaccess(vnode_t *, int *, int, vnode_t *,
+ cred_t *);
+extern int smb_vop_lookup(vnode_t *, char *, vnode_t **,
+ char *, int, vnode_t *, cred_t *);
+extern int smb_vop_create(vnode_t *, char *, smb_attr_t *,
+ vnode_t **, int, cred_t *, vsecattr_t *);
+extern int smb_vop_remove(vnode_t *, char *, int, cred_t *);
+extern int smb_vop_rename(vnode_t *, char *, vnode_t *,
+ char *, int, cred_t *);
+extern int smb_vop_mkdir(vnode_t *, char *, smb_attr_t *,
+ vnode_t **, int, cred_t *, vsecattr_t *);
+extern int smb_vop_rmdir(vnode_t *, char *, int, cred_t *);
+extern int smb_vop_readdir(vnode_t *, uint32_t *, char *,
+ int *, ino64_t *, vnode_t **, char *, int, cred_t *);
+extern int smb_vop_commit(vnode_t *, cred_t *);
+extern int smb_vop_getdents(struct smb_node *, uint32_t *,
+ uint64_t *, int32_t *, char *, char *,
+ uint32_t, struct smb_request *, cred_t *);
+extern int smb_vop_statfs(vnode_t *, struct statvfs64 *, cred_t *);
+extern int smb_vop_stream_lookup(vnode_t *, char *,
+ vnode_t **, char *, vnode_t **, int, vnode_t *, cred_t *);
+extern int smb_vop_stream_create(vnode_t *, char *,
+ smb_attr_t *, vnode_t **, vnode_t **, int, cred_t *);
+extern int smb_vop_stream_remove(vnode_t *, char *, int, cred_t *);
+extern int smb_vop_stream_readdir(vnode_t *, uint32_t *,
+ struct fs_stream_info *, vnode_t **, vnode_t **, int, cred_t *);
+extern int smb_vop_lookup_xattrdir(vnode_t *, vnode_t **, int, cred_t *);
+extern int smb_vop_traverse_check(vnode_t **);
+
+int smb_vop_acl_read(vnode_t *, acl_t **, int, acl_type_t, cred_t *);
+int smb_vop_acl_write(vnode_t *, acl_t *, int, cred_t *);
+acl_type_t smb_vop_acl_type(vnode_t *);
+
+int smb_vop_shrlock(vnode_t *, uint32_t, uint32_t, uint32_t, cred_t *);
+int smb_vop_unshrlock(vnode_t *, uint32_t, cred_t *);
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/smbsrv/smbinfo.h b/usr/src/uts/common/smbsrv/smbinfo.h
index 2426b54b61..01404f3a55 100644
--- a/usr/src/uts/common/smbsrv/smbinfo.h
+++ b/usr/src/uts/common/smbsrv/smbinfo.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -127,18 +127,17 @@ typedef struct smb_kmod_cfg {
uint32_t skc_maxworkers;
uint32_t skc_maxconnections;
uint32_t skc_keepalive;
- uint32_t skc_restrict_anon;
- uint32_t skc_signing_enable;
- uint32_t skc_signing_required;
- uint32_t skc_signing_check;
- uint32_t skc_oplock_enable;
uint32_t skc_oplock_timeout;
- uint32_t skc_flush_required;
- uint32_t skc_sync_enable;
- uint32_t skc_dirsymlink_enable;
- uint32_t skc_announce_quota;
- uint32_t skc_secmode;
- uint32_t skc_lmlevel;
+ int32_t skc_restrict_anon;
+ int32_t skc_signing_enable;
+ int32_t skc_signing_required;
+ int32_t skc_signing_check;
+ int32_t skc_oplock_enable;
+ int32_t skc_flush_required;
+ int32_t skc_sync_enable;
+ int32_t skc_dirsymlink_enable;
+ int32_t skc_announce_quota;
+ int32_t skc_secmode;
char skc_resource_domain[SMB_PI_MAX_DOMAIN];
char skc_hostname[SMB_PI_MAX_HOST];
@@ -173,7 +172,6 @@ int smbnative_pdc_value(char *native_lm);
#define SMBD_DOOR_PARAM_GET 2
#define SMBD_DOOR_PARAM_SET 3
#define SMBD_DOOR_NETBIOS_RECONFIG 4
-#define SMBD_DOOR_ADS_DOMAIN_CHANGED 5
#ifdef __cplusplus
}
diff --git a/usr/src/uts/common/smbsrv/smbvar.h b/usr/src/uts/common/smbsrv/smbvar.h
index edcfbe7187..f4e11582a0 100644
--- a/usr/src/uts/common/smbsrv/smbvar.h
+++ b/usr/src/uts/common/smbsrv/smbvar.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -389,6 +389,7 @@ typedef enum {
typedef struct smb_node {
uint32_t n_magic;
smb_rwx_t n_lock;
+ krwlock_t n_share_lock;
list_node_t n_lnd;
smb_node_state_t n_state;
uint32_t n_refcnt;
@@ -835,6 +836,7 @@ typedef struct smb_ofile {
mlsvc_pipe_t *f_pipe_info;
+ uint32_t f_uniqid;
uint32_t f_refcnt;
uint64_t f_seek_pos;
uint32_t f_flags;
@@ -1198,11 +1200,8 @@ struct smb_request {
label_t exjb;
cred_t *user_cr;
- caller_context_t ct;
};
-caller_context_t local_ct;
-
#define SMB_READ_PROTOCOL(smb_nh_ptr) \
LE_IN32(((smb_nethdr_t *)(smb_nh_ptr))->sh_protocol)
@@ -1317,6 +1316,7 @@ typedef struct smb_info {
volatile uint64_t si_global_kid;
volatile uint32_t si_gmtoff;
+ volatile uint32_t si_uniq_fid;
smb_thread_t si_nbt_daemon;
smb_thread_t si_tcp_daemon;
@@ -1354,11 +1354,13 @@ typedef struct smb_info {
#define SMB_INFO_ENCRYPT_PASSWORDS 0x80000000
#define SMB_NEW_KID() atomic_inc_64_nv(&smb_info.si_global_kid)
+#define SMB_UNIQ_FID() atomic_inc_32_nv(&smb_info.si_uniq_fid)
typedef struct {
+ uint32_t severity;
+ uint32_t status;
uint16_t errcls;
uint16_t errcode;
- DWORD status;
} smb_error_t;
/*