summaryrefslogtreecommitdiff
path: root/source4/libcli/smb2
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libcli/smb2')
-rw-r--r--source4/libcli/smb2/smb2_calls.h12
-rw-r--r--source4/libcli/smb2/smb2_constants.h22
-rw-r--r--source4/libcli/smb2/util.c78
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);