mirror of
https://github.com/samba-team/samba.git
synced 2025-02-08 05:57:51 +03:00
r4618: - tidied up the alter_context client code a bit
- there is no alter_nak or alter_ack packet, its all done in an alter_response - auto-allocated the contex_ids - tried to fix up the dcom code to work again with alter_context. Jelmer, please take a look :)
This commit is contained in:
parent
0129ec947a
commit
dd1c54add8
@ -563,6 +563,7 @@
|
||||
#define NT_STATUS_NOT_A_REPARSE_POINT NT_STATUS(0xC0000000 | 0x0275)
|
||||
#define NT_STATUS_NO_SUCH_JOB NT_STATUS(0xC0000000 | 0xEDE) /* scheduler */
|
||||
#define NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED NT_STATUS(0xC0000000 | 0x20004)
|
||||
#define NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX NT_STATUS(0xC0000000 | 0x20026)
|
||||
|
||||
|
||||
/* I use NT_STATUS_FOOBAR when I have no idea what error code to use -
|
||||
|
@ -341,41 +341,54 @@ WERROR dcom_get_class_object(struct dcom_context *ctx, struct GUID *clsid, const
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
NTSTATUS dcom_get_pipe (struct dcom_interface_p *iface, struct dcerpc_pipe **p)
|
||||
NTSTATUS dcom_get_pipe (struct dcom_interface_p *iface, struct dcerpc_pipe **pp)
|
||||
{
|
||||
struct dcerpc_binding binding;
|
||||
struct GUID iid;
|
||||
HYPER_T oxid;
|
||||
NTSTATUS status;
|
||||
int i;
|
||||
struct dcerpc_pipe *p;
|
||||
TALLOC_CTX *tmp_ctx;
|
||||
const char *uuid;
|
||||
|
||||
*p = NULL;
|
||||
tmp_ctx = talloc_new(NULL);
|
||||
|
||||
p = iface->ox->pipe;
|
||||
|
||||
oxid = iface->ox->oxid;
|
||||
iid = iface->interface->iid;
|
||||
|
||||
#warning "dcerpc_alter needed"
|
||||
#if 0
|
||||
if (iface->ox->pipe) {
|
||||
if (!GUID_equal(&iface->ox->pipe->syntax.uuid, &iid)) {
|
||||
uuid = GUID_string(tmp_ctx, &iid);
|
||||
|
||||
if (p) {
|
||||
if (!GUID_equal(&p->syntax.uuid, &iid)) {
|
||||
struct dcerpc_pipe *p2;
|
||||
iface->ox->pipe->syntax.uuid = iid;
|
||||
status = dcerpc_alter(iface->ox->pipe, iface->ctx);
|
||||
if (NT_STATUS_IS_ERR(status)) {
|
||||
return status;
|
||||
status = dcerpc_secondary_context(p, &p2, uuid, 0);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
p = p2;
|
||||
}
|
||||
} else {
|
||||
p = talloc_reference(NULL, p);
|
||||
}
|
||||
*p = iface->ox->pipe;
|
||||
return NT_STATUS_OK;
|
||||
*pp = p;
|
||||
talloc_free(tmp_ctx);
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
status = dcerpc_binding_from_STRINGBINDING(iface->ctx, &binding, iface->ox->bindings.stringbindings[i]);
|
||||
if (NT_STATUS_IS_ERR(status)) {
|
||||
status = dcerpc_binding_from_STRINGBINDING(iface->ctx, &binding,
|
||||
iface->ox->bindings.stringbindings[i]);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
DEBUG(1, ("Error parsing string binding"));
|
||||
} else {
|
||||
binding.flags = iface->ctx->dcerpc_flags;
|
||||
status = dcerpc_pipe_connect_b(&iface->ox->pipe, &binding, GUID_string(iface->ctx, &iid) , 0.0, iface->ctx->domain, iface->ctx->user, iface->ctx->password);
|
||||
status = dcerpc_pipe_connect_b(&p, &binding,
|
||||
uuid, 0.0,
|
||||
iface->ctx->domain, iface->ctx->user,
|
||||
iface->ctx->password);
|
||||
}
|
||||
|
||||
i++;
|
||||
@ -383,12 +396,15 @@ NTSTATUS dcom_get_pipe (struct dcom_interface_p *iface, struct dcerpc_pipe **p)
|
||||
|
||||
if (NT_STATUS_IS_ERR(status)) {
|
||||
DEBUG(0, ("Unable to connect to remote host - %s\n", nt_errstr(status)));
|
||||
talloc_free(tmp_ctx);
|
||||
return status;
|
||||
}
|
||||
|
||||
DEBUG(2, ("Successfully connected to OXID %llx\n", oxid));
|
||||
|
||||
*p = iface->ox->pipe;
|
||||
*pp = p;
|
||||
talloc_free(tmp_ctx);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
@ -537,6 +537,7 @@ static const nt_err_code_struct nt_errs[] =
|
||||
{ "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE },
|
||||
{ "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES },
|
||||
{ "NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED", NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED },
|
||||
{ "NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX", NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX },
|
||||
{ "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES },
|
||||
{ "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED },
|
||||
{ NULL, NT_STATUS(0) }
|
||||
|
@ -160,7 +160,7 @@ interface dcerpc
|
||||
DCERPC_PKT_BIND_ACK = 12,
|
||||
DCERPC_PKT_BIND_NAK = 13,
|
||||
DCERPC_PKT_ALTER = 14,
|
||||
DCERPC_PKT_ALTER_ACK = 15,
|
||||
DCERPC_PKT_ALTER_RESP = 15,
|
||||
DCERPC_PKT_AUTH3 = 16,
|
||||
DCERPC_PKT_SHUTDOWN = 17,
|
||||
DCERPC_PKT_CO_CANCEL = 18,
|
||||
@ -168,15 +168,15 @@ interface dcerpc
|
||||
} dcerpc_pkt_type;
|
||||
|
||||
typedef [nodiscriminant] union {
|
||||
[case(DCERPC_PKT_REQUEST)] dcerpc_request request;
|
||||
[case(DCERPC_PKT_RESPONSE)] dcerpc_response response;
|
||||
[case(DCERPC_PKT_BIND)] dcerpc_bind bind;
|
||||
[case(DCERPC_PKT_BIND_ACK)] dcerpc_bind_ack bind_ack;
|
||||
[case(DCERPC_PKT_ALTER)] dcerpc_bind alter;
|
||||
[case(DCERPC_PKT_ALTER_ACK)] dcerpc_bind_ack alter_ack;
|
||||
[case(DCERPC_PKT_FAULT)] dcerpc_fault fault;
|
||||
[case(DCERPC_PKT_AUTH3)] dcerpc_auth3 auth3;
|
||||
[case(DCERPC_PKT_BIND_NAK)] dcerpc_bind_nak bind_nak;
|
||||
[case(DCERPC_PKT_REQUEST)] dcerpc_request request;
|
||||
[case(DCERPC_PKT_RESPONSE)] dcerpc_response response;
|
||||
[case(DCERPC_PKT_BIND)] dcerpc_bind bind;
|
||||
[case(DCERPC_PKT_BIND_ACK)] dcerpc_bind_ack bind_ack;
|
||||
[case(DCERPC_PKT_ALTER)] dcerpc_bind alter;
|
||||
[case(DCERPC_PKT_ALTER_RESP)] dcerpc_bind_ack alter_resp;
|
||||
[case(DCERPC_PKT_FAULT)] dcerpc_fault fault;
|
||||
[case(DCERPC_PKT_AUTH3)] dcerpc_auth3 auth3;
|
||||
[case(DCERPC_PKT_BIND_NAK)] dcerpc_bind_nak bind_nak;
|
||||
} dcerpc_payload;
|
||||
|
||||
|
||||
|
@ -562,6 +562,18 @@ static NTSTATUS full_request(struct dcerpc_connection *c,
|
||||
return state->status;
|
||||
}
|
||||
|
||||
/*
|
||||
map a bind nak reason to a NTSTATUS
|
||||
*/
|
||||
static NTSTATUS dcerpc_map_reason(uint16_t reason)
|
||||
{
|
||||
switch (reason) {
|
||||
case DCERPC_BIND_REASON_ASYNTAX:
|
||||
return NT_STATUS_RPC_UNSUPPORTED_NAME_SYNTAX;
|
||||
}
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
perform a bind using the given syntax
|
||||
@ -622,7 +634,7 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
|
||||
|
||||
if (pkt.ptype == DCERPC_PKT_BIND_NAK) {
|
||||
DEBUG(2,("dcerpc: bind_nak reason %d\n", pkt.u.bind_nak.reject_reason));
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
return dcerpc_map_reason(pkt.u.bind_nak.reject_reason);
|
||||
}
|
||||
|
||||
if ((pkt.ptype != DCERPC_PKT_BIND_ACK) ||
|
||||
@ -1387,20 +1399,23 @@ NTSTATUS dcerpc_alter_context(struct dcerpc_pipe *p,
|
||||
return status;
|
||||
}
|
||||
|
||||
if (pkt.ptype == DCERPC_PKT_BIND_NAK) {
|
||||
DEBUG(2,("dcerpc: alter_nak reason %d\n", pkt.u.bind_nak.reject_reason));
|
||||
return NT_STATUS_ACCESS_DENIED;
|
||||
if (pkt.ptype == DCERPC_PKT_ALTER_RESP &&
|
||||
pkt.u.alter_resp.num_results == 1 &&
|
||||
pkt.u.alter_resp.ctx_list[0].result != 0) {
|
||||
DEBUG(2,("dcerpc: alter_resp failed - reason %d\n",
|
||||
pkt.u.alter_resp.ctx_list[0].reason));
|
||||
return dcerpc_map_reason(pkt.u.alter_resp.ctx_list[0].reason);
|
||||
}
|
||||
|
||||
if ((pkt.ptype != DCERPC_PKT_ALTER_ACK) ||
|
||||
pkt.u.alter_ack.num_results == 0 ||
|
||||
pkt.u.alter_ack.ctx_list[0].result != 0) {
|
||||
if (pkt.ptype != DCERPC_PKT_ALTER_RESP ||
|
||||
pkt.u.alter_resp.num_results == 0 ||
|
||||
pkt.u.alter_resp.ctx_list[0].result != 0) {
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* the alter_ack might contain a reply set of credentials */
|
||||
if (p->conn->security_state.auth_info && pkt.u.alter_ack.auth_info.length) {
|
||||
status = ndr_pull_struct_blob(&pkt.u.alter_ack.auth_info,
|
||||
/* the alter_resp might contain a reply set of credentials */
|
||||
if (p->conn->security_state.auth_info && pkt.u.alter_resp.auth_info.length) {
|
||||
status = ndr_pull_struct_blob(&pkt.u.alter_resp.auth_info,
|
||||
mem_ctx,
|
||||
p->conn->security_state.auth_info,
|
||||
(ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
|
||||
|
@ -76,6 +76,9 @@ struct dcerpc_connection {
|
||||
|
||||
/* private pointer for pending full requests */
|
||||
void *full_request_private;
|
||||
|
||||
/* the next context_id to be assigned */
|
||||
uint32_t next_context_id;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -123,92 +123,3 @@ done:
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#warning "bind_alter not implemented"
|
||||
#if 0
|
||||
NTSTATUS dcerpc_bind_alter(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t auth_level,
|
||||
const char *uuid, uint_t version)
|
||||
{
|
||||
NTSTATUS status;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
DATA_BLOB credentials;
|
||||
DATA_BLOB null_data_blob = data_blob(NULL, 0);
|
||||
|
||||
mem_ctx = talloc_init("dcerpc_bind_auth");
|
||||
if (!mem_ctx) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (!p->conn->security_state.generic_state) {
|
||||
status = gensec_client_start(p, &p->conn->security_state.generic_state);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state,
|
||||
auth_type, auth_level);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
p->conn->security_state.auth_info = talloc_p(p, struct dcerpc_auth);
|
||||
if (!p->conn->security_state.auth_info) {
|
||||
status = NT_STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
p->conn->security_state.auth_info->auth_type = auth_type;
|
||||
p->conn->security_state.auth_info->auth_level = auth_level;
|
||||
p->conn->security_state.auth_info->auth_pad_length = 0;
|
||||
p->conn->security_state.auth_info->auth_reserved = 0;
|
||||
p->conn->security_state.auth_info->auth_context_id = random();
|
||||
p->conn->security_state.auth_info->credentials = null_data_blob;
|
||||
|
||||
status = gensec_update(p->conn->security_state.generic_state, mem_ctx,
|
||||
null_data_blob,
|
||||
&credentials);
|
||||
|
||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
p->conn->security_state.auth_info->credentials = credentials;
|
||||
|
||||
status = dcerpc_bind_byuuid(p, mem_ctx, uuid, version);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
status = gensec_update(p->conn->security_state.generic_state, mem_ctx,
|
||||
p->conn->security_state.auth_info->credentials,
|
||||
&credentials);
|
||||
|
||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
p->conn->security_state.auth_info->credentials = credentials;
|
||||
|
||||
status = dcerpc_alter(p, mem_ctx);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
talloc_destroy(mem_ctx);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
talloc_free(p->conn->security_state.generic_state);
|
||||
ZERO_STRUCT(p->conn->security_state);
|
||||
} else {
|
||||
/* Authenticated connections use the generic session key */
|
||||
p->conn->security_state.session_key = dcerpc_generic_session_key;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
@ -24,8 +24,11 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#warning "this needs dcerpc_alter"
|
||||
#if 0
|
||||
/*
|
||||
metze, can you tell me what you're trying to do with this?
|
||||
*/
|
||||
|
||||
/*
|
||||
do spnego style authentication on a gensec pipe
|
||||
*/
|
||||
|
@ -1272,8 +1272,8 @@ void dcerpc_log_packet(const struct dcerpc_interface_table *ndr,
|
||||
|
||||
this uses dcerpc_alter_context() to create a new dcerpc context_id
|
||||
*/
|
||||
NTSTATUS dcerpc_secondary_context(struct dcerpc_pipe *p, struct dcerpc_pipe **pp2,
|
||||
uint32_t context_id,
|
||||
NTSTATUS dcerpc_secondary_context(struct dcerpc_pipe *p,
|
||||
struct dcerpc_pipe **pp2,
|
||||
const char *pipe_uuid,
|
||||
uint32_t pipe_version)
|
||||
{
|
||||
@ -1286,7 +1286,7 @@ NTSTATUS dcerpc_secondary_context(struct dcerpc_pipe *p, struct dcerpc_pipe **pp
|
||||
}
|
||||
p2->conn = talloc_reference(p2, p->conn);
|
||||
|
||||
p2->context_id = context_id;
|
||||
p2->context_id = ++p->conn->next_context_id;
|
||||
|
||||
status = GUID_from_string(pipe_uuid, &p2->syntax.uuid);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
|
@ -580,22 +580,22 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
|
||||
dcesrv_init_hdr(&pkt);
|
||||
pkt.auth_length = 0;
|
||||
pkt.call_id = call->pkt.call_id;
|
||||
pkt.ptype = DCERPC_PKT_ALTER_ACK;
|
||||
pkt.ptype = DCERPC_PKT_ALTER_RESP;
|
||||
pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
|
||||
pkt.u.alter_ack.max_xmit_frag = 0x2000;
|
||||
pkt.u.alter_ack.max_recv_frag = 0x2000;
|
||||
pkt.u.alter_ack.assoc_group_id = call->pkt.u.bind.assoc_group_id;
|
||||
pkt.u.alter_ack.secondary_address = NULL;
|
||||
pkt.u.alter_ack.num_results = 1;
|
||||
pkt.u.alter_ack.ctx_list = talloc_p(call, struct dcerpc_ack_ctx);
|
||||
if (!pkt.u.alter_ack.ctx_list) {
|
||||
pkt.u.alter_resp.max_xmit_frag = 0x2000;
|
||||
pkt.u.alter_resp.max_recv_frag = 0x2000;
|
||||
pkt.u.alter_resp.assoc_group_id = call->pkt.u.bind.assoc_group_id;
|
||||
pkt.u.alter_resp.secondary_address = NULL;
|
||||
pkt.u.alter_resp.num_results = 1;
|
||||
pkt.u.alter_resp.ctx_list = talloc_p(call, struct dcerpc_ack_ctx);
|
||||
if (!pkt.u.alter_resp.ctx_list) {
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
pkt.u.alter_ack.ctx_list[0].result = result;
|
||||
pkt.u.alter_ack.ctx_list[0].reason = reason;
|
||||
GUID_from_string(NDR_GUID, &pkt.u.alter_ack.ctx_list[0].syntax.uuid);
|
||||
pkt.u.alter_ack.ctx_list[0].syntax.if_version = NDR_GUID_VERSION;
|
||||
pkt.u.alter_ack.auth_info = data_blob(NULL, 0);
|
||||
pkt.u.alter_resp.ctx_list[0].result = result;
|
||||
pkt.u.alter_resp.ctx_list[0].reason = reason;
|
||||
GUID_from_string(NDR_GUID, &pkt.u.alter_resp.ctx_list[0].syntax.uuid);
|
||||
pkt.u.alter_resp.ctx_list[0].syntax.if_version = NDR_GUID_VERSION;
|
||||
pkt.u.alter_resp.auth_info = data_blob(NULL, 0);
|
||||
|
||||
if (!dcesrv_auth_alter_ack(call, &pkt)) {
|
||||
return dcesrv_bind_nak(call, 0);
|
||||
|
@ -49,12 +49,19 @@ BOOL torture_rpc_alter_context(void)
|
||||
}
|
||||
|
||||
printf("Opening secondary DSSETUP context\n");
|
||||
status = dcerpc_secondary_context(p, &p2, 1, DCERPC_DSSETUP_UUID, DCERPC_DSSETUP_VERSION);
|
||||
status = dcerpc_secondary_context(p, &p2, DCERPC_DSSETUP_UUID, DCERPC_DSSETUP_VERSION);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
printf("dcerpc_alter_context failed - %s\n", nt_errstr(status));
|
||||
return False;
|
||||
}
|
||||
|
||||
printf("Opening bad secondary connection\n");
|
||||
status = dcerpc_secondary_context(p, &p2, DCERPC_DSSETUP_UUID, DCERPC_DSSETUP_VERSION+100);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
printf("dcerpc_alter_context with wrong version should fail\n");
|
||||
return False;
|
||||
}
|
||||
|
||||
printf("testing DSSETUP pipe operations\n");
|
||||
ret &= test_DsRoleGetPrimaryDomainInformation(p2, mem_ctx);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user