summaryrefslogtreecommitdiff
path: root/source4/librpc/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'source4/librpc/rpc')
-rw-r--r--source4/librpc/rpc/dcerpc.h25
-rw-r--r--source4/librpc/rpc/dcerpc_schannel.c36
-rw-r--r--source4/librpc/rpc/dcerpc_util.c84
3 files changed, 88 insertions, 57 deletions
diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h
index 74bdaf878e..d81f0ab965 100644
--- a/source4/librpc/rpc/dcerpc.h
+++ b/source4/librpc/rpc/dcerpc.h
@@ -71,21 +71,28 @@ struct dcerpc_pipe {
};
/* dcerpc pipe flags */
-#define DCERPC_DEBUG_PRINT_IN (1<<0)
-#define DCERPC_DEBUG_PRINT_OUT (1<<1)
+#define DCERPC_DEBUG_PRINT_IN (1<<0)
+#define DCERPC_DEBUG_PRINT_OUT (1<<1)
#define DCERPC_DEBUG_PRINT_BOTH (DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT)
-#define DCERPC_DEBUG_VALIDATE_IN 4
-#define DCERPC_DEBUG_VALIDATE_OUT 8
+#define DCERPC_DEBUG_VALIDATE_IN (1<<2)
+#define DCERPC_DEBUG_VALIDATE_OUT (1<<3)
#define DCERPC_DEBUG_VALIDATE_BOTH (DCERPC_DEBUG_VALIDATE_IN | DCERPC_DEBUG_VALIDATE_OUT)
-#define DCERPC_SIGN 16
-#define DCERPC_SEAL 32
+#define DCERPC_SIGN (1<<4)
+#define DCERPC_SEAL (1<<5)
-#define DCERPC_PUSH_BIGENDIAN 64
-#define DCERPC_PULL_BIGENDIAN 128
+#define DCERPC_PUSH_BIGENDIAN (1<<6)
+#define DCERPC_PULL_BIGENDIAN (1<<7)
-#define DCERPC_SCHANNEL 256
+#define DCERPC_SCHANNEL_BDC (1<<8)
+#define DCERPC_SCHANNEL_WORKSTATION (1<<9)
+#define DCERPC_SCHANNEL_DOMAIN (1<<10)
+#define DCERPC_SCHANNEL_ANY (DCERPC_SCHANNEL_BDC| \
+ DCERPC_SCHANNEL_DOMAIN| \
+ DCERPC_SCHANNEL_WORKSTATION)
+
+#define DCERPC_AUTH_OPTIONS (DCERPC_SEAL|DCERPC_SIGN|DCERPC_SCHANNEL_ANY)
/*
this is used to find pointers to calls
diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c
index 61db90d1e3..f81429c1f3 100644
--- a/source4/librpc/rpc/dcerpc_schannel.c
+++ b/source4/librpc/rpc/dcerpc_schannel.c
@@ -81,7 +81,7 @@ NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
const char *username,
const char *password,
int chan_type,
- uint8_t new_session_key[8])
+ uint8_t new_session_key[16])
{
NTSTATUS status;
struct dcerpc_pipe *p2;
@@ -91,7 +91,7 @@ NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
struct samr_Password mach_pwd;
struct creds_CredentialState creds;
const char *workgroup, *workstation;
- uint32_t negotiate_flags = 0;
+ uint32_t negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
workstation = username;
workgroup = domain;
@@ -99,10 +99,10 @@ NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
/*
step 1 - establish a netlogon connection, with no authentication
*/
- status = dcerpc_secondary_smb(p, &p2,
- DCERPC_NETLOGON_NAME,
- DCERPC_NETLOGON_UUID,
- DCERPC_NETLOGON_VERSION);
+ status = dcerpc_secondary_connection(p, &p2,
+ DCERPC_NETLOGON_NAME,
+ DCERPC_NETLOGON_UUID,
+ DCERPC_NETLOGON_VERSION);
/*
@@ -152,7 +152,7 @@ NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
*/
dcerpc_pipe_close(p2);
- memcpy(new_session_key, creds.session_key, 8);
+ memcpy(new_session_key, creds.session_key, 16);
return NT_STATUS_OK;
}
@@ -167,17 +167,13 @@ NTSTATUS dcerpc_bind_auth_schannel_key(struct dcerpc_pipe *p,
const char *uuid, uint_t version,
const char *domain,
const char *username,
- const uint8_t session_key[8])
+ const uint8_t session_key[16])
{
NTSTATUS status;
- uint8_t full_session_key[16];
struct schannel_state *schannel_state;
const char *workgroup, *workstation;
struct dcerpc_bind_schannel bind_schannel;
- memcpy(full_session_key, session_key, 8);
- memset(full_session_key+8, 0, 8);
-
workstation = username;
workgroup = domain;
@@ -234,7 +230,7 @@ NTSTATUS dcerpc_bind_auth_schannel_key(struct dcerpc_pipe *p,
goto done;
}
- status = schannel_start(&schannel_state, full_session_key, True);
+ status = schannel_start(&schannel_state, session_key, True);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
@@ -265,11 +261,19 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p,
const char *password)
{
NTSTATUS status;
- uint8_t session_key[8];
+ uint8_t session_key[16];
+ int chan_type = 0;
+
+ if (p->flags & DCERPC_SCHANNEL_BDC) {
+ chan_type = SEC_CHAN_BDC;
+ } else if (p->flags & DCERPC_SCHANNEL_WORKSTATION) {
+ chan_type = SEC_CHAN_WKSTA;
+ } else if (p->flags & DCERPC_SCHANNEL_DOMAIN) {
+ chan_type = SEC_CHAN_DOMAIN;
+ }
status = dcerpc_schannel_key(p, domain, username, password,
- lp_server_role() == ROLE_DOMAIN_BDC? SEC_CHAN_BDC:SEC_CHAN_WKSTA,
- session_key);
+ chan_type, session_key);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
index 623d5ec24a..c7edf043ec 100644
--- a/source4/librpc/rpc/dcerpc_util.c
+++ b/source4/librpc/rpc/dcerpc_util.c
@@ -275,7 +275,6 @@ static const struct {
} ncacn_options[] = {
{"sign", DCERPC_SIGN},
{"seal", DCERPC_SEAL},
- {"schannel", DCERPC_SCHANNEL},
{"validate", DCERPC_DEBUG_VALIDATE_BOTH},
{"print", DCERPC_DEBUG_PRINT_BOTH},
{"bigendian", DCERPC_PUSH_BIGENDIAN}
@@ -458,11 +457,18 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
pipe_name += 6;
}
- status = cli_full_connection(&cli, lp_netbios_name(),
- binding->host, NULL,
- "ipc$", "?????",
- username, username[0]?domain:"",
- password, 0, &retry);
+ if ((binding->flags & DCERPC_SCHANNEL_ANY) || !username || !username[0]) {
+ status = cli_full_connection(&cli, lp_netbios_name(),
+ binding->host, NULL,
+ "ipc$", "?????",
+ "", "", NULL, 0, &retry);
+ } else {
+ status = cli_full_connection(&cli, lp_netbios_name(),
+ binding->host, NULL,
+ "ipc$", "?????",
+ username, domain,
+ password, 0, &retry);
+ }
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to connect to %s - %s\n", binding->host, nt_errstr(status)));
return status;
@@ -482,23 +488,15 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
(*p)->flags = binding->flags;
- if (binding->flags & DCERPC_SCHANNEL) {
- const char *trust_password = NULL; // samdb_fetch_member_password();
- if (!trust_password) {
- DEBUG(0,("Unable to fetch machine password\n"));
- goto done;
- }
+ if (binding->flags & DCERPC_SCHANNEL_ANY) {
status = dcerpc_bind_auth_schannel(*p, pipe_uuid, pipe_version,
- lp_workgroup(),
- lp_netbios_name(),
- trust_password);
+ domain, username, password);
} else if (binding->flags & (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);
}
-done:
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
dcerpc_pipe_close(*p);
@@ -552,7 +550,10 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p,
(*p)->flags = binding->flags;
- if (!(binding->flags & (DCERPC_SIGN|DCERPC_SEAL)) && !username[0]) {
+ if (binding->flags & DCERPC_SCHANNEL_ANY) {
+ status = dcerpc_bind_auth_schannel(*p, pipe_uuid, pipe_version,
+ domain, username, password);
+ } else if (!(binding->flags & (DCERPC_SIGN|DCERPC_SEAL)) && !username[0]) {
status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
} else {
status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version,
@@ -560,7 +561,8 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p,
}
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
+ DEBUG(0,("Failed to bind to uuid %s - %s\n",
+ pipe_uuid, nt_errstr(status)));
dcerpc_pipe_close(*p);
return status;
}
@@ -635,28 +637,46 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **p,
/*
- create a secondary dcerpc connection from a primary SMB connection
+ create a secondary dcerpc connection from a primary connection
- the secondary connection will be on the same SMB connection, but use a new fnum
+ if the primary is a SMB connection then the secondary connection
+ will be on the same SMB connection, but use a new fnum
*/
-NTSTATUS dcerpc_secondary_smb(struct dcerpc_pipe *p, struct dcerpc_pipe **p2,
- const char *pipe_name,
- const char *pipe_uuid,
- uint32_t pipe_version)
+NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, struct dcerpc_pipe **p2,
+ const char *pipe_name,
+ const char *pipe_uuid,
+ uint32_t pipe_version)
{
- NTSTATUS status;
struct cli_tree *tree;
+ NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
+ struct dcerpc_binding b;
- tree = dcerpc_smb_tree(p);
- if (!tree) {
- return NT_STATUS_INVALID_PARAMETER;
+ switch (p->transport.transport) {
+ case NCACN_NP:
+ tree = dcerpc_smb_tree(p);
+ if (!tree) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ status = dcerpc_pipe_open_smb(p2, tree, pipe_name);
+ break;
+
+ case NCACN_IP_TCP:
+ status = dcerpc_parse_binding(p->mem_ctx, p->binding_string, &b);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ b.flags &= ~DCERPC_AUTH_OPTIONS;
+ status = dcerpc_pipe_connect_ncacn_ip_tcp(p2, &b, pipe_uuid,
+ pipe_version, NULL,
+ NULL, NULL);
+ break;
}
- status = dcerpc_pipe_open_smb(p2, tree, pipe_name);
if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
+ return status;
+ }
+
(*p2)->flags = p->flags;
status = dcerpc_bind_auth_none(*p2, pipe_uuid, pipe_version);