#include "../libcli/auth/libcli_auth.h"
#include "../librpc/gen_ndr/xattr.h"
#include "../librpc/gen_ndr/ndr_security.h"
-#include "../librpc/gen_ndr/open_files.h"
#include "libcli/security/security.h"
#include "trans2.h"
#include "auth.h"
#include "printing.h"
#include "lib/util_ea.h"
#include "lib/readdir_attr.h"
+#include "messages.h"
#define DIR_ENTRY_SAFETY_MARGIN 4096
static bool smbd_dirptr_lanman2_mode_fn(TALLOC_CTX *ctx,
void *private_data,
struct smb_filename *smb_fname,
+ bool get_dosmode,
uint32_t *_mode)
{
struct smbd_dirptr_lanman2_state *state =
if (ms_dfs_link) {
mode = dos_mode_msdfs(state->conn, smb_fname);
- } else {
+ } else if (get_dosmode) {
mode = dos_mode(state->conn, smb_fname);
}
int requires_resume_key,
bool dont_descend,
bool ask_sharemode,
+ bool get_dosmode,
uint8_t align,
bool do_pad,
char **ppdata,
char *base_data,
char *end_data,
int space_remaining,
+ struct smb_filename **_smb_fname,
bool *got_exact_match,
int *_last_entry_off,
struct ea_list *name_list,
dirtype,
dont_descend,
ask_sharemode,
+ get_dosmode,
smbd_dirptr_lanman2_match_fn,
smbd_dirptr_lanman2_mode_fn,
&state,
*file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
}
- TALLOC_FREE(fname);
+ if (!NT_STATUS_IS_OK(status) &&
+ !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
+ {
+ TALLOC_FREE(smb_fname);
+ TALLOC_FREE(fname);
+ return status;
+ }
+
+ if (_smb_fname != NULL) {
+ struct smb_filename *name = NULL;
+
+ name = synthetic_smb_fname(ctx, fname, NULL, &smb_fname->st, 0);
+ if (name == NULL) {
+ TALLOC_FREE(smb_fname);
+ TALLOC_FREE(fname);
+ return NT_STATUS_NO_MEMORY;
+ }
+ *_smb_fname = name;
+ }
+
TALLOC_FREE(smb_fname);
+ TALLOC_FREE(fname);
+
if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
dptr_SeekDir(dirptr, prev_dirpos);
return status;
}
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
*_last_entry_off = last_entry_off;
return NT_STATUS_OK;
return smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
path_mask, dirtype, info_level,
requires_resume_key, dont_descend, ask_sharemode,
- align, do_pad,
+ true, align, do_pad,
ppdata, base_data, end_data,
space_remaining,
+ NULL,
got_exact_match,
last_entry_off, name_list, NULL);
}
ZERO_STRUCT(smb_fname);
smb_fname.base_name = discard_const_p(char, filename);
- if(SMB_VFS_STAT(conn, &smb_fname) != 0) {
+ if(info_level != SMB_FS_QUOTA_INFORMATION
+ && SMB_VFS_STAT(conn, &smb_fname) != 0) {
DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
return map_nt_error_from_unix(errno);
}
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
- DEBUG(6,("smb_set_file_size: size: %.0f ", (double)size));
+ DBG_INFO("size: %"PRIu64", file_size_stat=%"PRIu64"\n",
+ (uint64_t)size,
+ get_file_size_stat(psbuf));
if (size == get_file_size_stat(psbuf)) {
return NT_STATUS_OK;
int total_data,
struct smb_filename *smb_fname)
{
+ struct server_id self = messaging_server_id(conn->sconn->msg_ctx);
NTSTATUS status = NT_STATUS_OK;
files_struct *fsp = NULL;
uint16_t flags = 0;
char del = 1;
int info = 0;
int create_options = 0;
- int i;
struct share_mode_lock *lck = NULL;
+ bool other_nonposix_opens;
if (total_data < 2) {
return NT_STATUS_INVALID_PARAMETER;
return NT_STATUS_INVALID_PARAMETER;
}
- /*
- * See if others still have the file open. If this is the case, then
- * don't delete. If all opens are POSIX delete we can set the delete
- * on close disposition.
- */
- for (i=0; i<lck->data->num_share_modes; i++) {
- struct share_mode_entry *e = &lck->data->share_modes[i];
- if (is_valid_share_mode_entry(e)) {
- if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
- continue;
- }
- if (share_mode_stale_pid(lck->data, i)) {
- continue;
- }
- /* Fail with sharing violation. */
- TALLOC_FREE(lck);
- close_file(req, fsp, NORMAL_CLOSE);
- return NT_STATUS_SHARING_VIOLATION;
- }
+ other_nonposix_opens = has_other_nonposix_opens(lck, fsp, self);
+ if (other_nonposix_opens) {
+ /* Fail with sharing violation. */
+ TALLOC_FREE(lck);
+ close_file(req, fsp, NORMAL_CLOSE);
+ return NT_STATUS_SHARING_VIOLATION;
}
/*