#include "rpc_server/dcerpc_server.h"
#include "rpc_server/common/common.h"
#include "dsdb/samdb/samdb.h"
-#include "rpc_server/drsuapi/dcesrv_drsuapi.h"
#include "libcli/security/security.h"
+#include "libcli/security/session.h"
+#include "rpc_server/drsuapi/dcesrv_drsuapi.h"
#include "auth/auth.h"
#include "param/param.h"
+#include "lib/messaging/irpc.h"
#define DRSUAPI_UNSUPPORTED(fname) do { \
DEBUG(1,(__location__ ": Unsupported DRS call %s\n", #fname)); \
int ret;
struct auth_session_info *auth_info;
WERROR werr;
+ bool connected_as_system = false;
r->out.bind_info = NULL;
ZERO_STRUCTP(r->out.bind_handle);
W_ERROR_HAVE_NO_MEMORY(b_state);
/* if this is a DC connecting, give them system level access */
- werr = drs_security_level_check(dce_call, NULL, SECURITY_DOMAIN_CONTROLLER);
+ werr = drs_security_level_check(dce_call, NULL, SECURITY_DOMAIN_CONTROLLER, NULL);
if (W_ERROR_IS_OK(werr)) {
DEBUG(3,(__location__ ": doing DsBind with system_session\n"));
auth_info = system_session(dce_call->conn->dce_ctx->lp_ctx);
+ connected_as_system = true;
} else {
auth_info = dce_call->conn->auth_state.session_info;
}
* connect to the samdb
*/
b_state->sam_ctx = samdb_connect(b_state, dce_call->event_ctx,
- dce_call->conn->dce_ctx->lp_ctx, auth_info);
+ dce_call->conn->dce_ctx->lp_ctx, auth_info, 0);
if (!b_state->sam_ctx) {
return WERR_FOOBAR;
}
+ if (connected_as_system) {
+ b_state->sam_ctx_system = b_state->sam_ctx;
+ } else {
+ /* an RODC also needs system samdb access for secret
+ attribute replication */
+ werr = drs_security_level_check(dce_call, NULL, SECURITY_RO_DOMAIN_CONTROLLER,
+ samdb_domain_sid(b_state->sam_ctx));
+ if (W_ERROR_IS_OK(werr)) {
+ b_state->sam_ctx_system = samdb_connect(b_state, dce_call->event_ctx,
+ dce_call->conn->dce_ctx->lp_ctx,
+ system_session(dce_call->conn->dce_ctx->lp_ctx), 0);
+ if (!b_state->sam_ctx_system) {
+ return WERR_FOOBAR;
+ }
+ }
+ }
+
/*
* find out the guid of our own site
*/
if (ntds_res->count != 1) {
return WERR_DS_DRA_INTERNAL_ERROR;
}
- repl_epoch = samdb_result_uint(ntds_res->msgs[0], "ms-DS-ReplicationEpoch", 0);
+ repl_epoch = ldb_msg_find_attr_as_uint(ntds_res->msgs[0],
+ "ms-DS-ReplicationEpoch", 0);
/*
* The "process identifier" of the client.
#if 0 /* we don't support XPRESS compression yet */
b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_XPRESS_COMPRESS;
#endif
+ b_state->local_info28.supported_extensions |= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V10;
b_state->local_info28.site_guid = site_guid;
b_state->local_info28.pid = pid;
b_state->local_info28.repl_epoch = repl_epoch;
struct drsuapi_DsReplicaSync *r)
{
WERROR status;
+ uint32_t timeout;
- status = drs_security_level_check(dce_call, "DsReplicaSync", SECURITY_DOMAIN_CONTROLLER);
+ status = drs_security_level_check(dce_call, "DsReplicaSync", SECURITY_DOMAIN_CONTROLLER, NULL);
if (!W_ERROR_IS_OK(status)) {
return status;
}
- dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, r, NDR_DRSUAPI_DSREPLICASYNC,
+ if (r->in.level != 1) {
+ DEBUG(0,("DsReplicaSync called with unsupported level %d\n", r->in.level));
+ return WERR_DS_DRA_INVALID_PARAMETER;
+ }
+
+ if (r->in.req->req1.options & DRSUAPI_DRS_ASYNC_OP) {
+ timeout = IRPC_CALL_TIMEOUT;
+ } else {
+ /*
+ * use Infinite time for timeout in case
+ * the caller made a sync call
+ */
+ timeout = IRPC_CALL_TIMEOUT_INF;
+ }
+
+ dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx,
+ r, NDR_DRSUAPI_DSREPLICASYNC,
&ndr_table_drsuapi,
- "dreplsrv", "DsReplicaSync");
+ "dreplsrv", "DsReplicaSync",
+ timeout);
return WERR_OK;
}
static WERROR dcesrv_drsuapi_DsReplicaAdd(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct drsuapi_DsReplicaAdd *r)
{
- DRSUAPI_UNSUPPORTED(drsuapi_DsReplicaAdd);
+ WERROR status;
+
+ status = drs_security_level_check(dce_call, "DsReplicaAdd", SECURITY_DOMAIN_CONTROLLER, NULL);
+ if (!W_ERROR_IS_OK(status)) {
+ return status;
+ }
+
+ dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx,
+ r, NDR_DRSUAPI_DSREPLICAADD,
+ &ndr_table_drsuapi,
+ "dreplsrv", "DsReplicaAdd",
+ IRPC_CALL_TIMEOUT);
+
+ return WERR_OK;
}
static WERROR dcesrv_drsuapi_DsReplicaDel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct drsuapi_DsReplicaDel *r)
{
- DRSUAPI_UNSUPPORTED(drsuapi_DsReplicaDel);
+ WERROR status;
+
+ status = drs_security_level_check(dce_call, "DsReplicaDel", SECURITY_DOMAIN_CONTROLLER, NULL);
+ if (!W_ERROR_IS_OK(status)) {
+ return status;
+ }
+
+ dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx,
+ r, NDR_DRSUAPI_DSREPLICADEL,
+ &ndr_table_drsuapi,
+ "dreplsrv", "DsReplicaDel",
+ IRPC_CALL_TIMEOUT);
+
+ return WERR_OK;
}
static WERROR dcesrv_drsuapi_DsReplicaMod(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct drsuapi_DsReplicaMod *r)
{
- DRSUAPI_UNSUPPORTED(drsuapi_DsReplicaMod);
+ WERROR status;
+
+ status = drs_security_level_check(dce_call, "DsReplicaMod", SECURITY_DOMAIN_CONTROLLER, NULL);
+ if (!W_ERROR_IS_OK(status)) {
+ return status;
+ }
+
+ dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx,
+ r, NDR_DRSUAPI_DSREPLICAMOD,
+ &ndr_table_drsuapi,
+ "dreplsrv", "DsReplicaMod",
+ IRPC_CALL_TIMEOUT);
+
+ return WERR_OK;
}
DRSUAPI_UNSUPPORTED(drsuapi_DsGetNT4ChangeLog);
}
-
/*
drsuapi_DsCrackNames
*/
static WERROR dcesrv_drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct drsuapi_DsCrackNames *r)
{
- WERROR status;
struct drsuapi_bind_state *b_state;
struct dcesrv_handle *h;
switch (r->in.level) {
case 1: {
- struct drsuapi_DsNameCtr1 *ctr1;
- struct drsuapi_DsNameInfo1 *names;
- uint32_t i, count;
-
- ctr1 = talloc(mem_ctx, struct drsuapi_DsNameCtr1);
- W_ERROR_HAVE_NO_MEMORY(ctr1);
-
- count = r->in.req->req1.count;
- names = talloc_array(mem_ctx, struct drsuapi_DsNameInfo1, count);
- W_ERROR_HAVE_NO_MEMORY(names);
-
- for (i=0; i < count; i++) {
- status = DsCrackNameOneName(b_state->sam_ctx, mem_ctx,
- r->in.req->req1.format_flags,
- r->in.req->req1.format_offered,
- r->in.req->req1.format_desired,
- r->in.req->req1.names[i].str,
- &names[i]);
- if (!W_ERROR_IS_OK(status)) {
- return status;
- }
+ switch(r->in.req->req1.format_offered){
+ case DRSUAPI_DS_NAME_FORMAT_UPN_AND_ALTSECID:
+ case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN_EX:
+ case DRSUAPI_DS_NAME_FORMAT_LIST_GLOBAL_CATALOG_SERVERS:
+ case DRSUAPI_DS_NAME_FORMAT_UPN_FOR_LOGON:
+ case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_WITH_DCS_IN_SITE:
+ case DRSUAPI_DS_NAME_FORMAT_STRING_SID_NAME:
+ case DRSUAPI_DS_NAME_FORMAT_ALT_SECURITY_IDENTITIES_NAME:
+ case DRSUAPI_DS_NAME_FORMAT_LIST_NCS:
+ case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS:
+ case DRSUAPI_DS_NAME_FORMAT_MAP_SCHEMA_GUID:
+ case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN:
+ case DRSUAPI_DS_NAME_FORMAT_LIST_INFO_FOR_SERVER:
+ case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_FOR_DOMAIN_IN_SITE:
+ case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS_IN_SITE:
+ case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_IN_SITE:
+ case DRSUAPI_DS_NAME_FORMAT_LIST_SITES:
+ DEBUG(0, ("DsCrackNames: Unsupported operation requested: %X",
+ r->in.req->req1.format_offered));
+ return WERR_OK;
+ case DRSUAPI_DS_NAME_FORMAT_LIST_ROLES:
+ return dcesrv_drsuapi_ListRoles(b_state->sam_ctx, mem_ctx,
+ &r->in.req->req1, &r->out.ctr->ctr1);
+ default:/* format_offered is in the enum drsuapi_DsNameFormat*/
+ return dcesrv_drsuapi_CrackNamesByNameFormat(b_state->sam_ctx, mem_ctx,
+ &r->in.req->req1, &r->out.ctr->ctr1);
}
-
- ctr1->count = count;
- ctr1->array = names;
- r->out.ctr->ctr1 = ctr1;
-
- return WERR_OK;
}
}
-
return WERR_UNKNOWN_LEVEL;
}
*r->out.level_out = 1;
- status = drs_security_level_check(dce_call, "DsRemoveDSServer", SECURITY_DOMAIN_CONTROLLER);
+ status = drs_security_level_check(dce_call, "DsRemoveDSServer", SECURITY_DOMAIN_CONTROLLER, NULL);
if (!W_ERROR_IS_OK(status)) {
return status;
}
LDB_SCOPE_BASE, attrs_ntds, "objectClass=nTDSDSA");
if (ret == LDB_SUCCESS && res_ntds->count == 1) {
ctr2->array[i].is_gc
- = (ldb_msg_find_attr_as_int(res_ntds->msgs[0], "options", 0) == 1);
+ = (ldb_msg_find_attr_as_uint(res_ntds->msgs[0], "options", 0) & DS_NTDSDSA_OPT_IS_GC);
ctr2->array[i].ntds_guid
= samdb_result_guid(res_ntds->msgs[0], "objectGUID");
ctr2->array[i].ntds_dn = ldb_dn_get_linearized(res_ntds->msgs[0]->dn);
struct drsuapi_DsExecuteKCC *r)
{
WERROR status;
- status = drs_security_level_check(dce_call, "DsExecuteKCC", SECURITY_DOMAIN_CONTROLLER);
+ status = drs_security_level_check(dce_call, "DsExecuteKCC", SECURITY_DOMAIN_CONTROLLER, NULL);
if (!W_ERROR_IS_OK(status)) {
return status;
}
dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, r, NDR_DRSUAPI_DSEXECUTEKCC,
- &ndr_table_drsuapi, "kccsrv", "DsExecuteKCC");
+ &ndr_table_drsuapi, "kccsrv", "DsExecuteKCC",
+ IRPC_CALL_TIMEOUT);
return WERR_OK;
}
if (!lpcfg_parm_bool(dce_call->conn->dce_ctx->lp_ctx, NULL,
"drs", "disable_sec_check", false)) {
level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
- if (level < SECURITY_ADMINISTRATOR) {
+ if (level < SECURITY_DOMAIN_CONTROLLER) {
DEBUG(1,(__location__ ": Administrator access required for DsReplicaGetInfo\n"));
- security_token_debug(2, dce_call->conn->auth_state.session_info->security_token);
+ security_token_debug(0, 2, dce_call->conn->auth_state.session_info->security_token);
return WERR_DS_DRA_ACCESS_DENIED;
}
}
dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, r, NDR_DRSUAPI_DSREPLICAGETINFO,
- &ndr_table_drsuapi, "kccsrv", "DsReplicaGetInfo");
+ &ndr_table_drsuapi, "kccsrv", "DsReplicaGetInfo",
+ IRPC_CALL_TIMEOUT);
return WERR_OK;
}