From bd3f7f03c6af172ceb36ebf65b9688b9e9391972 Mon Sep 17 00:00:00 2001 From: Anatoliy Atanasov Date: Wed, 28 Jul 2010 14:50:18 +0300 Subject: [PATCH] s4: update dNSHostName on Server object during DsAddEntry --- source4/rpc_server/drsuapi/addentry.c | 86 +++++++++++++++++++++++++++++++++ 1 files changed, 86 insertions(+), 0 deletions(-) diff --git a/source4/rpc_server/drsuapi/addentry.c b/source4/rpc_server/drsuapi/addentry.c index ab75ff4..f45da15 100644 --- a/source4/rpc_server/drsuapi/addentry.c +++ b/source4/rpc_server/drsuapi/addentry.c @@ -29,6 +29,86 @@ #include "librpc/gen_ndr/ndr_drsuapi.h" #include "libcli/security/security.h" + +/* + * objectClass=server must have dNSHostName attribute generated by the server + */ +static WERROR drsuapi_update_dnshostname(struct drsuapi_bind_state *b_state, + struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + const struct drsuapi_DsReplicaObjectListItem *first_object) +{ + int ret; + const struct drsuapi_DsReplicaObjectListItem *obj; + const char *attrs[] = { "serverReference", NULL }; + + for (obj = first_object; obj; obj=obj->next_object) { + const char *dn_string = obj->object.identifier->dn; + struct ldb_dn *dn = ldb_dn_new(mem_ctx, b_state->sam_ctx, dn_string); + struct ldb_dn *dn_server = ldb_dn_get_parent(mem_ctx, dn); + struct ldb_message *msg; + struct ldb_message_element *el; + const char *dNSHostName; + struct ldb_result *res, *res2; + struct ldb_dn *ref_dn; + const char *attrs2[] = { "dNSHostName", NULL }; + + ret = ldb_search(b_state->sam_ctx, mem_ctx, &res, + dn, LDB_SCOPE_BASE, attrs, + "(objectClass=nTDSDSA)"); + if (ret != LDB_SUCCESS || res->count < 1) { + DEBUG(0,(__location__ ": Failed to find dn '%s'\n", dn_string)); + return WERR_DS_DRA_INTERNAL_ERROR; + } + + ref_dn = samdb_result_dn(b_state->sam_ctx, mem_ctx, res->msgs[0], "serverReference", NULL); + if (ref_dn == NULL) { + /* we only add SPNs for objects with a + serverReference */ + continue; + } + + ret = ldb_search(b_state->sam_ctx, mem_ctx, &res2, + ref_dn, LDB_SCOPE_BASE, attrs2, NULL); + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ ": Failed to find ref_dn '%s'\n", + ldb_dn_get_linearized(ref_dn))); + return WERR_DS_DRA_INTERNAL_ERROR; + } + + dNSHostName = ldb_msg_find_attr_as_string(res2->msgs[0], "dNSHostName", NULL); + if (!dNSHostName) { + DEBUG(0,(__location__ ": Failed to find dNSHostName for '%s'\n", + ldb_dn_get_linearized(ref_dn))); + return WERR_DS_DRA_INTERNAL_ERROR; + } + /* + * construct a modify request to add the new SPNs to + * the machine account + */ + msg = ldb_msg_new(mem_ctx); + if (msg == NULL) { + return WERR_NOMEM; + } + + msg->dn = dn_server; + ret = ldb_msg_add_empty(msg, "dNSHostName", LDB_FLAG_MOD_ADD, &el); + if (ret != LDB_SUCCESS) { + return WERR_NOMEM; + } + + ldb_msg_add_steal_string(msg, + "dNSHostName", + talloc_asprintf(el->values, "%s", dNSHostName)); + ret = dsdb_modify(b_state->sam_ctx, msg, DSDB_MODIFY_PERMISSIVE); + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ ": Failed to add dnsHostName to the Server object: %s\n", + ldb_errstring(b_state->sam_ctx))); + return WERR_DS_DRA_INTERNAL_ERROR; + } + } + return WERR_OK; +} + /* add special SPNs needed for DRS replication to machine accounts when an AddEntry is done to create a nTDSDSA object @@ -206,6 +286,12 @@ WERROR dcesrv_drsuapi_DsAddEntry(struct dcesrv_call_state *dce_call, TALLOC_CTX return WERR_FOOBAR; } + /* update dNSHostName attribute for the Server entry */ + status = drsuapi_update_dnshostname(b_state, dce_call, mem_ctx, first_object); + if (!W_ERROR_IS_OK(status)) { + DEBUG(0,(__location__ ": DsAddEntry update dNSHostName - %s\n", win_errstr(status))); + } + /* if any of the added entries are nTDSDSA objects then we * need to add the SPNs to the machine account */ -- 1.7.0.4