s4-drs: Dump exact error when failure occurs during DsReplicaUpdateRefs call
[samba.git] / source4 / rpc_server / drsuapi / updaterefs.c
index dd3a3342b59919b941ffbe1c30418f61b561f582..8efdfbbdbbaf4d7a8a1814d2f86c729f2d260a2e 100644 (file)
@@ -23,6 +23,8 @@
 #include "rpc_server/dcerpc_server.h"
 #include "dsdb/samdb/samdb.h"
 #include "rpc_server/drsuapi/dcesrv_drsuapi.h"
+#include "libcli/security/security.h"
+#include "auth/session.h"
 
 struct repsTo {
        uint32_t count;
@@ -134,15 +136,17 @@ WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ct
        }
 
        if (ldb_transaction_start(b_state->sam_ctx) != LDB_SUCCESS) {
-               DEBUG(0,(__location__ ": Failed to start transaction on samdb\n"));
+               DEBUG(0,(__location__ ": Failed to start transaction on samdb: %s\n",
+                        ldb_errstring(b_state->sam_ctx)));
                return WERR_DS_DRA_INTERNAL_ERROR;              
        }
 
        if (req->options & DRSUAPI_DRS_DEL_REF) {
                werr = uref_del_dest(b_state->sam_ctx, mem_ctx, dn, &req->dest_dsa_guid, req->options);
                if (!W_ERROR_IS_OK(werr)) {
-                       DEBUG(0,("Failed to delete repsTo for %s\n",
-                                GUID_string(mem_ctx, &req->dest_dsa_guid)));
+                       DEBUG(0,("Failed to delete repsTo for %s: %s\n",
+                                GUID_string(mem_ctx, &req->dest_dsa_guid),
+                                win_errstr(werr)));
                        goto failed;
                }
        }
@@ -161,14 +165,16 @@ WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ct
 
                werr = uref_add_dest(b_state->sam_ctx, mem_ctx, dn, &dest, req->options);
                if (!W_ERROR_IS_OK(werr)) {
-                       DEBUG(0,("Failed to add repsTo for %s\n",
-                                GUID_string(mem_ctx, &dest.source_dsa_obj_guid)));
+                       DEBUG(0,("Failed to add repsTo for %s: %s\n",
+                                GUID_string(mem_ctx, &dest.source_dsa_obj_guid),
+                                win_errstr(werr)));
                        goto failed;
                }
        }
 
        if (ldb_transaction_commit(b_state->sam_ctx) != LDB_SUCCESS) {
-               DEBUG(0,(__location__ ": Failed to commit transaction on samdb\n"));
+               DEBUG(0,(__location__ ": Failed to commit transaction on samdb: %s\n",
+                        ldb_errstring(b_state->sam_ctx)));
                return WERR_DS_DRA_INTERNAL_ERROR;              
        }
 
@@ -189,11 +195,14 @@ WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TA
        struct drsuapi_bind_state *b_state;
        struct drsuapi_DsReplicaUpdateRefsRequest1 *req;
        WERROR werr;
+       int ret;
+       enum security_user_level security_level;
 
        DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
        b_state = h->data;
 
-       werr = drs_security_level_check(dce_call, "DsReplicaUpdateRefs");
+       werr = drs_security_level_check(dce_call, "DsReplicaUpdateRefs", SECURITY_RO_DOMAIN_CONTROLLER,
+                                       samdb_domain_sid(b_state->sam_ctx));
        if (!W_ERROR_IS_OK(werr)) {
                return werr;
        }
@@ -205,7 +214,20 @@ WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TA
 
        req = &r->in.req.req1;
 
+       security_level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
+       if (security_level < SECURITY_ADMINISTRATOR) {
+               /* check that they are using an DSA objectGUID that they own */
+               ret = dsdb_validate_dsa_guid(b_state->sam_ctx,
+                                            &req->dest_dsa_guid,
+                                            &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]);
+               if (ret != LDB_SUCCESS) {
+                       DEBUG(0,(__location__ ": Refusing DsReplicaUpdateRefs for sid %s with GUID %s\n",
+                                dom_sid_string(mem_ctx,
+                                               &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]),
+                                GUID_string(mem_ctx, &req->dest_dsa_guid)));
+                       return WERR_DS_DRA_ACCESS_DENIED;
+               }
+       }
+
        return drsuapi_UpdateRefs(b_state, mem_ctx, req);
 }
-
-