s4-dsdb Reorganise and clarify the LSA objectClass check (forbidden on LDAP)
authorAndrew Bartlett <abartlet@samba.org>
Thu, 25 Nov 2010 23:11:30 +0000 (10:11 +1100)
committerMatthias Dieter Wallnöfer <mdw@samba.org>
Fri, 26 Nov 2010 12:10:00 +0000 (13:10 +0100)
This arranged the check to avoid talloc_strdup() (the schema pointers
are constant, and can be relied upon), and checks the untrusted bit
first (it is faster), before the ldb_attr_cmp().

The strcmp() here was valid, if unusual, because the ldapDisplayName
values are already in the correct case, but strcasecmp() is more
correct, as for the small extra cost, we avoid a difficult to diagnose
bug later.

Andrew Bartlett

Signed-off-by: Matthias Dieter Wallnöfer <mdw@samba.org>
source4/dsdb/samdb/ldb_modules/objectclass.c

index 0eceaefce4a15a45824e1e45ac34ec18637552e4..66e6e393eabada7c3b579e62d359c3fb241d363d 100644 (file)
@@ -368,7 +368,6 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
        struct oc_context *ac;
        struct ldb_dn *parent_dn;
        const struct ldb_val *val;
-       char *value;
        int ret;
        static const char * const parent_attrs[] = { "objectClass", NULL };
 
@@ -566,25 +565,39 @@ static int objectclass_do_add(struct oc_context *ac)
 
                /* Move from the linked list back into an ldb msg */
                for (current = sorted; current; current = current->next) {
-                       value = talloc_strdup(msg,
-                                             current->objectclass->lDAPDisplayName);
-                       if (value == NULL) {
-                               talloc_free(mem_ctx);
-                               return ldb_module_oom(ac->module);
-                       }
-
-                       /* LSA-specific objectclasses per default not allowed */
-                       if (((strcmp(value, "secret") == 0) ||
-                            (strcmp(value, "trustedDomain") == 0)) &&
-                           ldb_req_is_untrusted(ac->req)) {
+                       const char *objectclass_name = current->objectclass->lDAPDisplayName;
+
+                       /* LSA-specific objectclasses per default not
+                        * allowed to be created over LDAP, so we need
+                        * to tell if this connection is LDAP (ie
+                        * marked as untrusted), and if the client is
+                        * adding these particular objectClass values
+                        * we must reject */
+
+                       /* Hongwei Sun from Microsoft explians:
+                          The constraint in 3.1.1.5.2.2 MS-ADTS means that the TDO
+                          cannot be added through LDAP interface, instead it can only be
+                          created through LSA Policy API.  This is also explained in
+                          7.1.6.9.7 MS-ADTS as follows:
+
+                          "Despite being replicated normally between peer DCs in a domain,
+                          the process of creating or manipulating TDOs is specifically
+                          restricted to the LSA Policy APIs, as detailed in [MS-LSAD] section
+                          3.1.1.5. Unlike other objects in the DS, TDOs may not be created or
+                          manipulated by client machines over the LDAPv3 transport."
+                       */
+
+                       if (ldb_req_is_untrusted(ac->req) &&
+                           ((strcasecmp(objectclass_name, "secret") == 0) ||
+                            (strcasecmp(objectclass_name, "trustedDomain") == 0))) {
                                ldb_asprintf_errstring(ldb,
-                                                      "objectclass: object class '%s' is LSA-specific, rejecting creation of '%s'!",
-                                                      value,
+                                                      "objectclass: object class '%s' is LSA-specific, rejecting creation of '%s' over LDAP!",
+                                                      objectclass_name,
                                                       ldb_dn_get_linearized(msg->dn));
                                return LDB_ERR_UNWILLING_TO_PERFORM;
                        }
 
-                       ret = ldb_msg_add_string(msg, "objectClass", value);
+                       ret = ldb_msg_add_string(msg, "objectClass", objectclass_name);
                        if (ret != LDB_SUCCESS) {
                                ldb_set_errstring(ldb,
                                                  "objectclass: could not re-add sorted "