+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;
+}
+