From 2c1b3a072061d40f112c3f1112fd9ae08b6038e4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 2 Jan 2007 12:10:46 +0000 Subject: r20470: Jeremy, another one to check: The only error path of can_delete() that we're interested in ntcreate&x is the one of can_delete_file_in_directory(), so call that directly. The only other one where we might get a NT_STATUS_ACCESS_DENIED is from the lstat in can_delete, but this is covered later in the open_directory and open_file_ntcreate calls. open_directory does a stat() in the open case which also covers the (potential) symlink, and open_file_ntcreate does the open(2) itself, so this should also work. This makes can_delete() static to reply.c. Volker (This used to be commit d289037fdbc8bd3e0723784888946d5b39ffadef) --- source3/smbd/nttrans.c | 39 +++++++++++++++++---------------------- source3/smbd/reply.c | 4 +++- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 5c96669987..faa3e25bae 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -647,21 +647,18 @@ int reply_ntcreate_and_X(connection_struct *conn, expensive (it may have to read the parent directory permissions). So for now we're not doing it unless we have a strong hint the client is really going to delete this file. */ - if (desired_access & DELETE_ACCESS) { + if ((desired_access & DELETE_ACCESS) + && !can_delete_file_in_directory(conn, fname)) { #else /* Setting FILE_SHARE_DELETE is the hint. */ - if (lp_acl_check_permissions(SNUM(conn)) && (share_access & FILE_SHARE_DELETE) - && (access_mask & DELETE_ACCESS)) { + if (lp_acl_check_permissions(SNUM(conn)) + && (share_access & FILE_SHARE_DELETE) + && (access_mask & DELETE_ACCESS) + && !can_delete_file_in_directory(conn, fname)) { #endif - status = can_delete(conn, fname, file_attributes, bad_path, True); - /* We're only going to fail here if it's access denied, as that's the - only error we care about for "can we delete this ?" questions. */ - if (NT_STATUS_EQUAL(status,NT_STATUS_ACCESS_DENIED) || - NT_STATUS_EQUAL(status,NT_STATUS_CANNOT_DELETE)) { - restore_case_semantics(conn, file_attributes); - END_PROFILE(SMBntcreateX); - return ERROR_NT(NT_STATUS_ACCESS_DENIED); - } + restore_case_semantics(conn, file_attributes); + END_PROFILE(SMBntcreateX); + return ERROR_NT(NT_STATUS_ACCESS_DENIED); } /* @@ -1276,19 +1273,17 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o expensive (it may have to read the parent directory permissions). So for now we're not doing it unless we have a strong hint the client is really going to delete this file. */ - if (desired_access & DELETE_ACCESS) { + if ((desired_access & DELETE_ACCESS) + && !can_delete_file_in_directory(conn, fname)) { #else /* Setting FILE_SHARE_DELETE is the hint. */ - if (lp_acl_check_permissions(SNUM(conn)) && (share_access & FILE_SHARE_DELETE) && (access_mask & DELETE_ACCESS)) { + if (lp_acl_check_permissions(SNUM(conn)) + && (share_access & FILE_SHARE_DELETE) + && (access_mask & DELETE_ACCESS) + && !can_delete_file_in_directory(conn, fname)) { #endif - status = can_delete(conn, fname, file_attributes, bad_path, True); - /* We're only going to fail here if it's access denied, as that's the - only error we care about for "can we delete this ?" questions. */ - if (NT_STATUS_EQUAL(status,NT_STATUS_ACCESS_DENIED) || - NT_STATUS_EQUAL(status,NT_STATUS_CANNOT_DELETE)) { - restore_case_semantics(conn, file_attributes); - return ERROR_NT(status); - } + restore_case_semantics(conn, file_attributes); + return ERROR_NT(NT_STATUS_ACCESS_DENIED); } if (ea_len) { diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index e29ecab8ba..607c12f8b1 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1888,7 +1888,9 @@ static NTSTATUS can_rename(connection_struct *conn, char *fname, uint16 dirtype, Check if a user is allowed to delete a file. ********************************************************************/ -NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL bad_path, BOOL check_is_at_open) +static NTSTATUS can_delete(connection_struct *conn, char *fname, + uint32 dirtype, BOOL bad_path, + BOOL check_is_at_open) { SMB_STRUCT_STAT sbuf; uint32 fattr; -- cgit