nt-quotas: vfs_get_ntquota() return NTSTATUS
[kai/samba-autobuild/.git] / source3 / smbd / trans2.c
index eb9966096ad8a9c901fb6618cfccc165eaa8ba31..0e1c6d9eb84230c9dfb490b5bd32101ff2d4f606 100644 (file)
@@ -60,7 +60,7 @@ static char *store_file_unix_basic_info2(connection_struct *conn,
 
 static NTSTATUS refuse_symlink(connection_struct *conn,
                        const files_struct *fsp,
-                       const char *name)
+                       const struct smb_filename *smb_fname)
 {
        SMB_STRUCT_STAT sbuf;
        const SMB_STRUCT_STAT *pst = NULL;
@@ -69,7 +69,7 @@ static NTSTATUS refuse_symlink(connection_struct *conn,
                pst = &fsp->fsp_name->st;
        } else {
                int ret = vfs_stat_smb_basename(conn,
-                               name,
+                               smb_fname,
                                &sbuf);
                if (ret == -1) {
                        return map_nt_error_from_unix(errno);
@@ -230,9 +230,12 @@ NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
        return NT_STATUS_OK;
 }
 
-NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
-                               files_struct *fsp, const char *fname,
-                               char ***pnames, size_t *pnum_names)
+NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx,
+                               connection_struct *conn,
+                               files_struct *fsp,
+                               const struct smb_filename *smb_fname,
+                               char ***pnames,
+                               size_t *pnum_names)
 {
        /* Get a list of all xattrs. Max namesize is 64k. */
        size_t ea_namelist_size = 1024;
@@ -253,7 +256,7 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
                return NT_STATUS_OK;
        }
 
