#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 -
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++;
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;
}
{ "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) }
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,
} 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;
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
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) ||
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);
/* private pointer for pending full requests */
void *full_request_private;
+
+ /* the next context_id to be assigned */
+ uint32_t next_context_id;
};
/*
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
#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
*/
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)
{
}
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)) {
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);
}
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);