NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p,
const char *uuid, uint_t version)
{
- TALLOC_CTX *mem_ctx;
+ TALLOC_CTX *tmp_ctx = talloc_new(p);
NTSTATUS status;
- mem_ctx = talloc_init("dcerpc_bind_auth_ntlm");
- if (!mem_ctx) {
- return NT_STATUS_NO_MEMORY;
- }
-
- status = dcerpc_bind_byuuid(p, mem_ctx, uuid, version);
- talloc_destroy(mem_ctx);
+ status = dcerpc_bind_byuuid(p, tmp_ctx, uuid, version);
+ talloc_free(tmp_ctx);
return status;
}
-NTSTATUS dcerpc_bind_auth3(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t auth_level,
+/*
+ perform a multi-part authenticated bind
+*/
+NTSTATUS dcerpc_bind_auth(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t auth_level,
const char *uuid, uint_t version)
{
NTSTATUS status;
- TALLOC_CTX *mem_ctx;
+ TALLOC_CTX *tmp_ctx = talloc_new(p);
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;
- }
+ if (!NT_STATUS_IS_OK(status)) goto done;
status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state,
auth_type, auth_level);
-
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ if (!NT_STATUS_IS_OK(status)) goto done;
}
p->conn->security_state.auth_info = talloc(p, struct dcerpc_auth);
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,
+ status = gensec_update(p->conn->security_state.generic_state, tmp_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);
+ status = dcerpc_bind_byuuid(p, tmp_ctx, uuid, version);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- status = gensec_update(p->conn->security_state.generic_state, mem_ctx,
+ status = gensec_update(p->conn->security_state.generic_state, tmp_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_auth3(p->conn, mem_ctx);
+ do {
+ p->conn->security_state.auth_info->credentials = credentials;
+
+ if (auth_type == DCERPC_AUTH_TYPE_SPNEGO) {
+ status = dcerpc_alter_context(p, tmp_ctx, &p->syntax, &p->transfer_syntax);
+ if (NT_STATUS_IS_OK(status)) {
+ status = gensec_update(p->conn->security_state.generic_state, tmp_ctx,
+ p->conn->security_state.auth_info->credentials,
+ &credentials);
+ }
+ } else {
+ status = dcerpc_auth3(p->conn, tmp_ctx);
+ }
+ } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED));
+
done:
- talloc_destroy(mem_ctx);
+ talloc_free(tmp_ctx);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(p->conn->security_state.generic_state);
return status;
}
+
{"sign", DCERPC_SIGN},
{"seal", DCERPC_SEAL},
{"connect", DCERPC_CONNECT},
+ {"spnego", DCERPC_AUTH_SPNEGO},
{"validate", DCERPC_DEBUG_VALIDATE_BOTH},
{"print", DCERPC_DEBUG_PRINT_BOTH},
{"padcheck", DCERPC_DEBUG_PAD_CHECK},
}
+/*
+ perform an authenticated bind if needed
+*/
+static NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p,
+ struct dcerpc_binding *binding,
+ const char *pipe_uuid,
+ uint32_t pipe_version,
+ const char *domain,
+ const char *username,
+ const char *password)
+{
+ NTSTATUS status;
+
+ p->conn->flags = binding->flags;
+
+ /* remember the binding string for possible secondary connections */
+ p->conn->binding_string = dcerpc_binding_string(p, binding);
+
+ if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
+ status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version,
+ domain, username, password);
+ } else if (username && username[0] && (binding->flags & DCERPC_AUTH_SPNEGO)) {
+ status = dcerpc_bind_auth_spnego(p, pipe_uuid, pipe_version, domain, username, password);
+ } else if (username && username[0]) {
+ status = dcerpc_bind_auth_ntlm(p, pipe_uuid, pipe_version, domain, username, password);
+ } else {
+ status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version);
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
+ }
+ return status;
+}
+
+
/* open a rpc connection to a rpc pipe on SMB using the binding
structure to determine the endpoint and options */
static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp,
return status;
}
- p->conn->flags = binding->flags;
-
- /* remember the binding string for possible secondary connections */
- p->conn->binding_string = dcerpc_binding_string(p, binding);
-
- if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
- status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version,
- domain, username, password);
- } else if (username && username[0] &&
- (binding->flags & (DCERPC_CONNECT|DCERPC_SIGN|DCERPC_SEAL))) {
- status = dcerpc_bind_auth_ntlm(p, pipe_uuid, pipe_version, domain, username, password);
- } else {
- status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version);
-
- }
-
+ status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
talloc_free(p);
return status;
}
return status;
}
- p->conn->flags = binding->flags;
-
- /* remember the binding string for possible secondary connections */
- p->conn->binding_string = dcerpc_binding_string(p, binding);
-
- if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
- status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version,
- domain, username, password);
- } else if (username && username[0]) {
- status = dcerpc_bind_auth_ntlm(p, pipe_uuid, pipe_version, domain, username, password);
- } else {
- status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version);
- }
-
+ status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
talloc_free(p);
return status;
}
return status;
}
- p->conn->flags = binding->flags;
-
- /* remember the binding string for possible secondary connections */
- p->conn->binding_string = dcerpc_binding_string(p, binding);
-
- if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
- status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version,
- domain, username, password);
- } else if (username && username[0]) {
- status = dcerpc_bind_auth_ntlm(p, pipe_uuid, pipe_version, domain, username, password);
- } else {
- status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version);
- }
-
+ status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
talloc_free(p);
return status;
}
return status;
}
- p->conn->flags = binding->flags;
-
- /* remember the binding string for possible secondary connections */
- p->conn->binding_string = dcerpc_binding_string(p, binding);
-
- if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
- status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version,
- domain, username, password);
- } else if (username && username[0]) {
- status = dcerpc_bind_auth_ntlm(p, pipe_uuid, pipe_version, domain, username, password);
- } else {
- status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version);
- }
-
+ status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("Failed to bind to uuid %s - %s\n",
- pipe_uuid, nt_errstr(status)));
talloc_free(p);
return status;
}
if (!tree) {
return NT_STATUS_INVALID_PARAMETER;
}
-
status = dcerpc_pipe_open_smb((*p2)->conn, tree, pipe_name);
break;
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- b.flags &= ~DCERPC_AUTH_OPTIONS;
status = dcerpc_pipe_open_tcp((*p2)->conn, b.host, atoi(b.endpoint));
break;
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- b.flags &= ~DCERPC_AUTH_OPTIONS;
status = dcerpc_pipe_open_pipe((*p2)->conn, b.endpoint);
break;