The branch, master has been updated via a44030fc10217940c94a927c3d0988648058e0e2 (commit) via 0285d568c55410f3e2a5cfda5693873be2841151 (commit) via f800d4998dc5cfa1e8ed2639dc334add78ceaea5 (commit) via a021d5513846968c54d6e065dbcb25948418676f (commit) via 9c1e230bc217e7d1ce0ef713a17982a8536584a1 (commit) via b43479741a3d9ae1abb91a5297a36f9d5e6d864b (commit) from 40b09f689bea23eaa6dbaa3e29b0a91adcd06a53 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit a44030fc10217940c94a927c3d0988648058e0e2 Author: Andrew Tridgell <tri...@samba.org> Date: Tue Oct 6 18:59:47 2009 +1100 s4-drs: added some debug lines to DsAddEntry() commit 0285d568c55410f3e2a5cfda5693873be2841151 Author: Andrew Tridgell <tri...@samba.org> Date: Tue Oct 6 18:59:30 2009 +1100 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 commit f800d4998dc5cfa1e8ed2639dc334add78ceaea5 Author: Andrew Tridgell <tri...@samba.org> Date: Tue Oct 6 18:58:41 2009 +1100 s4-drs: fixed error message for drs_security_level_check commit a021d5513846968c54d6e065dbcb25948418676f Author: Andrew Tridgell <tri...@samba.org> Date: Tue Oct 6 18:58:13 2009 +1100 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. commit 9c1e230bc217e7d1ce0ef713a17982a8536584a1 Author: Andrew Tridgell <tri...@samba.org> Date: Tue Oct 6 18:57:06 2009 +1100 s4-ldb: fixed error on single value error When you try to add a 2nd value to a single valued attribute you get LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS. w2k8-r2 join to s4 relies on this error, doing a replace after it sees the error commit b43479741a3d9ae1abb91a5297a36f9d5e6d864b Author: Andrew Tridgell <tri...@samba.org> Date: Tue Oct 6 18:55:14 2009 +1100 s4-repl: added RELAX control and fix transactions Added the RELAX control to dsdb_origin_objects_commit(), as it needs to modify system objects. This patch also fixes the use of ldb transactions in that function, and fixes a memory leak. ----------------------------------------------------------------------- Summary of changes: source4/dsdb/repl/replicated_objects.c | 65 +++++++++++++++++++++++--- source4/lib/ldb/ldb_tdb/ldb_tdb.c | 2 +- source4/rpc_server/drsuapi/addentry.c | 3 + source4/rpc_server/drsuapi/dcesrv_drsuapi.c | 15 ++++++- source4/rpc_server/drsuapi/drsutil.c | 4 +- source4/rpc_server/drsuapi/getncchanges.c | 33 ++++--------- source4/rpc_server/drsuapi/updaterefs.c | 29 +++++------- 7 files changed, 99 insertions(+), 52 deletions(-) Changeset truncated at 500 lines: diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c index 5d7ae11..9877803 100644 --- a/source4/dsdb/repl/replicated_objects.c +++ b/source4/dsdb/repl/replicated_objects.c @@ -424,35 +424,78 @@ WERROR dsdb_origin_objects_commit(struct ldb_context *ldb, return WERR_OK; } + ret = ldb_transaction_start(ldb); + if (ret != LDB_SUCCESS) { + return WERR_DS_INTERNAL_FAILURE; + } + objects = talloc_array(mem_ctx, struct ldb_message *, num_objects); - W_ERROR_HAVE_NO_MEMORY(objects); + if (objects == NULL) { + status = WERR_NOMEM; + goto cancel; + } for (i=0, cur = first_object; cur; cur = cur->next_object, i++) { status = dsdb_convert_object(ldb, schema, cur, objects, &objects[i]); - W_ERROR_NOT_OK_RETURN(status); + if (!W_ERROR_IS_OK(status)) { + goto cancel; + } } - ids = talloc_array(mem_ctx, + ids = talloc_array(objects, struct drsuapi_DsReplicaObjectIdentifier2, num_objects); - W_ERROR_HAVE_NO_MEMORY(objects); + if (ids == NULL) { + status = WERR_NOMEM; + goto cancel; + } for (i=0; i < num_objects; i++) { struct dom_sid *sid = NULL; + struct ldb_request *add_req; DEBUG(6,(__location__ ": adding %s\n", ldb_dn_get_linearized(objects[i]->dn))); + + ret = ldb_build_add_req(&add_req, + ldb, + objects, + objects[i], + NULL, + NULL, + ldb_op_default_callback, + NULL); + if (ret != LDB_SUCCESS) { + status = WERR_DS_INTERNAL_FAILURE; + goto cancel; + } + + ret = ldb_request_add_control(add_req, LDB_CONTROL_RELAX_OID, true, NULL); + if (ret != LDB_SUCCESS) { + status = WERR_DS_INTERNAL_FAILURE; + goto cancel; + } - ret = ldb_add(ldb, objects[i]); - if (ret != 0) { + ret = ldb_request(ldb, add_req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(add_req->handle, LDB_WAIT_ALL); + } + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ ": Failed add of %s - %s\n", + ldb_dn_get_linearized(objects[i]->dn), ldb_errstring(ldb))); + status = WERR_DS_INTERNAL_FAILURE; goto cancel; } + + talloc_free(add_req); + ret = ldb_search(ldb, objects, &res, objects[i]->dn, LDB_SCOPE_BASE, attrs, "(objectClass=*)"); - if (ret != 0) { + if (ret != LDB_SUCCESS) { + status = WERR_DS_INTERNAL_FAILURE; goto cancel; } ids[i].guid = samdb_result_guid(res->msgs[0], "objectGUID"); @@ -464,13 +507,19 @@ WERROR dsdb_origin_objects_commit(struct ldb_context *ldb, } } + ret = ldb_transaction_commit(ldb); + if (ret != LDB_SUCCESS) { + return WERR_DS_INTERNAL_FAILURE; + } + talloc_free(objects); *_num = num_objects; *_ids = ids; return WERR_OK; + cancel: talloc_free(objects); ldb_transaction_cancel(ldb); - return WERR_FOOBAR; + return status; } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 0820895..66a10b6 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -664,7 +664,7 @@ int ltdb_modify_internal(struct ldb_module *module, * exists in the object, then we violoate the * single-value rule */ if (a && a->flags & LDB_ATTR_FLAG_SINGLE_VALUE) { - ret = LDB_ERR_CONSTRAINT_VIOLATION; + ret = LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; goto failed; } diff --git a/source4/rpc_server/drsuapi/addentry.c b/source4/rpc_server/drsuapi/addentry.c index 7bf8f39..2c913dd 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; } diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index 9903f08..f11cc23 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; } diff --git a/source4/rpc_server/drsuapi/drsutil.c b/source4/rpc_server/drsuapi/drsutil.c index 84bb5ff..1b4c28c 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; } diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index 2bfdf52..5713d41 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 e12be6f..d01fabf 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; } -- Samba Shared Repository