s4-drs: only allow replication with the right invocationId
authorAndrew Tridgell <tridge@samba.org>
Thu, 22 Apr 2010 04:56:19 +0000 (14:56 +1000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 22 Apr 2010 09:36:16 +0000 (19:36 +1000)
Non-administrator replication checks the invocationId matches
the sid of the user token being used

Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>

source4/rpc_server/drsuapi/getncchanges.c

index 5c378e50de1d70f2b1244de79ecbee8cedfb0257..50de087662e93a833332495485d9e189903fd182 100644 (file)
@@ -32,6 +32,7 @@
 #include "libcli/security/security.h"
 #include "lib/util/binsearch.h"
 #include "lib/util/tsort.h"
+#include "auth/session.h"
 
 /*
   build a DsReplicaObjectIdentifier from a ldb msg
@@ -699,6 +700,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
        uint32_t max_objects;
        struct ldb_dn *search_dn = NULL;
        bool am_rodc;
+       enum security_user_level security_level;
 
        DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
        b_state = h->data;
@@ -749,7 +751,24 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_
                return WERR_DS_DRA_SOURCE_DISABLED;
        }
 
-       if (req8->replica_flags & DRSUAPI_DRS_WRIT_REP)  {
+       /* for non-administrator replications, check that they have
+          given the correct source_dsa_invocation_id */
+       security_level = security_session_user_level(dce_call->conn->auth_state.session_info);
+
+       if (security_level < SECURITY_ADMINISTRATOR) {
+               /* validate their guid */
+               ret = dsdb_validate_invocation_id(b_state->sam_ctx,
+                                                 &req8->source_dsa_invocation_id,
+                                                 dce_call->conn->auth_state.session_info->security_token->user_sid);
+               if (ret != LDB_SUCCESS) {
+                       DEBUG(0,(__location__ ": Attempted replication with invalid invocationId %s\n",
+                                GUID_string(mem_ctx, &req8->source_dsa_invocation_id)));
+                       return WERR_DS_DRA_INVALID_PARAMETER;
+               }
+       }
+
+       if (security_level < SECURITY_ADMINISTRATOR &&
+           (req8->replica_flags & DRSUAPI_DRS_WRIT_REP)) {
                bool is_rodc;
                ret = samdb_is_rodc(b_state->sam_ctx, &req8->source_dsa_invocation_id, &is_rodc);
                if (ret != LDB_SUCCESS || is_rodc) {