-       status = refuse_symlink(conn, fsp, fname);
+       status = refuse_symlink(conn, fsp, smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                /*
                 * Just return no EA's on a symlink.
@@ -285,8 +288,10 @@ NTSTATUS get_ea_names_from_file(TALLOC_CTX *mem_ctx, connection_struct *conn,
                        sizeret = SMB_VFS_FLISTXATTR(fsp, ea_namelist,
                                                     ea_namelist_size);
                } else {
-                       sizeret = SMB_VFS_LISTXATTR(conn, fname, ea_namelist,
-                                                   ea_namelist_size);
+                       sizeret = SMB_VFS_LISTXATTR(conn,
+                                       smb_fname->base_name,
+                                       ea_namelist,
+                                       ea_namelist_size);
                }
 
                if ((sizeret == -1) && (errno == ERANGE)) {
@@ -366,15 +371,23 @@ static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx,
        size_t i, num_names;
        char **names;
        struct ea_list *ea_list_head = NULL;
+       bool posix_pathnames = false;
        NTSTATUS status;
 
        *pea_total_len = 0;
        *ea_list = NULL;
 
+       if (fsp) {
+               posix_pathnames =
+                       (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
+       } else {
+               posix_pathnames = (smb_fname->flags & SMB_FILENAME_POSIX_PATH);
+       }
+
        status = get_ea_names_from_file(talloc_tos(),
                                conn,
                                fsp,
-                               smb_fname->base_name,
+                               smb_fname,
                                &names,
                                &num_names);
 
@@ -399,7 +412,7 @@ static NTSTATUS get_ea_list_from_file_path(TALLOC_CTX *mem_ctx,
                 * Filter out any underlying POSIX EA names
                 * that a Windows client can't handle.
                 */
-               if (!lp_posix_pathnames() &&
+               if (!posix_pathnames &&
                                is_invalid_windows_ea_name(names[i])) {
                        continue;
                }
@@ -687,12 +700,20 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
                const struct smb_filename *smb_fname, struct ea_list *ea_list)
 {
        NTSTATUS status;
+       bool posix_pathnames = false;
 
        if (!lp_ea_support(SNUM(conn))) {
                return NT_STATUS_EAS_NOT_SUPPORTED;
        }
 
-       status = refuse_symlink(conn, fsp, smb_fname->base_name);
+       if (fsp) {
+               posix_pathnames =
+                       (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH);
+       } else {
+               posix_pathnames = (smb_fname->flags & SMB_FILENAME_POSIX_PATH);
+       }
+
+       status = refuse_symlink(conn, fsp, smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -712,7 +733,7 @@ NTSTATUS set_ea(connection_struct *conn, files_struct *fsp,
         * we set *any* of them.
         */
 
-       if (ea_list_has_invalid_name(ea_list)) {
+       if (!posix_pathnames && ea_list_has_invalid_name(ea_list)) {
                return STATUS_INVALID_EA_NAME;
        }
 
@@ -1292,7 +1313,8 @@ static void call_trans2open(connection_struct *conn,
                        goto out;
                }
 
-               if (ea_list_has_invalid_name(ea_list)) {
+               if (!req->posix_pathnames &&
+                               ea_list_has_invalid_name(ea_list)) {
                        int param_len = 30;
                        *pparams = (char *)SMB_REALLOC(*pparams, param_len);
                        if(*pparams == NULL ) {
@@ -3690,9 +3712,11 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                                return NT_STATUS_ACCESS_DENIED;
                        }
 
-                       if (vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE, NULL, &quotas)!=0) {
+                       status = vfs_get_ntquota(&fsp, SMB_USER_FS_QUOTA_TYPE,
+                                                NULL, &quotas);
+                       if (!NT_STATUS_IS_OK(status)) {
                                DEBUG(0,("vfs_get_ntquota() failed for service [%s]\n",lp_servicename(talloc_tos(), SNUM(conn))));
-                               return map_nt_error_from_unix(errno);
+                               return status;
                        }
 
                        data_len = 48;
@@ -5394,7 +5418,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
 
                                status = refuse_symlink(conn,
                                                fsp,
-                                               smb_fname->base_name);
+                                               smb_fname);
                                if (!NT_STATUS_IS_OK(status)) {
                                        return status;
                                }
@@ -5758,8 +5782,11 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
 
                        /* Create an smb_filename with stream_name == NULL. */
                        smb_fname_base = synthetic_smb_fname(
-                               talloc_tos(), smb_fname->base_name,
-                               NULL, NULL);
+                                               talloc_tos(),
+                                               smb_fname->base_name,
+                                               NULL,
+                                               NULL,
+                                               smb_fname->flags);
                        if (smb_fname_base == NULL) {
                                reply_nterror(req, NT_STATUS_NO_MEMORY);
                                return;
@@ -6157,8 +6184,11 @@ static NTSTATUS smb_set_file_dosmode(connection_struct *conn,
        }
 
        /* Always operate on the base_name, even if a stream was passed in. */
-       smb_fname_base = synthetic_smb_fname(
-               talloc_tos(), smb_fname->base_name, NULL, &smb_fname->st);
+       smb_fname_base = synthetic_smb_fname(talloc_tos(),
+                                       smb_fname->base_name,
+                                       NULL,
+                                       &smb_fname->st,
+                                       smb_fname->flags);
        if (smb_fname_base == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -6660,9 +6690,11 @@ static NTSTATUS smb2_file_rename_information(connection_struct *conn,
                }
 
                /* Create an smb_fname to call rename_internals_fsp() with. */
-               smb_fname_dst = synthetic_smb_fname(
-                       talloc_tos(), fsp->base_fsp->fsp_name->base_name,
-                       newname, NULL);
+               smb_fname_dst = synthetic_smb_fname(talloc_tos(),
+                                       fsp->base_fsp->fsp_name->base_name,
+                                       newname,
+                                       NULL,
+                                       fsp->base_fsp->fsp_name->flags);
                if (smb_fname_dst == NULL) {
                        status = NT_STATUS_NO_MEMORY;
                        goto out;
@@ -6846,7 +6878,7 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
        status = resolve_dfspath_wcard(ctx, conn,
                                       req->flags2 & FLAGS2_DFS_PATHNAMES,
                                       newname,
-                                      true,
+                                      UCF_COND_ALLOW_WCARD_LCOMP,
                                       !conn->sconn->using_smb2,
                                       &newname,
                                       &dest_has_wcard);
@@ -6866,9 +6898,11 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
                }
 
                /* Create an smb_fname to call rename_internals_fsp() with. */
-               smb_fname_dst = synthetic_smb_fname(
-                       talloc_tos(), fsp->base_fsp->fsp_name->base_name,
-                       newname, NULL);
+               smb_fname_dst = synthetic_smb_fname(talloc_tos(),
+                                       fsp->base_fsp->fsp_name->base_name,
+                                       newname,
+                                       NULL,
+                                       fsp->base_fsp->fsp_name->flags);
                if (smb_fname_dst == NULL) {
                        status = NT_STATUS_NO_MEMORY;
                        goto out;
@@ -6938,8 +6972,11 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
                                goto out;
                        }
                        /* Create an smb_fname to call rename_internals_fsp() */
-                       smb_fname_dst = synthetic_smb_fname(
-                               ctx, base_name, NULL, NULL);
+                       smb_fname_dst = synthetic_smb_fname(ctx,
+                                               base_name,
+                                               NULL,
+                                               NULL,
+                                               smb_fname_src->flags);
                        if (smb_fname_dst == NULL) {
                                status = NT_STATUS_NO_MEMORY;
                                goto out;
@@ -7013,7 +7050,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       status = refuse_symlink(conn, fsp, smb_fname->base_name);
+       status = refuse_symlink(conn, fsp, smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }