drsuapi: Check that the GUID specified in the request is the really the GUID of the NC
authorMatthieu Patou <mat@matws.net>
Sun, 14 Oct 2012 08:06:15 +0000 (01:06 -0700)
committerMatthieu Patou <mat@matws.net>
Sun, 18 May 2014 04:51:15 +0000 (21:51 -0700)
Up to now it was possible to specify in the request the GUID of
CN=Computer,DC=domain,DC=tld but DC=domain,DC=tld as the NC's dn and
still avoid the BAD_NC.

This is because the dsdb_find_nc_root for the specified extended dn will
return DC=domain,DC=tld which is the same as the string part of the DN
specified in the request.

Problem was spoted by Andrew Bartlett <abartlett@samba.org>, thanks !

Signed-off-by: Matthieu Patou <mat@matws.net>
source4/rpc_server/drsuapi/updaterefs.c

index e00e119f03874b12cffb31817b7e39330e1b9ae7..b2abefb5be2be51eab8581702aefe22a295b6d36 100644 (file)
@@ -22,6 +22,7 @@
 #include "includes.h"
 #include "rpc_server/dcerpc_server.h"
 #include "dsdb/samdb/samdb.h"
+#include "dsdb/common/util.h"
 #include "libcli/security/security.h"
 #include "libcli/security/session.h"
 #include "rpc_server/drsuapi/dcesrv_drsuapi.h"
@@ -146,6 +147,8 @@ WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ct
        struct ldb_dn *dn;
        struct ldb_dn *nc_root;
        struct ldb_context *sam_ctx = b_state->sam_ctx_system?b_state->sam_ctx_system:b_state->sam_ctx;
+       const char *attrs[] = { NULL };
+       struct ldb_result *res;
 
        dn = drs_ObjectIdentifier_to_dn(mem_ctx, sam_ctx, req->naming_context);
        W_ERROR_HAVE_NO_MEMORY(dn);
@@ -153,7 +156,7 @@ WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ct
        DEBUG(4,("DsReplicaUpdateRefs for host '%s' with GUID %s options 0x%08x nc=%s\n",
                 req->dest_dsa_dns_name, GUID_string(mem_ctx, &req->dest_dsa_guid),
                 req->options,
-                ldb_dn_get_extended_linearized(dn)));
+                ldb_dn_get_extended_linearized(mem_ctx, dn, 1)));
 
        /*
         * 4.1.26.2 Server Behavior of the IDL_DRSUpdateRefs Method
@@ -172,6 +175,26 @@ WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ct
                return WERR_DS_DRA_INVALID_PARAMETER;
        }
 
+       /*
+        * Force a search on the constructed DN to actually be
+        * sure that the GUID, SID and DN are all synchronized.
+        * That is to say that the string part of the DN is really the
+        * DN which has the specified GUID as objectGUID.
+        */
+       ret = dsdb_search_dn(sam_ctx, mem_ctx, &res, dn, attrs,
+                            DSDB_SEARCH_SHOW_EXTENDED_DN);
+       if (ret != LDB_SUCCESS) {
+               return WERR_DS_DRA_BAD_NC;
+       }
+       talloc_free(dn);
+       dn = talloc_steal(mem_ctx, res->msgs[0]->dn);
+
+       /*
+        * Now that we are sure that the string part of the DN
+        * and the GUID identify the same DN we get the NC
+        * for this DN and if the DN of the NC != of the DN
+        * in the request we return BAD_NC
+        */
        ret = dsdb_find_nc_root(sam_ctx, dn, dn, &nc_root);
        if (ret != LDB_SUCCESS) {
                DEBUG(2, ("Didn't find a nc for %s\n", ldb_dn_get_linearized(dn)));