svn commit: samba r9039 - in trunk/source: include rpc_server smbd
jra at samba.org
jra at samba.org
Thu Aug 4 03:04:58 GMT 2005
Author: jra
Date: 2005-08-04 03:04:58 +0000 (Thu, 04 Aug 2005)
New Revision: 9039
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=9039
Log:
Added comments to 2 factor auth in sesssetup.c.
We now create the reply blob for the SPNEGO ntlmssp blob - now
to learn how to return it...
Jeremy.
Modified:
trunk/source/include/ntdomain.h
trunk/source/rpc_server/srv_pipe.c
trunk/source/smbd/sesssetup.c
Changeset:
Modified: trunk/source/include/ntdomain.h
===================================================================
--- trunk/source/include/ntdomain.h 2005-08-04 02:59:19 UTC (rev 9038)
+++ trunk/source/include/ntdomain.h 2005-08-04 03:04:58 UTC (rev 9039)
@@ -185,11 +185,6 @@
uint32 ntlmssp_seq_num;
};
-/* auth state for spnego ntlmssp. */
-struct spnego_ntlmssp_auth_struct {
- AUTH_NTLMSSP_STATE *auth_ntlmssp_state;
-};
-
/* auth state for all bind types. */
struct pipe_auth_data {
@@ -197,7 +192,7 @@
union {
struct ntlmssp_auth_struct *ntlmssp_auth;
struct schannel_auth_struct *schannel_auth;
- struct spnego_ntlmssp_auth_struct *spnego_auth;
+ AUTH_NTLMSSP_STATE *auth_ntlmssp_state;
} a_u;
void (*auth_data_free_func)(struct pipe_auth_data *);
};
Modified: trunk/source/rpc_server/srv_pipe.c
===================================================================
--- trunk/source/rpc_server/srv_pipe.c 2005-08-04 02:59:19 UTC (rev 9038)
+++ trunk/source/rpc_server/srv_pipe.c 2005-08-04 03:04:58 UTC (rev 9039)
@@ -839,6 +839,7 @@
/*******************************************************************
Register commands to an RPC pipe
*******************************************************************/
+
NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *srv, const struct api_struct *cmds, int size)
{
struct rpc_table *rpc_entry;
@@ -898,26 +899,33 @@
static void free_pipe_spnego_auth_data(struct pipe_auth_data *auth)
{
- AUTH_NTLMSSP_STATE *a = auth->a_u.spnego_auth->auth_ntlmssp_state;
+ AUTH_NTLMSSP_STATE *a = auth->a_u.auth_ntlmssp_state;
if (a) {
auth_ntlmssp_end(&a);
}
+ auth->a_u.auth_ntlmssp_state = NULL;
}
/*******************************************************************
- Handle a SPNEGO bind auth.
+ Handle the first part of a SPNEGO bind auth.
*******************************************************************/
static BOOL pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth)
{
- DATA_BLOB secblob;
DATA_BLOB blob;
+ DATA_BLOB secblob;
+ DATA_BLOB response;
+ DATA_BLOB chal;
char *OIDs[ASN1_MAX_OIDS];
int i;
+ NTSTATUS status;
BOOL got_kerberos_mechanism = False;
+ AUTH_NTLMSSP_STATE *a = NULL;
ZERO_STRUCT(secblob);
+ ZERO_STRUCT(chal);
+ ZERO_STRUCT(response);
/* Grab the SPNEGO blob. */
blob = data_blob(NULL,p->hdr.auth_len);
@@ -925,20 +933,17 @@
if (!prs_copy_data_out(blob.data, rpc_in_p, p->hdr.auth_len)) {
DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to pull %u bytes - the SPNEGO auth header.\n",
(unsigned int)p->hdr.auth_len ));
- data_blob_free(&blob);
- return False;
+ goto err;
}
if (blob.data[0] != ASN1_APPLICATION(0)) {
- data_blob_free(&blob);
- return False;
+ goto err;
}
/* parse out the OIDs and the first sec blob */
if (!parse_negTokenTarg(blob, OIDs, &secblob)) {
DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to parse the security blob.\n"));
- data_blob_free(&blob);
- return False;
+ goto err;
}
if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) {
@@ -958,35 +963,56 @@
return ret;
}
- if (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP && p->auth.a_u.spnego_auth) {
+ if (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP && p->auth.a_u.auth_ntlmssp_state) {
/* Free any previous auth type. */
free_pipe_spnego_auth_data(&p->auth);
}
- p->auth.a_u.spnego_auth = TALLOC_P(p->pipe_state_mem_ctx, struct spnego_ntlmssp_auth_struct);
- if (!p->auth.a_u.spnego_auth) {
- return False;
+ /* Initialize the NTLM engine. */
+ status = auth_ntlmssp_start(&a);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto err;
}
+ /*
+ * Pass the first security blob of data to it.
+ * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED
+ * which means we need another packet to complete the bind.
+ */
+
+ status = auth_ntlmssp_update(a, secblob, &chal);
+
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n"));
+ goto err;
+ }
+
+ /* Generate the response blob we need for step 2 of the bind. */
+ response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP);
+
+ p->auth.a_u.auth_ntlmssp_state = a;
p->auth.auth_data_free_func = &free_pipe_spnego_auth_data;
p->auth.auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP;
+ data_blob_free(&blob);
+ data_blob_free(&secblob);
+ data_blob_free(&chal);
+ data_blob_free(&response);
+
+ /* We can't set pipe_bound True yet - we need a response packet... */
return False;
-#if 0
- nt_status = auth_ntlmssp_start(auth_ntlmssp_state);
- if (!NT_STATUS_IS_OK(nt_status)) {
- return ERROR_NT(nt_status);
- }
- nt_status = auth_ntlmssp_update(*auth_ntlmssp_state, secblob, &chal);
+ err:
- data_blob_free(&secblob);
+ data_blob_free(&blob);
+ data_blob_free(&secblob);
+ data_blob_free(&chal);
+ data_blob_free(&response);
- reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, auth_ntlmssp_state, &chal, nt_status);
- data_blob_free(&chal);
- data_blob_free(&secblob);
- return True;
-#endif
+ p->auth.a_u.auth_ntlmssp_state = NULL;
+ p->auth.auth_type = PIPE_AUTH_TYPE_NONE;
+
+ return False;
}
/*******************************************************************
@@ -1015,9 +1041,6 @@
return False;
}
- p->auth.auth_data_free_func = NULL;
- p->auth.auth_type = PIPE_AUTH_TYPE_SCHANNEL;
-
memset(p->auth.a_u.schannel_auth->sess_key, 0, sizeof(p->auth.a_u.schannel_auth->sess_key));
memcpy(p->auth.a_u.schannel_auth->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key));
@@ -1053,6 +1076,9 @@
neg.domain, neg.myname));
/* We're finished with this bind - no more packets. */
+ p->auth.auth_data_free_func = NULL;
+ p->auth.auth_type = PIPE_AUTH_TYPE_SCHANNEL;
+
p->pipe_bound = True;
return True;
@@ -1095,9 +1121,6 @@
return False;
}
- p->auth.auth_data_free_func = NULL;
-
- p->auth.auth_type = PIPE_AUTH_TYPE_NTLMSSP;
p->auth.a_u.ntlmssp_auth->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS;
p->auth.a_u.ntlmssp_auth->ntlmssp_auth_requested = True;
@@ -1136,6 +1159,9 @@
DEBUG(10,("pipe_ntlmssp_auth_bind: NTLMSSP auth: domain [%s] myname [%s]\n",
ntlmssp_neg.domain, ntlmssp_neg.myname));
+ p->auth.auth_data_free_func = NULL;
+ p->auth.auth_type = PIPE_AUTH_TYPE_NTLMSSP;
+
/* We can't set pipe_bound True yet - we need a response packet... */
return True;
}
Modified: trunk/source/smbd/sesssetup.c
===================================================================
--- trunk/source/smbd/sesssetup.c 2005-08-04 02:59:19 UTC (rev 9038)
+++ trunk/source/smbd/sesssetup.c 2005-08-04 03:04:58 UTC (rev 9039)
@@ -348,6 +348,8 @@
Send a session setup reply, wrapped in SPNEGO.
Get vuid and check first.
End the NTLMSSP exchange context if we are OK/complete fail
+ This should be split into two functions, one to handle each
+ leg of the NTLM auth steps.
***************************************************************************/
static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *outbuf,
@@ -422,6 +424,7 @@
and the other end, that we are not finished yet. */
if (!ret || !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ /* NB. This is *NOT* an error case. JRA */
auth_ntlmssp_end(auth_ntlmssp_state);
/* Kill the intermediate vuid */
invalidate_vuid(vuid);
More information about the samba-cvs
mailing list