diff options
Diffstat (limited to 'source4/libcli/smb2')
-rw-r--r-- | source4/libcli/smb2/smb2_calls.h | 12 | ||||
-rw-r--r-- | source4/libcli/smb2/smb2_constants.h | 22 | ||||
-rw-r--r-- | source4/libcli/smb2/util.c | 78 |
3 files changed, 64 insertions, 48 deletions
diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index b89770fbe6..bea0573c26 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -52,18 +52,6 @@ struct smb2_negprot { } out; }; -/* getinfo classes */ -#define SMB2_GETINFO_FILE 0x01 -#define SMB2_GETINFO_FS 0x02 -#define SMB2_GETINFO_SECURITY 0x03 -#define SMB2_GETINFO_QUOTA 0x04 - -#define SMB2_GETINFO_ADD_OWNER_SECURITY 0x01 -#define SMB2_GETINFO_ADD_GROUP_SECURITY 0x02 -#define SMB2_GETINFO_ADD_DACL_SECURITY 0x04 -#define SMB2_GETINFO_ADD_SACL_SECURITY 0x08 -#define SMB2_GETINFO_ADD_LABEL_SECURITY 0x10 - /* NOTE! the getinfo fs and file levels exactly match up with the 'passthru' SMB levels, which are levels >= 1000. The SMB2 client lib uses the names from the libcli/raw/ library */ diff --git a/source4/libcli/smb2/smb2_constants.h b/source4/libcli/smb2/smb2_constants.h index f1681a3076..3047809b74 100644 --- a/source4/libcli/smb2/smb2_constants.h +++ b/source4/libcli/smb2/smb2_constants.h @@ -150,4 +150,26 @@ #define SMB2_CREATE_OPTIONS_NOT_SUPPORTED_MASK (NTCREATEX_OPTIONS_TREE_CONNECTION | \ NTCREATEX_OPTIONS_OPFILTER) +/* + SMB2 uses different level numbers for the same old SMB trans2 search levels +*/ +#define SMB2_FIND_DIRECTORY_INFO 0x01 +#define SMB2_FIND_FULL_DIRECTORY_INFO 0x02 +#define SMB2_FIND_BOTH_DIRECTORY_INFO 0x03 +#define SMB2_FIND_NAME_INFO 0x0C +#define SMB2_FIND_ID_BOTH_DIRECTORY_INFO 0x25 +#define SMB2_FIND_ID_FULL_DIRECTORY_INFO 0x26 + +/* flags for SMB2 find */ +#define SMB2_CONTINUE_FLAG_RESTART 0x01 +#define SMB2_CONTINUE_FLAG_SINGLE 0x02 +#define SMB2_CONTINUE_FLAG_INDEX 0x04 +#define SMB2_CONTINUE_FLAG_REOPEN 0x10 + +/* getinfo classes */ +#define SMB2_GETINFO_FILE 0x01 +#define SMB2_GETINFO_FS 0x02 +#define SMB2_GETINFO_SECURITY 0x03 +#define SMB2_GETINFO_QUOTA 0x04 + #endif diff --git a/source4/libcli/smb2/util.c b/source4/libcli/smb2/util.c index a360d8fbdf..8602c91a9f 100644 --- a/source4/libcli/smb2/util.c +++ b/source4/libcli/smb2/util.c @@ -113,6 +113,7 @@ int smb2_deltree(struct smb2_tree *tree, const char *dname) TALLOC_CTX *tmp_ctx = talloc_new(tree); struct smb2_find f; struct smb2_create create_parm; + bool did_delete; /* it might be a file */ status = smb2_util_unlink(tree, dname); @@ -154,45 +155,50 @@ int smb2_deltree(struct smb2_tree *tree, const char *dname) } - ZERO_STRUCT(f); - f.in.file.handle = create_parm.out.file.handle; - f.in.max_response_size = 0x10000; - f.in.level = SMB2_FIND_NAME_INFO; - f.in.pattern = "*"; - - status = smb2_find_level(tree, tmp_ctx, &f, &count, &list); - if (NT_STATUS_IS_ERR(status)) { - DEBUG(2,("Failed to list %s - %s\n", - dname, nt_errstr(status))); - smb2_util_close(tree, create_parm.out.file.handle); - talloc_free(tmp_ctx); - return -1; - } - - for (i=0;i<count;i++) { - char *name; - if (strcmp(".", list[i].name_info.name.s) == 0 || - strcmp("..", list[i].name_info.name.s) == 0) { - continue; + do { + did_delete = false; + + ZERO_STRUCT(f); + f.in.file.handle = create_parm.out.file.handle; + f.in.max_response_size = 0x10000; + f.in.level = SMB2_FIND_NAME_INFO; + f.in.pattern = "*"; + + status = smb2_find_level(tree, tmp_ctx, &f, &count, &list); + if (NT_STATUS_IS_ERR(status)) { + DEBUG(2,("Failed to list %s - %s\n", + dname, nt_errstr(status))); + smb2_util_close(tree, create_parm.out.file.handle); + talloc_free(tmp_ctx); + return -1; } - name = talloc_asprintf(tmp_ctx, "%s\\%s", dname, list[i].name_info.name.s); - status = smb2_util_unlink(tree, name); - if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) { - /* it could be read-only */ - status = smb2_util_setatr(tree, name, FILE_ATTRIBUTE_NORMAL); + + for (i=0;i<count;i++) { + char *name; + if (strcmp(".", list[i].name_info.name.s) == 0 || + strcmp("..", list[i].name_info.name.s) == 0) { + continue; + } + name = talloc_asprintf(tmp_ctx, "%s\\%s", dname, list[i].name_info.name.s); status = smb2_util_unlink(tree, name); + if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) { + /* it could be read-only */ + status = smb2_util_setatr(tree, name, FILE_ATTRIBUTE_NORMAL); + status = smb2_util_unlink(tree, name); + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) { + int ret; + ret = smb2_deltree(tree, name); + if (ret > 0) total_deleted += ret; + } + talloc_free(name); + if (NT_STATUS_IS_OK(status)) { + total_deleted++; + did_delete = true; + } } - - if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) { - int ret; - ret = smb2_deltree(tree, name); - if (ret > 0) total_deleted += ret; - } - talloc_free(name); - if (NT_STATUS_IS_OK(status)) { - total_deleted++; - } - } + } while (did_delete); smb2_util_close(tree, create_parm.out.file.handle); |