From 4cb055cacdc8a28f1efee1d40546baa05515e24e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 2 Oct 2009 12:02:00 +1000 Subject: ds-flags: use the new name DS_DNS_FOREST_ROOT Update to use the new DS_DNS_FOREST_ROOT name, which makes it clearer what this bit means (according to MS-ADTS doc) --- source4/rpc_server/netlogon/dcerpc_netlogon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 1a45711c57..5eccd7f6a8 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -1440,7 +1440,7 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA info->domain_guid = samdb_result_guid(res[0], "objectGUID"); info->domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); info->forest_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); - info->dc_flags = DS_DNS_FOREST | + info->dc_flags = DS_DNS_FOREST_ROOT | DS_DNS_DOMAIN | DS_DNS_CONTROLLER | DS_SERVER_WRITABLE | -- cgit From caa9e3ff8e0da229253f43e26980a394bb76e3ca Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 2 Oct 2009 16:02:42 +1000 Subject: s4-samr: fake up a samr_ValidatePassword response mdw is working on the correct call to check the password strength --- source4/rpc_server/samr/dcesrv_samr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 6dda06a6b8..b8af5fdeb3 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -4342,7 +4342,11 @@ static NTSTATUS dcesrv_samr_SetDsrmPassword(struct dcesrv_call_state *dce_call, static NTSTATUS dcesrv_samr_ValidatePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct samr_ValidatePassword *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + /* just say it's OK for now - we need to hook this into our + password strength code later */ + DEBUG(0,(__location__ ": Faking samr_ValidatePassword reply\n")); + (*r->out.rep) = talloc_zero(mem_ctx, union samr_ValidatePasswordRep); + return NT_STATUS_OK; } -- cgit From f390daef475126b4ff5a3d0ffd2babbd87d4c22b Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 29 Sep 2009 11:49:50 +0200 Subject: s4/srvsvc: deactivate a "ntvfs_connect" with a wrong parameter In the srvsvc code for s4 (NTVFS module) there exists a call to "ntvfs_connect" which is performed with a totally wrong argument. Since I'm not able to fix this, I commented it out and added a "FIXME" comment. --- source4/rpc_server/srvsvc/srvsvc_ntvfs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/srvsvc/srvsvc_ntvfs.c b/source4/rpc_server/srvsvc/srvsvc_ntvfs.c index f1cb35bdd8..15bd749ad1 100644 --- a/source4/rpc_server/srvsvc/srvsvc_ntvfs.c +++ b/source4/rpc_server/srvsvc/srvsvc_ntvfs.c @@ -128,7 +128,9 @@ NTSTATUS srvsvc_create_ntvfs_context(struct dcesrv_call_state *dce_call, NT_STATUS_HAVE_NO_MEMORY(ntvfs_req); /* Invoke NTVFS connection hook */ - status = ntvfs_connect(ntvfs_req, scfg->name); + /* FIXME: Here is the right parameter missing! + * status = ntvfs_connect(ntvfs_req, ); */ + status = NT_STATUS_UNSUCCESSFUL; /* return this for now */ if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("srvsvc_create_ntvfs_context: NTVFS ntvfs_connect() failed!\n")); return status; -- cgit From 44df2488e30da783add33b4fb85d96ce65856484 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 29 Sep 2009 11:49:50 +0200 Subject: s4: fix various warnings (not "const" related ones) --- source4/rpc_server/common/common.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/common/common.h b/source4/rpc_server/common/common.h index 17c2a7db02..ba023e1fd8 100644 --- a/source4/rpc_server/common/common.h +++ b/source4/rpc_server/common/common.h @@ -26,6 +26,8 @@ struct share_config; struct dcesrv_context; struct dcesrv_context; +struct dcesrv_call_state; +struct ndr_interface_table; struct dcerpc_server_info { const char *domain_name; @@ -34,8 +36,6 @@ struct dcerpc_server_info { uint32_t version_build; }; -struct ndr_interface_table; -struct dcesrv_call_state; #include "rpc_server/common/proto.h" #endif /* _DCERPC_SERVER_COMMON_H_ */ -- cgit From a021d5513846968c54d6e065dbcb25948418676f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 6 Oct 2009 18:58:13 +1100 Subject: s4-drs: open samdb with system credentials when authorised When a DC connects to DRS, open the samdb with system session credentials, so that we don't have to re-open it each time on other calls. --- source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index 9903f08746..f11cc232f0 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -27,6 +27,7 @@ #include "dsdb/samdb/samdb.h" #include "rpc_server/drsuapi/dcesrv_drsuapi.h" #include "libcli/security/security.h" +#include "auth/auth.h" /* drsuapi_DsBind @@ -47,6 +48,8 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C uint32_t pid; uint32_t repl_epoch; int ret; + struct auth_session_info *auth_info; + WERROR werr; r->out.bind_info = NULL; ZERO_STRUCTP(r->out.bind_handle); @@ -54,10 +57,20 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C b_state = talloc_zero(mem_ctx, struct drsuapi_bind_state); 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); + if (W_ERROR_IS_OK(werr)) { + DEBUG(0,(__location__ ": doing DsBind with system_session\n")); + auth_info = system_session(b_state, dce_call->conn->dce_ctx->lp_ctx); + } 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, dce_call->conn->auth_state.session_info); + b_state->sam_ctx = samdb_connect(b_state, dce_call->event_ctx, + dce_call->conn->dce_ctx->lp_ctx, auth_info); if (!b_state->sam_ctx) { return WERR_FOOBAR; } -- cgit From f800d4998dc5cfa1e8ed2639dc334add78ceaea5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 6 Oct 2009 18:58:41 +1100 Subject: s4-drs: fixed error message for drs_security_level_check --- source4/rpc_server/drsuapi/drsutil.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/drsuapi/drsutil.c b/source4/rpc_server/drsuapi/drsutil.c index 84bb5ffc01..1b4c28c4ab 100644 --- a/source4/rpc_server/drsuapi/drsutil.c +++ b/source4/rpc_server/drsuapi/drsutil.c @@ -127,7 +127,9 @@ WERROR drs_security_level_check(struct dcesrv_call_state *dce_call, const char* if (security_session_user_level(dce_call->conn->auth_state.session_info) < SECURITY_DOMAIN_CONTROLLER) { - DEBUG(0,("DsReplicaGetInfo refused for security token\n")); + if (call) { + DEBUG(0,("%s refused for security token\n", call)); + } return WERR_DS_DRA_ACCESS_DENIED; } -- cgit From 0285d568c55410f3e2a5cfda5693873be2841151 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 6 Oct 2009 18:59:30 +1100 Subject: s4-drs: take advantage of system session auth in dsbind Now that the bind opens samdb with the right credentials, we no longer need the re-open in updaterefs and getncchanges --- source4/rpc_server/drsuapi/getncchanges.c | 33 ++++++++++--------------------- source4/rpc_server/drsuapi/updaterefs.c | 29 +++++++++++---------------- 2 files changed, 21 insertions(+), 41 deletions(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index 2bfdf5280a..5713d41f84 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -66,7 +66,7 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem if (instance_type & INSTANCE_TYPE_IS_NC_HEAD) { struct ldb_result *res; int ret; - char *dnstr = ldb_dn_get_linearized(msg->dn); + const char *dnstr = ldb_dn_get_linearized(msg->dn); msg->dn = ldb_dn_new(msg, sam_ctx, dnstr); /* we need to re-search the msg, to avoid the * broken dual message problems with our @@ -322,7 +322,6 @@ static WERROR get_nc_changes_udv(struct ldb_context *sam_ctx, struct drsuapi_getncchanges_state { struct ldb_result *site_res; uint32_t num_sent; - struct ldb_context *sam_ctx; struct ldb_dn *ncRoot_dn; uint32_t min_usn; }; @@ -393,18 +392,6 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ return WERR_NOMEM; } b_state->getncchanges_state = getnc_state; - - - /* - * connect to the samdb. TODO: We need to check that the caller - * has the rights to do this. This exposes all attributes, - * including all passwords. - */ - getnc_state->sam_ctx = samdb_connect(getnc_state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, - system_session(getnc_state, dce_call->conn->dce_ctx->lp_ctx)); - if (!getnc_state->sam_ctx) { - return WERR_FOOBAR; - } } /* we need the session key for encrypting password attributes */ @@ -431,14 +418,14 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ search_filter); } - getnc_state->ncRoot_dn = ldb_dn_new(getnc_state, getnc_state->sam_ctx, ncRoot->dn); + getnc_state->ncRoot_dn = ldb_dn_new(getnc_state, b_state->sam_ctx, ncRoot->dn); if (r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_ASYNC_REP) { scope = LDB_SCOPE_BASE; } DEBUG(6,(__location__ ": getncchanges on %s using filter %s\n", ldb_dn_get_linearized(getnc_state->ncRoot_dn), search_filter)); - ret = drsuapi_search_with_extended_dn(getnc_state->sam_ctx, getnc_state, &getnc_state->site_res, + ret = drsuapi_search_with_extended_dn(b_state->sam_ctx, getnc_state, &getnc_state->site_res, getnc_state->ncRoot_dn, scope, attrs, "distinguishedName", search_filter); @@ -448,7 +435,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ } /* Prefix mapping */ - schema = dsdb_get_schema(getnc_state->sam_ctx); + schema = dsdb_get_schema(b_state->sam_ctx); if (!schema) { DEBUG(0,("No schema in sam_ctx\n")); return WERR_DS_DRA_INTERNAL_ERROR; @@ -457,7 +444,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ r->out.ctr->ctr6.naming_context = talloc(mem_ctx, struct drsuapi_DsReplicaObjectIdentifier); *r->out.ctr->ctr6.naming_context = *ncRoot; - if (dsdb_find_guid_by_dn(getnc_state->sam_ctx, getnc_state->ncRoot_dn, + if (dsdb_find_guid_by_dn(b_state->sam_ctx, getnc_state->ncRoot_dn, &r->out.ctr->ctr6.naming_context->guid) != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to find GUID of ncRoot_dn %s\n", ldb_dn_get_linearized(getnc_state->ncRoot_dn))); @@ -465,13 +452,13 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ } /* find the SID if there is one */ - dsdb_find_sid_by_dn(getnc_state->sam_ctx, getnc_state->ncRoot_dn, &r->out.ctr->ctr6.naming_context->sid); + dsdb_find_sid_by_dn(b_state->sam_ctx, getnc_state->ncRoot_dn, &r->out.ctr->ctr6.naming_context->sid); dsdb_get_oid_mappings_drsuapi(schema, true, mem_ctx, &ctr); r->out.ctr->ctr6.mapping_ctr = *ctr; - r->out.ctr->ctr6.source_dsa_guid = *(samdb_ntds_objectGUID(getnc_state->sam_ctx)); - r->out.ctr->ctr6.source_dsa_invocation_id = *(samdb_ntds_invocation_id(getnc_state->sam_ctx)); + r->out.ctr->ctr6.source_dsa_guid = *(samdb_ntds_objectGUID(b_state->sam_ctx)); + r->out.ctr->ctr6.source_dsa_invocation_id = *(samdb_ntds_invocation_id(b_state->sam_ctx)); r->out.ctr->ctr6.old_highwatermark = r->in.req->req8.highwatermark; r->out.ctr->ctr6.new_highwatermark = r->in.req->req8.highwatermark; @@ -493,7 +480,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ } werr = get_nc_changes_build_object(obj, getnc_state->site_res->msgs[i], - getnc_state->sam_ctx, getnc_state->ncRoot_dn, + b_state->sam_ctx, getnc_state->ncRoot_dn, schema, &session_key, getnc_state->min_usn, r->in.req->req8.replica_flags); if (!W_ERROR_IS_OK(werr)) { @@ -528,7 +515,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ r->out.ctr->ctr6.new_highwatermark.highest_usn = r->out.ctr->ctr6.new_highwatermark.tmp_highest_usn; - werr = get_nc_changes_udv(getnc_state->sam_ctx, getnc_state->ncRoot_dn, + werr = get_nc_changes_udv(b_state->sam_ctx, getnc_state->ncRoot_dn, r->out.ctr->ctr6.uptodateness_vector); if (!W_ERROR_IS_OK(werr)) { return werr; diff --git a/source4/rpc_server/drsuapi/updaterefs.c b/source4/rpc_server/drsuapi/updaterefs.c index e12be6f058..d01fabf575 100644 --- a/source4/rpc_server/drsuapi/updaterefs.c +++ b/source4/rpc_server/drsuapi/updaterefs.c @@ -101,9 +101,13 @@ WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TA struct drsuapi_DsReplicaUpdateRefs *r) { struct drsuapi_DsReplicaUpdateRefsRequest1 *req; - struct ldb_context *sam_ctx; WERROR werr; struct ldb_dn *dn; + struct dcesrv_handle *h; + struct drsuapi_bind_state *b_state; + + DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); + b_state = h->data; werr = drs_security_level_check(dce_call, "DsReplicaUpdateRefs"); if (!W_ERROR_IS_OK(werr)) { @@ -121,27 +125,18 @@ WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TA req->options, drs_ObjectIdentifier_to_string(mem_ctx, req->naming_context))); - /* TODO: We need to authenticate this operation pretty carefully */ - sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, - system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx)); - if (!sam_ctx) { - return WERR_DS_DRA_INTERNAL_ERROR; - } - - dn = ldb_dn_new(mem_ctx, sam_ctx, req->naming_context->dn); + dn = ldb_dn_new(mem_ctx, b_state->sam_ctx, req->naming_context->dn); if (dn == NULL) { - talloc_free(sam_ctx); return WERR_DS_INVALID_DN_SYNTAX; } - if (ldb_transaction_start(sam_ctx) != LDB_SUCCESS) { + if (ldb_transaction_start(b_state->sam_ctx) != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to start transaction on samdb\n")); - talloc_free(sam_ctx); return WERR_DS_DRA_INTERNAL_ERROR; } if (req->options & DRSUAPI_DS_REPLICA_UPDATE_DELETE_REFERENCE) { - werr = uref_del_dest(sam_ctx, mem_ctx, dn, &req->dest_dsa_guid); + werr = uref_del_dest(b_state->sam_ctx, mem_ctx, dn, &req->dest_dsa_guid); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("Failed to delete repsTo for %s\n", GUID_string(dce_call, &req->dest_dsa_guid))); @@ -161,7 +156,7 @@ WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TA dest.source_dsa_obj_guid = req->dest_dsa_guid; dest.replica_flags = req->options; - werr = uref_add_dest(sam_ctx, mem_ctx, dn, &dest); + werr = uref_add_dest(b_state->sam_ctx, mem_ctx, dn, &dest); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("Failed to delete repsTo for %s\n", GUID_string(dce_call, &dest.source_dsa_obj_guid))); @@ -169,16 +164,14 @@ WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TA } } - if (ldb_transaction_commit(sam_ctx) != LDB_SUCCESS) { + if (ldb_transaction_commit(b_state->sam_ctx) != LDB_SUCCESS) { DEBUG(0,(__location__ ": Failed to commit transaction on samdb\n")); return WERR_DS_DRA_INTERNAL_ERROR; } - talloc_free(sam_ctx); return WERR_OK; failed: - ldb_transaction_cancel(sam_ctx); - talloc_free(sam_ctx); + ldb_transaction_cancel(b_state->sam_ctx); return werr; } -- cgit From a44030fc10217940c94a927c3d0988648058e0e2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 6 Oct 2009 18:59:47 +1100 Subject: s4-drs: added some debug lines to DsAddEntry() --- source4/rpc_server/drsuapi/addentry.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/drsuapi/addentry.c b/source4/rpc_server/drsuapi/addentry.c index 7bf8f39592..2c913dd91d 100644 --- a/source4/rpc_server/drsuapi/addentry.c +++ b/source4/rpc_server/drsuapi/addentry.c @@ -180,6 +180,7 @@ WERROR dcesrv_drsuapi_DsAddEntry(struct dcesrv_call_state *dce_call, TALLOC_CTX if (!W_ERROR_IS_OK(status)) { r->out.ctr->ctr3.error->info1.status = status; ldb_transaction_cancel(b_state->sam_ctx); + DEBUG(0,(__location__ ": DsAddEntry failed - %s\n", win_errstr(status))); return status; } @@ -198,11 +199,13 @@ WERROR dcesrv_drsuapi_DsAddEntry(struct dcesrv_call_state *dce_call, TALLOC_CTX if (!W_ERROR_IS_OK(status)) { r->out.ctr->ctr3.error->info1.status = status; ldb_transaction_cancel(b_state->sam_ctx); + DEBUG(0,(__location__ ": DsAddEntry add SPNs failed - %s\n", win_errstr(status))); return status; } ret = ldb_transaction_commit(b_state->sam_ctx); if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ ": DsAddEntry commit failed\n")); return WERR_DS_DRA_INTERNAL_ERROR; } -- cgit From 607ceff234c5c85849975087e9a40416b943c269 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Fri, 25 Sep 2009 22:44:00 +0200 Subject: s3/s4 - Adapt the IDL changes on various locations --- source4/rpc_server/samr/samr_password.c | 39 +++++++++++++++++---------------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c index 450af82895..1e6eb47e86 100644 --- a/source4/rpc_server/samr/samr_password.c +++ b/source4/rpc_server/samr/samr_password.c @@ -177,8 +177,9 @@ NTSTATUS dcesrv_samr_ChangePasswordUser(struct dcesrv_call_state *dce_call, /* samr_OemChangePasswordUser2 */ -NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct samr_OemChangePasswordUser2 *r) +NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, + TALLOC_CTX *mem_ctx, + struct samr_OemChangePasswordUser2 *r) { NTSTATUS status; DATA_BLOB new_password, new_unicode_password; @@ -335,8 +336,8 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, samr_ChangePasswordUser3 */ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, - TALLOC_CTX *mem_ctx, - struct samr_ChangePasswordUser3 *r) + TALLOC_CTX *mem_ctx, + struct samr_ChangePasswordUser3 *r) { NTSTATUS status; DATA_BLOB new_password; @@ -348,8 +349,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, struct samr_Password *nt_pwd, *lm_pwd; DATA_BLOB nt_pwd_blob; struct samr_DomInfo1 *dominfo = NULL; - struct samr_ChangeReject *reject = NULL; - enum samr_RejectReason reason = SAMR_REJECT_OTHER; + struct userPwdChangeFailureInformation *reject = NULL; + enum samPwdChangeReason reason = SAM_PWD_CHANGE_NO_ERROR; uint8_t new_nt_hash[16], new_lm_hash[16]; struct samr_Password nt_verifier, lm_verifier; @@ -465,6 +466,7 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, true, /* this is a user password change */ &reason, &dominfo); + if (!NT_STATUS_IS_OK(status)) { goto failed; } @@ -494,18 +496,16 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, failed: ldb_transaction_cancel(sam_ctx); - talloc_free(sam_ctx); - reject = talloc(mem_ctx, struct samr_ChangeReject); - *r->out.dominfo = dominfo; - *r->out.reject = reject; + reject = talloc(mem_ctx, struct userPwdChangeFailureInformation); + if (reject != NULL) { + ZERO_STRUCTP(reject); + reject->extendedFailureReason = reason; - if (reject == NULL) { - return status; + *r->out.reject = reject; } - ZERO_STRUCTP(reject); - reject->reason = reason; + *r->out.dominfo = dominfo; return status; } @@ -516,12 +516,13 @@ failed: easy - just a subset of samr_ChangePasswordUser3 */ -NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct samr_ChangePasswordUser2 *r) +NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, + TALLOC_CTX *mem_ctx, + struct samr_ChangePasswordUser2 *r) { struct samr_ChangePasswordUser3 r2; struct samr_DomInfo1 *dominfo = NULL; - struct samr_ChangeReject *reject = NULL; + struct userPwdChangeFailureInformation *reject = NULL; r2.in.server = r->in.server; r2.in.account = r->in.account; @@ -584,7 +585,8 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call, */ NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call, struct ldb_context *sam_ctx, - struct ldb_dn *account_dn, struct ldb_dn *domain_dn, + struct ldb_dn *account_dn, + struct ldb_dn *domain_dn, TALLOC_CTX *mem_ctx, struct ldb_message *msg, struct samr_CryptPasswordEx *pwbuf) @@ -627,4 +629,3 @@ NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call, NULL, NULL); } - -- cgit From 0c0eb14767f4e77780a531ff2873dcad9204a16a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 12 Oct 2009 13:30:52 +1100 Subject: s4-drs: make DsBind a bit less verbose --- source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index f11cc232f0..9f903716dc 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -60,7 +60,7 @@ static WERROR dcesrv_drsuapi_DsBind(struct dcesrv_call_state *dce_call, TALLOC_C /* if this is a DC connecting, give them system level access */ werr = drs_security_level_check(dce_call, NULL); if (W_ERROR_IS_OK(werr)) { - DEBUG(0,(__location__ ": doing DsBind with system_session\n")); + DEBUG(2,(__location__ ": doing DsBind with system_session\n")); auth_info = system_session(b_state, dce_call->conn->dce_ctx->lp_ctx); } else { auth_info = dce_call->conn->auth_state.session_info; -- cgit From 4423173b08ebba1ff8494a4997e46e28525c1d7a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Oct 2009 13:09:07 +1100 Subject: s4-repl: check that a DsGetNCChanges is a continuation, and fix sorting When we indicate that a getncchanges request is not complete, we set the more_data flag to true in the response. The client usually then asks for the next block of data. If the client decides it wants to skip that replication and do a different replication then we need to make sure that the next call is in fact a continuation of the existing call, and not a new call. This relies on returning the results sorted by uSNChanged, as the client uses the tmp_highest_usn in each result to see if progress is being made. --- source4/rpc_server/drsuapi/drsutil.c | 2 +- source4/rpc_server/drsuapi/getncchanges.c | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/drsuapi/drsutil.c b/source4/rpc_server/drsuapi/drsutil.c index 1b4c28c4ab..752861cc26 100644 --- a/source4/rpc_server/drsuapi/drsutil.c +++ b/source4/rpc_server/drsuapi/drsutil.c @@ -98,7 +98,7 @@ int drsuapi_search_with_extended_dn(struct ldb_context *ldb, sort_control[0] = talloc(req, struct ldb_server_sort_control); sort_control[0]->attributeName = sort_attrib; sort_control[0]->orderingRule = NULL; - sort_control[0]->reverse = 1; + sort_control[0]->reverse = 0; sort_control[1] = NULL; ret = ldb_request_add_control(req, LDB_CONTROL_SERVER_SORT_OID, true, sort_control); diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index 5713d41f84..ae1b2e61eb 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -411,7 +411,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ search_filter = talloc_asprintf(mem_ctx, "(uSNChanged>=%llu)", (unsigned long long)(getnc_state->min_usn+1)); - + if (r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_CRITICAL_ONLY) { search_filter = talloc_asprintf(mem_ctx, "(&%s(isCriticalSystemObject=TRUE))", @@ -427,11 +427,24 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ ldb_dn_get_linearized(getnc_state->ncRoot_dn), search_filter)); ret = drsuapi_search_with_extended_dn(b_state->sam_ctx, getnc_state, &getnc_state->site_res, getnc_state->ncRoot_dn, scope, attrs, - "distinguishedName", + "uSNChanged", search_filter); if (ret != LDB_SUCCESS) { return WERR_DS_DRA_INTERNAL_ERROR; } + } else { + /* check that this request is for the same NC as the previous one */ + struct ldb_dn *dn; + dn = ldb_dn_new(getnc_state, b_state->sam_ctx, ncRoot->dn); + if (!dn) { + return WERR_NOMEM; + } + if (ldb_dn_compare(dn, getnc_state->ncRoot_dn) != 0) { + DEBUG(0,(__location__ ": DsGetNCChanges 2nd replication on different DN %s %s\n", + ldb_dn_get_linearized(dn), + ldb_dn_get_linearized(getnc_state->ncRoot_dn))); + return WERR_DS_DRA_BAD_NC; + } } /* Prefix mapping */ @@ -525,7 +538,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ b_state->getncchanges_state = NULL; } - DEBUG(3,("DsGetNCChanges with uSNChanged >= %llu on %s gave %u objects\n", + DEBUG(2,("DsGetNCChanges with uSNChanged >= %llu on %s gave %u objects\n", (unsigned long long)(r->in.req->req8.highwatermark.highest_usn+1), ncRoot->dn, r->out.ctr->ctr6.object_count)); -- cgit From 6e19a9e05d6085224c0e6a0b46a0f7e468188124 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 13 Oct 2009 00:15:19 +0200 Subject: s4:dcesrv_samr - Cosmetics Make more use of constants and add some braces around "if" blocks --- source4/rpc_server/samr/dcesrv_samr.c | 54 ++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 23 deletions(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index b8af5fdeb3..e354df7f41 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -949,7 +949,7 @@ static NTSTATUS dcesrv_samr_SetDomainInfo(struct dcesrv_call_state *dce_call, TA /* modify the samdb record */ ret = ldb_modify(sam_ctx, msg); - if (ret != 0) { + if (ret != LDB_SUCCESS) { DEBUG(1,("Failed to modify record %s: %s\n", ldb_dn_get_linearized(d_state->domain_dn), ldb_errstring(sam_ctx))); @@ -1234,7 +1234,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL */ ret = ldb_transaction_start(d_state->sam_ctx); - if (ret != 0) { + if (ret != LDB_SUCCESS) { DEBUG(0,("Failed to start a transaction for user creation: %s\n", ldb_errstring(d_state->sam_ctx))); return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -1389,7 +1389,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL /* modify the samdb record */ ret = samdb_replace(a_state->sam_ctx, mem_ctx, msg); - if (ret != 0) { + if (ret != LDB_SUCCESS) { DEBUG(0,("Failed to modify account record %s to set userAccountControl: %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(d_state->sam_ctx))); @@ -1400,7 +1400,7 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL } ret = ldb_transaction_commit(d_state->sam_ctx); - if (ret != 0) { + if (ret != LDB_SUCCESS) { DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n", ldb_dn_get_linearized(msg->dn), ldb_errstring(d_state->sam_ctx))); @@ -2193,7 +2193,7 @@ static NTSTATUS dcesrv_samr_SetGroupInfo(struct dcesrv_call_state *dce_call, TAL /* modify the samdb record */ ret = ldb_modify(g_state->sam_ctx, msg); - if (ret != 0) { + if (ret != LDB_SUCCESS) { /* we really need samdb.c to return NTSTATUS */ return NT_STATUS_UNSUCCESSFUL; } @@ -2224,8 +2224,9 @@ static NTSTATUS dcesrv_samr_AddGroupMember(struct dcesrv_call_state *dce_call, T d_state = a_state->domain_state; membersid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid); - if (membersid == NULL) + if (membersid == NULL) { return NT_STATUS_NO_MEMORY; + } /* In native mode, AD can also nest domain groups. Not sure yet * whether this is also available via RPC. */ @@ -2234,7 +2235,7 @@ static NTSTATUS dcesrv_samr_AddGroupMember(struct dcesrv_call_state *dce_call, T "(&(objectSid=%s)(objectclass=user))", ldap_encode_ndr_dom_sid(mem_ctx, membersid)); - if (ret != 0) { + if (ret != LDB_SUCCESS) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -2258,9 +2259,11 @@ static NTSTATUS dcesrv_samr_AddGroupMember(struct dcesrv_call_state *dce_call, T mod->dn = talloc_reference(mem_ctx, a_state->account_dn); - if (samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member", - memberdn) != 0) + ret = samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member", + memberdn); + if (ret != LDB_SUCCESS) { return NT_STATUS_UNSUCCESSFUL; + } ret = ldb_modify(a_state->sam_ctx, mod); switch (ret) { @@ -2273,7 +2276,6 @@ static NTSTATUS dcesrv_samr_AddGroupMember(struct dcesrv_call_state *dce_call, T default: return NT_STATUS_UNSUCCESSFUL; } - } @@ -2294,7 +2296,7 @@ static NTSTATUS dcesrv_samr_DeleteDomainGroup(struct dcesrv_call_state *dce_call a_state = h->data; ret = ldb_delete(a_state->sam_ctx, a_state->account_dn); - if (ret != 0) { + if (ret != LDB_SUCCESS) { return NT_STATUS_UNSUCCESSFUL; } @@ -2336,7 +2338,7 @@ static NTSTATUS dcesrv_samr_DeleteGroupMember(struct dcesrv_call_state *dce_call "(&(objectSid=%s)(objectclass=user))", ldap_encode_ndr_dom_sid(mem_ctx, membersid)); - if (ret != 0) { + if (ret != LDB_SUCCESS) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -2360,8 +2362,9 @@ static NTSTATUS dcesrv_samr_DeleteGroupMember(struct dcesrv_call_state *dce_call mod->dn = talloc_reference(mem_ctx, a_state->account_dn); - if (samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, "member", - memberdn) != 0) { + ret = samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, "member", + memberdn); + if (ret != LDB_SUCCESS) { return NT_STATUS_NO_MEMORY; } @@ -2732,12 +2735,15 @@ static NTSTATUS dcesrv_samr_AddAliasMember(struct dcesrv_call_state *dce_call, T mod->dn = talloc_reference(mem_ctx, a_state->account_dn); - if (samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member", - ldb_dn_alloc_linearized(mem_ctx, memberdn)) != 0) + ret = samdb_msg_add_addval(d_state->sam_ctx, mem_ctx, mod, "member", + ldb_dn_alloc_linearized(mem_ctx, memberdn)); + if (ret != LDB_SUCCESS) { return NT_STATUS_UNSUCCESSFUL; + } - if (ldb_modify(a_state->sam_ctx, mod) != 0) + if (ldb_modify(a_state->sam_ctx, mod) != LDB_SUCCESS) { return NT_STATUS_UNSUCCESSFUL; + } return NT_STATUS_OK; } @@ -2754,6 +2760,7 @@ static NTSTATUS dcesrv_samr_DeleteAliasMember(struct dcesrv_call_state *dce_call struct samr_domain_state *d_state; struct ldb_message *mod; const char *memberdn; + int ret; DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS); @@ -2774,11 +2781,12 @@ static NTSTATUS dcesrv_samr_DeleteAliasMember(struct dcesrv_call_state *dce_call mod->dn = talloc_reference(mem_ctx, a_state->account_dn); - if (samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, "member", - memberdn) != 0) + ret = samdb_msg_add_delval(d_state->sam_ctx, mem_ctx, mod, "member", + memberdn); + if (ret != LDB_SUCCESS) return NT_STATUS_UNSUCCESSFUL; - if (ldb_modify(a_state->sam_ctx, mod) != 0) + if (ldb_modify(a_state->sam_ctx, mod) != LDB_SUCCESS) return NT_STATUS_UNSUCCESSFUL; return NT_STATUS_OK; @@ -2947,7 +2955,7 @@ static NTSTATUS dcesrv_samr_DeleteUser(struct dcesrv_call_state *dce_call, TALLO a_state = h->data; ret = ldb_delete(a_state->sam_ctx, a_state->account_dn); - if (ret != 0) { + if (ret != LDB_SUCCESS) { DEBUG(1, ("Failed to delete user: %s: %s\n", ldb_dn_get_linearized(a_state->account_dn), ldb_errstring(a_state->sam_ctx))); @@ -3604,7 +3612,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL /* modify the samdb record */ ret = ldb_modify(a_state->sam_ctx, msg); - if (ret != 0) { + if (ret != LDB_SUCCESS) { DEBUG(1,("Failed to modify record %s: %s\n", ldb_dn_get_linearized(a_state->account_dn), ldb_errstring(a_state->sam_ctx))); @@ -4188,8 +4196,8 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL "pwdProperties", 1); talloc_free(msgs); - talloc_free(sam_ctx); + return NT_STATUS_OK; } -- cgit From 7c53386adfb4658df11ed951614bbb7ec74af1cb Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 13 Oct 2009 00:45:26 +0200 Subject: s4:dcesrv_samr - Add additional "talloc_free"s --- source4/rpc_server/samr/dcesrv_samr.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index e354df7f41..b73add66c9 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -4183,10 +4183,14 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &msgs, attrs); if (ret <= 0) { + talloc_free(sam_ctx); + return NT_STATUS_NO_SUCH_DOMAIN; } if (ret > 1) { talloc_free(msgs); + talloc_free(sam_ctx); + return NT_STATUS_INTERNAL_DB_CORRUPTION; } -- cgit From 6b91a2ad8ebf6368c81eefdd225548e42a2ed0c4 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 13 Oct 2009 00:48:15 +0200 Subject: s4:dcesrv_samr - prevent "ldb_modify" on a possibly empty message In this code part under certain circumstances we can end up with an empty message. Since our new behaviour denies them (like the real AD) we need to bypass them on LDB modify calls. --- source4/rpc_server/samr/dcesrv_samr.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index b73add66c9..00820a3ab2 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -3611,14 +3611,16 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL } /* modify the samdb record */ - ret = ldb_modify(a_state->sam_ctx, msg); - if (ret != LDB_SUCCESS) { - DEBUG(1,("Failed to modify record %s: %s\n", - ldb_dn_get_linearized(a_state->account_dn), - ldb_errstring(a_state->sam_ctx))); - - /* we really need samdb.c to return NTSTATUS */ - return NT_STATUS_UNSUCCESSFUL; + if (msg->num_elements > 0) { + ret = ldb_modify(a_state->sam_ctx, msg); + if (ret != LDB_SUCCESS) { + DEBUG(1,("Failed to modify record %s: %s\n", + ldb_dn_get_linearized(a_state->account_dn), + ldb_errstring(a_state->sam_ctx))); + + /* we really need samdb.c to return NTSTATUS */ + return NT_STATUS_UNSUCCESSFUL; + } } return NT_STATUS_OK; -- cgit From c183acc782ffa881dac770b093f3a50cc24b6262 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 13 Oct 2009 17:29:52 +0200 Subject: s4:dcesrv_samr - add another constant --- source4/rpc_server/samr/dcesrv_samr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 00820a3ab2..6c5f5b845f 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -2646,7 +2646,7 @@ static NTSTATUS dcesrv_samr_SetAliasInfo(struct dcesrv_call_state *dce_call, TAL /* modify the samdb record */ ret = ldb_modify(a_state->sam_ctx, msg); - if (ret != 0) { + if (ret != LDB_SUCCESS) { /* we really need samdb.c to return NTSTATUS */ return NT_STATUS_UNSUCCESSFUL; } -- cgit From e9686985cbf1f5234d9e9731176b1eb4e02911e8 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Mon, 12 Oct 2009 19:09:18 +0200 Subject: s4: Changes the old occurences of "lp_realm" in "lp_dnsdomain" where needed For KERBEROS applications the realm should be upcase (function "lp_realm") but for DNS ones it should be used lowcase (function "lp_dnsdomain"). This patch implements the use of both in the right way. --- source4/rpc_server/drsuapi/addentry.c | 2 +- source4/rpc_server/netlogon/dcerpc_netlogon.c | 12 ++++++------ source4/rpc_server/spoolss/dcesrv_spoolss.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/drsuapi/addentry.c b/source4/rpc_server/drsuapi/addentry.c index 2c913dd91d..dbaf627130 100644 --- a/source4/rpc_server/drsuapi/addentry.c +++ b/source4/rpc_server/drsuapi/addentry.c @@ -82,7 +82,7 @@ static WERROR drsuapi_add_SPNs(struct drsuapi_bind_state *b_state, ntds_guid_str = GUID_string(res, &ntds_guid); - dom_string = lp_realm(dce_call->conn->dce_ctx->lp_ctx); + dom_string = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx); /* * construct a modify request to add the new SPNs to diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 5eccd7f6a8..f763069a3b 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -643,7 +643,7 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6); NT_STATUS_HAVE_NO_MEMORY(sam6); sam6->base = *sam; - sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx); + sam6->forest.string = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx); sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s", sam->account_name.string, sam6->forest.string); NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string); @@ -1096,7 +1096,7 @@ static NTSTATUS fill_one_domain_info(TALLOC_CTX *mem_ctx, if (is_local) { info->domainname.string = lp_sam_name(lp_ctx); - info->dns_domainname.string = lp_realm(lp_ctx); + info->dns_domainname.string = lp_dnsdomain(lp_ctx); info->domain_guid = samdb_result_guid(res, "objectGUID"); info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "objectSid"); } else { @@ -1432,14 +1432,14 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA */ info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s", lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx), - lp_realm(dce_call->conn->dce_ctx->lp_ctx)); + lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx)); W_ERROR_HAVE_NO_MEMORY(info->dc_unc); info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0"); W_ERROR_HAVE_NO_MEMORY(info->dc_address); info->dc_address_type = DS_ADDRESS_TYPE_INET; info->domain_guid = samdb_result_guid(res[0], "objectGUID"); - info->domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); - info->forest_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); + info->domain_name = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx); + info->forest_name = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx); info->dc_flags = DS_DNS_FOREST_ROOT | DS_DNS_DOMAIN | DS_DNS_CONTROLLER | @@ -1614,7 +1614,7 @@ static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce /* TODO: add filtering by trust_flags, and correct trust_type and attributes */ trusts->array[0].netbios_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx); - trusts->array[0].dns_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); + trusts->array[0].dns_name = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx); trusts->array[0].trust_flags = NETR_TRUST_FLAG_TREEROOT | NETR_TRUST_FLAG_IN_FOREST | diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.c b/source4/rpc_server/spoolss/dcesrv_spoolss.c index d380b10d8e..0e071dc74c 100644 --- a/source4/rpc_server/spoolss/dcesrv_spoolss.c +++ b/source4/rpc_server/spoolss/dcesrv_spoolss.c @@ -150,6 +150,7 @@ static WERROR dcesrv_spoolss_check_server_name(struct dcesrv_call_state *dce_cal bool ret; struct socket_address *myaddr; const char **aliases; + const char *dnsdomain; int i; /* NULL is ok */ @@ -186,12 +187,13 @@ static WERROR dcesrv_spoolss_check_server_name(struct dcesrv_call_state *dce_cal /* DNS NAME is ok * TODO: we need to check if aliases are also ok */ - if (lp_realm(dce_call->conn->dce_ctx->lp_ctx)) { + dnsdomain = lp_dnsdomain(dce_call->conn->dce_ctx->lp_ctx); + if (dnsdomain != NULL) { char *str; str = talloc_asprintf(mem_ctx, "%s.%s", lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx), - lp_realm(dce_call->conn->dce_ctx->lp_ctx)); + dnsdomain); W_ERROR_HAVE_NO_MEMORY(str); ret = strequal(str, server_name); -- cgit From f1bf262497d0a0f71bc52b0fac8c8aee8ecf13d9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Oct 2009 19:49:08 +1100 Subject: drs: improved error checking Check the validity of the requested options in DsGetNCChanges --- source4/rpc_server/drsuapi/getncchanges.c | 65 +++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 16 deletions(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index ae1b2e61eb..5957038ad2 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -328,6 +328,8 @@ struct drsuapi_getncchanges_state { /* drsuapi_DsGetNCChanges + + see MS-DRSR 4.1.10.5.2 for basic logic of this function */ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct drsuapi_DsGetNCChanges *r) @@ -345,6 +347,8 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ struct dcesrv_handle *h; struct drsuapi_bind_state *b_state; struct drsuapi_getncchanges_state *getnc_state; + struct drsuapi_DsGetNCChangesRequest8 *req8; + uint32_t options; DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); b_state = h->data; @@ -359,25 +363,43 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ r->out.ctr->ctr6.more_data = false; r->out.ctr->ctr6.uptodateness_vector = NULL; - /* Check request revision. */ + /* a RODC doesn't allow for any replication */ + if (samdb_rodc(ldb_get_opaque(b_state->sam_ctx, "loadparm"))) { + DEBUG(0,(__location__ ": DsGetNCChanges attempt on RODC\n")); + return WERR_DS_DRA_SOURCE_DISABLED; + } + + /* Check request revision. + TODO: Adding mappings to req8 from the other levels + */ if (r->in.level != 8) { + DEBUG(0,(__location__ ": Request for DsGetNCChanges with unsupported level %u\n", + r->in.level)); return WERR_REVISION_MISMATCH; } + req8 = &r->in.req->req8; + /* Perform access checks. */ - if (r->in.req->req8.naming_context == NULL) { + ncRoot = req8->naming_context; + if (ncRoot == NULL) { + DEBUG(0,(__location__ ": Request for DsGetNCChanges with no NC\n")); return WERR_DS_DRA_INVALID_PARAMETER; } - ncRoot = r->in.req->req8.naming_context; - if (ncRoot == NULL) { - return WERR_DS_DRA_BAD_NC; + if (samdb_ntds_options(b_state->sam_ctx, &options) != LDB_SUCCESS) { + return WERR_DS_DRA_INTERNAL_ERROR; + } + + if ((options & DS_NTDSDSA_OPT_DISABLE_OUTBOUND_REPL) && + !(req8->replica_flags & DRSUAPI_DRS_SYNC_FORCED)) { + return WERR_DS_DRA_SOURCE_DISABLED; } - if ((r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_FULL_SYNC_PACKET) - == DRSUAPI_DS_REPLICA_NEIGHBOUR_FULL_SYNC_PACKET) { + + if (req8->replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_FULL_SYNC_PACKET) { /* Ignore the _in_ uptpdateness vector*/ - r->in.req->req8.uptodateness_vector = NULL; + req8->uptodateness_vector = NULL; } werr = drs_security_level_check(dce_call, "DsGetNCChanges"); @@ -401,25 +423,36 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ return WERR_DS_DRA_INTERNAL_ERROR; } + /* we don't yet support extended operations */ + if (req8->extended_op != DRSUAPI_EXOP_NONE) { + DEBUG(0,(__location__ ": Request for DsGetNCChanges extended op 0x%x\n", + (unsigned)req8->extended_op)); + return WERR_DS_DRA_NOT_SUPPORTED; + } + + /* + TODO: MS-DRSR section 4.1.10.1.1 + Work out if this is the start of a new cycle */ + if (getnc_state->site_res == NULL) { char* search_filter; enum ldb_scope scope = LDB_SCOPE_SUBTREE; - getnc_state->min_usn = r->in.req->req8.highwatermark.highest_usn; + getnc_state->min_usn = req8->highwatermark.highest_usn; /* Construct response. */ search_filter = talloc_asprintf(mem_ctx, "(uSNChanged>=%llu)", (unsigned long long)(getnc_state->min_usn+1)); - if (r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_CRITICAL_ONLY) { + if (req8->replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_CRITICAL_ONLY) { search_filter = talloc_asprintf(mem_ctx, "(&%s(isCriticalSystemObject=TRUE))", search_filter); } getnc_state->ncRoot_dn = ldb_dn_new(getnc_state, b_state->sam_ctx, ncRoot->dn); - if (r->in.req->req8.replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_ASYNC_REP) { + if (req8->replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_ASYNC_REP) { scope = LDB_SCOPE_BASE; } @@ -473,15 +506,15 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ r->out.ctr->ctr6.source_dsa_guid = *(samdb_ntds_objectGUID(b_state->sam_ctx)); r->out.ctr->ctr6.source_dsa_invocation_id = *(samdb_ntds_invocation_id(b_state->sam_ctx)); - r->out.ctr->ctr6.old_highwatermark = r->in.req->req8.highwatermark; - r->out.ctr->ctr6.new_highwatermark = r->in.req->req8.highwatermark; + r->out.ctr->ctr6.old_highwatermark = req8->highwatermark; + r->out.ctr->ctr6.new_highwatermark = req8->highwatermark; r->out.ctr->ctr6.first_object = NULL; currentObject = &r->out.ctr->ctr6.first_object; for(i=getnc_state->num_sent; isite_res->count && - (r->out.ctr->ctr6.object_count < r->in.req->req8.max_object_count); + (r->out.ctr->ctr6.object_count < req8->max_object_count); i++) { int uSN; struct drsuapi_DsReplicaObjectListItemEx *obj; @@ -495,7 +528,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ werr = get_nc_changes_build_object(obj, getnc_state->site_res->msgs[i], b_state->sam_ctx, getnc_state->ncRoot_dn, schema, &session_key, getnc_state->min_usn, - r->in.req->req8.replica_flags); + req8->replica_flags); if (!W_ERROR_IS_OK(werr)) { return werr; } @@ -539,7 +572,7 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ } DEBUG(2,("DsGetNCChanges with uSNChanged >= %llu on %s gave %u objects\n", - (unsigned long long)(r->in.req->req8.highwatermark.highest_usn+1), + (unsigned long long)(req8->highwatermark.highest_usn+1), ncRoot->dn, r->out.ctr->ctr6.object_count)); return WERR_OK; -- cgit From 59818f2f793ecc6349b87ee0debc7dd558272552 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 14 Oct 2009 20:25:48 +1100 Subject: s4-drs: implement more of DsUpdateRefs The DsUpdateRefs calls takes a set of flags that indicates if the server should ignore specific add/delete error codes. This patch also exposes the core UpdateRefs call into a public function, so that it can be called from DsGetNCChanges --- source4/rpc_server/drsuapi/dcesrv_drsuapi.h | 2 + source4/rpc_server/drsuapi/updaterefs.c | 88 ++++++++++++++++++++--------- 2 files changed, 63 insertions(+), 27 deletions(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.h b/source4/rpc_server/drsuapi/dcesrv_drsuapi.h index 82899c8432..e42d9569e7 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.h +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.h @@ -39,6 +39,8 @@ struct drsuapi_bind_state { /* prototypes of internal functions */ +WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ctx, + struct drsuapi_DsReplicaUpdateRefsRequest1 *req); WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct drsuapi_DsReplicaUpdateRefs *r); WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, diff --git a/source4/rpc_server/drsuapi/updaterefs.c b/source4/rpc_server/drsuapi/updaterefs.c index d01fabf575..60a70c5032 100644 --- a/source4/rpc_server/drsuapi/updaterefs.c +++ b/source4/rpc_server/drsuapi/updaterefs.c @@ -35,16 +35,29 @@ struct repsTo { add a replication destination for a given partition GUID */ static WERROR uref_add_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, - struct ldb_dn *dn, struct repsFromTo1 *dest) + struct ldb_dn *dn, struct repsFromTo1 *dest, + uint32_t options) { struct repsTo reps; WERROR werr; + int i; werr = dsdb_loadreps(sam_ctx, mem_ctx, dn, "repsTo", &reps.r, &reps.count); if (!W_ERROR_IS_OK(werr)) { return werr; } + for (i=0; isource_dsa_obj_guid, + &reps.r[i].ctr.ctr1.source_dsa_obj_guid) == 0) { + if (options & DRSUAPI_DS_REPLICA_UPDATE_GETCHG_CHECK) { + return WERR_OK; + } else { + return WERR_DS_DRA_REF_ALREADY_EXISTS; + } + } + } + reps.r = talloc_realloc(mem_ctx, reps.r, struct repsFromToBlob, reps.count+1); if (reps.r == NULL) { return WERR_DS_DRA_INTERNAL_ERROR; @@ -66,11 +79,13 @@ static WERROR uref_add_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, delete a replication destination for a given partition GUID */ static WERROR uref_del_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, - struct ldb_dn *dn, struct GUID *dest_guid) + struct ldb_dn *dn, struct GUID *dest_guid, + uint32_t options) { struct repsTo reps; WERROR werr; int i; + bool found = false; werr = dsdb_loadreps(sam_ctx, mem_ctx, dn, "repsTo", &reps.r, &reps.count); if (!W_ERROR_IS_OK(werr)) { @@ -83,6 +98,7 @@ static WERROR uref_del_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, memmove(&reps.r[i], &reps.r[i+1], sizeof(reps.r[i])*(reps.count-(i+1))); } reps.count--; + found = true; } } @@ -91,35 +107,22 @@ static WERROR uref_del_dest(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, return werr; } + if (!found && !(options & DRSUAPI_DS_REPLICA_UPDATE_GETCHG_CHECK)) { + return WERR_DS_DRA_REF_NOT_FOUND; + } + return WERR_OK; } /* - drsuapi_DsReplicaUpdateRefs + drsuapi_DsReplicaUpdateRefs - a non RPC version callable from getncchanges */ -WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct drsuapi_DsReplicaUpdateRefs *r) +WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ctx, + struct drsuapi_DsReplicaUpdateRefsRequest1 *req) { - struct drsuapi_DsReplicaUpdateRefsRequest1 *req; WERROR werr; struct ldb_dn *dn; - struct dcesrv_handle *h; - struct drsuapi_bind_state *b_state; - - DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); - b_state = h->data; - - werr = drs_security_level_check(dce_call, "DsReplicaUpdateRefs"); - if (!W_ERROR_IS_OK(werr)) { - return werr; - } - if (r->in.level != 1) { - DEBUG(0,("DrReplicUpdateRefs - unsupported level %u\n", r->in.level)); - return WERR_DS_DRA_INVALID_PARAMETER; - } - - req = &r->in.req.req1; 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, @@ -136,10 +139,10 @@ WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TA } if (req->options & DRSUAPI_DS_REPLICA_UPDATE_DELETE_REFERENCE) { - werr = uref_del_dest(b_state->sam_ctx, mem_ctx, dn, &req->dest_dsa_guid); + 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(dce_call, &req->dest_dsa_guid))); + GUID_string(mem_ctx, &req->dest_dsa_guid))); goto failed; } } @@ -156,10 +159,10 @@ WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TA dest.source_dsa_obj_guid = req->dest_dsa_guid; dest.replica_flags = req->options; - werr = uref_add_dest(b_state->sam_ctx, mem_ctx, dn, &dest); + werr = uref_add_dest(b_state->sam_ctx, mem_ctx, dn, &dest, req->options); if (!W_ERROR_IS_OK(werr)) { - DEBUG(0,("Failed to delete repsTo for %s\n", - GUID_string(dce_call, &dest.source_dsa_obj_guid))); + DEBUG(0,("Failed to add repsTo for %s\n", + GUID_string(mem_ctx, &dest.source_dsa_obj_guid))); goto failed; } } @@ -175,3 +178,34 @@ failed: ldb_transaction_cancel(b_state->sam_ctx); return werr; } + +/* + drsuapi_DsReplicaUpdateRefs +*/ +WERROR dcesrv_drsuapi_DsReplicaUpdateRefs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct drsuapi_DsReplicaUpdateRefs *r) +{ + struct dcesrv_handle *h; + struct drsuapi_bind_state *b_state; + struct drsuapi_DsReplicaUpdateRefsRequest1 *req; + WERROR werr; + + DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); + b_state = h->data; + + werr = drs_security_level_check(dce_call, "DsReplicaUpdateRefs"); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + + if (r->in.level != 1) { + DEBUG(0,("DrReplicUpdateRefs - unsupported level %u\n", r->in.level)); + return WERR_DS_DRA_INVALID_PARAMETER; + } + + req = &r->in.req.req1; + + return drsuapi_UpdateRefs(b_state, mem_ctx, req); +} + + -- cgit From d1784e7ca92ba8c6579da6a6238a3f95d67a463d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 14 Oct 2009 20:29:39 +1100 Subject: s4-drs: support DRSUAPI_DRS_ADD_REF flag The DRSUAPI_DRS_ADD_REF flag tells the DRS server to run an UpdateRefs call on behalf of the client after the DsGetNCChanges call. The lack of support for this option may explain why the repsTo attribute was not being created for w2k8-r2 replication partners. --- source4/rpc_server/drsuapi/getncchanges.c | 34 ++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index 5957038ad2..90ddab083c 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -141,8 +141,10 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem instanceType then don't include it */ if (md.ctr.ctr1.array[i].local_usn < highest_usn && md.ctr.ctr1.array[i].attid != DRSUAPI_ATTRIBUTE_instanceType) continue; + /* don't include the rDN */ if (md.ctr.ctr1.array[i].attid == rdn_sa->attributeID_id) continue; + obj->meta_data_ctr->meta_data[n].originating_change_time = md.ctr.ctr1.array[i].originating_change_time; obj->meta_data_ctr->meta_data[n].version = md.ctr.ctr1.array[i].version; obj->meta_data_ctr->meta_data[n].originating_invocation_id = md.ctr.ctr1.array[i].originating_invocation_id; @@ -205,12 +207,10 @@ static WERROR get_nc_changes_build_object(struct drsuapi_DsReplicaObjectListItem sa->lDAPDisplayName, win_errstr(werr))); return werr; } - /* if DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING is set + /* if DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING is set * check if attribute is secret and send a null value - * TODO: check if we can make this in the database layer */ - if ((replica_flags & DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING) - == DRSUAPI_DS_REPLICA_NEIGHBOUR_SPECIAL_SECRET_PROCESSING) { + if (replica_flags & DRSUAPI_DRS_SPECIAL_SECRET_PROCESSING) { drsuapi_process_secret_attribute(&obj->object.attribute_ctr.attributes[i], &obj->meta_data_ctr->meta_data[i]); } @@ -551,6 +551,29 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ r->out.ctr->ctr6.nc_object_count = getnc_state->site_res->count; + /* the client can us to call UpdateRefs on its behalf to + re-establish monitoring of the NC */ + if ((req8->replica_flags & DRSUAPI_DRS_ADD_REF) && + !GUID_all_zero(&req8->destination_dsa_guid)) { + struct drsuapi_DsReplicaUpdateRefsRequest1 ureq; + ureq.naming_context = ncRoot; + ureq.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "%s._msdcs.%s", + GUID_string(mem_ctx, &req8->destination_dsa_guid), + lp_realm(dce_call->conn->dce_ctx->lp_ctx)); + if (!ureq.dest_dsa_dns_name) { + return WERR_NOMEM; + } + ureq.dest_dsa_guid = req8->destination_dsa_guid; + ureq.options = DRSUAPI_DS_REPLICA_UPDATE_ADD_REFERENCE | + DRSUAPI_DS_REPLICA_UPDATE_ASYNCHRONOUS_OPERATION | + DRSUAPI_DS_REPLICA_UPDATE_GETCHG_CHECK; + werr = drsuapi_UpdateRefs(b_state, mem_ctx, &ureq); + if (!W_ERROR_IS_OK(werr)) { + DEBUG(0,(__location__ ": Failed UpdateRefs in DsGetNCChanges - %s\n", + win_errstr(werr))); + } + } + if (i < getnc_state->site_res->count) { r->out.ctr->ctr6.more_data = true; } else { @@ -571,8 +594,9 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ b_state->getncchanges_state = NULL; } - DEBUG(2,("DsGetNCChanges with uSNChanged >= %llu on %s gave %u objects\n", + DEBUG(2,("DsGetNCChanges with uSNChanged >= %llu flags 0x%08x on %s gave %u objects\n", (unsigned long long)(req8->highwatermark.highest_usn+1), + req8->replica_flags, ncRoot->dn, r->out.ctr->ctr6.object_count)); return WERR_OK; -- cgit From c35f18513ac804b6734630a943d70811bb8fb2d0 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Thu, 15 Oct 2009 13:24:30 +0200 Subject: s4:dcerpc_server - Read the generic session key out from "dcerpc_generic_session_key" I don't think that this code needs to exist identically on the server and on the client side. This patch leaves it on the client side (dcerpc lib) and calls it from the server. --- source4/rpc_server/dcerpc_server.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index df0c2e7345..75c5035459 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -336,13 +336,10 @@ NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p, return NT_STATUS_NO_USER_SESSION_KEY; } -NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *p, +NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *c, DATA_BLOB *session_key) { - /* this took quite a few CPU cycles to find ... */ - session_key->data = discard_const_p(uint8_t, "SystemLibraryDTC"); - session_key->length = 16; - return NT_STATUS_OK; + return dcerpc_generic_session_key(NULL, session_key); } /* -- cgit From 30be3fd143bc558ffdac2a6fcf992d5a39f8f7d9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 Oct 2009 17:05:27 +1100 Subject: s4-privileges: moved privileges to private/privilege.ldb We were storing privileges in the sam, which was OK when we were a standalone DC, but is no good when we replicate with a windows DC. This moves the privileges to a separate (local) database --- source4/rpc_server/lsa/dcesrv_lsa.c | 69 ++++++++++++++++++++----------------- source4/rpc_server/lsa/lsa.h | 1 + source4/rpc_server/lsa/lsa_init.c | 7 ++++ 3 files changed, 45 insertions(+), 32 deletions(-) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 3d6352af46..0a5fc54d68 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -80,7 +80,7 @@ static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx, TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid); - NT_STATUS_NOT_OK_RETURN(status); + NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx); domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS); NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid, tmp_ctx); @@ -694,7 +694,7 @@ static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALL /* NOTE: This call must only return accounts that have at least one privilege set */ - ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, + ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, "(&(objectSid=*)(privilege=*))"); if (ret < 0) { return NT_STATUS_NO_SUCH_USER; @@ -1830,7 +1830,7 @@ static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, return NT_STATUS_NO_MEMORY; } - ret = gendb_search(astate->policy->sam_ldb, mem_ctx, NULL, &res, attrs, + ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs, "objectSid=%s", sidstr); if (ret != 1) { return NT_STATUS_OK; @@ -1886,7 +1886,7 @@ static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, return NT_STATUS_NO_MEMORY; } - ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, + ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, "(&(objectSid=%s)(privilege=*))", sidstr); if (ret == 0) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; @@ -1897,7 +1897,7 @@ static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, if (ret == -1) { DEBUG(3, ("searching for account rights for SID: %s failed: %s", dom_sid_string(mem_ctx, r->in.sid), - ldb_errstring(state->sam_ldb))); + ldb_errstring(state->pdb))); return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -1932,40 +1932,29 @@ static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_ struct dom_sid *sid, const struct lsa_RightSet *rights) { - const char *sidstr; + const char *sidstr, *sidndrstr; struct ldb_message *msg; struct ldb_message_element *el; int i, ret; struct lsa_EnumAccountRights r2; - - sidstr = ldap_encode_ndr_dom_sid(mem_ctx, sid); - if (sidstr == NULL) { - return NT_STATUS_NO_MEMORY; - } + char *dnstr; msg = ldb_msg_new(mem_ctx); if (msg == NULL) { return NT_STATUS_NO_MEMORY; } - msg->dn = samdb_search_dn(state->sam_ldb, mem_ctx, - NULL, "objectSid=%s", sidstr); - if (msg->dn == NULL) { - NTSTATUS status; - if (ldb_flag == LDB_FLAG_MOD_DELETE) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - status = samdb_create_foreign_security_principal(state->sam_ldb, mem_ctx, - sid, &msg->dn); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - return NT_STATUS_NO_SUCH_USER; - } + sidndrstr = ldap_encode_ndr_dom_sid(msg, sid); + NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg); - if (ldb_msg_add_empty(msg, "privilege", ldb_flag, NULL)) { - return NT_STATUS_NO_MEMORY; - } + sidstr = dom_sid_string(msg, sid); + NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg); + + dnstr = talloc_asprintf(msg, "sid=%s", sidstr); + NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg); + + msg->dn = ldb_dn_new(msg, state->pdb, dnstr); + NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg); if (ldb_flag == LDB_FLAG_MOD_ADD) { NTSTATUS status; @@ -1982,6 +1971,7 @@ static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_ for (i=0;icount;i++) { if (sec_privilege_id(rights->names[i].string) == -1) { + talloc_free(msg); return NT_STATUS_NO_SUCH_PRIVILEGE; } @@ -1998,26 +1988,41 @@ static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_ ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string); if (ret != LDB_SUCCESS) { + talloc_free(msg); return NT_STATUS_NO_MEMORY; } } el = ldb_msg_find_element(msg, "privilege"); if (!el) { + talloc_free(msg); return NT_STATUS_OK; } - ret = ldb_modify(state->sam_ldb, msg); + el->flags = ldb_flag; + + ret = ldb_modify(state->pdb, msg); + if (ret == LDB_ERR_NO_SUCH_OBJECT) { + if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) { + talloc_free(msg); + return NT_STATUS_NO_MEMORY; + } + samdb_msg_add_string(state->pdb, msg, msg, "comment", "added via LSA"); + ret = ldb_add(state->pdb, msg); + } if (ret != 0) { if (ldb_flag == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + talloc_free(msg); + return NT_STATUS_OK; } DEBUG(3, ("Could not %s attributes from %s: %s", ldb_flag == LDB_FLAG_MOD_DELETE ? "delete" : "add", - ldb_dn_get_linearized(msg->dn), ldb_errstring(state->sam_ldb))); + ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb))); + talloc_free(msg); return NT_STATUS_UNEXPECTED_IO_ERROR; } + talloc_free(msg); return NT_STATUS_OK; } @@ -2880,7 +2885,7 @@ static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *d return NT_STATUS_NO_SUCH_PRIVILEGE; } - ret = gendb_search(state->sam_ldb, mem_ctx, NULL, &res, attrs, + ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, "privilege=%s", privname); if (ret == -1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; diff --git a/source4/rpc_server/lsa/lsa.h b/source4/rpc_server/lsa/lsa.h index ffdf96d091..53fe102630 100644 --- a/source4/rpc_server/lsa/lsa.h +++ b/source4/rpc_server/lsa/lsa.h @@ -40,6 +40,7 @@ struct lsa_policy_state { struct dcesrv_handle *handle; struct ldb_context *sam_ldb; + struct ldb_context *pdb; uint32_t access_mask; struct ldb_dn *domain_dn; struct ldb_dn *forest_dn; diff --git a/source4/rpc_server/lsa/lsa_init.c b/source4/rpc_server/lsa/lsa_init.c index ae565a3ff1..dd7d46b41d 100644 --- a/source4/rpc_server/lsa/lsa_init.c +++ b/source4/rpc_server/lsa/lsa_init.c @@ -21,6 +21,7 @@ */ #include "rpc_server/lsa/lsa.h" +#include "dsdb/samdb/samdb_proto.h" NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct lsa_policy_state **_state) @@ -48,6 +49,12 @@ NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_ return NT_STATUS_INVALID_SYSTEM_SERVICE; } + /* and the privilege database */ + state->pdb = privilege_connect(state, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx); + if (state->pdb == NULL) { + return NT_STATUS_INVALID_SYSTEM_SERVICE; + } + /* work out the domain_dn - useful for so many calls its worth fetching here */ state->domain_dn = ldb_get_default_basedn(state->sam_ldb); -- cgit From 9526487010fff240d2f55f29352e7f74d3cec65a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 Oct 2009 18:22:48 +1100 Subject: s4-lsasrv: make sure only admins can alter privileges --- source4/rpc_server/lsa/dcesrv_lsa.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/rpc_server') diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 0a5fc54d68..0e6a55ec2f 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -1939,6 +1939,12 @@ static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_ struct lsa_EnumAccountRights r2; char *dnstr; + if (security_session_user_level(dce_call->conn->auth_state.session_info) < + SECURITY_ADMINISTRATOR) { + DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n")); + return NT_STATUS_ACCESS_DENIED; + } + msg = ldb_msg_new(mem_ctx); if (msg == NULL) { return NT_STATUS_NO_MEMORY; -- cgit