summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/include/nterr.h1
-rw-r--r--source4/lib/dcom/common/main.c48
-rw-r--r--source4/libcli/util/nterr.c1
-rw-r--r--source4/librpc/idl/dcerpc.idl20
-rw-r--r--source4/librpc/rpc/dcerpc.c35
-rw-r--r--source4/librpc/rpc/dcerpc.h3
-rw-r--r--source4/librpc/rpc/dcerpc_auth.c89
-rw-r--r--source4/librpc/rpc/dcerpc_spnego.c5
-rw-r--r--source4/librpc/rpc/dcerpc_util.c6
-rw-r--r--source4/rpc_server/dcerpc_server.c26
-rw-r--r--source4/torture/rpc/alter_context.c9
11 files changed, 100 insertions, 143 deletions
diff --git a/source4/include/nterr.h b/source4/include/nterr.h
index 9cf9e0f086..6680b7ecec 100644
--- a/source4/include/nterr.h
+++ b/source4/include/nterr.h
@@ -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 -
diff --git a/source4/lib/dcom/common/main.c b/source4/lib/dcom/common/main.c
index 02e1dea139..b9f6127c6c 100644
--- a/source4/lib/dcom/common/main.c
+++ b/source4/lib/dcom/common/main.c
@@ -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;
+
+ tmp_ctx = talloc_new(NULL);
- *p = 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;
}
diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c
index d2d87eeb1c..9317f0e37a 100644
--- a/source4/libcli/util/nterr.c
+++ b/source4/libcli/util/nterr.c
@@ -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) }
diff --git a/source4/librpc/idl/dcerpc.idl b/source4/librpc/idl/dcerpc.idl
index d9ed119abd..d4fb026c8c 100644
--- a/source4/librpc/idl/dcerpc.idl
+++ b/source4/librpc/idl/dcerpc.idl
@@ -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;
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
index d75f6db935..e133c77d07 100644
--- a/source4/librpc/rpc/dcerpc.c
+++ b/source4/librpc/rpc/dcerpc.c
@@ -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);
diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h
index 00f1fb6488..f5ed637d0b 100644
--- a/source4/librpc/rpc/dcerpc.h
+++ b/source4/librpc/rpc/dcerpc.h
@@ -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;
};
/*
diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c
index 9d43218e4b..4ff8fe549e 100644
--- a/source4/librpc/rpc/dcerpc_auth.c
+++ b/source4/librpc/rpc/dcerpc_auth.c
@@ -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
diff --git a/source4/librpc/rpc/dcerpc_spnego.c b/source4/librpc/rpc/dcerpc_spnego.c
index cab8865d6b..f67dd2c7cb 100644
--- a/source4/librpc/rpc/dcerpc_spnego.c
+++ b/source4/librpc/rpc/dcerpc_spnego.c
@@ -24,9 +24,12 @@
#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
*/
NTSTATUS dcerpc_bind_auth_spnego(struct dcerpc_pipe *p,
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
index 702a1f6ecf..305c1c7725 100644
--- a/source4/librpc/rpc/dcerpc_util.c
+++ b/source4/librpc/rpc/dcerpc_util.c
@@ -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)) {
diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c
index f0791e5928..c86ffb2cd0 100644
--- a/source4/rpc_server/dcerpc_server.c
+++ b/source4/rpc_server/dcerpc_server.c
@@ -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);
diff --git a/source4/torture/rpc/alter_context.c b/source4/torture/rpc/alter_context.c
index d10604fa04..2c6f209404 100644
--- a/source4/torture/rpc/alter_context.c
+++ b/source4/torture/rpc/alter_context.c
@@ -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);