s4 rpc_server_samr: DomGeneralInformation use dsdb_domain_count
authorGary Lockyer <gary@catalyst.net.nz>
Wed, 13 Feb 2019 20:33:57 +0000 (09:33 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 14 Feb 2019 04:03:23 +0000 (05:03 +0100)
Use dsdb_domain_count instead of samdb_search_count to determine the
number of users, groups and aliases.  This gives a performance gain of
around 10%, reduces the total memory allocated and fixes the incorrect
count returned for aliases.

Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
selftest/knownfail.d/dom_general_information [deleted file]
source4/rpc_server/samr/dcesrv_samr.c

diff --git a/selftest/knownfail.d/dom_general_information b/selftest/knownfail.d/dom_general_information
deleted file mode 100644 (file)
index 6891e22..0000000
+++ /dev/null
@@ -1 +0,0 @@
-^samba.tests.dcerpc.sam.samba.tests.dcerpc.sam.SamrTests.test_DomGeneralInformation_num_aliases
index 8440028..7edb0fb 100644 (file)
@@ -540,6 +540,10 @@ static NTSTATUS dcesrv_samr_info_DomGeneralInformation(struct samr_domain_state
                                                       struct ldb_message **dom_msgs,
                                                       struct samr_DomGeneralInformation *info)
 {
+       size_t count = 0;
+       const enum ldb_scope scope = LDB_SCOPE_SUBTREE;
+       int ret = 0;
+
        /* MS-SAMR 2.2.4.1 - ReplicaSourceNodeName: "domainReplica" attribute */
        info->primary.string = ldb_msg_find_attr_as_string(dom_msgs[0],
                                                           "domainReplica",
@@ -578,21 +582,62 @@ static NTSTATUS dcesrv_samr_info_DomGeneralInformation(struct samr_domain_state
                break;
        }
 
-       info->num_users = samdb_search_count(state->sam_ctx, mem_ctx,
-                                            state->domain_dn,
-                                            "(objectClass=user)");
-       info->num_groups = samdb_search_count(state->sam_ctx, mem_ctx,
-                                             state->domain_dn,
-                                             "(&(objectClass=group)(|(groupType=%d)(groupType=%d)))",
-                                             GTYPE_SECURITY_UNIVERSAL_GROUP,
-                                             GTYPE_SECURITY_GLOBAL_GROUP);
-       info->num_aliases = samdb_search_count(state->sam_ctx, mem_ctx,
-                                              state->domain_dn,
-                                              "(&(objectClass=group)(|(groupType=%d)(groupType=%d)))",
-                                              GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
-                                              GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
+       /*
+        * Users are not meant to be in BUILTIN
+        * so to speed up the query we do not filter on domain_sid
+        */
+       ret = dsdb_domain_count(
+               state->sam_ctx,
+               &count,
+               state->domain_dn,
+               NULL,
+               scope,
+               "(objectClass=user)");
+       if (ret != LDB_SUCCESS || count > UINT32_MAX) {
+               goto error;
+       }
+       info->num_users = count;
+
+       /*
+        * Groups are not meant to be in BUILTIN
+        * so to speed up the query we do not filter on domain_sid
+        */
+       ret = dsdb_domain_count(
+               state->sam_ctx,
+               &count,
+               state->domain_dn,
+               NULL,
+               scope,
+               "(&(objectClass=group)(|(groupType=%d)(groupType=%d)))",
+               GTYPE_SECURITY_UNIVERSAL_GROUP,
+               GTYPE_SECURITY_GLOBAL_GROUP);
+       if (ret != LDB_SUCCESS || count > UINT32_MAX) {
+               goto error;
+       }
+       info->num_groups = count;
+
+       ret = dsdb_domain_count(
+               state->sam_ctx,
+               &count,
+               state->domain_dn,
+               state->domain_sid,
+               scope,
+               "(&(objectClass=group)(|(groupType=%d)(groupType=%d)))",
+               GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
+               GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
+       if (ret != LDB_SUCCESS || count > UINT32_MAX) {
+               goto error;
+       }
+       info->num_aliases = count;
 
        return NT_STATUS_OK;
+
+error:
+       if (count > UINT32_MAX) {
+               return NT_STATUS_INTEGER_OVERFLOW;
+       }
+       return dsdb_ldb_err_to_ntstatus(ret);
+
 }
 
 /*