mirror of
https://github.com/samba-team/samba.git
synced 2025-01-15 23:24:37 +03:00
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-test
This commit is contained in:
commit
18c683d7e8
@ -542,6 +542,25 @@ static NTSTATUS odb_ctdb_rename(struct odb_lock *lck, const char *path)
|
||||
return odb_push_record(lck, &file);
|
||||
}
|
||||
|
||||
/*
|
||||
get the path of an open file
|
||||
*/
|
||||
static NTSTATUS odb_ctdb_get_path(struct odb_lock *lck, const char **path)
|
||||
{
|
||||
struct opendb_file file;
|
||||
NTSTATUS status;
|
||||
|
||||
*path = NULL;
|
||||
|
||||
status = odb_pull_record(lck, &file);
|
||||
/* we don't ignore NT_STATUS_OBJECT_NAME_NOT_FOUND here */
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
|
||||
*path = file.path;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
update delete on close flag on an open file
|
||||
*/
|
||||
@ -653,6 +672,7 @@ static const struct opendb_ops opendb_ctdb_ops = {
|
||||
.odb_close_file = odb_ctdb_close_file,
|
||||
.odb_remove_pending = odb_ctdb_remove_pending,
|
||||
.odb_rename = odb_ctdb_rename,
|
||||
.odb_get_path = odb_ctdb_get_path,
|
||||
.odb_set_delete_on_close = odb_ctdb_set_delete_on_close,
|
||||
.odb_get_delete_on_close = odb_ctdb_get_delete_on_close,
|
||||
.odb_can_open = odb_ctdb_can_open,
|
||||
|
@ -142,6 +142,14 @@ _PUBLIC_ NTSTATUS odb_rename(struct odb_lock *lck, const char *path)
|
||||
return ops->odb_rename(lck, path);
|
||||
}
|
||||
|
||||
/*
|
||||
get back the path of an open file
|
||||
*/
|
||||
_PUBLIC_ NTSTATUS odb_get_path(struct odb_lock *lck, const char **path)
|
||||
{
|
||||
return ops->odb_get_path(lck, path);
|
||||
}
|
||||
|
||||
/*
|
||||
update delete on close flag on an open file
|
||||
*/
|
||||
|
@ -36,6 +36,7 @@ struct opendb_ops {
|
||||
const char **delete_path);
|
||||
NTSTATUS (*odb_remove_pending)(struct odb_lock *lck, void *private);
|
||||
NTSTATUS (*odb_rename)(struct odb_lock *lck, const char *path);
|
||||
NTSTATUS (*odb_get_path)(struct odb_lock *lck, const char **path);
|
||||
NTSTATUS (*odb_set_delete_on_close)(struct odb_lock *lck, bool del_on_close);
|
||||
NTSTATUS (*odb_get_delete_on_close)(struct odb_context *odb,
|
||||
DATA_BLOB *key, bool *del_on_close);
|
||||
|
@ -713,6 +713,25 @@ static NTSTATUS odb_tdb_rename(struct odb_lock *lck, const char *path)
|
||||
return odb_push_record(lck, &file);
|
||||
}
|
||||
|
||||
/*
|
||||
get the path of an open file
|
||||
*/
|
||||
static NTSTATUS odb_tdb_get_path(struct odb_lock *lck, const char **path)
|
||||
{
|
||||
struct opendb_file file;
|
||||
NTSTATUS status;
|
||||
|
||||
*path = NULL;
|
||||
|
||||
status = odb_pull_record(lck, &file);
|
||||
/* we don't ignore NT_STATUS_OBJECT_NAME_NOT_FOUND here */
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
|
||||
*path = file.path;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
update delete on close flag on an open file
|
||||
*/
|
||||
@ -802,6 +821,7 @@ static const struct opendb_ops opendb_tdb_ops = {
|
||||
.odb_close_file = odb_tdb_close_file,
|
||||
.odb_remove_pending = odb_tdb_remove_pending,
|
||||
.odb_rename = odb_tdb_rename,
|
||||
.odb_get_path = odb_tdb_get_path,
|
||||
.odb_set_delete_on_close = odb_tdb_set_delete_on_close,
|
||||
.odb_get_delete_on_close = odb_tdb_get_delete_on_close,
|
||||
.odb_can_open = odb_tdb_can_open,
|
||||
|
@ -144,8 +144,8 @@ static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs,
|
||||
form the lock context used for opendb locking. Note that we must
|
||||
zero here to take account of possible padding on some architectures
|
||||
*/
|
||||
static NTSTATUS pvfs_locking_key(struct pvfs_filename *name,
|
||||
TALLOC_CTX *mem_ctx, DATA_BLOB *key)
|
||||
NTSTATUS pvfs_locking_key(struct pvfs_filename *name,
|
||||
TALLOC_CTX *mem_ctx, DATA_BLOB *key)
|
||||
{
|
||||
struct {
|
||||
dev_t device;
|
||||
|
@ -368,7 +368,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs,
|
||||
}
|
||||
|
||||
/* update the file information */
|
||||
status = pvfs_resolve_name_fd(pvfs, h->fd, h->name);
|
||||
status = pvfs_resolve_name_handle(pvfs, h);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
@ -265,8 +265,15 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
|
||||
of a name */
|
||||
return NT_STATUS_ILLEGAL_CHARACTER;
|
||||
}
|
||||
if (p > p_start && p[1] == 0) {
|
||||
*p = 0;
|
||||
if (p > p_start && (p[1] == '\\' || p[1] == '\0')) {
|
||||
/* see if it is definately a "\\" or
|
||||
* a trailing "\". If it is then fail here,
|
||||
* and let the next layer up try again after
|
||||
* pvfs_reduce_name() if it wants to. This is
|
||||
* much more efficient on average than always
|
||||
* scanning for these separately
|
||||
*/
|
||||
return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
|
||||
} else {
|
||||
*p = '/';
|
||||
}
|
||||
@ -399,7 +406,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx,
|
||||
if (ISDOTDOT(components[i])) {
|
||||
if (i < 1) return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
|
||||
memmove(&components[i-1], &components[i+1],
|
||||
sizeof(char *)*(num_components-(i+1)));
|
||||
sizeof(char *)*(num_components-i));
|
||||
i -= 2;
|
||||
continue;
|
||||
}
|
||||
@ -616,6 +623,86 @@ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd,
|
||||
return pvfs_fill_dos_info(pvfs, name, fd);
|
||||
}
|
||||
|
||||
/*
|
||||
fill in the pvfs_filename info for an open file, given the current
|
||||
info for a (possibly) non-open file. This is used by places that need
|
||||
to update the pvfs_filename stat information, and the path
|
||||
after a possible rename on a different handle.
|
||||
*/
|
||||
NTSTATUS pvfs_resolve_name_handle(struct pvfs_state *pvfs,
|
||||
struct pvfs_file_handle *h)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
if (h->have_opendb_entry) {
|
||||
struct odb_lock *lck;
|
||||
const char *name = NULL;
|
||||
|
||||
lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key);
|
||||
if (lck == NULL) {
|
||||
DEBUG(0,("%s: failed to lock file '%s' in opendb\n",
|
||||
__FUNCTION__, h->name->full_name));
|
||||
/* we were supposed to do a blocking lock, so something
|
||||
is badly wrong! */
|
||||
return NT_STATUS_INTERNAL_DB_CORRUPTION;
|
||||
}
|
||||
|
||||
status = odb_get_path(lck, &name);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
/*
|
||||
* This relies an the fact that
|
||||
* renames of open files are only
|
||||
* allowed by setpathinfo() and setfileinfo()
|
||||
* and there're only renames within the same
|
||||
* directory supported
|
||||
*/
|
||||
if (strcmp(h->name->full_name, name) != 0) {
|
||||
const char *orig_dir;
|
||||
const char *new_file;
|
||||
const char *new_orig;
|
||||
char *delim;
|
||||
|
||||
delim = strrchr(name, '/');
|
||||
if (!delim) {
|
||||
talloc_free(lck);
|
||||
return NT_STATUS_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
new_file = delim + 1;
|
||||
delim = strrchr(h->name->original_name, '\\');
|
||||
if (delim) {
|
||||
delim[0] = '\0';
|
||||
orig_dir = h->name->original_name;
|
||||
new_orig = talloc_asprintf(h->name, "%s\\%s",
|
||||
orig_dir, new_file);
|
||||
if (!new_orig) {
|
||||
talloc_free(lck);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
} else {
|
||||
new_orig = talloc_strdup(h->name, new_file);
|
||||
if (!new_orig) {
|
||||
talloc_free(lck);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
talloc_free(h->name->original_name);
|
||||
talloc_free(h->name->full_name);
|
||||
h->name->full_name = talloc_steal(h->name, name);
|
||||
h->name->original_name = new_orig;
|
||||
}
|
||||
}
|
||||
|
||||
talloc_free(lck);
|
||||
}
|
||||
|
||||
status = pvfs_resolve_name_fd(pvfs, h->fd, h->name);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
resolve the parent of a given name
|
||||
|
@ -82,11 +82,13 @@ static uint32_t pvfs_setfileinfo_access(union smb_setfileinfo *info)
|
||||
static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
|
||||
struct ntvfs_request *req,
|
||||
struct pvfs_filename *name,
|
||||
DATA_BLOB *odb_locking_key,
|
||||
union smb_setfileinfo *info)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct pvfs_filename *name2;
|
||||
char *new_name, *p;
|
||||
struct odb_lock *lck = NULL;
|
||||
|
||||
/* renames are only allowed within a directory */
|
||||
if (strchr_m(info->rename_information.in.new_name, '\\') &&
|
||||
@ -94,11 +96,6 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
|
||||
return NT_STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) {
|
||||
/* don't allow this for now */
|
||||
return NT_STATUS_FILE_IS_A_DIRECTORY;
|
||||
}
|
||||
|
||||
/* don't allow stream renames for now */
|
||||
if (name->stream_name) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
@ -168,7 +165,18 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
|
||||
return status;
|
||||
}
|
||||
|
||||
lck = odb_lock(req, pvfs->odb_context, odb_locking_key);
|
||||
if (lck == NULL) {
|
||||
DEBUG(0,("Unable to lock opendb for can_stat\n"));
|
||||
return NT_STATUS_INTERNAL_DB_CORRUPTION;
|
||||
}
|
||||
|
||||
status = pvfs_do_rename(pvfs, name, name2->full_name);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
status = odb_rename(lck, name2->full_name);
|
||||
}
|
||||
talloc_free(lck);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
name->full_name = talloc_steal(name, name2->full_name);
|
||||
name->original_name = talloc_steal(name, name2->original_name);
|
||||
@ -289,7 +297,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
|
||||
}
|
||||
|
||||
/* update the file information */
|
||||
status = pvfs_resolve_name_fd(pvfs, h->fd, h->name);
|
||||
status = pvfs_resolve_name_handle(pvfs, h);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
@ -391,7 +399,8 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
|
||||
|
||||
case RAW_SFILEINFO_RENAME_INFORMATION:
|
||||
case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
|
||||
return pvfs_setfileinfo_rename(pvfs, req, h->name,
|
||||
return pvfs_setfileinfo_rename(pvfs, req, h->name,
|
||||
&h->odb_locking_key,
|
||||
info);
|
||||
|
||||
case RAW_SFILEINFO_SEC_DESC:
|
||||
@ -565,6 +574,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
|
||||
uint32_t access_needed;
|
||||
uint32_t change_mask = 0;
|
||||
struct odb_lock *lck = NULL;
|
||||
DATA_BLOB odb_locking_key;
|
||||
|
||||
/* resolve the cifs name to a posix name */
|
||||
status = pvfs_resolve_name(pvfs, req, info->generic.in.file.path,
|
||||
@ -696,8 +706,12 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
|
||||
|
||||
case RAW_SFILEINFO_RENAME_INFORMATION:
|
||||
case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
|
||||
return pvfs_setfileinfo_rename(pvfs, req, name,
|
||||
info);
|
||||
status = pvfs_locking_key(name, name, &odb_locking_key);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
status = pvfs_setfileinfo_rename(pvfs, req, name,
|
||||
&odb_locking_key, info);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
return NT_STATUS_OK;
|
||||
|
||||
case RAW_SFILEINFO_DISPOSITION_INFO:
|
||||
case RAW_SFILEINFO_DISPOSITION_INFORMATION:
|
||||
|
@ -3,8 +3,6 @@ local.iconv.*.next_codepoint()
|
||||
base.delaywrite.finfo update on close
|
||||
base.delete.*.deltest20a
|
||||
base.delete.*.deltest20b
|
||||
raw.oplock.*BATCH19
|
||||
raw.oplock.*BATCH20
|
||||
rpc.winreg
|
||||
local.registry.*.security # Not implemented yet
|
||||
rpc.wkssvc
|
||||
|
@ -54,24 +54,68 @@ static NTSTATUS single_search(struct smbcli_state *cli,
|
||||
return status;
|
||||
}
|
||||
|
||||
static bool test_path(struct smbcli_state *cli, const char *path, NTSTATUS expected, NTSTATUS dos_expected)
|
||||
static bool test_path_ex(struct smbcli_state *cli, struct torture_context *tctx,
|
||||
const char *path, const char *path_expected,
|
||||
NTSTATUS expected, NTSTATUS dos_expected)
|
||||
{
|
||||
union smb_chkpath io;
|
||||
union smb_fileinfo finfo;
|
||||
NTSTATUS status;
|
||||
|
||||
io.chkpath.in.path = path;
|
||||
status = smb_raw_chkpath(cli->tree, &io);
|
||||
if (!NT_STATUS_EQUAL(status, expected) && !NT_STATUS_EQUAL(status, dos_expected)) {
|
||||
printf("%-40s FAILED %s should be %s or %s\n",
|
||||
printf("FAILED %-30s chkpath %s should be %s or %s\n",
|
||||
path, nt_errstr(status), nt_errstr(expected), nt_errstr(dos_expected));
|
||||
return false;
|
||||
} else {
|
||||
printf("%-40s correct (%s)\n", path, nt_errstr(status));
|
||||
|
||||
printf("%-30s chkpath correct (%s)\n", path, nt_errstr(status));
|
||||
}
|
||||
|
||||
if (NT_STATUS_EQUAL(expected, NT_STATUS_NOT_A_DIRECTORY)) {
|
||||
expected = NT_STATUS_OK;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(finfo);
|
||||
finfo.generic.level = RAW_FILEINFO_NAME_INFO;
|
||||
finfo.generic.in.file.path = path;
|
||||
status = smb_raw_pathinfo(cli->tree, cli, &finfo);
|
||||
if (!NT_STATUS_EQUAL(status, expected) && !NT_STATUS_EQUAL(status, dos_expected)) {
|
||||
printf("FAILED: %-30s pathinfo %s should be %s or %s\n",
|
||||
path, nt_errstr(status), nt_errstr(expected), nt_errstr(dos_expected));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("%-30s chkpath correct (%s)\n", path, nt_errstr(status));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (path_expected &&
|
||||
(!finfo.name_info.out.fname.s ||
|
||||
strcmp(finfo.name_info.out.fname.s, path_expected) != 0)) {
|
||||
if (tctx && torture_setting_bool(tctx, "samba4", false)) {
|
||||
printf("IGNORE: %-30s => %-20s should be %s\n",
|
||||
path, finfo.name_info.out.fname.s, path_expected);
|
||||
return true;
|
||||
}
|
||||
printf("FAILED: %-30s => %-20s should be %s\n",
|
||||
path, finfo.name_info.out.fname.s, path_expected);
|
||||
return false;
|
||||
}
|
||||
printf("%-30s => %-20s correct\n",
|
||||
path, finfo.name_info.out.fname.s);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
|
||||
static bool test_path(struct smbcli_state *cli, const char *path,
|
||||
NTSTATUS expected, NTSTATUS dos_expected)
|
||||
{
|
||||
return test_path_ex(cli, NULL, path, path, expected, dos_expected);
|
||||
}
|
||||
|
||||
static bool test_chkpath(struct smbcli_state *cli, struct torture_context *tctx)
|
||||
{
|
||||
union smb_chkpath io;
|
||||
NTSTATUS status;
|
||||
@ -86,7 +130,7 @@ static bool test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
|
||||
|
||||
ret &= test_path(cli, BASEDIR "\\nodir", NT_STATUS_OBJECT_NAME_NOT_FOUND, NT_STATUS_DOS(ERRDOS,ERRbadpath));
|
||||
|
||||
fnum = create_complex_file(cli, mem_ctx, BASEDIR "\\test.txt..");
|
||||
fnum = create_complex_file(cli, tctx, BASEDIR "\\test.txt..");
|
||||
if (fnum == -1) {
|
||||
printf("failed to open test.txt - %s\n", smbcli_errstr(cli->tree));
|
||||
ret = false;
|
||||
@ -101,9 +145,20 @@ static bool test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret &= test_path(cli, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path(cli, BASEDIR "\\foo\\..\\test.txt..", NT_STATUS_NOT_A_DIRECTORY, NT_STATUS_DOS(ERRDOS,ERRbadpath));
|
||||
ret &= test_path(cli, "", NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, BASEDIR, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR) + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR"\\\\") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR"\\foo\\..") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR"\\f\\o\\o\\..\\..\\..") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR"\\foo\\\\\..\\\\") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, BASEDIR"\\", BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, BASEDIR"\\\\..\\"BASEDIR, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, BASEDIR"\\\\\\", BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, "\\\\\\\\"BASEDIR"\\\\\\\\", BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, "\\\\\\\\"BASEDIR, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, BASEDIR "\\foo\\..\\test.txt..", BASEDIR "\\test.txt..",
|
||||
NT_STATUS_NOT_A_DIRECTORY, NT_STATUS_DOS(ERRDOS,ERRbadpath));
|
||||
ret &= test_path_ex(cli, tctx, "", "\\", NT_STATUS_OK, NT_STATUS_OK);
|
||||
ret &= test_path(cli, ".", NT_STATUS_OBJECT_NAME_INVALID, NT_STATUS_DOS(ERRDOS,ERRbadpath));
|
||||
ret &= test_path(cli, ".\\", NT_STATUS_OBJECT_NAME_INVALID, NT_STATUS_DOS(ERRDOS,ERRbadpath));
|
||||
ret &= test_path(cli, "\\\\\\.\\", NT_STATUS_OBJECT_NAME_INVALID, NT_STATUS_DOS(ERRDOS,ERRbadpath));
|
||||
@ -122,7 +177,7 @@ static bool test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
|
||||
give different NT status returns for chkpth and findfirst. */
|
||||
|
||||
printf("testing findfirst on %s\n", "\\.\\\\\\\\\\\\.");
|
||||
status = single_search(cli, mem_ctx, "\\.\\\\\\\\\\\\.");
|
||||
status = single_search(cli, tctx, "\\.\\\\\\\\\\\\.");
|
||||
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRinvalidname));
|
||||
|
||||
ret &= test_path(cli, "\\.\\\\\\\\\\\\.", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
|
||||
@ -164,7 +219,7 @@ static bool test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
|
||||
ret &= test_path(cli, "\\..\\", NT_STATUS_OBJECT_PATH_SYNTAX_BAD,NT_STATUS_DOS(ERRDOS,ERRinvalidpath));
|
||||
ret &= test_path(cli, "\\..", NT_STATUS_OBJECT_PATH_SYNTAX_BAD,NT_STATUS_DOS(ERRDOS,ERRinvalidpath));
|
||||
ret &= test_path(cli, BASEDIR "\\.", NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRbadpath));
|
||||
ret &= test_path(cli, BASEDIR "\\..", NT_STATUS_OK,NT_STATUS_OK);
|
||||
ret &= test_path_ex(cli, tctx, BASEDIR "\\..", "\\", NT_STATUS_OK,NT_STATUS_OK);
|
||||
ret &= test_path(cli, BASEDIR "\\nt\\V S\\VB98\\vb600", NT_STATUS_OBJECT_NAME_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
|
||||
ret &= test_path(cli, BASEDIR "\\nt\\V S\\VB98\\vb6.exe", NT_STATUS_NOT_A_DIRECTORY,NT_STATUS_DOS(ERRDOS,ERRbadpath));
|
||||
|
||||
@ -183,7 +238,7 @@ static bool test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
|
||||
CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
|
||||
|
||||
printf("testing findfirst on %s\n", BASEDIR".\\.\\.\\.\\foo\\..\\.\\");
|
||||
status = single_search(cli, mem_ctx, BASEDIR".\\.\\.\\.\\foo\\..\\.\\");
|
||||
status = single_search(cli, tctx, BASEDIR".\\.\\.\\.\\foo\\..\\.\\");
|
||||
CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
|
||||
|
||||
/* We expect this open to fail with the same error code as the chkpath below. */
|
||||
|
@ -453,6 +453,10 @@ bool torture_raw_sfileinfo_rename(struct torture_context *torture,
|
||||
char *fnum_fname_new;
|
||||
char *path_fname;
|
||||
char *path_fname_new;
|
||||
char *path_dname;
|
||||
char *path_dname_new;
|
||||
char *saved_name;
|
||||
char *saved_name_new;
|
||||
union smb_fileinfo finfo1, finfo2;
|
||||
union smb_setfileinfo sfinfo;
|
||||
NTSTATUS status, status2;
|
||||
@ -464,6 +468,8 @@ bool torture_raw_sfileinfo_rename(struct torture_context *torture,
|
||||
asprintf(&path_fname_new, BASEDIR "\\fname_test_new_%d.txt", n);
|
||||
asprintf(&fnum_fname, BASEDIR "\\fnum_test_%d.txt", n);
|
||||
asprintf(&fnum_fname_new, BASEDIR "\\fnum_test_new_%d.txt", n);
|
||||
asprintf(&path_dname, BASEDIR "\\dname_test_%d", n);
|
||||
asprintf(&path_dname_new, BASEDIR "\\dname_test_new_%d", n);
|
||||
|
||||
if (!torture_setup_dir(cli, BASEDIR)) {
|
||||
return false;
|
||||
@ -553,17 +559,112 @@ bool torture_raw_sfileinfo_rename(struct torture_context *torture,
|
||||
sfinfo.rename_information.in.root_fid = d_fnum;
|
||||
CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_INVALID_PARAMETER);
|
||||
CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
|
||||
smbcli_close(cli->tree, d_fnum);
|
||||
|
||||
printf("Trying rename directory\n");
|
||||
if (!torture_setup_dir(cli, path_dname)) {
|
||||
ret = false;
|
||||
goto done;
|
||||
}
|
||||
saved_name = path_fname;
|
||||
saved_name_new = path_fname_new;
|
||||
path_fname = path_dname;
|
||||
path_fname_new = path_dname_new;
|
||||
sfinfo.rename_information.in.new_name = path_dname_new+strlen(BASEDIR)+1;
|
||||
sfinfo.rename_information.in.overwrite = 0;
|
||||
sfinfo.rename_information.in.root_fid = 0;
|
||||
CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
|
||||
CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
|
||||
path_fname = saved_name;
|
||||
path_fname_new = saved_name_new;
|
||||
|
||||
if (torture_setting_bool(torture, "samba3", false)) {
|
||||
printf("SKIP: Trying rename directory with a handle\n");
|
||||
printf("SKIP: Trying rename by path while a handle is open\n");
|
||||
printf("SKIP: Trying rename directory by path while a handle is open\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
printf("Trying rename directory with a handle\n");
|
||||
status = create_directory_handle(cli->tree, path_dname_new, &d_fnum);
|
||||
fnum_saved = fnum;
|
||||
fnum = d_fnum;
|
||||
saved_name = fnum_fname;
|
||||
saved_name_new = fnum_fname_new;
|
||||
fnum_fname = path_dname;
|
||||
fnum_fname_new = path_dname_new;
|
||||
sfinfo.rename_information.in.new_name = path_dname+strlen(BASEDIR)+1;
|
||||
sfinfo.rename_information.in.overwrite = 0;
|
||||
sfinfo.rename_information.in.root_fid = 0;
|
||||
CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
|
||||
CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
|
||||
smbcli_close(cli->tree, d_fnum);
|
||||
fnum = fnum_saved;
|
||||
fnum_fname = saved_name;
|
||||
fnum_fname_new = saved_name_new;
|
||||
|
||||
printf("Trying rename by path while a handle is open\n");
|
||||
fnum_saved = fnum;
|
||||
fnum = create_complex_file(cli, torture, path_fname);
|
||||
sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
|
||||
sfinfo.rename_information.in.overwrite = 0;
|
||||
sfinfo.rename_information.in.root_fid = 0;
|
||||
CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
|
||||
CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
|
||||
/* check that the handle returns the same name */
|
||||
check_fnum = true;
|
||||
CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
|
||||
/* rename it back on the handle */
|
||||
sfinfo.rename_information.in.new_name = path_fname+strlen(BASEDIR)+1;
|
||||
CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
|
||||
CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
|
||||
check_fnum = false;
|
||||
CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
|
||||
smbcli_close(cli->tree, fnum);
|
||||
fnum = fnum_saved;
|
||||
|
||||
printf("Trying rename directory by path while a handle is open\n");
|
||||
status = create_directory_handle(cli->tree, path_dname, &d_fnum);
|
||||
fnum_saved = fnum;
|
||||
fnum = d_fnum;
|
||||
saved_name = path_fname;
|
||||
saved_name_new = path_fname_new;
|
||||
path_fname = path_dname;
|
||||
path_fname_new = path_dname_new;
|
||||
sfinfo.rename_information.in.new_name = path_dname_new+strlen(BASEDIR)+1;
|
||||
sfinfo.rename_information.in.overwrite = 0;
|
||||
sfinfo.rename_information.in.root_fid = 0;
|
||||
CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
|
||||
CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
|
||||
path_fname = saved_name;
|
||||
path_fname_new = saved_name_new;
|
||||
saved_name = fnum_fname;
|
||||
saved_name_new = fnum_fname_new;
|
||||
fnum_fname = path_dname;
|
||||
fnum_fname_new = path_dname_new;
|
||||
/* check that the handle returns the same name */
|
||||
check_fnum = true;
|
||||
CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
|
||||
/* rename it back on the handle */
|
||||
sfinfo.rename_information.in.new_name = path_dname+strlen(BASEDIR)+1;
|
||||
CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
|
||||
CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
|
||||
fnum_fname = saved_name;
|
||||
fnum_fname_new = saved_name_new;
|
||||
saved_name = path_fname;
|
||||
saved_name_new = path_fname_new;
|
||||
path_fname = path_dname;
|
||||
path_fname_new = path_dname_new;
|
||||
check_fnum = false;
|
||||
CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
|
||||
smbcli_close(cli->tree, d_fnum);
|
||||
fnum = fnum_saved;
|
||||
path_fname = saved_name;
|
||||
path_fname_new = saved_name_new;
|
||||
|
||||
done:
|
||||
smb_raw_exit(cli->session);
|
||||
smbcli_close(cli->tree, fnum);
|
||||
if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fnum_fname))) {
|
||||
printf("Failed to delete %s - %s\n", fnum_fname, smbcli_errstr(cli->tree));
|
||||
}
|
||||
if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, path_fname))) {
|
||||
printf("Failed to delete %s - %s\n", path_fname, smbcli_errstr(cli->tree));
|
||||
}
|
||||
|
||||
smbcli_deltree(cli->tree, BASEDIR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user