summaryrefslogtreecommitdiff
path: root/source4/libcli
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2004-08-25 02:25:20 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:58:19 -0500
commitfa5a99b7a6e4f9bffa82eed1393e8e5e1f6404dc (patch)
tree608b29fcba6b323474690cd4adcc7f2a4bb5b117 /source4/libcli
parentb13a9a8f98469fffe0db4cce7e077390d35984a3 (diff)
downloadsamba-fa5a99b7a6e4f9bffa82eed1393e8e5e1f6404dc.tar.gz
samba-fa5a99b7a6e4f9bffa82eed1393e8e5e1f6404dc.tar.bz2
samba-fa5a99b7a6e4f9bffa82eed1393e8e5e1f6404dc.zip
r2041: Fix NTLMSSP RPC sealing, client -> win2k3 server.
The bug (found by tridge) is that Win2k3 is being tighter about the NTLMSSP flags. If we don't negotiate sealing, we can't use it. We now have a way to indicate to the GENSEC implementation mechanisms what things we want for a connection. Andrew Bartlett (This used to be commit 86f61568ea44c5719f9b583beeeefb12e0c26f4c)
Diffstat (limited to 'source4/libcli')
-rw-r--r--source4/libcli/auth/gensec.c41
-rw-r--r--source4/libcli/auth/gensec.h6
-rw-r--r--source4/libcli/auth/gensec_ntlmssp.c26
-rw-r--r--source4/libcli/auth/ntlmssp.c22
-rw-r--r--source4/libcli/auth/ntlmssp_sign.c10
-rw-r--r--source4/libcli/raw/clisession.c2
6 files changed, 90 insertions, 17 deletions
diff --git a/source4/libcli/auth/gensec.c b/source4/libcli/auth/gensec.c
index 24c2c18877..8188701558 100644
--- a/source4/libcli/auth/gensec.c
+++ b/source4/libcli/auth/gensec.c
@@ -145,6 +145,7 @@ static NTSTATUS gensec_start(struct gensec_security **gensec_security)
(*gensec_security)->default_user.realm = talloc_strdup(mem_ctx, lp_realm());
(*gensec_security)->subcontext = False;
+ (*gensec_security)->want_features = 0;
return NT_STATUS_OK;
}
@@ -232,13 +233,20 @@ static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security)
*/
NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security,
- uint8_t authtype)
+ uint8_t auth_type, uint8_t auth_level)
{
- gensec_security->ops = gensec_security_by_authtype(authtype);
+ gensec_security->ops = gensec_security_by_authtype(auth_type);
if (!gensec_security->ops) {
- DEBUG(3, ("Could not find GENSEC backend for authtype=%d\n", (int)authtype));
+ DEBUG(3, ("Could not find GENSEC backend for auth_type=%d\n", (int)auth_type));
return NT_STATUS_INVALID_PARAMETER;
}
+ if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
+ gensec_want_feature(gensec_security, GENSEC_WANT_SIGN);
+ }
+ if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
+ gensec_want_feature(gensec_security, GENSEC_WANT_SIGN);
+ gensec_want_feature(gensec_security, GENSEC_WANT_SEAL);
+ }
return gensec_start_mech(gensec_security);
}
@@ -308,6 +316,10 @@ NTSTATUS gensec_check_packet(struct gensec_security *gensec_security,
if (!gensec_security->ops->check_packet) {
return NT_STATUS_NOT_IMPLEMENTED;
}
+ if (!(gensec_security->want_features & GENSEC_WANT_SIGN)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
return gensec_security->ops->check_packet(gensec_security, mem_ctx, data, length, sig);
}
@@ -319,6 +331,10 @@ NTSTATUS gensec_seal_packet(struct gensec_security *gensec_security,
if (!gensec_security->ops->seal_packet) {
return NT_STATUS_NOT_IMPLEMENTED;
}
+ if (!(gensec_security->want_features & GENSEC_WANT_SEAL)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
return gensec_security->ops->seal_packet(gensec_security, mem_ctx, data, length, sig);
}
@@ -330,6 +346,10 @@ NTSTATUS gensec_sign_packet(struct gensec_security *gensec_security,
if (!gensec_security->ops->sign_packet) {
return NT_STATUS_NOT_IMPLEMENTED;
}
+ if (!(gensec_security->want_features & GENSEC_WANT_SIGN)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
return gensec_security->ops->sign_packet(gensec_security, mem_ctx, data, length, sig);
}
@@ -339,6 +359,10 @@ NTSTATUS gensec_session_key(struct gensec_security *gensec_security,
if (!gensec_security->ops->session_key) {
return NT_STATUS_NOT_IMPLEMENTED;
}
+ if (!(gensec_security->want_features & GENSEC_WANT_SESSION_KEY)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
return gensec_security->ops->session_key(gensec_security, session_key);
}
@@ -393,6 +417,17 @@ void gensec_end(struct gensec_security **gensec_security)
}
/**
+ * Set the requirement for a certain feature on the connection
+ *
+ */
+
+void gensec_want_feature(struct gensec_security *gensec_security,
+ uint32 feature)
+{
+ gensec_security->want_features |= feature;
+}
+
+/**
* Set a username on a GENSEC context - ensures it is talloc()ed
*
*/
diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h
index 880ee45265..73a5f6b463 100644
--- a/source4/libcli/auth/gensec.h
+++ b/source4/libcli/auth/gensec.h
@@ -36,7 +36,10 @@ struct gensec_target {
const struct sock_addr *addr;
const char *service;
};
-
+
+#define GENSEC_WANT_SESSION_KEY 0x1
+#define GENSEC_WANT_SIGN 0x2
+#define GENSEC_WANT_SEAL 0x4
/* GENSEC mode */
enum gensec_role
@@ -86,6 +89,7 @@ struct gensec_security {
struct gensec_target target;
enum gensec_role gensec_role;
BOOL subcontext;
+ uint32 want_features;
};
/* this structure is used by backends to determine the size of some critical types */
diff --git a/source4/libcli/auth/gensec_ntlmssp.c b/source4/libcli/auth/gensec_ntlmssp.c
index 99247fb626..ae03bc88e6 100644
--- a/source4/libcli/auth/gensec_ntlmssp.c
+++ b/source4/libcli/auth/gensec_ntlmssp.c
@@ -179,6 +179,13 @@ static NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_secur
return nt_status;
}
+ if (gensec_security->want_features & GENSEC_WANT_SIGN) {
+ gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
+ }
+ if (gensec_security->want_features & GENSEC_WANT_SEAL) {
+ gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
+ }
+
ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state;
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&gensec_ntlmssp_state->auth_context))) {
return nt_status;
@@ -211,6 +218,25 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur
return status;
}
+ if (gensec_security->want_features & GENSEC_WANT_SESSION_KEY) {
+ /*
+ * We need to set this to allow a later SetPassword
+ * via the SAMR pipe to succeed. Strange.... We could
+ * also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
+ *
+ * Without this, Windows will not create the master key
+ * that it thinks is only used for NTLMSSP signing and
+ * sealing. (It is actually pulled out and used directly)
+ */
+ gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
+ }
+ if (gensec_security->want_features & GENSEC_WANT_SIGN) {
+ gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
+ }
+ if (gensec_security->want_features & GENSEC_WANT_SEAL) {
+ gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
+ }
+
status = ntlmssp_set_domain(gensec_ntlmssp_state->ntlmssp_state,
gensec_security->user.domain);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source4/libcli/auth/ntlmssp.c b/source4/libcli/auth/ntlmssp.c
index 893e8520c2..4d2dd6b576 100644
--- a/source4/libcli/auth/ntlmssp.c
+++ b/source4/libcli/auth/ntlmssp.c
@@ -375,6 +375,14 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
}
+ if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
+ }
+
+ if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
+ }
+
if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
}
@@ -933,9 +941,7 @@ NTSTATUS ntlmssp_server_start(struct ntlmssp_state **ntlmssp_state)
NTLMSSP_NEGOTIATE_128 |
NTLMSSP_NEGOTIATE_NTLM |
/* NTLMSSP_NEGOTIATE_NTLM2 | */
- NTLMSSP_NEGOTIATE_KEY_EXCH |
- NTLMSSP_NEGOTIATE_SIGN |
- NTLMSSP_NEGOTIATE_SEAL;
+ NTLMSSP_NEGOTIATE_KEY_EXCH;
return NT_STATUS_OK;
}
@@ -1289,16 +1295,6 @@ NTSTATUS ntlmssp_client_start(struct ntlmssp_state **ntlmssp_state)
NTLMSSP_NEGOTIATE_NTLM |
/* NTLMSSP_NEGOTIATE_NTLM2 |*/
NTLMSSP_NEGOTIATE_KEY_EXCH |
- /*
- * We need to set this to allow a later SetPassword
- * via the SAMR pipe to succeed. Strange.... We could
- * also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
- *
- * Without this, Windows will not create the master key
- * that it thinks is only used for NTLMSSP signing and
- * sealing. (It is actually pulled out and used directly)
- */
- NTLMSSP_NEGOTIATE_SIGN |
NTLMSSP_REQUEST_TARGET;
return NT_STATUS_OK;
diff --git a/source4/libcli/auth/ntlmssp_sign.c b/source4/libcli/auth/ntlmssp_sign.c
index 80ce1cccc0..6c770b87b9 100644
--- a/source4/libcli/auth/ntlmssp_sign.c
+++ b/source4/libcli/auth/ntlmssp_sign.c
@@ -178,6 +178,11 @@ NTSTATUS ntlmssp_sign_packet(struct ntlmssp_state *ntlmssp_state,
return NT_STATUS_NO_USER_SESSION_KEY;
}
+ if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
+ DEBUG(3, ("NTLMSSP Signing not negotiated - cannot sign packet!\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
nt_status = ntlmssp_make_packet_signature(ntlmssp_state, sig_mem_ctx,
data, length, NTLMSSP_SEND, sig);
@@ -268,6 +273,11 @@ NTSTATUS ntlmssp_seal_packet(struct ntlmssp_state *ntlmssp_state,
return NT_STATUS_NO_USER_SESSION_KEY;
}
+ if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
+ DEBUG(3, ("NTLMSSP Sealing not negotiated - cannot seal packet!\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
DEBUG(10,("ntlmssp_seal_data: seal\n"));
dump_data_pw("ntlmssp clear data\n", data, length);
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c
index af8a63328c..32be6b68ed 100644
--- a/source4/libcli/raw/clisession.c
+++ b/source4/libcli/raw/clisession.c
@@ -399,6 +399,8 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess
goto done;
}
+ gensec_want_feature(session->gensec, GENSEC_WANT_SESSION_KEY);
+
status = gensec_set_domain(session->gensec, parms->generic.in.domain);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n",