From 2e28f8ff0e3bb50ac5b2742c7678c39cb65bcd95 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Jan 2002 04:55:41 +0000 Subject: I've decided to move the auth code around a bit more... The auth_authsupplied_info typedef is now just a plain struct - auth_context, but it has been modified to contain the function pointers to the rest of the auth subsystem's components. (Who needs non-static functions anyway?) In working all this mess out, I fixed a number of memory leaks and moved the entire auth subsystem over to talloc(). Note that the TALLOC_CTX attached to the auth_context can be rather long-lived, it is provided for things that are intended to live as long. (The global_negprot_auth_context lasts the whole life of the smbd). I've also adjusted a few things in auth_domain.c, mainly passing the domain as a paramater to a few functions instead of looking up lp_workgroup(). I'm hopign to make this entire thing a bit more trusted domains (as PDC) freindly in the near future. Other than that, I moved a bit of the code around, hence the rather messy diff. Andrew Bartlett (This used to be commit 12f5515f556cf39fea98134fe3e2ac4540501048) --- source3/smbd/negprot.c | 51 +++++++++++++----------- source3/smbd/process.c | 12 +++--- source3/smbd/server.c | 6 ++- source3/smbd/sesssetup.c | 101 ++++++++++++++++++++++++++--------------------- 4 files changed, 94 insertions(+), 76 deletions(-) (limited to 'source3/smbd') diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index d3afa19d00..52ba5e9789 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -27,7 +27,28 @@ extern fstring global_myworkgroup; extern fstring remote_machine; BOOL global_encrypted_passwords_negotiated = False; BOOL global_spnego_negotiated = False; -auth_authsupplied_info *negprot_global_auth_info = NULL; +struct auth_context *negprot_global_auth_context = NULL; + +static void get_challange(char buff[8]) +{ + NTSTATUS nt_status; + const uint8 *cryptkey; + + /* We might be called more than once, muliple negprots are premitted */ + if (negprot_global_auth_context) { + DEBUG(3, ("get challange: is this a secondary negprot? negprot_global_auth_context is non-NULL!\n")); + negprot_global_auth_context->free(&negprot_global_auth_context); + } + + DEBUG(10, ("get challange: creating negprot_global_auth_context\n")); + if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&negprot_global_auth_context))) { + DEBUG(0, ("make_auth_context_subsystem returned %s", get_nt_error_msg(nt_status))); + smb_panic("cannot make_negprot_global_auth_context!\n"); + } + DEBUG(10, ("get challange: getting challange\n")); + cryptkey = negprot_global_auth_context->get_ntlm_challenge(negprot_global_auth_context); + memcpy(buff, cryptkey, 8); +} /**************************************************************************** reply for the core protocol @@ -69,7 +90,6 @@ static int reply_lanman1(char *inbuf, char *outbuf) int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0); int secword=0; time_t t = time(NULL); - DATA_BLOB cryptkey; global_encrypted_passwords_negotiated = lp_encrypted_passwords(); @@ -80,12 +100,7 @@ static int reply_lanman1(char *inbuf, char *outbuf) SSVAL(outbuf,smb_vwv1,secword); /* Create a token value and add it to the outgoing packet. */ if (global_encrypted_passwords_negotiated) { - if (!make_auth_info_subsystem(&negprot_global_auth_info)) { - smb_panic("cannot make_negprot_global_auth_info!\n"); - } - cryptkey = auth_get_challenge(negprot_global_auth_info); - memcpy(smb_buf(outbuf), cryptkey.data, 8); - data_blob_free(&cryptkey); + get_challange(smb_buf(outbuf)); } Protocol = PROTOCOL_LANMAN1; @@ -114,7 +129,6 @@ static int reply_lanman2(char *inbuf, char *outbuf) int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0); int secword=0; time_t t = time(NULL); - DATA_BLOB cryptkey; global_encrypted_passwords_negotiated = lp_encrypted_passwords(); @@ -125,13 +139,9 @@ static int reply_lanman2(char *inbuf, char *outbuf) SSVAL(outbuf,smb_vwv1,secword); SIVAL(outbuf,smb_vwv6,sys_getpid()); + /* Create a token value and add it to the outgoing packet. */ if (global_encrypted_passwords_negotiated) { - if (!make_auth_info_subsystem(&negprot_global_auth_info)) { - smb_panic("cannot make_negprot_global_auth_info!\n"); - } - cryptkey = auth_get_challenge(negprot_global_auth_info); - memcpy(smb_buf(outbuf), cryptkey.data, 8); - data_blob_free(&cryptkey); + get_challange(smb_buf(outbuf)); } Protocol = PROTOCOL_LANMAN2; @@ -216,7 +226,6 @@ static int reply_nt1(char *inbuf, char *outbuf) int secword=0; time_t t = time(NULL); - DATA_BLOB cryptkey; char *p, *q; BOOL negotiate_spnego = False; @@ -275,13 +284,9 @@ static int reply_nt1(char *inbuf, char *outbuf) p = q = smb_buf(outbuf); if (!negotiate_spnego) { - if (global_encrypted_passwords_negotiated) { - if (!make_auth_info_subsystem(&negprot_global_auth_info)) { - smb_panic("cannot make_negprot_global_auth_info!\n"); - } - cryptkey = auth_get_challenge(negprot_global_auth_info); - memcpy(p, cryptkey.data, 8); - data_blob_free(&cryptkey); + /* Create a token value and add it to the outgoing packet. */ + if (global_encrypted_passwords_negotiated) { + get_challange(p); } SSVALS(outbuf,smb_vwv16+1,8); p += 8; diff --git a/source3/smbd/process.c b/source3/smbd/process.c index af081d5059..2b31a24ced 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -1112,7 +1112,7 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t if (keepalive && (t - last_keepalive_sent_time)>keepalive) { - extern auth_authsupplied_info *negprot_global_auth_info; + extern struct auth_context *negprot_global_auth_context; if (!send_keepalive(smbd_server_fd())) { DEBUG( 2, ( "Keepalive failed - exiting.\n" ) ); return False; @@ -1121,11 +1121,11 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t /* send a keepalive for a password server or the like. This is attached to the auth_info created in the negprot */ - if (negprot_global_auth_info - && negprot_global_auth_info->challenge_set_method - && negprot_global_auth_info->challenge_set_method->send_keepalive) { - negprot_global_auth_info->challenge_set_method->send_keepalive - (&negprot_global_auth_info->challenge_set_method->private_data); + if (negprot_global_auth_context + && negprot_global_auth_context->challenge_set_method + && negprot_global_auth_context->challenge_set_method->send_keepalive) { + negprot_global_auth_context->challenge_set_method->send_keepalive + (&negprot_global_auth_context->challenge_set_method->private_data); } last_keepalive_sent_time = t; diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 900f5b4846..1fab45048d 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -475,7 +475,7 @@ void exit_server(char *reason) { static int firsttime=1; extern char *last_inbuf; - extern auth_authsupplied_info *negprot_global_auth_info; + extern struct auth_context *negprot_global_auth_context; if (!firsttime) exit(0); @@ -484,7 +484,9 @@ void exit_server(char *reason) change_to_root_user(); DEBUG(2,("Closing connections\n")); - free_auth_info(&negprot_global_auth_info); + if (negprot_global_auth_context) { + negprot_global_auth_context->free(&negprot_global_auth_context); + } conn_close_all(); diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 41a7a657e2..737ecade7d 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -23,7 +23,7 @@ #include "includes.h" uint32 global_client_caps = 0; -static auth_authsupplied_info *ntlmssp_auth_info; +static struct auth_context *ntlmssp_auth_context; /* on a logon error possibly map the error to success if "map to guest" @@ -72,8 +72,7 @@ static void add_signature(char *outbuf) ****************************************************************************/ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) { - - auth_authsupplied_info *auth_info; + struct auth_context *auth_context; auth_usersupplied_info *user_info = NULL; NTSTATUS nt_status; @@ -83,11 +82,17 @@ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) DEBUG(3,("Got anonymous request\n")); - make_user_info_guest(&user_info); - make_auth_info_fixed(&auth_info, chal); + if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context, chal))) { + return nt_status; + } + + if (!make_user_info_guest(&user_info)) { + auth_context->free(&auth_context); + return NT_STATUS_NO_MEMORY; + } - nt_status = check_password(user_info, auth_info, server_info); - free_auth_info(&auth_info); + nt_status = auth_context->check_ntlm_password(auth_context, user_info, server_info); + auth_context->free(&auth_context); free_user_info(&user_info); return nt_status; } @@ -233,8 +238,9 @@ static int reply_spnego_negotiate(connection_struct *conn, int i; uint32 ntlmssp_command, neg_flags; DATA_BLOB sess_key, chal, spnego_chal; - DATA_BLOB cryptkey; + const uint8 *cryptkey; BOOL got_kerberos = False; + NTSTATUS nt_status; /* parse out the OIDs and the first sec blob */ if (!parse_negTokenTarg(blob1, OIDs, &secblob)) { @@ -282,11 +288,15 @@ static int reply_spnego_negotiate(connection_struct *conn, DEBUG(3,("Got neg_flags=%08x\n", neg_flags)); - if (!make_auth_info_subsystem(&ntlmssp_auth_info)) { - return ERROR_NT(NT_STATUS_NO_MEMORY); + if (!ntlmssp_auth_context) { + ntlmssp_auth_context->free(&ntlmssp_auth_context); + } + + if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&ntlmssp_auth_context))) { + return ERROR_NT(nt_status); } - cryptkey = auth_get_challenge(ntlmssp_auth_info); + cryptkey = ntlmssp_auth_context->get_ntlm_challenge(ntlmssp_auth_context); /* Give them the challenge. For now, ignore neg_flags and just return the flags we want. Obviously this is not correct */ @@ -301,7 +311,7 @@ static int reply_spnego_negotiate(connection_struct *conn, 0, 0x30, /* ?? */ neg_flags, - cryptkey.data, cryptkey.length, + cryptkey, sizeof(cryptkey), 0, 0, 0, 0x3000); /* ?? */ @@ -314,7 +324,6 @@ static int reply_spnego_negotiate(connection_struct *conn, reply_sesssetup_blob(conn, outbuf, spnego_chal); data_blob_free(&chal); - data_blob_free(&cryptkey); data_blob_free(&spnego_chal); /* and tell smbd that we have already replied to this packet */ @@ -382,7 +391,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, return ERROR_NT(NT_STATUS_NO_MEMORY); } - nt_status = check_password(user_info, ntlmssp_auth_info, &server_info); + nt_status = ntlmssp_auth_context->check_ntlm_password(ntlmssp_auth_context, user_info, &server_info); if (!NT_STATUS_IS_OK(nt_status)) { nt_status = do_map_to_guest(nt_status, &server_info, user, workgroup); @@ -391,7 +400,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, SAFE_FREE(workgroup); SAFE_FREE(machine); - free_auth_info(&ntlmssp_auth_info); + ntlmssp_auth_context->free(&ntlmssp_auth_context); free_user_info(&user_info); @@ -544,7 +553,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, extern int max_send; auth_usersupplied_info *user_info = NULL; - extern auth_authsupplied_info *negprot_global_auth_info; + extern struct auth_context *negprot_global_auth_context; auth_serversupplied_info *server_info = NULL; NTSTATUS nt_status; @@ -671,13 +680,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, remote_machine)); - if (*user) { - if (global_spnego_negotiated) { - DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at 'normal' session setup after negotiating spnego.\n")); - return ERROR_NT(NT_STATUS_UNSUCCESSFUL); - } - } - if (*user) { pstrcpy(sub_user, user); } else { @@ -702,37 +704,46 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } if (!*user) { + if (global_spnego_negotiated) { + + /* This has to be here, becouse this is a perfectly valid behaviour for guest logons :-( */ + + DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at 'normal' session setup after negotiating spnego.\n")); + return ERROR_NT(NT_STATUS_UNSUCCESSFUL); + } nt_status = check_guest_password(&server_info); } else if (doencrypt) { if (!make_user_info_for_reply_enc(&user_info, user, domain, - lm_resp, nt_resp, - plaintext_password)) { - return ERROR_NT(NT_STATUS_NO_MEMORY); + lm_resp, nt_resp)) { + nt_status = NT_STATUS_NO_MEMORY; + } else { + nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context, + user_info, + &server_info); } - - nt_status = check_password(user_info, negprot_global_auth_info, &server_info); } else { - auth_authsupplied_info *plaintext_auth_info = NULL; - DATA_BLOB chal; - if (!make_auth_info_subsystem(&plaintext_auth_info)) { - return ERROR_NT(NT_STATUS_NO_MEMORY); - } - - chal = auth_get_challenge(plaintext_auth_info); - - if (!make_user_info_for_reply(&user_info, - user, domain, chal.data, - plaintext_password)) { - return ERROR_NT(NT_STATUS_NO_MEMORY); - } - - nt_status = check_password(user_info, plaintext_auth_info, &server_info); + struct auth_context *plaintext_auth_context = NULL; + const uint8 *chal; + if (NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) { + chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context); + + if (!make_user_info_for_reply(&user_info, + user, domain, chal, + plaintext_password)) { + nt_status = NT_STATUS_NO_MEMORY; + } - data_blob_free(&chal); - free_auth_info(&plaintext_auth_info); + if (NT_STATUS_IS_OK(nt_status)) { + nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context, + user_info, + &server_info); + + plaintext_auth_context->free(&plaintext_auth_context); + } + } } free_user_info(&user_info); -- cgit