diff options
Diffstat (limited to 'source4/rpc_server')
-rw-r--r-- | source4/rpc_server/common/server_info.c | 18 | ||||
-rw-r--r-- | source4/rpc_server/dcerpc_server.c | 28 | ||||
-rw-r--r-- | source4/rpc_server/dcerpc_server.h | 8 | ||||
-rw-r--r-- | source4/rpc_server/drsuapi/getncchanges.c | 186 | ||||
-rw-r--r-- | source4/rpc_server/lsa/dcesrv_lsa.c | 2 | ||||
-rw-r--r-- | source4/rpc_server/netlogon/dcerpc_netlogon.c | 17 | ||||
-rw-r--r-- | source4/rpc_server/samr/dcesrv_samr.c | 7 |
7 files changed, 172 insertions, 94 deletions
diff --git a/source4/rpc_server/common/server_info.c b/source4/rpc_server/common/server_info.c index 7f533ecf77..68985d81aa 100644 --- a/source4/rpc_server/common/server_info.c +++ b/source4/rpc_server/common/server_info.c @@ -68,22 +68,8 @@ uint32_t dcesrv_common_get_server_type(TALLOC_CTX *mem_ctx, struct tevent_contex default_server_announce |= SV_TYPE_SERVER; default_server_announce |= SV_TYPE_SERVER_UNIX; - switch (lpcfg_announce_as(dce_ctx->lp_ctx)) { - case ANNOUNCE_AS_NT_SERVER: - default_server_announce |= SV_TYPE_SERVER_NT; - /* fall through... */ - case ANNOUNCE_AS_NT_WORKSTATION: - default_server_announce |= SV_TYPE_NT; - break; - case ANNOUNCE_AS_WIN95: - default_server_announce |= SV_TYPE_WIN95_PLUS; - break; - case ANNOUNCE_AS_WFW: - default_server_announce |= SV_TYPE_WFW; - break; - default: - break; - } + default_server_announce |= SV_TYPE_SERVER_NT; + default_server_announce |= SV_TYPE_NT; switch (lpcfg_server_role(dce_ctx->lp_ctx)) { case ROLE_DOMAIN_MEMBER: diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index cd079da5c9..cbba5e2408 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -366,7 +366,7 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint *ep, struct auth_session_info *session_info, struct tevent_context *event_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct server_id server_id, uint32_t state_flags, struct dcesrv_connection **_p) @@ -1235,7 +1235,7 @@ void dcerpc_server_init(struct loadparm_context *lp_ctx) } initialized = true; - shared_init = load_samba_modules(NULL, lp_ctx, "dcerpc_server"); + shared_init = load_samba_modules(NULL, "dcerpc_server"); run_init_functions(static_init); run_init_functions(shared_init); @@ -1353,7 +1353,7 @@ static void dcesrv_sock_reply_done(struct tevent_req *subreq) ret = tstream_writev_queue_recv(subreq, &sys_errno); TALLOC_FREE(subreq); if (ret == -1) { - status = map_nt_error_from_unix(sys_errno); + status = map_nt_error_from_unix_common(sys_errno); dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status)); return; } @@ -1436,7 +1436,7 @@ static void dcesrv_sock_accept(struct stream_connection *srv_conn) socket_get_fd(srv_conn->socket), &dcesrv_conn->stream); if (ret == -1) { - status = map_nt_error_from_unix(errno); + status = map_nt_error_from_unix_common(errno); DEBUG(0, ("dcesrv_sock_accept: " "failed to setup tstream: %s\n", nt_errstr(status))); @@ -1648,7 +1648,7 @@ static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx, model_ops, &dcesrv_stream_ops, - "ipv4", address, &port, + "ip", address, &port, lpcfg_socket_options(dce_ctx->lp_ctx), dcesrv_sock); if (!NT_STATUS_IS_OK(status)) { @@ -1678,18 +1678,24 @@ static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx, int i; struct interface *ifaces; - load_interfaces(dce_ctx, lpcfg_interfaces(lp_ctx), &ifaces); + load_interface_list(dce_ctx, lp_ctx, &ifaces); - num_interfaces = iface_count(ifaces); + num_interfaces = iface_list_count(ifaces); for(i = 0; i < num_interfaces; i++) { - const char *address = iface_n_ip(ifaces, i); + const char *address = iface_list_n_ip(ifaces, i); status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address); NT_STATUS_NOT_OK_RETURN(status); } } else { - status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, - lpcfg_socket_address(lp_ctx)); - NT_STATUS_NOT_OK_RETURN(status); + const char **wcard; + int i; + wcard = iface_list_wildcard(dce_ctx, lp_ctx); + NT_STATUS_HAVE_NO_MEMORY(wcard); + for (i=0; wcard[i]; i++) { + status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]); + NT_STATUS_NOT_OK_RETURN(status); + } + talloc_free(wcard); } return NT_STATUS_OK; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 024009ab70..4fcb5c50a1 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -23,7 +23,7 @@ #ifndef SAMBA_DCERPC_SERVER_H #define SAMBA_DCERPC_SERVER_H -#include "librpc/gen_ndr/server_id4.h" +#include "librpc/gen_ndr/server_id.h" #include "librpc/rpc/dcerpc.h" #include "librpc/ndr/libndr.h" @@ -111,7 +111,7 @@ struct dcesrv_call_state { struct tevent_context *event_ctx; /* the message_context that will be used for async replies */ - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; /* this is the pointer to the allocated function struct */ void *r; @@ -200,7 +200,7 @@ struct dcesrv_connection { struct tevent_context *event_ctx; /* the message_context that will be used for this connection */ - struct messaging_context *msg_ctx; + struct imessaging_context *msg_ctx; /* the server_id that will be used for this connection */ struct server_id server_id; @@ -319,7 +319,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint *ep, struct auth_session_info *session_info, struct tevent_context *event_ctx, - struct messaging_context *msg_ctx, + struct imessaging_context *msg_ctx, struct server_id server_id, uint32_t state_flags, struct dcesrv_connection **_p); diff --git a/source4/rpc_server/drsuapi/getncchanges.c b/source4/rpc_server/drsuapi/getncchanges.c index 8ae536823d..c57fec2049 100644 --- a/source4/rpc_server/drsuapi/getncchanges.c +++ b/source4/rpc_server/drsuapi/getncchanges.c @@ -360,27 +360,37 @@ static WERROR get_nc_changes_add_la(TALLOC_CTX *mem_ctx, la->attid = sa->attributeID_id; la->flags = active?DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE:0; - status = dsdb_get_extended_dn_nttime(dsdb_dn->dn, &la->originating_add_time, "RMD_ADDTIME"); - if (!NT_STATUS_IS_OK(status)) { - return ntstatus_to_werror(status); - } status = dsdb_get_extended_dn_uint32(dsdb_dn->dn, &la->meta_data.version, "RMD_VERSION"); if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,(__location__ " No RMD_VERSION in linked attribute '%s' in '%s'\n", + sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn))); return ntstatus_to_werror(status); } status = dsdb_get_extended_dn_nttime(dsdb_dn->dn, &la->meta_data.originating_change_time, "RMD_CHANGETIME"); if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,(__location__ " No RMD_CHANGETIME in linked attribute '%s' in '%s'\n", + sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn))); return ntstatus_to_werror(status); } status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &la->meta_data.originating_invocation_id, "RMD_INVOCID"); if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,(__location__ " No RMD_INVOCID in linked attribute '%s' in '%s'\n", + sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn))); return ntstatus_to_werror(status); } status = dsdb_get_extended_dn_uint64(dsdb_dn->dn, &la->meta_data.originating_usn, "RMD_ORIGINATING_USN"); if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,(__location__ " No RMD_ORIGINATING_USN in linked attribute '%s' in '%s'\n", + sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn))); return ntstatus_to_werror(status); } + status = dsdb_get_extended_dn_nttime(dsdb_dn->dn, &la->originating_add_time, "RMD_ADDTIME"); + if (!NT_STATUS_IS_OK(status)) { + /* this is possible for upgraded links */ + la->originating_add_time = la->meta_data.originating_change_time; + } + werr = dsdb_dn_la_to_blob(sam_ctx, sa, schema, *la_list, dsdb_dn, &la->value.blob); W_ERROR_NOT_OK_RETURN(werr); @@ -993,12 +1003,14 @@ static WERROR getncchanges_change_master(struct drsuapi_bind_state *b_state, msg->dn = drs_ObjectIdentifier_to_dn(msg, ldb, req10->naming_context); W_ERROR_HAVE_NO_MEMORY(msg->dn); + /* TODO: make sure ntds_dn is a valid nTDSDSA object */ ret = dsdb_find_dn_by_guid(ldb, msg, &req10->destination_dsa_guid, &ntds_dn); if (ret != LDB_SUCCESS) { DEBUG(0, (__location__ ": Unable to find NTDS object for guid %s - %s\n", GUID_string(mem_ctx, &req10->destination_dsa_guid), ldb_errstring(ldb))); talloc_free(msg); - return WERR_DS_DRA_INTERNAL_ERROR; + ctr6->extended_ret = DRSUAPI_EXOP_ERR_UNKNOWN_CALLER; + return WERR_OK; } ret = ldb_msg_add_string(msg, "fSMORoleOwner", ldb_dn_get_linearized(ntds_dn)); @@ -1161,6 +1173,91 @@ getncchanges_map_req8(TALLOC_CTX *mem_ctx, } +/** + * Collects object for normal replication cycle. + */ +static WERROR getncchanges_collect_objects(struct drsuapi_bind_state *b_state, + TALLOC_CTX *mem_ctx, + struct drsuapi_DsGetNCChangesRequest10 *req10, + struct ldb_dn *search_dn, + const char *extra_filter, + struct ldb_result **search_res) +{ + int ret; + char* search_filter; + enum ldb_scope scope = LDB_SCOPE_SUBTREE; + //const char *extra_filter; + struct drsuapi_getncchanges_state *getnc_state = b_state->getncchanges_state; + const char *attrs[] = { "uSNChanged", + "objectGUID" , + NULL }; + + if (req10->extended_op == DRSUAPI_EXOP_REPL_OBJ || + req10->extended_op == DRSUAPI_EXOP_REPL_SECRET) { + scope = LDB_SCOPE_BASE; + } + + //extra_filter = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "object filter"); + + //getnc_state->min_usn = req10->highwatermark.highest_usn; + + /* Construct response. */ + search_filter = talloc_asprintf(mem_ctx, + "(uSNChanged>=%llu)", + (unsigned long long)(getnc_state->min_usn+1)); + + if (extra_filter) { + search_filter = talloc_asprintf(mem_ctx, "(&%s(%s))", search_filter, extra_filter); + } + + if (req10->replica_flags & DRSUAPI_DRS_CRITICAL_ONLY) { + search_filter = talloc_asprintf(mem_ctx, + "(&%s(isCriticalSystemObject=TRUE))", + search_filter); + } + + if (req10->replica_flags & DRSUAPI_DRS_ASYNC_REP) { + scope = LDB_SCOPE_BASE; + } + + if (!search_dn) { + search_dn = getnc_state->ncRoot_dn; + } + + DEBUG(2,(__location__ ": getncchanges on %s using filter %s\n", + ldb_dn_get_linearized(getnc_state->ncRoot_dn), search_filter)); + ret = drsuapi_search_with_extended_dn(b_state->sam_ctx, getnc_state, search_res, + search_dn, scope, attrs, + search_filter); + if (ret != LDB_SUCCESS) { + return WERR_DS_DRA_INTERNAL_ERROR; + } + + return WERR_OK; +} + +/** + * Collects object for normal replication cycle. + */ +static WERROR getncchanges_collect_objects_exop(struct drsuapi_bind_state *b_state, + TALLOC_CTX *mem_ctx, + struct drsuapi_DsGetNCChangesRequest10 *req10, + struct drsuapi_DsGetNCChangesCtr6 *ctr6, + struct ldb_dn *search_dn, + const char *extra_filter, + struct ldb_result **search_res) +{ + /* we have nothing to do in case of ex-op failure */ + if (ctr6->extended_ret != DRSUAPI_EXOP_ERR_SUCCESS) { + return WERR_OK; + } + + /* TODO: implement extended op specific collection + * of objects. Right now we just normal procedure + * for collecting objects */ + return getncchanges_collect_objects(b_state, mem_ctx, req10, search_dn, extra_filter, search_res); +} + /* drsuapi_DsGetNCChanges @@ -1177,9 +1274,6 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ struct drsuapi_DsReplicaObjectListItemEx **currentObject; NTSTATUS status; DATA_BLOB session_key; - const char *attrs[] = { "uSNChanged", - "objectGUID" , - NULL }; WERROR werr; struct dcesrv_handle *h; struct drsuapi_bind_state *b_state; @@ -1327,6 +1421,10 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ ldb_get_schema_basedn(b_state->sam_ctx)); getnc_state->is_schema_nc = (0 == ret); + if (req10->extended_op != DRSUAPI_EXOP_NONE) { + r->out.ctr->ctr6.extended_ret = DRSUAPI_EXOP_ERR_SUCCESS; + } + /* * This is the first replication cycle and it is * a good place to handle extended operations @@ -1391,64 +1489,39 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ Work out if this is the start of a new cycle */ if (getnc_state->guids == NULL) { - char* search_filter; - enum ldb_scope scope = LDB_SCOPE_SUBTREE; const char *extra_filter; - struct ldb_result *search_res; - - if (req10->extended_op == DRSUAPI_EXOP_REPL_OBJ || - req10->extended_op == DRSUAPI_EXOP_REPL_SECRET) { - scope = LDB_SCOPE_BASE; - } + struct ldb_result *search_res = NULL; extra_filter = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "object filter"); getnc_state->min_usn = req10->highwatermark.highest_usn; - /* Construct response. */ - search_filter = talloc_asprintf(mem_ctx, - "(uSNChanged>=%llu)", - (unsigned long long)(getnc_state->min_usn+1)); - - if (extra_filter) { - search_filter = talloc_asprintf(mem_ctx, "(&%s(%s))", search_filter, extra_filter); - } - - if (req10->replica_flags & DRSUAPI_DRS_CRITICAL_ONLY) { - search_filter = talloc_asprintf(mem_ctx, - "(&%s(isCriticalSystemObject=TRUE))", - search_filter); - } - - if (req10->replica_flags & DRSUAPI_DRS_ASYNC_REP) { - scope = LDB_SCOPE_BASE; - } - - if (!search_dn) { - search_dn = getnc_state->ncRoot_dn; - } - - DEBUG(2,(__location__ ": getncchanges on %s using filter %s\n", - ldb_dn_get_linearized(getnc_state->ncRoot_dn), search_filter)); - ret = drsuapi_search_with_extended_dn(sam_ctx, getnc_state, &search_res, - search_dn, scope, attrs, - search_filter); - if (ret != LDB_SUCCESS) { - return WERR_DS_DRA_INTERNAL_ERROR; - } - - if (req10->replica_flags & DRSUAPI_DRS_GET_ANC) { - TYPESAFE_QSORT(search_res->msgs, - search_res->count, - site_res_cmp_parent_order); + if (req10->extended_op == DRSUAPI_EXOP_NONE) { + werr = getncchanges_collect_objects(b_state, mem_ctx, req10, + search_dn, extra_filter, + &search_res); } else { - TYPESAFE_QSORT(search_res->msgs, - search_res->count, - site_res_cmp_usn_order); + werr = getncchanges_collect_objects_exop(b_state, mem_ctx, req10, + &r->out.ctr->ctr6, + search_dn, extra_filter, + &search_res); + } + W_ERROR_NOT_OK_RETURN(werr); + + if (search_res) { + if (req10->replica_flags & DRSUAPI_DRS_GET_ANC) { + TYPESAFE_QSORT(search_res->msgs, + search_res->count, + site_res_cmp_parent_order); + } else { + TYPESAFE_QSORT(search_res->msgs, + search_res->count, + site_res_cmp_usn_order); + } } /* extract out the GUIDs list */ - getnc_state->num_records = search_res->count; + getnc_state->num_records = search_res ? search_res->count : 0; getnc_state->guids = talloc_array(getnc_state, struct GUID, getnc_state->num_records); W_ERROR_HAVE_NO_MEMORY(getnc_state->guids); @@ -1705,7 +1778,6 @@ WERROR dcesrv_drsuapi_DsGetNCChanges(struct dcesrv_call_state *dce_call, TALLOC_ r->out.ctr->ctr6.uptodateness_vector = NULL; r->out.ctr->ctr6.nc_object_count = 0; ZERO_STRUCT(r->out.ctr->ctr6.new_highwatermark); - r->out.ctr->ctr6.extended_ret = DRSUAPI_EXOP_ERR_SUCCESS; } DEBUG(r->out.ctr->ctr6.more_data?4:2, diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index b9fe5a3f40..50ce2346ad 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -1429,7 +1429,7 @@ static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx, { const struct ldb_val *orig_val; uint32_t orig_uint = 0; - int flags = 0; + unsigned int flags = 0; int ret; orig_val = ldb_msg_find_ldb_val(orig, attribute); diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index bf8b4844a0..d5a7eebb55 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -37,6 +37,7 @@ #include "lib/tsocket/tsocket.h" #include "librpc/gen_ndr/ndr_netlogon.h" #include "librpc/gen_ndr/ndr_irpc.h" +#include "lib/socket/netif.h" struct netlogon_server_pipe_state { struct netr_Credential client_challenge; @@ -600,7 +601,7 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_check(const struct netr_LogonSamLogonE static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_LogonSamLogonEx *r, struct netlogon_creds_CredentialState *creds) { - struct auth_context *auth_context; + struct auth4_context *auth_context; struct auth_usersupplied_info *user_info; struct auth_user_info_dc *user_info_dc; NTSTATUS nt_status; @@ -1233,6 +1234,7 @@ static NTSTATUS dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state static NTSTATUS dcesrv_netr_LogonGetCapabilities(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_LogonGetCapabilities *r) { + /* we don't support AES yet */ return NT_STATUS_NOT_IMPLEMENTED; } @@ -1710,6 +1712,8 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, NTSTATUS status; const char *dc_name = NULL; const char *domain_name = NULL; + struct interface *ifaces; + const char *pdc_ip; ZERO_STRUCTP(r->out.info); @@ -1815,10 +1819,15 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, W_ERROR_HAVE_NO_MEMORY(info); info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s", dc_name); W_ERROR_HAVE_NO_MEMORY(info->dc_unc); - info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", - response.data.nt5_ex.sockaddr.pdc_ip); + + load_interface_list(mem_ctx, lp_ctx, &ifaces); + pdc_ip = iface_list_best_ip(ifaces, addr); + if (pdc_ip == NULL) { + pdc_ip = "127.0.0.1"; + } + info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", pdc_ip); W_ERROR_HAVE_NO_MEMORY(info->dc_address); - info->dc_address_type = DS_ADDRESS_TYPE_INET; /* TODO: make this dynamic? for ipv6 */ + info->dc_address_type = DS_ADDRESS_TYPE_INET; info->domain_guid = response.data.nt5_ex.domain_uuid; info->domain_name = domain_name; info->forest_name = response.data.nt5_ex.forest; diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 1c7416cb7b..32aafcd23f 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -510,6 +510,9 @@ static NTSTATUS dcesrv_samr_info_DomGeneralInformation(struct samr_domain_state info->role = SAMR_ROLE_DOMAIN_BDC; } break; + case ROLE_DOMAIN_PDC: + info->role = SAMR_ROLE_DOMAIN_PDC; + break; case ROLE_DOMAIN_MEMBER: info->role = SAMR_ROLE_DOMAIN_MEMBER; break; @@ -613,6 +616,9 @@ static NTSTATUS dcesrv_samr_info_DomInfo7(struct samr_domain_state *state, info->role = SAMR_ROLE_DOMAIN_BDC; } break; + case ROLE_DOMAIN_PDC: + info->role = SAMR_ROLE_DOMAIN_PDC; + break; case ROLE_DOMAIN_MEMBER: info->role = SAMR_ROLE_DOMAIN_MEMBER; break; @@ -1205,7 +1211,6 @@ static NTSTATUS dcesrv_samr_CreateUser2(struct dcesrv_call_state *dce_call, TALL } a_state = talloc(mem_ctx, struct samr_account_state); if (!a_state) { - ldb_transaction_cancel(d_state->sam_ctx); return NT_STATUS_NO_MEMORY; } a_state->sam_ctx = d_state->sam_ctx; |