Refactor to create check_parent_access() which can be called for file creation too.
authorJeremy Allison <jra@samba.org>
Thu, 20 Oct 2011 17:01:12 +0000 (10:01 -0700)
committerJeremy Allison <jra@samba.org>
Thu, 20 Oct 2011 18:29:22 +0000 (20:29 +0200)
Autobuild-User: Jeremy Allison <jra@samba.org>
Autobuild-Date: Thu Oct 20 20:29:22 CEST 2011 on sn-devel-104

source3/smbd/open.c

index a03e41da3e470ed4ba29b8f1423d976bd89b0aa3..1e21799868e5a61f9d0d53225d68329ee78694f1 100644 (file)
@@ -134,6 +134,63 @@ NTSTATUS smbd_check_open_rights(struct connection_struct *conn,
        return status;
 }
 
+static NTSTATUS check_parent_access(struct connection_struct *conn,
+                               struct smb_filename *smb_fname,
+                               uint32_t access_mask,
+                               char **pp_parent_dir,
+                               struct security_descriptor **pp_parent_sd)
+{
+       NTSTATUS status;
+       char *parent_dir = NULL;
+       struct security_descriptor *parent_sd = NULL;
+       uint32_t access_granted = 0;
+
+       if (!parent_dirname(talloc_tos(),
+                               smb_fname->base_name,
+                               &parent_dir,
+                               NULL)) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       status = SMB_VFS_GET_NT_ACL(conn,
+                               parent_dir,
+                               SECINFO_DACL,
+                               &parent_sd);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(5,("check_parent_access: SMB_VFS_GET_NT_ACL failed for "
+                       "%s with error %s\n",
+                       parent_dir,
+                       nt_errstr(status)));
+               return status;
+       }
+
+       status = smb1_file_se_access_check(conn,
+                                       parent_sd,
+                                       get_current_nttok(conn),
+                                       access_mask,
+                                       &access_granted);
+       if(!NT_STATUS_IS_OK(status)) {
+               DEBUG(5,("check_parent_access: access check "
+                       "on directory %s for "
+                       "path %s for mask 0x%x returned (0x%x) %s\n",
+                       parent_dir,
+                       smb_fname->base_name,
+                       access_mask,
+                       access_granted,
+                       nt_errstr(status) ));
+               return status;
+       }
+
+       if (pp_parent_dir) {
+               *pp_parent_dir = parent_dir;
+       }
+       if (pp_parent_sd) {
+               *pp_parent_sd = parent_sd;
+       }
+       return NT_STATUS_OK;
+}
+
 /****************************************************************************
  fd support routines - attempt to do a dos_open.
 ****************************************************************************/
@@ -2437,13 +2494,11 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
                               uint32 file_attributes)
 {
        mode_t mode;
-       char *parent_dir;
+       char *parent_dir = NULL;
        NTSTATUS status;
        bool posix_open = false;
        bool need_re_stat = false;
-       struct security_descriptor *parent_sd = NULL;
        uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
-       uint32_t access_granted = 0;
 
        if(access_mask & ~(conn->share_access)) {
                DEBUG(5,("mkdir_internal: failing share access "
@@ -2468,30 +2523,16 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
                mode = unix_mode(conn, FILE_ATTRIBUTE_DIRECTORY, smb_dname, parent_dir);
        }
 
-       status = SMB_VFS_GET_NT_ACL(conn,
-                               parent_dir,
-                               SECINFO_DACL,
-                               &parent_sd);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(5,("mkdir_internal: SMB_VFS_GET_NT_ACL failed for "
-                       "%s with error %s\n",
-                       parent_dir,
-                       nt_errstr(status)));
-               return status;
-       }
-
-       status = smb1_file_se_access_check(conn,
-                                       parent_sd,
-                                       get_current_nttok(conn),
+       status = check_parent_access(conn,
+                                       smb_dname,
                                        access_mask,
-                                       &access_granted);
+                                       &parent_dir,
+                                       NULL);
        if(!NT_STATUS_IS_OK(status)) {
-               DEBUG(5,("mkdir_internal: access check "
-                       "on directory %s for "
-                       "path %s for mask 0x%x returned %s\n",
+               DEBUG(5,("mkdir_internal: check_parent_access "
+                       "on directory %s for path %s returned %s\n",
                        parent_dir,
                        smb_dname->base_name,
-                       access_mask,
                        nt_errstr(status) ));
                return status;
        }