From 9b30c5c1457a42a92a61086f8127caf6c60fc076 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 16 Jun 2009 17:23:54 -0700 Subject: Fix msdfs after the change to smb_filename struct. We must *always* pull the pathname, then call resolve_dfspath(), before unix_convert(). Jeremy. --- source3/rpc_server/srv_srvsvc_nt.c | 25 +++++++++++- source3/smbd/nttrans.c | 42 ++++++++++++++++++-- source3/smbd/reply.c | 79 ++++++++++++++++++++++++++++++-------- source3/smbd/smb2_create.c | 15 +++++++- source3/smbd/trans2.c | 29 +++++++++++--- 5 files changed, 161 insertions(+), 29 deletions(-) diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 7887f81ba3..1b07fc213e 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -2042,6 +2042,7 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, connection_struct *conn = NULL; struct sec_desc_buf *sd_buf = NULL; files_struct *fsp = NULL; + char *fname = NULL; int snum; char *oldcwd = NULL; @@ -2066,7 +2067,17 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p, goto error_exit; } - nt_status = unix_convert(talloc_tos(), conn, r->in.file, &smb_fname, + nt_status = resolve_dfspath(talloc_tos(), + conn, + false, + r->in.file, + &fname); + if (!NT_STATUS_IS_OK(nt_status)) { + werr = ntstatus_to_werror(nt_status); + goto error_exit; + } + + nt_status = unix_convert(talloc_tos(), conn, fname, &smb_fname, 0); if (!NT_STATUS_IS_OK(nt_status)) { werr = ntstatus_to_werror(nt_status); @@ -2169,6 +2180,7 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, char *oldcwd = NULL; struct security_descriptor *psd = NULL; uint32_t security_info_sent = 0; + char *fname = NULL; ZERO_STRUCT(st); @@ -2191,7 +2203,16 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, goto error_exit; } - nt_status = unix_convert(talloc_tos(), conn, r->in.file, &smb_fname, + nt_status = resolve_dfspath(talloc_tos(), + conn, + false, + r->in.file, + &fname); + if (!NT_STATUS_IS_OK(nt_status)) { + werr = ntstatus_to_werror(nt_status); + goto error_exit; + } + nt_status = unix_convert(talloc_tos(), conn, fname, &smb_fname, 0); if (!NT_STATUS_IS_OK(nt_status)) { werr = ntstatus_to_werror(nt_status); diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 7d0324bcda..a8716d36a3 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -507,6 +507,23 @@ void reply_ntcreate_and_X(struct smb_request *req) ? BATCH_OPLOCK : 0; } + status = resolve_dfspath(ctx, + conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + fname, + &fname); + + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + goto out; + } + reply_nterror(req, status); + goto out; + } + status = unix_convert(ctx, conn, fname, &smb_fname, 0); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -976,10 +993,21 @@ static void call_nt_transact_create(connection_struct *conn, goto out; } - oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; - if (oplock_request) { - oplock_request |= (flags & REQUEST_BATCH_OPLOCK) - ? BATCH_OPLOCK : 0; + status = resolve_dfspath(ctx, + conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + fname, + &fname); + + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + goto out; + } + reply_nterror(req, status); + goto out; } status = unix_convert(ctx, conn, fname, &smb_fname, 0); @@ -988,6 +1016,12 @@ static void call_nt_transact_create(connection_struct *conn, goto out; } + oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0; + if (oplock_request) { + oplock_request |= (flags & REQUEST_BATCH_OPLOCK) + ? BATCH_OPLOCK : 0; + } + status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 9c78b9bde0..996cba208b 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1769,12 +1769,20 @@ void reply_open(struct smb_request *req) goto out; } - if (!map_open_params_to_ntcreate( - fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask, - &share_mode, &create_disposition, &create_options)) { - reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess)); - END_PROFILE(SMBopen); - return; + status = resolve_dfspath(ctx, + conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + fname, + &fname); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + goto out; + } + reply_nterror(req, status); + goto out; } status = unix_convert(ctx, conn, fname, &smb_fname, 0); @@ -1783,6 +1791,13 @@ void reply_open(struct smb_request *req) goto out; } + if (!map_open_params_to_ntcreate( + fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask, + &share_mode, &create_disposition, &create_options)) { + reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess)); + goto out; + } + status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ @@ -1915,10 +1930,19 @@ void reply_open_and_X(struct smb_request *req) goto out; } - if (!map_open_params_to_ntcreate( - fname, deny_mode, smb_ofun, &access_mask, - &share_mode, &create_disposition, &create_options)) { - reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess)); + status = resolve_dfspath(ctx, + conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + fname, + &fname); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + goto out; + } + reply_nterror(req, status); goto out; } @@ -1928,6 +1952,13 @@ void reply_open_and_X(struct smb_request *req) goto out; } + if (!map_open_params_to_ntcreate( + fname, deny_mode, smb_ofun, &access_mask, + &share_mode, &create_disposition, &create_options)) { + reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess)); + goto out; + } + status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ @@ -2112,6 +2143,28 @@ void reply_mknew(struct smb_request *req) goto out; } + status = resolve_dfspath(ctx, + conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + fname, + &fname); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + goto out; + } + reply_nterror(req, status); + goto out; + } + + status = unix_convert(ctx, conn, fname, &smb_fname, 0); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + goto out; + } + if (fattr & aVOLID) { DEBUG(0,("Attempt to create file (%s) with volid set - " "please report this\n", fname)); @@ -2125,12 +2178,6 @@ void reply_mknew(struct smb_request *req) create_disposition = FILE_OVERWRITE_IF; } - status = unix_convert(ctx, conn, fname, &smb_fname, 0); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto out; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index ad14b354a9..81879f1725 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -309,13 +309,26 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx, } info = FILE_WAS_CREATED; } else { + char *fname = NULL; + /* these are ignored for SMB2 */ in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */ in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */ - status = unix_convert(talloc_tos(), smbreq->conn, in_name, + status = resolve_dfspath(talloc_tos(), + smbreq->conn, + smbreq->flags2 & FLAGS2_DFS_PATHNAMES, + in_name, + &fname); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + goto out; + } + + status = unix_convert(talloc_tos(), smbreq->conn, fname, &smb_fname, 0); if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); goto out; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 977ef4e809..f275b94772 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -941,6 +941,28 @@ static void call_trans2open(connection_struct *conn, fname, (unsigned int)deny_mode, (unsigned int)open_attr, (unsigned int)open_ofun, open_size)); + status = resolve_dfspath(ctx, + conn, + req->flags2 & FLAGS2_DFS_PATHNAMES, + fname, + &fname); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + goto out; + } + reply_nterror(req, status); + goto out; + } + + status = unix_convert(ctx, conn, fname, &smb_fname, 0); + if (!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + goto out; + } + if (open_ofun == 0) { reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION); goto out; @@ -985,12 +1007,6 @@ static void call_trans2open(connection_struct *conn, goto out; } - status = unix_convert(ctx, conn, fname, &smb_fname, 0); - if (!NT_STATUS_IS_OK(status)) { - reply_nterror(req, status); - goto out; - } - status = SMB_VFS_CREATE_FILE( conn, /* conn */ req, /* req */ @@ -3987,6 +4003,7 @@ static void call_trans2qfilepathinfo(connection_struct *conn, reply_botherror(req, NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath); + return; } reply_nterror(req, status); return; -- cgit