diff options
Diffstat (limited to 'source3/smbd/sesssetup.c')
-rw-r--r-- | source3/smbd/sesssetup.c | 71 |
1 files changed, 55 insertions, 16 deletions
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7d77ed3071..88b442215d 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -3,7 +3,7 @@ handle SMBsessionsetup Copyright (C) Andrew Tridgell 1998-2001 Copyright (C) Andrew Bartlett 2001 - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002 Copyright (C) Luke Howard 2003 This program is free software; you can redistribute it and/or modify @@ -62,7 +62,7 @@ static int add_signature(char *outbuf, char *p) char *start = p; fstring lanman; - snprintf( lanman, sizeof(lanman), "Samba %s", VERSION ); + fstr_sprintf( lanman, "Samba %s", VERSION ); p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); p += srvstr_push(outbuf, p, lanman, -1, STR_TERMINATE); @@ -153,6 +153,7 @@ static int reply_spnego_kerberos(connection_struct *conn, uint8 session_key[16]; uint8 tok_id[2]; BOOL foreign = False; + DATA_BLOB nullblob = data_blob(NULL, 0); ZERO_STRUCT(ticket); ZERO_STRUCT(auth_data); @@ -235,7 +236,7 @@ static int reply_spnego_kerberos(connection_struct *conn, memcpy(server_info->session_key, session_key, sizeof(session_key)); /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, user); + sess_vuid = register_vuid(server_info, nullblob, user); free(user); @@ -250,6 +251,16 @@ static int reply_spnego_kerberos(connection_struct *conn, } SSVAL(outbuf, smb_uid, sess_vuid); + + if (!server_info->guest) { + /* We need to start the signing engine + * here but a W2K client sends the old + * "BSRSPYL " signature instead of the + * correct one. Subsequent packets will + * be correct. + */ + srv_check_sign_mac(inbuf); + } } /* wrap that up in a nice GSS-API wrapping */ @@ -275,7 +286,7 @@ static int reply_spnego_kerberos(connection_struct *conn, End the NTLMSSP exchange context if we are OK/complete fail ***************************************************************************/ -static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, +static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *outbuf, AUTH_NTLMSSP_STATE **auth_ntlmssp_state, DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status) { @@ -294,8 +305,10 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, if (NT_STATUS_IS_OK(nt_status)) { int sess_vuid; + DATA_BLOB nullblob = data_blob(NULL, 0); + /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, (*auth_ntlmssp_state)->ntlmssp_state->user); + sess_vuid = register_vuid(server_info, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user); (*auth_ntlmssp_state)->server_info = NULL; if (sess_vuid == -1) { @@ -310,6 +323,16 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, } SSVAL(outbuf,smb_uid,sess_vuid); + + if (!server_info->guest) { + /* We need to start the signing engine + * here but a W2K client sends the old + * "BSRSPYL " signature instead of the + * correct one. Subsequent packets will + * be correct. + */ + srv_check_sign_mac(inbuf); + } } } @@ -348,16 +371,27 @@ static int reply_spnego_negotiate(connection_struct *conn, if (!parse_negTokenTarg(blob1, OIDs, &secblob)) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } + + /* only look at the first OID for determining the mechToken -- + accoirding to RFC2478, we should choose the one we want + and renegotiate, but i smell a client bug here.. + + Problem observed when connecting to a member (samba box) + of an AD domain as a user in a Samba domain. Samba member + server sent back krb5/mskrb5/ntlmssp as mechtypes, but the + client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an + NTLMSSP mechtoken. --jerry */ + if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || + strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) { + got_kerberos = True; + } + for (i=0;OIDs[i];i++) { DEBUG(3,("Got OID %s\n", OIDs[i])); - if (strcmp(OID_KERBEROS5, OIDs[i]) == 0 || - strcmp(OID_KERBEROS5_OLD, OIDs[i]) == 0) { - got_kerberos = True; - } free(OIDs[i]); } - DEBUG(3,("Got secblob of size %d\n", secblob.length)); + DEBUG(3,("Got secblob of size %lu\n", (unsigned long)secblob.length)); #ifdef HAVE_KRB5 if (got_kerberos && (SEC_ADS == lp_security())) { @@ -382,7 +416,7 @@ static int reply_spnego_negotiate(connection_struct *conn, data_blob_free(&secblob); - reply_spnego_ntlmssp(conn, outbuf, &global_ntlmssp_state, + reply_spnego_ntlmssp(conn, inbuf, outbuf, &global_ntlmssp_state, &chal, nt_status); data_blob_free(&chal); @@ -419,7 +453,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, data_blob_free(&auth); - reply_spnego_ntlmssp(conn, outbuf, &global_ntlmssp_state, + reply_spnego_ntlmssp(conn, inbuf, outbuf, &global_ntlmssp_state, &auth_reply, nt_status); data_blob_free(&auth_reply); @@ -742,7 +776,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, free_user_info(&user_info); data_blob_free(&lm_resp); - data_blob_free(&nt_resp); data_blob_clear_free(&plaintext_password); if (!NT_STATUS_IS_OK(nt_status)) { @@ -750,9 +783,10 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } if (!NT_STATUS_IS_OK(nt_status)) { + data_blob_free(&nt_resp); return ERROR_NT(nt_status_squash(nt_status)); } - + /* it's ok - setup a reply */ set_message(outbuf,3,0,True); if (Protocol >= PROTOCOL_NT1) { @@ -770,12 +804,17 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, to a uid can get through without a password, on the same VC */ /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, sub_user); - + sess_vuid = register_vuid(server_info, nt_resp, sub_user); + data_blob_free(&nt_resp); + if (sess_vuid == -1) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } + if (!server_info->guest && !srv_check_sign_mac(inbuf)) { + exit_server("reply_sesssetup_and_X: bad smb signature"); + } + SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); |