summaryrefslogtreecommitdiff
path: root/source/smbd/open.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd/open.c')
-rw-r--r--source/smbd/open.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 31679b539d..c89a5f6178 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -59,6 +59,15 @@ static NTSTATUS check_open_rights(struct connection_struct *conn,
*access_granted = 0;
+ if (conn->server_info->utok.uid == 0 || conn->admin_user) {
+ /* I'm sorry sir, I didn't know you were root... */
+ *access_granted = access_mask;
+ if (access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
+ *access_granted |= FILE_GENERIC_ALL;
+ }
+ return NT_STATUS_OK;
+ }
+
status = SMB_VFS_GET_NT_ACL(conn, fname,
(OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
@@ -2382,6 +2391,14 @@ NTSTATUS open_directory(connection_struct *conn,
return status;
}
+ /* We need to support SeSecurityPrivilege for this. */
+ if (access_mask & SEC_RIGHT_SYSTEM_SECURITY) {
+ DEBUG(10, ("open_directory: open on %s "
+ "failed - SEC_RIGHT_SYSTEM_SECURITY denied.\n",
+ fname));
+ return NT_STATUS_PRIVILEGE_NOT_HELD;
+ }
+
switch( create_disposition ) {
case FILE_OPEN:
@@ -2462,6 +2479,25 @@ NTSTATUS open_directory(connection_struct *conn,
fname,
access_mask,
&access_granted);
+
+ /* Were we trying to do a directory open
+ * for delete and didn't get DELETE
+ * access (only) ? Check if the
+ * directory allows DELETE_CHILD.
+ * See here:
+ * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
+ * for details. */
+
+ if ((NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) &&
+ (access_mask & DELETE_ACCESS) &&
+ (access_granted == DELETE_ACCESS) &&
+ can_delete_file_in_directory(conn, fname))) {
+ DEBUG(10,("open_directory: overrode ACCESS_DENIED "
+ "on directory %s\n",
+ fname ));
+ status = NT_STATUS_OK;
+ }
+
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("open_directory: check_open_rights on "
"file %s failed with %s\n",
@@ -2896,6 +2932,20 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
status = NT_STATUS_PRIVILEGE_NOT_HELD;
goto fail;
}
+#else
+ /* We need to support SeSecurityPrivilege for this. */
+ if (access_mask & SEC_RIGHT_SYSTEM_SECURITY) {
+ status = NT_STATUS_PRIVILEGE_NOT_HELD;
+ goto fail;
+ }
+ /* Don't allow a SACL set from an NTtrans create until we
+ * support SeSecurityPrivilege. */
+ if (!VALID_STAT(sbuf) &&
+ lp_nt_acl_support(SNUM(conn)) &&
+ sd && (sd->sacl != NULL)) {
+ status = NT_STATUS_PRIVILEGE_NOT_HELD;
+ goto fail;
+ }
#endif
if ((conn->fs_capabilities & FILE_NAMED_STREAMS)