From 0c0dd06dbd558254ebb048223b0396454f7ee1dd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Oct 2001 07:50:21 +0000 Subject: split session setup code out of reply.c in preparation for adding NTLMSSP and kerberos support in smbd (This used to be commit 38a43d75e25bbebe0f6cdfcf389129a842ede842) --- source3/smbd/sesssetup.c | 355 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 source3/smbd/sesssetup.c (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c new file mode 100644 index 0000000000..45fa2d6a4a --- /dev/null +++ b/source3/smbd/sesssetup.c @@ -0,0 +1,355 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + handle SMBsessionsetup + Copyright (C) Andrew Tridgell 1998-2001 + Copyright (C) Andrew Bartlett 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/**************************************************************************** +reply to a session setup command +****************************************************************************/ +int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, + int length,int bufsize) +{ + int sess_vuid; + gid_t gid; + uid_t uid; + char* full_name; + int smb_bufsize; + int smb_apasslen = 0; + pstring smb_apasswd; + int smb_ntpasslen = 0; + pstring smb_ntpasswd; + pstring user; + pstring orig_user; + fstring domain; + fstring native_os; + fstring native_lanman; + BOOL guest=False; + static BOOL done_sesssetup = False; + extern BOOL global_encrypted_passwords_negotiated; + extern uint32 global_client_caps; + extern int Protocol; + extern fstring remote_machine; + extern userdom_struct current_user_info; + extern int max_send; + BOOL doencrypt = global_encrypted_passwords_negotiated; + START_PROFILE(SMBsesssetupX); + + *smb_apasswd = *smb_ntpasswd = 0; + + smb_bufsize = SVAL(inbuf,smb_vwv2); + + if (Protocol < PROTOCOL_NT1) { + smb_apasslen = SVAL(inbuf,smb_vwv7); + if (smb_apasslen > MAX_PASS_LEN) { + return ERROR_DOS(ERRDOS,ERRbuftoosmall); + } + + memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen); + srvstr_pull(inbuf, user, smb_buf(inbuf)+smb_apasslen, sizeof(user), -1, STR_TERMINATE); + + if (!doencrypt && (lp_security() != SEC_SERVER)) { + smb_apasslen = strlen(smb_apasswd); + } + } else { + uint16 passlen1 = SVAL(inbuf,smb_vwv7); + uint16 passlen2 = SVAL(inbuf,smb_vwv8); + enum remote_arch_types ra_type = get_remote_arch(); + char *p = smb_buf(inbuf); + + if(global_client_caps == 0) + global_client_caps = IVAL(inbuf,smb_vwv11); + + /* client_caps is used as final determination if client is NT or Win95. + This is needed to return the correct error codes in some + circumstances. + */ + + if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) { + if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) { + set_remote_arch( RA_WIN95); + } + } + + if (passlen1 != 24 && passlen2 < 24) + doencrypt = False; + + if (passlen1 > MAX_PASS_LEN) { + return ERROR_DOS(ERRDOS,ERRbuftoosmall); + } + + passlen1 = MIN(passlen1, MAX_PASS_LEN); + passlen2 = MIN(passlen2, MAX_PASS_LEN); + + if (!doencrypt) { + /* both Win95 and WinNT stuff up the password lengths for + non-encrypting systems. Uggh. + + if passlen1==24 its a win95 system, and its setting the + password length incorrectly. Luckily it still works with the + default code because Win95 will null terminate the password + anyway + + if passlen1>0 and passlen2>0 then maybe its a NT box and its + setting passlen2 to some random value which really stuffs + things up. we need to fix that one. */ + + if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && passlen2 != 1) + passlen2 = 0; + } + + if (lp_restrict_anonymous()) { + /* there seems to be no reason behind the + * differences in MS clients formatting + * various info like the domain, NativeOS, and + * NativeLanMan fields. Win95 in particular + * seems to have an extra null byte between + * the username and the domain, or the + * password length calculation is wrong, which + * throws off the string extraction routines + * below. This makes the value of domain be + * the empty string, which fails the restrict + * anonymous check further down. This + * compensates for that, and allows browsing + * to work in mixed NT and win95 environments + * even when restrict anonymous is true. AAB + * */ + dump_data(100, p, 0x70); + DEBUG(9, ("passlen1=%d, passlen2=%d\n", passlen1, passlen2)); + if (ra_type == RA_WIN95 && !passlen1 && !passlen2 && p[0] == 0 && p[1] == 0) { + DEBUG(0, ("restrict anonymous parameter used in a win95 environment!\n")); + DEBUG(0, ("client is win95 and broken passlen1 offset -- attempting fix\n")); + DEBUG(0, ("if win95 cilents are having difficulty browsing, you will be unable to use restrict anonymous\n")); + passlen1 = 1; + } + } + + /* Save the lanman2 password and the NT md4 password. */ + smb_apasslen = passlen1; + memcpy(smb_apasswd,p,smb_apasslen); + + smb_ntpasslen = passlen2; + memcpy(smb_ntpasswd,p+passlen1,smb_ntpasslen); + + if (smb_apasslen != 24 || !doencrypt) { + /* trim the password */ + smb_apasslen = strlen(smb_apasswd); + + /* wfwg sometimes uses a space instead of a null */ + if (strequal(smb_apasswd," ")) { + smb_apasslen = 0; + *smb_apasswd = 0; + } + } + + p += passlen1 + passlen2; + p += srvstr_pull(inbuf, user, p, sizeof(user), -1, + STR_TERMINATE); + p += srvstr_pull(inbuf, domain, p, sizeof(domain), + -1, STR_TERMINATE); + p += srvstr_pull(inbuf, native_os, p, sizeof(native_os), + -1, STR_TERMINATE); + p += srvstr_pull(inbuf, native_lanman, p, sizeof(native_lanman), + -1, STR_TERMINATE); + DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n", + domain,native_os,native_lanman)); + } + + /* don't allow for weird usernames or domains */ + alpha_strcpy(user, user, ". _-$", sizeof(user)); + alpha_strcpy(domain, domain, ". _-", sizeof(domain)); + if (strstr(user, "..") || strstr(domain,"..")) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + if (lp_security() == SEC_SHARE) { + /* in share level we should ignore any passwords */ + smb_ntpasslen = 0; + smb_apasslen = 0; + guest = True; + } + + + DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",user, domain, remote_machine)); + + if (done_sesssetup && lp_restrict_anonymous()) { + /* tests show that even if browsing is done over + * already validated connections without a username + * and password the domain is still provided, which it + * wouldn't be if it was a purely anonymous + * connection. So, in order to restrict anonymous, we + * only deny connections that have no session + * information. If a domain has been provided, then + * it's not a purely anonymous connection. AAB */ + if (!*user && !*smb_apasswd && !*domain) { + DEBUG(0, ("restrict anonymous is True and anonymous connection attempted. Denying access.\n")); + END_PROFILE(SMBsesssetupX); + return ERROR_DOS(ERRDOS,ERRnoaccess); + } + } + + /* If no username is sent use the guest account */ + if (!*user) { + pstrcpy(user,lp_guestaccount(-1)); + guest = True; + } + + pstrcpy(current_user_info.smb_name,user); + + reload_services(True); + + /* + * Save the username before mapping. We will use + * the original username sent to us for security=server + * and security=domain checking. + */ + + pstrcpy( orig_user, user); + + /* + * Always try the "DOMAIN\user" lookup first, as this is the most + * specific case. If this fails then try the simple "user" lookup. + * But don't do this for guests, as this is always a local user. + */ + + if (!guest) { + pstring dom_user; + + /* Work out who's who */ + + slprintf(dom_user, sizeof(dom_user) - 1,"%s%s%s", + domain, lp_winbind_separator(), user); + + if (sys_getpwnam(dom_user) != NULL) { + pstrcpy(user, dom_user); + DEBUG(3,("Using unix username %s\n", dom_user)); + } + + /* + * Pass the user through the NT -> unix user mapping + * function. + */ + + (void)map_username(user); + + /* + * Do any UNIX username case mangling. + */ + smb_getpwnam(user, True); + } + + add_session_user(user); + + if (!guest) { + NTSTATUS nt_status; + nt_status = pass_check_smb(orig_user, user, + domain, remote_machine, + (unsigned char *)smb_apasswd, + smb_apasslen, + (unsigned char *)smb_ntpasswd, + smb_ntpasslen); + + if NT_STATUS_IS_OK(nt_status) { + + } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) { + if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || + (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) { + DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain)); + pstrcpy(user,lp_guestaccount(-1)); + guest = True; + } else { + /* Match WinXP and don't give the game away */ + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) { + if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) { + pstrcpy(user,lp_guestaccount(-1)); + DEBUG(3,("Registered username %s for guest access\n",user)); + guest = True; + } else { + /* Match WinXP and don't give the game away */ + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + } else { + return ERROR_NT(nt_status); + } + } + + if (!strequal(user,lp_guestaccount(-1)) && + lp_servicenumber(user) < 0) { + add_home_service(user,get_user_home_dir(user)); + } + + + /* it's ok - setup a reply */ + if (Protocol < PROTOCOL_NT1) { + set_message(outbuf,3,0,True); + } else { + char *p; + set_message(outbuf,3,0,True); + p = smb_buf(outbuf); + p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); + set_message_end(outbuf,p); + /* perhaps grab OS version here?? */ + } + + /* Set the correct uid in the outgoing and incoming packets + We will use this on future requests to determine which + user we should become. + */ + { + const struct passwd *pw = smb_getpwnam(user,False); + if (!pw) { + DEBUG(1,("Username %s is invalid on this system\n",user)); + END_PROFILE(SMBsesssetupX); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + gid = pw->pw_gid; + uid = pw->pw_uid; + full_name = pw->pw_gecos; + } + + if (guest) + SSVAL(outbuf,smb_vwv2,1); + + /* register the name and uid as being validated, so further connections + to a uid can get through without a password, on the same VC */ + + sess_vuid = register_vuid(uid,gid,user,orig_user,domain,guest, full_name); + + if (sess_vuid == -1) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + + SSVAL(outbuf,smb_uid,sess_vuid); + SSVAL(inbuf,smb_uid,sess_vuid); + + if (!done_sesssetup) + max_send = MIN(max_send,smb_bufsize); + + done_sesssetup = True; + + END_PROFILE(SMBsesssetupX); + return chain_reply(inbuf,outbuf,length,bufsize); +} -- cgit From b728042334f67738fd1a6fdd03e619bdb78fe06a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Oct 2001 08:54:19 +0000 Subject: added basic NTLMSSP support in smbd. This is still quite rough, and loses things like username mapping. I wanted to get this in then discuss it a bit to see how we want to split up the existing session setup code (This used to be commit b74fda69bf23207c26d8b2af23910d8f2eb89875) --- source3/smbd/sesssetup.c | 258 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 45fa2d6a4a..34b431e404 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -22,6 +22,259 @@ #include "includes.h" + +/**************************************************************************** +send a security blob via a session setup reply +****************************************************************************/ +static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, + DATA_BLOB blob) +{ + char *p; + + set_message(outbuf,4,0,True); + + /* we set NT_STATUS_MORE_PROCESSING_REQUIRED to tell the other end + that we aren't finished yet */ + + SIVAL(outbuf, smb_rcls, NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED)); + SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */ + SSVAL(outbuf, smb_vwv3, blob.length); + p = smb_buf(outbuf); + memcpy(p, blob.data, blob.length); + p += blob.length; + p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); + set_message_end(outbuf,p); + + return send_smb(smbd_server_fd(),outbuf); +} + + + + +/**************************************************************************** +reply to a session setup spnego negotiate packet +****************************************************************************/ +static int reply_spnego_negotiate(connection_struct *conn, char *outbuf, + DATA_BLOB blob1) +{ + char *OIDs[ASN1_MAX_OIDS]; + DATA_BLOB secblob; + int i; + uint32 ntlmssp_command, neg_flags; + DATA_BLOB sess_key, chal, spnego_chal; + uint8 cryptkey[8]; + + /* parse out the OIDs and the first sec blob */ + if (!parse_negTokenTarg(blob1, OIDs, &secblob)) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + for (i=0;OIDs[i];i++) { + DEBUG(3,("Got OID %s\n", OIDs[i])); + free(OIDs[i]); + } + DEBUG(3,("Got secblob of size %d\n", secblob.length)); + + /* parse the NTLMSSP packet */ +#if 0 + file_save("secblob.dat", secblob.data, secblob.length); +#endif + + msrpc_parse(&secblob, "CddB", + "NTLMSSP", + &ntlmssp_command, + &neg_flags, + &sess_key); + + data_blob_free(&secblob); + data_blob_free(&sess_key); + + if (ntlmssp_command != NTLMSSP_NEGOTIATE) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + DEBUG(3,("Got neg_flags=%08x\n", neg_flags)); + + last_challenge(cryptkey); + + /* Give them the challenge. For now, ignore neg_flags and just + return the flags we want. Obviously this is not correct */ + + neg_flags = NTLMSSP_NEGOTIATE_UNICODE | + NTLMSSP_NEGOTIATE_LM_KEY | + NTLMSSP_NEGOTIATE_NTLM; + + msrpc_gen(&chal, "Cddddbdddd", + "NTLMSSP", + NTLMSSP_CHALLENGE, + 0, + 0x30, /* ?? */ + neg_flags, + cryptkey, 8, + 0, 0, 0, + 0x3000); /* ?? */ + + if (!spnego_gen_challenge(&spnego_chal, &chal, &chal)) { + DEBUG(3,("Failed to generate challenge\n")); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + /* now tell the client to send the auth packet */ + reply_sesssetup_blob(conn, outbuf, spnego_chal); + + data_blob_free(&chal); + data_blob_free(&spnego_chal); + + /* and tell smbd that we have already replied to this packet */ + return -1; +} + + +/**************************************************************************** +reply to a session setup spnego auth packet +****************************************************************************/ +static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, + int length, int bufsize, + DATA_BLOB blob1) +{ + DATA_BLOB auth; + char *workgroup, *user, *machine; + DATA_BLOB lmhash, nthash, sess_key; + uint32 ntlmssp_command, neg_flags; + NTSTATUS nt_status; + int sess_vuid; + gid_t gid; + uid_t uid; + char *full_name; + char *p; + const struct passwd *pw; + + if (!spnego_parse_auth(blob1, &auth)) { + file_save("auth.dat", blob1.data, blob1.length); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + /* now the NTLMSSP encoded auth hashes */ + if (!msrpc_parse(&auth, "CdBBUUUBd", + "NTLMSSP", + &ntlmssp_command, + &lmhash, + &nthash, + &workgroup, + &user, + &machine, + &sess_key, + &neg_flags)) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + data_blob_free(&auth); + data_blob_free(&sess_key); + + DEBUG(3,("Got user=[%s] workgroup=[%s] machine=[%s] len1=%d len2=%d\n", + user, workgroup, machine, lmhash.length, nthash.length)); + +#if 0 + file_save("nthash1.dat", nthash.data, nthash.length); + file_save("lmhash1.dat", lmhash.data, lmhash.length); +#endif + + nt_status = pass_check_smb(user, user, + workgroup, machine, + lmhash.data, + lmhash.length, + nthash.data, + nthash.length); + + data_blob_free(&nthash); + data_blob_free(&lmhash); + + if (!NT_STATUS_IS_OK(nt_status)) { + return ERROR_NT(nt_status); + } + + /* the password is good - let them in */ + pw = smb_getpwnam(user,False); + if (!pw) { + DEBUG(1,("Username %s is invalid on this system\n",user)); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + gid = pw->pw_gid; + uid = pw->pw_uid; + full_name = pw->pw_gecos; + + sess_vuid = register_vuid(uid,gid,user,user,workgroup,False, full_name); + + free(user); + free(workgroup); + free(machine); + + if (sess_vuid == -1) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + set_message(outbuf,4,0,True); + SSVAL(outbuf, smb_vwv3, 0); + p = smb_buf(outbuf); + p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); + set_message_end(outbuf,p); + + SSVAL(outbuf,smb_uid,sess_vuid); + SSVAL(inbuf,smb_uid,sess_vuid); + + return chain_reply(inbuf,outbuf,length,bufsize); +} + + +/**************************************************************************** +reply to a session setup command +****************************************************************************/ +static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,char *outbuf, + int length,int bufsize) +{ + uint8 *p; + DATA_BLOB blob1; + extern uint32 global_client_caps; + int ret; + + chdir("/home/tridge"); + + if (global_client_caps == 0) { + global_client_caps = IVAL(inbuf,smb_vwv10); + } + + p = smb_buf(inbuf); + + /* pull the spnego blob */ + blob1 = data_blob(p, SVAL(inbuf, smb_vwv7)); + + if (blob1.data[0] == ASN1_APPLICATION(0)) { + /* its a negTokenTarg packet */ + ret = reply_spnego_negotiate(conn, outbuf, blob1); + data_blob_free(&blob1); + return ret; + } + + if (blob1.data[0] == ASN1_CONTEXT(1)) { + /* its a auth packet */ + ret = reply_spnego_auth(conn, inbuf, outbuf, length, bufsize, blob1); + data_blob_free(&blob1); + return ret; + } + + /* what sort of packet is this? */ + DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n")); + + data_blob_free(&blob1); + + return ERROR_NT(NT_STATUS_LOGON_FAILURE); +} + + /**************************************************************************** reply to a session setup command ****************************************************************************/ @@ -53,6 +306,11 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, BOOL doencrypt = global_encrypted_passwords_negotiated; START_PROFILE(SMBsesssetupX); + if (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY) { + /* it's a SPNEGO session setup */ + return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize); + } + *smb_apasswd = *smb_ntpasswd = 0; smb_bufsize = SVAL(inbuf,smb_vwv2); -- cgit From adfa547aab4b83deb6c30cbf0f568fef366bd9a9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Oct 2001 10:46:46 +0000 Subject: removed some debug code (This used to be commit b9e1f05393aaadf1fbe09338417977e2a3cb4559) --- source3/smbd/sesssetup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 34b431e404..a833b7e706 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -152,7 +152,9 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, const struct passwd *pw; if (!spnego_parse_auth(blob1, &auth)) { +#if 0 file_save("auth.dat", blob1.data, blob1.length); +#endif return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -241,8 +243,6 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,cha extern uint32 global_client_caps; int ret; - chdir("/home/tridge"); - if (global_client_caps == 0) { global_client_caps = IVAL(inbuf,smb_vwv10); } -- cgit From 5ad7448359c7bc1d3b1579f105b7324290bf21ec Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Oct 2001 10:26:06 +0000 Subject: the beginnings of kerberos support in smbd. It doesn't work yet, but it should give something for others to hack on and possibly find what I'm doing wrong. (This used to be commit 353c290f059347265b9be2aa1010c2956da06485) --- source3/smbd/sesssetup.c | 100 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 91 insertions(+), 9 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index a833b7e706..7eb8f4e694 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -22,6 +22,71 @@ #include "includes.h" +#if HAVE_KRB5 +/**************************************************************************** +reply to a session setup spnego negotiate packet for kerberos +****************************************************************************/ +static int reply_spnego_kerberos(connection_struct *conn, char *outbuf, + DATA_BLOB *secblob) +{ + DATA_BLOB ticket; + krb5_context context; + krb5_principal server; + krb5_auth_context auth_context = NULL; + krb5_keytab keytab = NULL; + krb5_data packet; + krb5_ticket *tkt = NULL; + int ret; + char *realm, *client; + fstring service; + extern pstring global_myname; + + realm = lp_realm(); + + if (!spnego_parse_krb5_wrap(*secblob, &ticket)) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + /* the service is the wins name lowercase with $ tacked on */ + fstrcpy(service, global_myname); + strlower(service); + fstrcat(service, "$"); + + ret = krb5_init_context(&context); + if (ret) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + ret = krb5_build_principal(context, &server, strlen(realm), + realm, service, NULL); + if (ret) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + packet.length = ticket.length; + packet.data = (krb5_pointer)ticket.data; + + if ((ret = krb5_rd_req(context, &auth_context, &packet, + server, keytab, NULL, &tkt))) { + DEBUG(3,("krb5_rd_req failed with code %08x\n", ret)); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, + &client))) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + DEBUG(3,("Ticket name is [%s]\n", client)); + + /* well, if we got a client above then I think we have authenticated the user + but fail it for now until I understand it */ + + + return ERROR_NT(NT_STATUS_LOGON_FAILURE); +} +#endif + /**************************************************************************** send a security blob via a session setup reply @@ -50,9 +115,6 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, return send_smb(smbd_server_fd(),outbuf); } - - - /**************************************************************************** reply to a session setup spnego negotiate packet ****************************************************************************/ @@ -65,6 +127,7 @@ static int reply_spnego_negotiate(connection_struct *conn, char *outbuf, uint32 ntlmssp_command, neg_flags; DATA_BLOB sess_key, chal, spnego_chal; uint8 cryptkey[8]; + BOOL got_kerberos = False; /* parse out the OIDs and the first sec blob */ if (!parse_negTokenTarg(blob1, OIDs, &secblob)) { @@ -73,20 +136,33 @@ static int reply_spnego_negotiate(connection_struct *conn, char *outbuf, for (i=0;OIDs[i];i++) { DEBUG(3,("Got OID %s\n", OIDs[i])); + if (strcmp(OID_KERBEROS5_OLD, OIDs[i]) == 0) { + got_kerberos = True; + } free(OIDs[i]); } DEBUG(3,("Got secblob of size %d\n", secblob.length)); +#if HAVE_KRB5 + if (got_kerberos) { + int ret = reply_spnego_kerberos(conn, outbuf, &secblob); + data_blob_free(&secblob); + return ret; + } +#endif + /* parse the NTLMSSP packet */ #if 0 file_save("secblob.dat", secblob.data, secblob.length); #endif - msrpc_parse(&secblob, "CddB", - "NTLMSSP", - &ntlmssp_command, - &neg_flags, - &sess_key); + if (!msrpc_parse(&secblob, "CddB", + "NTLMSSP", + &ntlmssp_command, + &neg_flags, + &sess_key)) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } data_blob_free(&secblob); data_blob_free(&sess_key); @@ -97,7 +173,9 @@ static int reply_spnego_negotiate(connection_struct *conn, char *outbuf, DEBUG(3,("Got neg_flags=%08x\n", neg_flags)); - last_challenge(cryptkey); + if (!last_challenge(cryptkey)) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } /* Give them the challenge. For now, ignore neg_flags and just return the flags we want. Obviously this is not correct */ @@ -252,6 +330,10 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,cha /* pull the spnego blob */ blob1 = data_blob(p, SVAL(inbuf, smb_vwv7)); +#if 0 + file_save("negotiate.dat", blob1.data, blob1.length); +#endif + if (blob1.data[0] == ASN1_APPLICATION(0)) { /* its a negTokenTarg packet */ ret = reply_spnego_negotiate(conn, outbuf, blob1); -- cgit From 9884de2d3b00c560daa68930fb31cec23a0c6d44 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 20 Oct 2001 06:31:25 +0000 Subject: finished auth when we get a valid kerberos ticket smbd now works with kerberos authentication if you use a MIT KDC and smbclient. Next step is to make it work with a windows client (This used to be commit e0c99e1f3708b155b8db99950f9ac6e27763368f) --- source3/smbd/sesssetup.c | 66 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 8 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7eb8f4e694..0202a247cd 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -26,7 +26,9 @@ /**************************************************************************** reply to a session setup spnego negotiate packet for kerberos ****************************************************************************/ -static int reply_spnego_kerberos(connection_struct *conn, char *outbuf, +static int reply_spnego_kerberos(connection_struct *conn, + char *inbuf, char *outbuf, + int length, int bufsize, DATA_BLOB *secblob) { DATA_BLOB ticket; @@ -37,9 +39,15 @@ static int reply_spnego_kerberos(connection_struct *conn, char *outbuf, krb5_data packet; krb5_ticket *tkt = NULL; int ret; - char *realm, *client; + char *realm, *client, *p; fstring service; extern pstring global_myname; + const struct passwd *pw; + char *user; + gid_t gid; + uid_t uid; + char *full_name; + int sess_vuid; realm = lp_realm(); @@ -79,11 +87,48 @@ static int reply_spnego_kerberos(connection_struct *conn, char *outbuf, DEBUG(3,("Ticket name is [%s]\n", client)); - /* well, if we got a client above then I think we have authenticated the user - but fail it for now until I understand it */ + p = strchr_m(client, '@'); + if (!p) { + DEBUG(3,("Doesn't look like a valid principle\n")); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + *p = 0; + if (strcasecmp(p+1, realm) != 0) { + DEBUG(3,("Ticket for incorrect realm %s\n", p+1)); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + user = client; + + /* the password is good - let them in */ + pw = smb_getpwnam(user,False); + if (!pw) { + DEBUG(1,("Username %s is invalid on this system\n",user)); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + gid = pw->pw_gid; + uid = pw->pw_uid; + full_name = pw->pw_gecos; + sess_vuid = register_vuid(uid,gid,user,user,realm,False, full_name); + + if (sess_vuid == -1) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + set_message(outbuf,4,0,True); + SSVAL(outbuf, smb_vwv3, 0); + p = smb_buf(outbuf); + p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); + set_message_end(outbuf,p); + + SSVAL(outbuf,smb_uid,sess_vuid); + SSVAL(inbuf,smb_uid,sess_vuid); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return chain_reply(inbuf,outbuf,length,bufsize); } #endif @@ -118,7 +163,10 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, /**************************************************************************** reply to a session setup spnego negotiate packet ****************************************************************************/ -static int reply_spnego_negotiate(connection_struct *conn, char *outbuf, +static int reply_spnego_negotiate(connection_struct *conn, + char *inbuf, + char *outbuf, + int length, int bufsize, DATA_BLOB blob1) { char *OIDs[ASN1_MAX_OIDS]; @@ -145,7 +193,8 @@ static int reply_spnego_negotiate(connection_struct *conn, char *outbuf, #if HAVE_KRB5 if (got_kerberos) { - int ret = reply_spnego_kerberos(conn, outbuf, &secblob); + int ret = reply_spnego_kerberos(conn, inbuf, outbuf, + length, bufsize, &secblob); data_blob_free(&secblob); return ret; } @@ -331,12 +380,13 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,cha blob1 = data_blob(p, SVAL(inbuf, smb_vwv7)); #if 0 + chdir("/home/tridge"); file_save("negotiate.dat", blob1.data, blob1.length); #endif if (blob1.data[0] == ASN1_APPLICATION(0)) { /* its a negTokenTarg packet */ - ret = reply_spnego_negotiate(conn, outbuf, blob1); + ret = reply_spnego_negotiate(conn, inbuf, outbuf, length, bufsize, blob1); data_blob_free(&blob1); return ret; } -- cgit From 93645be91f7fd12dfee75b6f09dda6799f0ac902 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 20 Oct 2001 06:50:24 +0000 Subject: better krb5 error handling (thanks andrewb!) (This used to be commit fd3a3daef3b8f7140e7006d30d23d739ac3aad2f) --- source3/smbd/sesssetup.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 0202a247cd..c8bf2a4f94 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -62,12 +62,14 @@ static int reply_spnego_kerberos(connection_struct *conn, ret = krb5_init_context(&context); if (ret) { + DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } ret = krb5_build_principal(context, &server, strlen(realm), realm, service, NULL); if (ret) { + DEBUG(1,("krb5_build_principal failed (%s)\n", error_message(ret))); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -76,12 +78,15 @@ static int reply_spnego_kerberos(connection_struct *conn, if ((ret = krb5_rd_req(context, &auth_context, &packet, server, keytab, NULL, &tkt))) { - DEBUG(3,("krb5_rd_req failed with code %08x\n", ret)); + DEBUG(3,("krb5_rd_req failed (%s)\n", + error_message(ret))); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, &client))) { + DEBUG(3,("krb5_unparse_name failed (%s)\n", + error_message(ret))); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } -- cgit From 60747ab66e768ac6801838c460a1a4fc8bba32cf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 20 Oct 2001 11:47:44 +0000 Subject: crude fix for anonymous session setup with extended security negotiated (This used to be commit b3caf2109090cb2b97a829913bee7e50e7eacba8) --- source3/smbd/sesssetup.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index c8bf2a4f94..1ca7066c41 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -66,8 +66,15 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } +#if 0 + ret = krb5_build_principal(context, &server, strlen(realm), + realm, "HOST", "blu", NULL); +#else ret = krb5_build_principal(context, &server, strlen(realm), realm, service, NULL); +#endif + krb5_princ_type(context, server) = KRB5_NT_PRINCIPAL; + if (ret) { DEBUG(1,("krb5_build_principal failed (%s)\n", error_message(ret))); return ERROR_NT(NT_STATUS_LOGON_FAILURE); @@ -364,6 +371,55 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, } +/**************************************************************************** +reply to a session setup spnego anonymous packet +****************************************************************************/ +static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *outbuf, + int length, int bufsize) +{ + char *user; + int sess_vuid; + gid_t gid; + uid_t uid; + char *full_name; + char *p; + const struct passwd *pw; + + DEBUG(3,("Got anonymous request\n")); + + user = lp_guestaccount(-1); + + /* the password is good - let them in */ + pw = smb_getpwnam(user,False); + if (!pw) { + DEBUG(1,("Guest username %s is invalid on this system\n",user)); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + gid = pw->pw_gid; + uid = pw->pw_uid; + full_name = pw->pw_gecos; + + sess_vuid = register_vuid(uid,gid,user,user,lp_workgroup(),True,full_name); + + if (sess_vuid == -1) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + set_message(outbuf,4,0,True); + SSVAL(outbuf, smb_vwv3, 0); + p = smb_buf(outbuf); + p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); + set_message_end(outbuf,p); + + SSVAL(outbuf,smb_uid,sess_vuid); + SSVAL(inbuf,smb_uid,sess_vuid); + + return chain_reply(inbuf,outbuf,length,bufsize); +} + + /**************************************************************************** reply to a session setup command ****************************************************************************/ @@ -381,9 +437,14 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,cha p = smb_buf(inbuf); + if (SVAL(inbuf, smb_vwv7) == 0) { + /* an anonymous request */ + return reply_spnego_anonymous(conn, inbuf, outbuf, length, bufsize); + } + /* pull the spnego blob */ blob1 = data_blob(p, SVAL(inbuf, smb_vwv7)); - + #if 0 chdir("/home/tridge"); file_save("negotiate.dat", blob1.data, blob1.length); -- cgit From b7331220c65747c6d7de2b05372839c20f712439 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 21 Oct 2001 00:10:16 +0000 Subject: fixed the spnego detection code in session setup this gets share mode working again (This used to be commit 8286e5307ca47f14d27ee0d9bc9700d52151d56a) --- source3/smbd/sesssetup.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 1ca7066c41..3cac6f338b 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -80,6 +80,11 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } +#if 0 + chdir("/home/tridge"); + file_save("ticket.dat", ticket.data, ticket.length); +#endif + packet.length = ticket.length; packet.data = (krb5_pointer)ticket.data; @@ -196,7 +201,8 @@ static int reply_spnego_negotiate(connection_struct *conn, for (i=0;OIDs[i];i++) { DEBUG(3,("Got OID %s\n", OIDs[i])); - if (strcmp(OID_KERBEROS5_OLD, OIDs[i]) == 0) { + if (strcmp(OID_KERBEROS5, OIDs[i]) == 0 || + strcmp(OID_KERBEROS5_OLD, OIDs[i]) == 0) { got_kerberos = True; } free(OIDs[i]); @@ -504,7 +510,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, BOOL doencrypt = global_encrypted_passwords_negotiated; START_PROFILE(SMBsesssetupX); - if (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY) { + if (SVAL(inbuf, smb_wct) == 12) { /* it's a SPNEGO session setup */ return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize); } -- cgit From a0a42f2c1f7f9644d27c479951db443516a09c18 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 21 Oct 2001 03:27:13 +0000 Subject: change smbd to use HOST/hostname principle form until I work out how to use the other form in netjoin smb_wct is a char, not a word (This used to be commit 3dbb48b188980cf6c869dc762e3039dd375bf392) --- source3/smbd/sesssetup.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 3cac6f338b..7f9a09c79b 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -40,7 +40,8 @@ static int reply_spnego_kerberos(connection_struct *conn, krb5_ticket *tkt = NULL; int ret; char *realm, *client, *p; - fstring service; + fstring hostname; + char *principle; extern pstring global_myname; const struct passwd *pw; char *user; @@ -55,35 +56,24 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - /* the service is the wins name lowercase with $ tacked on */ - fstrcpy(service, global_myname); - strlower(service); - fstrcat(service, "$"); - + fstrcpy(hostname, global_myname); + strlower(hostname); + asprintf(&principle, "HOST/%s@%s", hostname, realm); + ret = krb5_init_context(&context); if (ret) { DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } -#if 0 - ret = krb5_build_principal(context, &server, strlen(realm), - realm, "HOST", "blu", NULL); -#else - ret = krb5_build_principal(context, &server, strlen(realm), - realm, service, NULL); -#endif - krb5_princ_type(context, server) = KRB5_NT_PRINCIPAL; - + ret = krb5_parse_name(context, principle, &server); if (ret) { - DEBUG(1,("krb5_build_principal failed (%s)\n", error_message(ret))); + DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", + principle, error_message(ret))); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } -#if 0 - chdir("/home/tridge"); - file_save("ticket.dat", ticket.data, ticket.length); -#endif + free(principle); packet.length = ticket.length; packet.data = (krb5_pointer)ticket.data; @@ -437,6 +427,8 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,cha extern uint32 global_client_caps; int ret; + DEBUG(3,("Doing spego session setup\n")); + if (global_client_caps == 0) { global_client_caps = IVAL(inbuf,smb_vwv10); } @@ -509,9 +501,13 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, extern int max_send; BOOL doencrypt = global_encrypted_passwords_negotiated; START_PROFILE(SMBsesssetupX); + + DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf, smb_wct), SVAL(inbuf, smb_flg2))); - if (SVAL(inbuf, smb_wct) == 12) { - /* it's a SPNEGO session setup */ + /* a SPNEGO session setup has 12 command words, whereas a normal + NT1 session setup has 13. See the cifs spec. */ + if (CVAL(inbuf, smb_wct) == 12 && + (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) { return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize); } -- cgit From cfd68eaac48a29dec245dc6de03aae0d58698862 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 21 Oct 2001 20:51:27 +0000 Subject: Ok, I know it's a language thing and it shouldn't matter.... but a kerberos name is a "principal", not a principle. English majors will complain :-). Jeremy. (This used to be commit b668d7d656cdd066820fb8044f24bcd4fda29524) --- source3/smbd/sesssetup.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7f9a09c79b..003cb0dc3d 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -41,7 +41,7 @@ static int reply_spnego_kerberos(connection_struct *conn, int ret; char *realm, *client, *p; fstring hostname; - char *principle; + char *principal; extern pstring global_myname; const struct passwd *pw; char *user; @@ -58,7 +58,7 @@ static int reply_spnego_kerberos(connection_struct *conn, fstrcpy(hostname, global_myname); strlower(hostname); - asprintf(&principle, "HOST/%s@%s", hostname, realm); + asprintf(&principal, "HOST/%s@%s", hostname, realm); ret = krb5_init_context(&context); if (ret) { @@ -66,14 +66,14 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - ret = krb5_parse_name(context, principle, &server); + ret = krb5_parse_name(context, principal, &server); if (ret) { DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", - principle, error_message(ret))); + principal, error_message(ret))); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - free(principle); + free(principal); packet.length = ticket.length; packet.data = (krb5_pointer)ticket.data; @@ -96,7 +96,7 @@ static int reply_spnego_kerberos(connection_struct *conn, p = strchr_m(client, '@'); if (!p) { - DEBUG(3,("Doesn't look like a valid principle\n")); + DEBUG(3,("Doesn't look like a valid principal\n")); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } -- cgit From fba157123ed1d6f59d40aa9161218fbfcf71253f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 22 Oct 2001 05:04:33 +0000 Subject: - fixed link order of krb5 libs - accept a wide range of principal names in session setup (This used to be commit 672df66296f540b606aa43effab5f021b8978e4b) --- source3/smbd/sesssetup.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 003cb0dc3d..fc6c694d9f 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -33,16 +33,12 @@ static int reply_spnego_kerberos(connection_struct *conn, { DATA_BLOB ticket; krb5_context context; - krb5_principal server; krb5_auth_context auth_context = NULL; krb5_keytab keytab = NULL; krb5_data packet; krb5_ticket *tkt = NULL; int ret; char *realm, *client, *p; - fstring hostname; - char *principal; - extern pstring global_myname; const struct passwd *pw; char *user; gid_t gid; @@ -56,30 +52,21 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - fstrcpy(hostname, global_myname); - strlower(hostname); - asprintf(&principal, "HOST/%s@%s", hostname, realm); - ret = krb5_init_context(&context); if (ret) { DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - ret = krb5_parse_name(context, principal, &server); - if (ret) { - DEBUG(1,("krb5_parse_name(%s) failed (%s)\n", - principal, error_message(ret))); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - - free(principal); - packet.length = ticket.length; packet.data = (krb5_pointer)ticket.data; +#if 0 + file_save("/tmp/ticket.dat", ticket.data, ticket.length); +#endif + if ((ret = krb5_rd_req(context, &auth_context, &packet, - server, keytab, NULL, &tkt))) { + NULL, keytab, NULL, &tkt))) { DEBUG(3,("krb5_rd_req failed (%s)\n", error_message(ret))); return ERROR_NT(NT_STATUS_LOGON_FAILURE); @@ -444,7 +431,6 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,cha blob1 = data_blob(p, SVAL(inbuf, smb_vwv7)); #if 0 - chdir("/home/tridge"); file_save("negotiate.dat", blob1.data, blob1.length); #endif -- cgit From 3ea349271355b39f7b877ce67530cc58e7db0ee8 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 23 Oct 2001 19:10:30 +0000 Subject: get rid of compiler warnings (casts and delete unused variables) (This used to be commit 51cb4411df61d1caec9d84809b1a53a6a632f808) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index fc6c694d9f..5412cc3bad 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -420,7 +420,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,cha global_client_caps = IVAL(inbuf,smb_vwv10); } - p = smb_buf(inbuf); + p = (uint8 *)smb_buf(inbuf); if (SVAL(inbuf, smb_vwv7) == 0) { /* an anonymous request */ -- cgit From 1f829e19eb3b81ad1c4451fe9a90617e6cee7dd7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 30 Oct 2001 13:54:54 +0000 Subject: Spnego on the 'server' end of security=server just does not work, so set the flags so we just do a 'normal' session setup. Also add some parinoia code to detect when sombody attempts to do a 'normal' session setup when spnego had been negoitiated. Andrew Bartlett (This used to be commit 190898586fa218c952fbd5bea56155d04e6f248b) --- source3/smbd/sesssetup.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 5412cc3bad..2d9f624b80 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -480,6 +480,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, BOOL guest=False; static BOOL done_sesssetup = False; extern BOOL global_encrypted_passwords_negotiated; + extern BOOL global_spnego_negotiated; extern uint32 global_client_caps; extern int Protocol; extern fstring remote_machine; @@ -492,11 +493,16 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* a SPNEGO session setup has 12 command words, whereas a normal NT1 session setup has 13. See the cifs spec. */ - if (CVAL(inbuf, smb_wct) == 12 && + if (CVAL(inbuf, smb_wct) == 12 && (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) { return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize); } + 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); + } + *smb_apasswd = *smb_ntpasswd = 0; smb_bufsize = SVAL(inbuf,smb_vwv2); -- cgit From 60f0627afb167faad57385d44f0b587186a7ac2b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 31 Oct 2001 10:46:25 +0000 Subject: This is a farily large patch (3300 lines) and reworks most of the AuthRewrite code. In particular this assists tpot in some of his work, becouse it provides the connection between the authenticaion and the vuid generation. Major Changes: - Fully malloc'ed structures. - Massive rework of the code so that all structures are made and destroyed using malloc and free, rather than hanging around on the stack. - SAM_ACCOUNT unix uids and gids are now pointers to the same, to allow them to be declared 'invalid' without the chance that people might get ROOT by default. - kill off some of the "DOMAIN\user" lookups. These can be readded at a more appropriate place (probably domain_client_validate.c) in the future. They don't belong in session setups. - Massive introduction of DATA_BLOB structures, particularly for passwords. - Use NTLMSSP flags to tell the backend what its getting, rather than magic lenghths. - Fix winbind back up again, but tpot is redoing this soon anyway. - Abstract much of the work in srv_netlog_nt back into auth helper functions. This is a LARGE change, and any assistance is testing it is appriciated. Domain logons are still broken (as far as I can tell) but other functionality seems intact. Needs testing with a wide variety of MS clients. Andrew Bartlett (This used to be commit f70fb819b2f57bd57232b51808345e2319d52f6c) --- source3/smbd/sesssetup.c | 356 +++++++++++++++++++++-------------------------- 1 file changed, 159 insertions(+), 197 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 2d9f624b80..5331127cb5 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -264,14 +264,16 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, DATA_BLOB auth; char *workgroup, *user, *machine; DATA_BLOB lmhash, nthash, sess_key; + DATA_BLOB plaintext_password = data_blob(NULL, 0); + DATA_BLOB sec_blob; uint32 ntlmssp_command, neg_flags; NTSTATUS nt_status; int sess_vuid; - gid_t gid; - uid_t uid; - char *full_name; char *p; - const struct passwd *pw; + char chal[8]; + + auth_usersupplied_info *user_info = NULL; + auth_serversupplied_info *server_info = NULL; if (!spnego_parse_auth(blob1, &auth)) { #if 0 @@ -305,36 +307,40 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, file_save("lmhash1.dat", lmhash.data, lmhash.length); #endif - nt_status = pass_check_smb(user, user, - workgroup, machine, - lmhash.data, - lmhash.length, - nthash.data, - nthash.length); - - data_blob_free(&nthash); + if (!last_challenge(chal)) { + DEBUG(0,("Encrypted login but no challange set!\n")); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + sec_blob = data_blob(chal, 8); + if (!sec_blob.data) { + return ERROR_NT(NT_STATUS_NO_MEMORY); + } + + if (!make_user_info_map(&user_info, + user, workgroup, + machine, sec_blob, + lmhash, nthash, + plaintext_password, + neg_flags, True)) { + return ERROR_NT(NT_STATUS_NO_MEMORY); + } + + nt_status = check_password(user_info, &server_info); + + free_user_info(&user_info); + data_blob_free(&lmhash); - + + data_blob_free(&nthash); + if (!NT_STATUS_IS_OK(nt_status)) { - return ERROR_NT(nt_status); + return ERROR_NT(nt_status_squash(nt_status)); } - /* the password is good - let them in */ - pw = smb_getpwnam(user,False); - if (!pw) { - DEBUG(1,("Username %s is invalid on this system\n",user)); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - gid = pw->pw_gid; - uid = pw->pw_uid; - full_name = pw->pw_gecos; - - sess_vuid = register_vuid(uid,gid,user,user,workgroup,False, full_name); + sess_vuid = register_vuid(server_info, user, False); - free(user); - free(workgroup); - free(machine); - + free_server_info(&server_info); + if (sess_vuid == -1) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -360,30 +366,16 @@ reply to a session setup spnego anonymous packet static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize) { - char *user; int sess_vuid; - gid_t gid; - uid_t uid; - char *full_name; char *p; - const struct passwd *pw; + auth_serversupplied_info *server_info = NULL; DEBUG(3,("Got anonymous request\n")); - user = lp_guestaccount(-1); - - /* the password is good - let them in */ - pw = smb_getpwnam(user,False); - if (!pw) { - DEBUG(1,("Guest username %s is invalid on this system\n",user)); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - gid = pw->pw_gid; - uid = pw->pw_uid; - full_name = pw->pw_gecos; - - sess_vuid = register_vuid(uid,gid,user,user,lp_workgroup(),True,full_name); - + make_server_info_guest(&server_info); + sess_vuid = register_vuid(server_info, lp_guestaccount(-1), False); + free_server_info(&server_info); + if (sess_vuid == -1) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -414,7 +406,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,cha extern uint32 global_client_caps; int ret; - DEBUG(3,("Doing spego session setup\n")); + DEBUG(3,("Doing spnego session setup\n")); if (global_client_caps == 0) { global_client_caps = IVAL(inbuf,smb_vwv10); @@ -464,16 +456,11 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, int length,int bufsize) { int sess_vuid; - gid_t gid; - uid_t uid; - char* full_name; int smb_bufsize; - int smb_apasslen = 0; - pstring smb_apasswd; - int smb_ntpasslen = 0; - pstring smb_ntpasswd; + DATA_BLOB lm_resp; + DATA_BLOB nt_resp; + DATA_BLOB plaintext_password; pstring user; - pstring orig_user; fstring domain; fstring native_os; fstring native_lanman; @@ -486,9 +473,18 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, extern fstring remote_machine; extern userdom_struct current_user_info; extern int max_send; + + auth_usersupplied_info *user_info = NULL; + auth_serversupplied_info *server_info = NULL; + BOOL doencrypt = global_encrypted_passwords_negotiated; + START_PROFILE(SMBsesssetupX); + ZERO_STRUCT(lm_resp); + ZERO_STRUCT(nt_resp); + ZERO_STRUCT(plaintext_password); + DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf, smb_wct), SVAL(inbuf, smb_flg2))); /* a SPNEGO session setup has 12 command words, whereas a normal @@ -503,28 +499,35 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_NT(NT_STATUS_UNSUCCESSFUL); } - *smb_apasswd = *smb_ntpasswd = 0; - smb_bufsize = SVAL(inbuf,smb_vwv2); - + if (Protocol < PROTOCOL_NT1) { - smb_apasslen = SVAL(inbuf,smb_vwv7); - if (smb_apasslen > MAX_PASS_LEN) { + uint16 passlen1 = SVAL(inbuf,smb_vwv7); + if (passlen1 > MAX_PASS_LEN) { return ERROR_DOS(ERRDOS,ERRbuftoosmall); } - memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen); - srvstr_pull(inbuf, user, smb_buf(inbuf)+smb_apasslen, sizeof(user), -1, STR_TERMINATE); - - if (!doencrypt && (lp_security() != SEC_SERVER)) { - smb_apasslen = strlen(smb_apasswd); + if (doencrypt) { + lm_resp = data_blob(smb_buf(inbuf), passlen1); + } else { + plaintext_password = data_blob(smb_buf(inbuf), passlen1+1); + if (!plaintext_password.data) { + DEBUG(0,("reply_sesssetup_and_X: malloc failed for plaintext_password!\n")); + return ERROR_NT(NT_STATUS_NO_MEMORY); + } else { + /* Ensure null termination */ + plaintext_password.data[passlen1] = 0; + } } + + srvstr_pull(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), -1, STR_TERMINATE); + } else { uint16 passlen1 = SVAL(inbuf,smb_vwv7); uint16 passlen2 = SVAL(inbuf,smb_vwv8); enum remote_arch_types ra_type = get_remote_arch(); char *p = smb_buf(inbuf); - + if(global_client_caps == 0) global_client_caps = IVAL(inbuf,smb_vwv11); @@ -539,16 +542,13 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } } - if (passlen1 != 24 && passlen2 < 24) - doencrypt = False; - if (passlen1 > MAX_PASS_LEN) { return ERROR_DOS(ERRDOS,ERRbuftoosmall); } - + passlen1 = MIN(passlen1, MAX_PASS_LEN); passlen2 = MIN(passlen2, MAX_PASS_LEN); - + if (!doencrypt) { /* both Win95 and WinNT stuff up the password lengths for non-encrypting systems. Uggh. @@ -591,23 +591,20 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, passlen1 = 1; } } - + /* Save the lanman2 password and the NT md4 password. */ - smb_apasslen = passlen1; - memcpy(smb_apasswd,p,smb_apasslen); - - smb_ntpasslen = passlen2; - memcpy(smb_ntpasswd,p+passlen1,smb_ntpasslen); - - if (smb_apasslen != 24 || !doencrypt) { - /* trim the password */ - smb_apasslen = strlen(smb_apasswd); - - /* wfwg sometimes uses a space instead of a null */ - if (strequal(smb_apasswd," ")) { - smb_apasslen = 0; - *smb_apasswd = 0; - } + + if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) { + doencrypt = False; + } + + if (doencrypt) { + lm_resp = data_blob(p, passlen1); + nt_resp = data_blob(p+passlen1, passlen2); + } else { + plaintext_password = data_blob(p, passlen1+1); + /* Ensure null termination */ + plaintext_password.data[passlen1] = 0; } p += passlen1 + passlen2; @@ -630,15 +627,29 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - if (lp_security() == SEC_SHARE) { - /* in share level we should ignore any passwords */ - smb_ntpasslen = 0; - smb_apasslen = 0; + DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, remote_machine)); + + /* If no username is sent use the guest account */ + if (!*user) { + pstrcpy(user,lp_guestaccount(-1)); guest = True; } + pstrcpy(current_user_info.smb_name,user); + + reload_services(True); + + if (lp_security() == SEC_SHARE) { + /* in share level we should ignore any passwords */ + + data_blob_free(&lm_resp); + data_blob_free(&nt_resp); + data_blob_free(&plaintext_password); - DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n",user, domain, remote_machine)); + guest = True; + map_username(user); + add_session_user(user); + } if (done_sesssetup && lp_restrict_anonymous()) { /* tests show that even if browsing is done over @@ -649,106 +660,61 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, * only deny connections that have no session * information. If a domain has been provided, then * it's not a purely anonymous connection. AAB */ - if (!*user && !*smb_apasswd && !*domain) { + if (!*user && !*domain) { DEBUG(0, ("restrict anonymous is True and anonymous connection attempted. Denying access.\n")); + + data_blob_free(&lm_resp); + data_blob_free(&nt_resp); + data_blob_free(&plaintext_password); + END_PROFILE(SMBsesssetupX); return ERROR_DOS(ERRDOS,ERRnoaccess); } } - - /* If no username is sent use the guest account */ - if (!*user) { - pstrcpy(user,lp_guestaccount(-1)); - guest = True; - } - - pstrcpy(current_user_info.smb_name,user); - - reload_services(True); - - /* - * Save the username before mapping. We will use - * the original username sent to us for security=server - * and security=domain checking. - */ - - pstrcpy( orig_user, user); - - /* - * Always try the "DOMAIN\user" lookup first, as this is the most - * specific case. If this fails then try the simple "user" lookup. - * But don't do this for guests, as this is always a local user. - */ if (!guest) { - pstring dom_user; - - /* Work out who's who */ - - slprintf(dom_user, sizeof(dom_user) - 1,"%s%s%s", - domain, lp_winbind_separator(), user); - - if (sys_getpwnam(dom_user) != NULL) { - pstrcpy(user, dom_user); - DEBUG(3,("Using unix username %s\n", dom_user)); + NTSTATUS nt_status; + if (!make_user_info_for_reply(&user_info, + user, domain, + lm_resp, nt_resp, + plaintext_password, doencrypt)) { + return ERROR_NT(NT_STATUS_NO_MEMORY); } - /* - * Pass the user through the NT -> unix user mapping - * function. - */ + nt_status = check_password(user_info, &server_info); - (void)map_username(user); + free_user_info(&user_info); - /* - * Do any UNIX username case mangling. - */ - smb_getpwnam(user, True); - } - - add_session_user(user); - - if (!guest) { - NTSTATUS nt_status; - nt_status = pass_check_smb(orig_user, user, - domain, remote_machine, - (unsigned char *)smb_apasswd, - smb_apasslen, - (unsigned char *)smb_ntpasswd, - smb_ntpasslen); - - if NT_STATUS_IS_OK(nt_status) { - - } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) { - if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || - (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) { - DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain)); - pstrcpy(user,lp_guestaccount(-1)); - guest = True; - } else { - /* Match WinXP and don't give the game away */ - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) { - if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) { - pstrcpy(user,lp_guestaccount(-1)); - DEBUG(3,("Registered username %s for guest access\n",user)); - guest = True; - } else { + data_blob_free(&lm_resp); + data_blob_free(&nt_resp); + data_blob_free(&plaintext_password); + + if (!NT_STATUS_IS_OK(nt_status)) { + if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) { + if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || + (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) { + DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain)); + pstrcpy(user,lp_guestaccount(-1)); + guest = True; + + } + } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) { + if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) { + pstrcpy(user,lp_guestaccount(-1)); + DEBUG(3,("Registered username %s for guest access\n",user)); + guest = True; + } /* Match WinXP and don't give the game away */ return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - } else { - return ERROR_NT(nt_status); + + if (!guest) { + free_server_info(&server_info); + return ERROR_NT(nt_status_squash(nt_status)); + } } } - if (!strequal(user,lp_guestaccount(-1)) && - lp_servicenumber(user) < 0) { - add_home_service(user,get_user_home_dir(user)); - } - - /* it's ok - setup a reply */ if (Protocol < PROTOCOL_NT1) { set_message(outbuf,3,0,True); @@ -763,30 +729,26 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* perhaps grab OS version here?? */ } - /* Set the correct uid in the outgoing and incoming packets - We will use this on future requests to determine which - user we should become. - */ - { - const struct passwd *pw = smb_getpwnam(user,False); - if (!pw) { - DEBUG(1,("Username %s is invalid on this system\n",user)); - END_PROFILE(SMBsesssetupX); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + if (guest) { + SSVAL(outbuf,smb_vwv2,1); + free_server_info(&server_info); + make_server_info_guest(&server_info); + } else { + const char *home_dir = pdb_get_homedir(server_info->sam_account); + const char *username = pdb_get_username(server_info->sam_account); + if ((home_dir && *home_dir) + && (lp_servicenumber(username) < 0)) { + add_home_service(username, home_dir); } - gid = pw->pw_gid; - uid = pw->pw_uid; - full_name = pw->pw_gecos; } - - if (guest) - SSVAL(outbuf,smb_vwv2,1); - + /* register the name and uid as being validated, so further connections to a uid can get through without a password, on the same VC */ - - sess_vuid = register_vuid(uid,gid,user,orig_user,domain,guest, full_name); - + + sess_vuid = register_vuid(server_info, user, guest); + + free_server_info(&server_info); + if (sess_vuid == -1) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } -- cgit From f32cf6dfbadf15ed073a228e5f17f3186852d068 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 31 Oct 2001 12:37:56 +0000 Subject: This should fix up the compile with krb5. This needs to use the auth interface at some stage, but for now this will do. (This used to be commit 8dc4f2e44b150cdcdecd2f6028bf06907ff90cad) --- source3/smbd/sesssetup.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 5331127cb5..7361db0205 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -41,10 +41,8 @@ static int reply_spnego_kerberos(connection_struct *conn, char *realm, *client, *p; const struct passwd *pw; char *user; - gid_t gid; - uid_t uid; - char *full_name; int sess_vuid; + auth_serversupplied_info *server_info = NULL; realm = lp_realm(); @@ -101,11 +99,15 @@ static int reply_spnego_kerberos(connection_struct *conn, DEBUG(1,("Username %s is invalid on this system\n",user)); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - gid = pw->pw_gid; - uid = pw->pw_uid; - full_name = pw->pw_gecos; + + if (!make_server_info_pw(&server_info,pw)) { + DEBUG(1,("make_server_info_from_pw failed!\n")); + return ERROR_NT(NT_STATUS_NO_MEMORY); + } - sess_vuid = register_vuid(uid,gid,user,user,realm,False, full_name); + sess_vuid = register_vuid(server_info, user, False); + + free_server_info(&server_info); if (sess_vuid == -1) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); -- cgit From acb81fe408f0e674088f0952aaba442ddb494b0c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 1 Nov 2001 05:02:41 +0000 Subject: Various post AuthRewrite cleanups, fixups and tidyups. Zero out some of the plaintext passwords for paranoia Fix up some of the other passdb backends with the change to *uid_t rather than uid_t. Make some of the code in srv_netlog_nt.c clearer, is passing an array around, so pass its lenght in is definition, not as a seperate paramater. Use sizeof() rather than magic numbers, it makes things easier to read. Cope with a PAM authenticated user who is not in /etc/passwd - currently by saying NO_SUCH_USER, but this can change in future. Andrew Bartlett (This used to be commit 514c91b16baca639bb04638042bf9894d881172a) --- source3/smbd/sesssetup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7361db0205..85ffadea08 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -646,7 +646,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, data_blob_free(&lm_resp); data_blob_free(&nt_resp); - data_blob_free(&plaintext_password); + data_blob_clear_free(&plaintext_password); guest = True; map_username(user); @@ -667,7 +667,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, data_blob_free(&lm_resp); data_blob_free(&nt_resp); - data_blob_free(&plaintext_password); + data_blob_clear_free(&plaintext_password); END_PROFILE(SMBsesssetupX); return ERROR_DOS(ERRDOS,ERRnoaccess); @@ -689,7 +689,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, data_blob_free(&lm_resp); data_blob_free(&nt_resp); - data_blob_free(&plaintext_password); + data_blob_clear_free(&plaintext_password); if (!NT_STATUS_IS_OK(nt_status)) { if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) { -- cgit From fdc03603c1535fc03bcc53ee3f45c85692a00c82 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 3 Nov 2001 00:19:56 +0000 Subject: Move the test for non-SPNEGO session setups when using SPNEGO, becouse its a perfectly vailid behaviour for guest logins. (This used to be commit 4db8d70ad74cdbd74c0578e66377fd0233195aaa) --- source3/smbd/sesssetup.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 85ffadea08..ce0e0d585e 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -496,11 +496,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize); } - 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); - } - smb_bufsize = SVAL(inbuf,smb_vwv2); if (Protocol < PROTOCOL_NT1) { @@ -635,6 +630,11 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if (!*user) { pstrcpy(user,lp_guestaccount(-1)); guest = True; + } else { + 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); + } } pstrcpy(current_user_info.smb_name,user); -- cgit From 0e14d9bee072e73114bf0d4ccbfb4c28cf81ef76 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 3 Nov 2001 00:59:57 +0000 Subject: anonymous logins are guest logins, so mark them as such. (Otherwise they can browse non-guest shares). (This used to be commit 7131fe3be4eb2c652f3afe2f3cd99d3f82e09654) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index ce0e0d585e..c7522b3402 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -375,7 +375,7 @@ static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *ou DEBUG(3,("Got anonymous request\n")); make_server_info_guest(&server_info); - sess_vuid = register_vuid(server_info, lp_guestaccount(-1), False); + sess_vuid = register_vuid(server_info, lp_guestaccount(-1), True); free_server_info(&server_info); if (sess_vuid == -1) { -- cgit From 55dfb66079333acd8e0aee91c0ee90d0a413a8e6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 8 Nov 2001 22:19:01 +0000 Subject: Change to guest logon code. This changes the way we process guest logons - we now treat them as normal logons, but set the 'guest' flag. In particular this is needed becouse Win2k will do an NTLMSSP login with username "", therefore missing our previous guest connection code - this is getting a pain to do as a special case all over the shop. Tridge: We don't seem to be setting a guest bit for NTLMSSP, in either the anonymous or authenticated case, can you take a look at this? Also some cleanups in the check_password() code that should make some of the debugs clearer. Various other minor cleanups: - change the session code to just take a vuser, rather than having to do a vuid lookup on vuser.vuid - Change some of the global_client_caps linking - Better debug in authorise_login(): show the vuid. Andrew Bartlett (This used to be commit 62f4e4bd0aef9ade653b3f8d575d2864c166ab4d) --- source3/smbd/sesssetup.c | 120 ++++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 58 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index c7522b3402..6e6d37c089 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -22,6 +22,8 @@ #include "includes.h" +uint32 global_client_caps = 0; + #if HAVE_KRB5 /**************************************************************************** reply to a session setup spnego negotiate packet for kerberos @@ -339,7 +341,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, return ERROR_NT(nt_status_squash(nt_status)); } - sess_vuid = register_vuid(server_info, user, False); + sess_vuid = register_vuid(server_info, user); free_server_info(&server_info); @@ -370,12 +372,18 @@ static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *ou { int sess_vuid; char *p; + auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; + NTSTATUS nt_status; + DEBUG(3,("Got anonymous request\n")); - make_server_info_guest(&server_info); - sess_vuid = register_vuid(server_info, lp_guestaccount(-1), True); + make_user_info_guest(&user_info); + + nt_status = check_password(user_info, &server_info); + + sess_vuid = register_vuid(server_info, lp_guestaccount(-1)); free_server_info(&server_info); if (sess_vuid == -1) { @@ -405,7 +413,6 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,cha { uint8 *p; DATA_BLOB blob1; - extern uint32 global_client_caps; int ret; DEBUG(3,("Doing spnego session setup\n")); @@ -463,14 +470,13 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, DATA_BLOB nt_resp; DATA_BLOB plaintext_password; pstring user; + pstring sub_user; /* Sainitised username for substituion */ fstring domain; fstring native_os; fstring native_lanman; - BOOL guest=False; static BOOL done_sesssetup = False; extern BOOL global_encrypted_passwords_negotiated; extern BOOL global_spnego_negotiated; - extern uint32 global_client_caps; extern int Protocol; extern fstring remote_machine; extern userdom_struct current_user_info; @@ -479,6 +485,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; + NTSTATUS nt_status; + BOOL doencrypt = global_encrypted_passwords_negotiated; START_PROFILE(SMBsesssetupX); @@ -626,18 +634,20 @@ 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 no username is sent use the guest account */ - if (!*user) { - pstrcpy(user,lp_guestaccount(-1)); - guest = True; - } else { + 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); } } - pstrcpy(current_user_info.smb_name,user); + if (*user) { + pstrcpy(sub_user, user); + } else { + pstrcpy(sub_user, lp_guestaccount(-1)); + } + + pstrcpy(current_user_info.smb_name,sub_user); reload_services(True); @@ -648,9 +658,10 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, data_blob_free(&nt_resp); data_blob_clear_free(&plaintext_password); - guest = True; - map_username(user); - add_session_user(user); + map_username(sub_user); + add_session_user(sub_user); + /* Then force it to null for the benfit of the code below */ + *user = 0; } if (done_sesssetup && lp_restrict_anonymous()) { @@ -673,50 +684,45 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_DOS(ERRDOS,ERRnoaccess); } } + + if (!make_user_info_for_reply(&user_info, + user, domain, + lm_resp, nt_resp, + plaintext_password, doencrypt)) { + return ERROR_NT(NT_STATUS_NO_MEMORY); + } - if (!guest) { - NTSTATUS nt_status; - if (!make_user_info_for_reply(&user_info, - user, domain, - lm_resp, nt_resp, - plaintext_password, doencrypt)) { - return ERROR_NT(NT_STATUS_NO_MEMORY); - } - - nt_status = check_password(user_info, &server_info); - - 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)) { - if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) { - if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || - (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) { - DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain)); - pstrcpy(user,lp_guestaccount(-1)); - guest = True; - - } - } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) { - if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) { - pstrcpy(user,lp_guestaccount(-1)); - DEBUG(3,("Registered username %s for guest access\n",user)); - guest = True; - } - /* Match WinXP and don't give the game away */ - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + nt_status = check_password(user_info, &server_info); + + 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)) { + if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) { + if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || + (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) { + + DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain)); + make_server_info_guest(&server_info); + nt_status = NT_STATUS_OK; + } + + } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) { + if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) { + DEBUG(3,("Registered username %s for guest access\n",user)); + make_server_info_guest(&server_info); + nt_status = NT_STATUS_OK; } - - if (!guest) { - free_server_info(&server_info); - return ERROR_NT(nt_status_squash(nt_status)); - } } } + if (!NT_STATUS_IS_OK(nt_status)) { + return ERROR_NT(nt_status_squash(nt_status)); + } + /* it's ok - setup a reply */ if (Protocol < PROTOCOL_NT1) { set_message(outbuf,3,0,True); @@ -731,10 +737,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* perhaps grab OS version here?? */ } - if (guest) { + if (server_info->guest) { SSVAL(outbuf,smb_vwv2,1); - free_server_info(&server_info); - make_server_info_guest(&server_info); } else { const char *home_dir = pdb_get_homedir(server_info->sam_account); const char *username = pdb_get_username(server_info->sam_account); @@ -747,7 +751,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* register the name and uid as being validated, so further connections to a uid can get through without a password, on the same VC */ - sess_vuid = register_vuid(server_info, user, guest); + sess_vuid = register_vuid(server_info, sub_user); free_server_info(&server_info); -- cgit From 50093d3bbda60634b76a7ec14ab60c76a4b83a42 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 9 Nov 2001 02:44:49 +0000 Subject: fix the tree so it compiles again grumble, mumble, ... (This used to be commit 72c1af6f8d9893dd5b8b4d105b301d8c621749c6) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 6e6d37c089..23d99d7352 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -107,7 +107,7 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_NO_MEMORY); } - sess_vuid = register_vuid(server_info, user, False); + sess_vuid = register_vuid(server_info, user); free_server_info(&server_info); -- cgit From 395aa946cd4fb9d5e07dd2fee418045a8064dfab Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 9 Nov 2001 11:16:06 +0000 Subject: This change updates lp_guestaccount() to be a *global* paramater, rather than per-share. I beleive that almost all the things that this could have done on a per-share basis can be done with other tools, like 'force user'. Almost all the user's of this paramater used it as a global anyway... While this is one step at a time, I hope it will allow me to considerably simplfy the make_connection() code, particularly for the user-level security case. This already removes an absolute truckload of extra attempted password lookups on the guest account. Andrew Bartlett (This used to be commit 8e708332eded210c1d1fe0cebca3c9c19f054b71) --- source3/smbd/sesssetup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 23d99d7352..e2edd5703e 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -383,7 +383,7 @@ static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *ou nt_status = check_password(user_info, &server_info); - sess_vuid = register_vuid(server_info, lp_guestaccount(-1)); + sess_vuid = register_vuid(server_info, lp_guestaccount()); free_server_info(&server_info); if (sess_vuid == -1) { @@ -644,7 +644,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if (*user) { pstrcpy(sub_user, user); } else { - pstrcpy(sub_user, lp_guestaccount(-1)); + pstrcpy(sub_user, lp_guestaccount()); } pstrcpy(current_user_info.smb_name,sub_user); -- cgit From 3d6154599a798e432360c001c25267e990f53d6d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Nov 2001 12:42:39 +0000 Subject: Kill off 'restrict anonymous' becouse it is useless in its current form. To be replaced with a real restriction in consultation with jra. (Hence why I've not touched loadparm.c). Andrew Bartlett (This used to be commit 95901449158a4ef7f95f75b22f63f6f8d43a01fe) --- source3/smbd/sesssetup.c | 47 ----------------------------------------------- 1 file changed, 47 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index e2edd5703e..6a2bfc2d97 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -571,32 +571,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, passlen2 = 0; } - if (lp_restrict_anonymous()) { - /* there seems to be no reason behind the - * differences in MS clients formatting - * various info like the domain, NativeOS, and - * NativeLanMan fields. Win95 in particular - * seems to have an extra null byte between - * the username and the domain, or the - * password length calculation is wrong, which - * throws off the string extraction routines - * below. This makes the value of domain be - * the empty string, which fails the restrict - * anonymous check further down. This - * compensates for that, and allows browsing - * to work in mixed NT and win95 environments - * even when restrict anonymous is true. AAB - * */ - dump_data(100, p, 0x70); - DEBUG(9, ("passlen1=%d, passlen2=%d\n", passlen1, passlen2)); - if (ra_type == RA_WIN95 && !passlen1 && !passlen2 && p[0] == 0 && p[1] == 0) { - DEBUG(0, ("restrict anonymous parameter used in a win95 environment!\n")); - DEBUG(0, ("client is win95 and broken passlen1 offset -- attempting fix\n")); - DEBUG(0, ("if win95 cilents are having difficulty browsing, you will be unable to use restrict anonymous\n")); - passlen1 = 1; - } - } - /* Save the lanman2 password and the NT md4 password. */ if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) { @@ -664,27 +638,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, *user = 0; } - if (done_sesssetup && lp_restrict_anonymous()) { - /* tests show that even if browsing is done over - * already validated connections without a username - * and password the domain is still provided, which it - * wouldn't be if it was a purely anonymous - * connection. So, in order to restrict anonymous, we - * only deny connections that have no session - * information. If a domain has been provided, then - * it's not a purely anonymous connection. AAB */ - if (!*user && !*domain) { - DEBUG(0, ("restrict anonymous is True and anonymous connection attempted. Denying access.\n")); - - data_blob_free(&lm_resp); - data_blob_free(&nt_resp); - data_blob_clear_free(&plaintext_password); - - END_PROFILE(SMBsesssetupX); - return ERROR_DOS(ERRDOS,ERRnoaccess); - } - } - if (!make_user_info_for_reply(&user_info, user, domain, lm_resp, nt_resp, -- cgit From 5abe3932cc9211263b2a93d58cdddb8de2d6f677 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 12 Nov 2001 00:08:30 +0000 Subject: Code duplication is bad. So add an add_signiture() function and just refernce that. (This used to be commit a82c8638576b2c2164eaf046aa529e233ffb71d6) --- source3/smbd/sesssetup.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 6a2bfc2d97..291685e9fc 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -24,6 +24,19 @@ uint32 global_client_caps = 0; +/**************************************************************************** + Add the standard 'Samba' signiture to the end of the session setup. +****************************************************************************/ +static void add_signiture(char *outbuf) +{ + char *p; + p = smb_buf(outbuf); + p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); + set_message_end(outbuf,p); +} + #if HAVE_KRB5 /**************************************************************************** reply to a session setup spnego negotiate packet for kerberos @@ -117,11 +130,7 @@ static int reply_spnego_kerberos(connection_struct *conn, set_message(outbuf,4,0,True); SSVAL(outbuf, smb_vwv3, 0); - p = smb_buf(outbuf); - p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); - set_message_end(outbuf,p); + add_signiture(outbuf); SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); @@ -273,7 +282,6 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, uint32 ntlmssp_command, neg_flags; NTSTATUS nt_status; int sess_vuid; - char *p; char chal[8]; auth_usersupplied_info *user_info = NULL; @@ -351,11 +359,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, set_message(outbuf,4,0,True); SSVAL(outbuf, smb_vwv3, 0); - p = smb_buf(outbuf); - p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); - set_message_end(outbuf,p); + add_signiture(outbuf); SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); @@ -371,7 +375,6 @@ static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *ou int length, int bufsize) { int sess_vuid; - char *p; auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; @@ -392,11 +395,7 @@ static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *ou set_message(outbuf,4,0,True); SSVAL(outbuf, smb_vwv3, 0); - p = smb_buf(outbuf); - p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); - set_message_end(outbuf,p); + add_signiture(outbuf); SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); @@ -680,13 +679,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if (Protocol < PROTOCOL_NT1) { set_message(outbuf,3,0,True); } else { - char *p; set_message(outbuf,3,0,True); - p = smb_buf(outbuf); - p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); - set_message_end(outbuf,p); + add_signiture(outbuf); /* perhaps grab OS version here?? */ } -- cgit From e5bd418963225d355c7050979776aeb555e4e033 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 12 Nov 2001 20:14:18 +0000 Subject: Spelling fixes. (This used to be commit 5c486bd28a5d4194b7cd50fd0fe3430d0d2eaa9b) --- source3/smbd/sesssetup.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 291685e9fc..c9c91ea71c 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -25,9 +25,9 @@ uint32 global_client_caps = 0; /**************************************************************************** - Add the standard 'Samba' signiture to the end of the session setup. + Add the standard 'Samba' signature to the end of the session setup. ****************************************************************************/ -static void add_signiture(char *outbuf) +static void add_signature(char *outbuf) { char *p; p = smb_buf(outbuf); @@ -130,7 +130,7 @@ static int reply_spnego_kerberos(connection_struct *conn, set_message(outbuf,4,0,True); SSVAL(outbuf, smb_vwv3, 0); - add_signiture(outbuf); + add_signature(outbuf); SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); @@ -359,7 +359,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, set_message(outbuf,4,0,True); SSVAL(outbuf, smb_vwv3, 0); - add_signiture(outbuf); + add_signature(outbuf); SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); @@ -395,7 +395,7 @@ static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *ou set_message(outbuf,4,0,True); SSVAL(outbuf, smb_vwv3, 0); - add_signiture(outbuf); + add_signature(outbuf); SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); @@ -680,7 +680,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, set_message(outbuf,3,0,True); } else { set_message(outbuf,3,0,True); - add_signiture(outbuf); + add_signature(outbuf); /* perhaps grab OS version here?? */ } -- cgit From c32526441668d75a8acf452e55559f00d5b87ba2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Nov 2001 08:50:04 +0000 Subject: add a hook to save the krb5 PAC (This used to be commit 1cbc18ae732671d9a60528f8300ca7609e124d11) --- source3/smbd/sesssetup.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index c9c91ea71c..b3e9b7be8f 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -85,6 +85,14 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } +#if 0 + if (tkt->enc_part2) { + file_save("/tmp/authdata.dat", + tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); + } +#endif + if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, &client))) { DEBUG(3,("krb5_unparse_name failed (%s)\n", -- cgit From d0a2faf78d316fec200497f5f7997df4c477a1e1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 24 Nov 2001 12:12:38 +0000 Subject: This is another rather major change to the samba authenticaion subystem. The particular aim is to modularized the interface - so that we can have arbitrary password back-ends. This code adds one such back-end, a 'winbind' module to authenticate against the winbind_auth_crap functionality. While fully-functional this code is mainly useful as a demonstration, because we don't get back the info3 as we would for direct ntdomain authentication. This commit introduced the new 'auth methods' parameter, in the spirit of the 'auth order' discussed on the lists. It is renamed because not all the methods may be consulted, even if previous methods fail - they may not have a suitable challenge for example. Also, we have a 'local' authentication method, for old-style 'unix if plaintext, sam if encrypted' authentication and a 'guest' module to handle guest logins in a single place. While this current design is not ideal, I feel that it does provide a better infrastructure than the current design, and can be built upon. The following parameters have changed: - use rhosts = This has been replaced by the 'rhosts' authentication method, and can be specified like 'auth methods = guest rhosts' - hosts equiv = This needs both this parameter and an 'auth methods' entry to be effective. (auth methods = guest hostsequiv ....) - plaintext to smbpasswd = This is replaced by specifying 'sam' rather than 'local' in the auth methods. The security = parameter is unchanged, and now provides defaults for the 'auth methods' parameter. The available auth methods are: guest rhosts hostsequiv sam (passdb direct hash access) unix (PAM, crypt() etc) local (the combination of the above, based on encryption) smbserver (old security=server) ntdomain (old security=domain) winbind (use winbind to cache DC connections) Assistance in testing, or the production of new and interesting authentication modules is always appreciated. Andrew Bartlett (This used to be commit 8d31eae52a9757739711dbb82035a4dfe6b40c99) --- source3/smbd/sesssetup.c | 123 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 85 insertions(+), 38 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index b3e9b7be8f..c9db359569 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -23,6 +23,7 @@ #include "includes.h" uint32 global_client_caps = 0; +static auth_authsupplied_info *ntlmssp_auth_info; /**************************************************************************** Add the standard 'Samba' signature to the end of the session setup. @@ -37,6 +38,31 @@ static void add_signature(char *outbuf) set_message_end(outbuf,p); } +/**************************************************************************** + Do a 'guest' logon, getting back the +****************************************************************************/ +static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) +{ + + auth_authsupplied_info *auth_info; + auth_usersupplied_info *user_info = NULL; + + NTSTATUS nt_status; + char chal[8]; + + ZERO_STRUCT(chal); + + DEBUG(3,("Got anonymous request\n")); + + make_user_info_guest(&user_info); + make_auth_info_fixed(&auth_info, chal); + + nt_status = check_password(user_info, auth_info, server_info); + free_auth_info(&auth_info); + return nt_status; +} + + #if HAVE_KRB5 /**************************************************************************** reply to a session setup spnego negotiate packet for kerberos @@ -189,7 +215,7 @@ static int reply_spnego_negotiate(connection_struct *conn, int i; uint32 ntlmssp_command, neg_flags; DATA_BLOB sess_key, chal, spnego_chal; - uint8 cryptkey[8]; + DATA_BLOB cryptkey; BOOL got_kerberos = False; /* parse out the OIDs and the first sec blob */ @@ -238,10 +264,12 @@ static int reply_spnego_negotiate(connection_struct *conn, DEBUG(3,("Got neg_flags=%08x\n", neg_flags)); - if (!last_challenge(cryptkey)) { - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + if (!make_auth_info_subsystem(&ntlmssp_auth_info)) { + return ERROR_NT(NT_STATUS_NO_MEMORY); } + cryptkey = auth_get_challange(ntlmssp_auth_info); + /* Give them the challenge. For now, ignore neg_flags and just return the flags we want. Obviously this is not correct */ @@ -255,7 +283,7 @@ static int reply_spnego_negotiate(connection_struct *conn, 0, 0x30, /* ?? */ neg_flags, - cryptkey, 8, + cryptkey.data, cryptkey.length, 0, 0, 0, 0x3000); /* ?? */ @@ -268,6 +296,7 @@ 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 */ @@ -286,11 +315,9 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, char *workgroup, *user, *machine; DATA_BLOB lmhash, nthash, sess_key; DATA_BLOB plaintext_password = data_blob(NULL, 0); - DATA_BLOB sec_blob; uint32 ntlmssp_command, neg_flags; NTSTATUS nt_status; int sess_vuid; - char chal[8]; auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; @@ -327,26 +354,19 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, file_save("lmhash1.dat", lmhash.data, lmhash.length); #endif - if (!last_challenge(chal)) { - DEBUG(0,("Encrypted login but no challange set!\n")); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - sec_blob = data_blob(chal, 8); - if (!sec_blob.data) { - return ERROR_NT(NT_STATUS_NO_MEMORY); - } - if (!make_user_info_map(&user_info, user, workgroup, - machine, sec_blob, + machine, lmhash, nthash, plaintext_password, neg_flags, True)) { return ERROR_NT(NT_STATUS_NO_MEMORY); } - nt_status = check_password(user_info, &server_info); + nt_status = check_password(user_info, ntlmssp_auth_info, &server_info); + free_auth_info(&ntlmssp_auth_info); + free_user_info(&user_info); data_blob_free(&lmhash); @@ -383,18 +403,17 @@ static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *ou int length, int bufsize) { int sess_vuid; - auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; - NTSTATUS nt_status; - DEBUG(3,("Got anonymous request\n")); - - make_user_info_guest(&user_info); + nt_status = check_guest_password(&server_info); - nt_status = check_password(user_info, &server_info); + if (!NT_STATUS_IS_OK(nt_status)) { + return ERROR_NT(nt_status_squash(nt_status)); + } sess_vuid = register_vuid(server_info, lp_guestaccount()); + free_server_info(&server_info); if (sess_vuid == -1) { @@ -490,6 +509,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; auth_serversupplied_info *server_info = NULL; NTSTATUS nt_status; @@ -523,16 +543,12 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, lm_resp = data_blob(smb_buf(inbuf), passlen1); } else { plaintext_password = data_blob(smb_buf(inbuf), passlen1+1); - if (!plaintext_password.data) { - DEBUG(0,("reply_sesssetup_and_X: malloc failed for plaintext_password!\n")); - return ERROR_NT(NT_STATUS_NO_MEMORY); - } else { - /* Ensure null termination */ - plaintext_password.data[passlen1] = 0; - } + /* Ensure null termination */ + plaintext_password.data[passlen1] = 0; } srvstr_pull(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), -1, STR_TERMINATE); + *domain = 0; } else { uint16 passlen1 = SVAL(inbuf,smb_vwv7); @@ -645,15 +661,41 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, *user = 0; } - if (!make_user_info_for_reply(&user_info, - user, domain, - lm_resp, nt_resp, - plaintext_password, doencrypt)) { - return ERROR_NT(NT_STATUS_NO_MEMORY); + if (!*user) { + + 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); + } + + 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_challange(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); + + data_blob_free(&chal); + free_auth_info(&plaintext_auth_info); } - - nt_status = check_password(user_info, &server_info); - + free_user_info(&user_info); data_blob_free(&lm_resp); @@ -726,3 +768,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, END_PROFILE(SMBsesssetupX); return chain_reply(inbuf,outbuf,length,bufsize); } + + + + + -- cgit From ad2974cd05b4d08c8b92f505bf95aa8e8533235f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 24 Nov 2001 14:16:41 +0000 Subject: added "net join" command this completes the first stage of the smbd ADS support (This used to be commit 058a5aee901e6609969ef7e1d482a720a84a4a12) --- source3/smbd/sesssetup.c | 43 +++++-------------------------------------- 1 file changed, 5 insertions(+), 38 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index c9db359569..854513bb47 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -73,16 +73,12 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB *secblob) { DATA_BLOB ticket; - krb5_context context; - krb5_auth_context auth_context = NULL; - krb5_keytab keytab = NULL; - krb5_data packet; - krb5_ticket *tkt = NULL; - int ret; char *realm, *client, *p; const struct passwd *pw; char *user; int sess_vuid; + NTSTATUS ret; + DATA_BLOB auth_data; auth_serversupplied_info *server_info = NULL; realm = lp_realm(); @@ -91,38 +87,9 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - ret = krb5_init_context(&context); - if (ret) { - DEBUG(1,("krb5_init_context failed (%s)\n", error_message(ret))); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - - packet.length = ticket.length; - packet.data = (krb5_pointer)ticket.data; - -#if 0 - file_save("/tmp/ticket.dat", ticket.data, ticket.length); -#endif - - if ((ret = krb5_rd_req(context, &auth_context, &packet, - NULL, keytab, NULL, &tkt))) { - DEBUG(3,("krb5_rd_req failed (%s)\n", - error_message(ret))); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - -#if 0 - if (tkt->enc_part2) { - file_save("/tmp/authdata.dat", - tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); - } -#endif - - if ((ret = krb5_unparse_name(context, tkt->enc_part2->client, - &client))) { - DEBUG(3,("krb5_unparse_name failed (%s)\n", - error_message(ret))); + ret = ads_verify_ticket(&ticket, &client, &auth_data); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(1,("Failed to verify incoming ticket!\n")); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } -- cgit From 178f6a64b26d828db6b516392d7072e9c29f6233 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 26 Nov 2001 04:05:28 +0000 Subject: challange -> challenge (This used to be commit d6318add27f6bca5be00cbedf2226b642341297a) --- source3/smbd/sesssetup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 854513bb47..1b6776ed70 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -235,7 +235,7 @@ static int reply_spnego_negotiate(connection_struct *conn, return ERROR_NT(NT_STATUS_NO_MEMORY); } - cryptkey = auth_get_challange(ntlmssp_auth_info); + cryptkey = auth_get_challenge(ntlmssp_auth_info); /* Give them the challenge. For now, ignore neg_flags and just return the flags we want. Obviously this is not correct */ @@ -649,7 +649,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_NT(NT_STATUS_NO_MEMORY); } - chal = auth_get_challange(plaintext_auth_info); + chal = auth_get_challenge(plaintext_auth_info); if (!make_user_info_for_reply(&user_info, user, domain, chal.data, -- cgit From 0b2763260e915620a6d9b1709d112b13a8566d74 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 Nov 2001 04:37:24 +0000 Subject: we can safely give NO_SUCH_USER if the ticket decodes but the local account doesn't exist (This used to be commit 477b6d27fd7281418739bc8ba0b984a53430ecda) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 1b6776ed70..d49dbc15d1 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -113,7 +113,7 @@ static int reply_spnego_kerberos(connection_struct *conn, pw = smb_getpwnam(user,False); if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(NT_STATUS_NO_SUCH_USER); } if (!make_server_info_pw(&server_info,pw)) { -- cgit From 6cf3434785ec369f6edbd5b1dd4dd1c26123b7c1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 Nov 2001 03:34:56 +0000 Subject: more memory leak fixes (This used to be commit 5abf8442033587b79651301d39260abd44b1c3fa) --- source3/smbd/sesssetup.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index d49dbc15d1..ac8ba91ff7 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -59,6 +59,7 @@ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) nt_status = check_password(user_info, auth_info, server_info); free_auth_info(&auth_info); + SAFE_FREE(user_info); return nt_status; } @@ -279,7 +280,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, DATA_BLOB blob1) { DATA_BLOB auth; - char *workgroup, *user, *machine; + char *workgroup = NULL, *user = NULL, *machine = NULL; DATA_BLOB lmhash, nthash, sess_key; DATA_BLOB plaintext_password = data_blob(NULL, 0); uint32 ntlmssp_command, neg_flags; @@ -329,6 +330,10 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, neg_flags, True)) { return ERROR_NT(NT_STATUS_NO_MEMORY); } + + SAFE_FREE(workgroup); + SAFE_FREE(user); + SAFE_FREE(machine); nt_status = check_password(user_info, ntlmssp_auth_info, &server_info); -- cgit From 67b347378031c3f48c937eb25c6b1b25b9fb528c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 Nov 2001 03:54:15 +0000 Subject: fixed another memory leak (This used to be commit 37aa2873e5f476a587316893b0ea3a6fbdfe746f) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index ac8ba91ff7..f9d52e9be4 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -59,7 +59,7 @@ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) nt_status = check_password(user_info, auth_info, server_info); free_auth_info(&auth_info); - SAFE_FREE(user_info); + free_user_info(&user_info); return nt_status; } -- cgit From f6b962fba37a1ac105301d699708e541ce34d3b4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 Nov 2001 23:54:07 +0000 Subject: fixed some krb5 ifdefs (This used to be commit 23ef22f11700bbaa5778a9678a990a2b041fcefe) --- source3/smbd/sesssetup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index f9d52e9be4..863a509042 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -64,7 +64,7 @@ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) } -#if HAVE_KRB5 +#ifdef HAVE_KRB5 /**************************************************************************** reply to a session setup spnego negotiate packet for kerberos ****************************************************************************/ @@ -201,7 +201,7 @@ static int reply_spnego_negotiate(connection_struct *conn, } DEBUG(3,("Got secblob of size %d\n", secblob.length)); -#if HAVE_KRB5 +#ifdef HAVE_KRB5 if (got_kerberos) { int ret = reply_spnego_kerberos(conn, inbuf, outbuf, length, bufsize, &secblob); -- cgit From fe64484824d8169bf66822ebf7f6a9180a238e6e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 29 Nov 2001 06:21:56 +0000 Subject: Make better use of the ads_init() function to get the kerberos relam etc. This allows us to use automagically obtained values in future, and the value from krb5.conf now. Also fix mem leaks etc. Andrew Bartlett (This used to be commit 8f9ce717819235d98a1463f20ac659cb4b4ebbd2) --- source3/smbd/sesssetup.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 863a509042..35155c0dec 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -74,23 +74,25 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB *secblob) { DATA_BLOB ticket; - char *realm, *client, *p; + char *client, *p; const struct passwd *pw; char *user; int sess_vuid; NTSTATUS ret; DATA_BLOB auth_data; auth_serversupplied_info *server_info = NULL; - - realm = lp_realm(); + ADS_STRUCT *ads; if (!spnego_parse_krb5_wrap(*secblob, &ticket)) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - ret = ads_verify_ticket(&ticket, &client, &auth_data); + ads = ads_init(NULL, NULL, NULL); + + ret = ads_verify_ticket(ads, &ticket, &client, &auth_data); if (!NT_STATUS_IS_OK(ret)) { - DEBUG(1,("Failed to verify incoming ticket!\n")); + DEBUG(1,("Failed to verify incoming ticket!\n")); + ads_destroy(&ads); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -99,15 +101,18 @@ static int reply_spnego_kerberos(connection_struct *conn, p = strchr_m(client, '@'); if (!p) { DEBUG(3,("Doesn't look like a valid principal\n")); + ads_destroy(&ads); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } *p = 0; - if (strcasecmp(p+1, realm) != 0) { + if (strcasecmp(p+1, ads->realm) != 0) { DEBUG(3,("Ticket for incorrect realm %s\n", p+1)); + ads_destroy(&ads); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - + ads_destroy(&ads); + user = client; /* the password is good - let them in */ -- cgit From 9421ad4a7a900b219f87754bc20fa14f2f22fd35 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Dec 2001 09:46:53 +0000 Subject: added a REALLY gross hack into kerberos_kinit_password so that winbindd can do a kinit this will be removed once we have code that gets a tgt and puts it in a place where cyrus-sasl can see it (This used to be commit 7d94f1b7365215a020d3678d03d820a7d086174f) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 35155c0dec..8e7ee38504 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -87,7 +87,7 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - ads = ads_init(NULL, NULL, NULL); + ads = ads_init(NULL, NULL, NULL, NULL); ret = ads_verify_ticket(ads, &ticket, &client, &auth_data); if (!NT_STATUS_IS_OK(ret)) { -- cgit From 3f387d19717c31a2eec265ec790293ece3381094 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 5 Dec 2001 10:50:26 +0000 Subject: Ensure we fill in the %U for NTLMSSP connections (This used to be commit d15ea4fa8e23469f104405c197206e2779461323) --- source3/smbd/sesssetup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 8e7ee38504..7190caa35b 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -337,7 +337,6 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, } SAFE_FREE(workgroup); - SAFE_FREE(user); SAFE_FREE(machine); nt_status = check_password(user_info, ntlmssp_auth_info, &server_info); @@ -351,12 +350,15 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, data_blob_free(&nthash); if (!NT_STATUS_IS_OK(nt_status)) { + SAFE_FREE(user); return ERROR_NT(nt_status_squash(nt_status)); } sess_vuid = register_vuid(server_info, user); free_server_info(&server_info); + + SAFE_FREE(user); if (sess_vuid == -1) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); -- cgit From 9220fd730c67352e2d0789f298e6e42063ca9e3c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 8 Dec 2001 02:12:17 +0000 Subject: Ensure that 'use spnego' restricts, rather than just advises our clients. This means that if a hole is found in the spnego code, we can tell people to just set 'use spengo' in their config file while we sort it out. Other than that, preventing 'unusual' behaviour is always a good thing. Andrew Bartlett (This used to be commit a8a53c08f7d607268a3959486a850a2df50ca7a2) --- source3/smbd/sesssetup.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7190caa35b..4c26bda4db 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -502,11 +502,16 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, ZERO_STRUCT(plaintext_password); DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf, smb_wct), SVAL(inbuf, smb_flg2))); - + /* a SPNEGO session setup has 12 command words, whereas a normal NT1 session setup has 13. See the cifs spec. */ if (CVAL(inbuf, smb_wct) == 12 && (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) { + if (!global_spnego_negotiated) { + DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at SPNEGO session setup when it was not negoitiated.\n")); + return ERROR_NT(NT_STATUS_UNSUCCESSFUL); + } + return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize); } -- cgit From 9126a40e2c33e0eb4cd57ab381634e08fa59e7a7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Dec 2001 09:53:30 +0000 Subject: added trusted realm support to ADS authentication the method used for checking if a domain is a trusted domain is very crude, we should really call a backend fn of some sort. For now I'm using winbindd to do the dirty work. (This used to be commit adf44a9bd0d997ba4dcfadc564a29149531525af) --- source3/smbd/sesssetup.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 4c26bda4db..60c9cd30e5 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -107,14 +107,18 @@ static int reply_spnego_kerberos(connection_struct *conn, *p = 0; if (strcasecmp(p+1, ads->realm) != 0) { - DEBUG(3,("Ticket for incorrect realm %s\n", p+1)); - ads_destroy(&ads); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1)); + if (!lp_allow_trusted_domains()) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + /* this gives a fully qualified user name (ie. with full realm). + that leads to very long usernames, but what else can we do? */ + asprintf(&user, "%s%s%s", p+1, lp_winbind_separator(), client); + } else { + user = strdup(client); } ads_destroy(&ads); - user = client; - /* the password is good - let them in */ pw = smb_getpwnam(user,False); if (!pw) { @@ -129,6 +133,7 @@ static int reply_spnego_kerberos(connection_struct *conn, sess_vuid = register_vuid(server_info, user); + free(user); free_server_info(&server_info); if (sess_vuid == -1) { -- cgit From 1a242b6fd9c6f7dc43b629d0dc22ff42053e3c32 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 20 Dec 2001 09:06:53 +0000 Subject: support "map to guest" with spnego (This used to be commit e873d0ff1eee9442ff6152d666b8d874b6a01972) --- source3/smbd/sesssetup.c | 64 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 21 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 60c9cd30e5..7fd0fd917a 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -25,6 +25,35 @@ uint32 global_client_caps = 0; static auth_authsupplied_info *ntlmssp_auth_info; +/* + on a logon error possibly map the error to success if "map to guest" + is set approriately +*/ +static NTSTATUS do_map_to_guest(NTSTATUS status, auth_serversupplied_info **server_info, + const char *user, const char *domain) +{ + if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) { + if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || + (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) { + DEBUG(3,("No such user %s [%s] - using guest account\n", + user, domain)); + make_server_info_guest(server_info); + status = NT_STATUS_OK; + } + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) { + if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) { + DEBUG(3,("Registered username %s for guest access\n",user)); + make_server_info_guest(server_info); + status = NT_STATUS_OK; + } + } + + return status; +} + + /**************************************************************************** Add the standard 'Samba' signature to the end of the session setup. ****************************************************************************/ @@ -341,11 +370,15 @@ 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); + + if (!NT_STATUS_IS_OK(nt_status)) { + nt_status = do_map_to_guest(nt_status, &server_info, user, workgroup); + } + SAFE_FREE(workgroup); SAFE_FREE(machine); - - nt_status = check_password(user_info, ntlmssp_auth_info, &server_info); - + free_auth_info(&ntlmssp_auth_info); free_user_info(&user_info); @@ -353,7 +386,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, data_blob_free(&lmhash); data_blob_free(&nthash); - + if (!NT_STATUS_IS_OK(nt_status)) { SAFE_FREE(user); return ERROR_NT(nt_status_squash(nt_status)); @@ -371,6 +404,11 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, set_message(outbuf,4,0,True); SSVAL(outbuf, smb_vwv3, 0); + + if (server_info->guest) { + SSVAL(outbuf,smb_vwv2,1); + } + add_signature(outbuf); SSVAL(outbuf,smb_uid,sess_vuid); @@ -663,7 +701,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } nt_status = check_password(user_info, negprot_global_auth_info, &server_info); - } else { auth_authsupplied_info *plaintext_auth_info = NULL; DATA_BLOB chal; @@ -692,22 +729,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, data_blob_clear_free(&plaintext_password); if (!NT_STATUS_IS_OK(nt_status)) { - if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) { - if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || - (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) { - - DEBUG(3,("No such user %s [%s] - using guest account\n",user, domain)); - make_server_info_guest(&server_info); - nt_status = NT_STATUS_OK; - } - - } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) { - if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) { - DEBUG(3,("Registered username %s for guest access\n",user)); - make_server_info_guest(&server_info); - nt_status = NT_STATUS_OK; - } - } + nt_status = do_map_to_guest(nt_status, &server_info, user, domain); } if (!NT_STATUS_IS_OK(nt_status)) { -- cgit From 01a382480a148f70384da65b38c936bedcb4ba6b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 20 Dec 2001 09:32:03 +0000 Subject: don't use server_info after its been freed (This used to be commit ee161a57289409e2fa43e33b045473077c7b6ba5) --- source3/smbd/sesssetup.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7fd0fd917a..8424e0e186 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -325,6 +325,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, uint32 ntlmssp_command, neg_flags; NTSTATUS nt_status; int sess_vuid; + BOOL as_guest; auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; @@ -392,8 +393,9 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, return ERROR_NT(nt_status_squash(nt_status)); } - sess_vuid = register_vuid(server_info, user); + as_guest = server_info->guest; + sess_vuid = register_vuid(server_info, user); free_server_info(&server_info); SAFE_FREE(user); @@ -405,7 +407,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, set_message(outbuf,4,0,True); SSVAL(outbuf, smb_vwv3, 0); - if (server_info->guest) { + if (as_guest) { SSVAL(outbuf,smb_vwv2,1); } -- cgit From 9eebd31e2c0dfb35e32c5524c21f544f89810866 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 20 Dec 2001 23:36:39 +0000 Subject: check for a winbindd username when doing a kerberos auth (This used to be commit 39f2e2e1623a011e2c99ecca64e0643b1e450657) --- source3/smbd/sesssetup.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 8424e0e186..7791637606 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -150,6 +150,17 @@ static int reply_spnego_kerberos(connection_struct *conn, /* the password is good - let them in */ pw = smb_getpwnam(user,False); + if (!pw && !strstr(user, lp_winbind_separator())) { + char *user2; + /* try it with a winbind domain prefix */ + asprintf(&user2, "%s%s%s", lp_workgroup(), lp_winbind_separator(), user); + pw = smb_getpwnam(user2,False); + if (pw) { + free(user); + user = user2; + } + } + if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); return ERROR_NT(NT_STATUS_NO_SUCH_USER); -- cgit From eb4e10115310b6ed23b92abac2e79454c80930b1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Dec 2001 13:46:26 +0000 Subject: - portablitity fixes for cc -64 on irix - fixed gid* bug in rpc_server (This used to be commit 48aa90c48c5f0e3054c4acdc49668e222e7c0d36) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7791637606..57e0ee2f3a 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -77,7 +77,7 @@ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) auth_usersupplied_info *user_info = NULL; NTSTATUS nt_status; - char chal[8]; + unsigned char chal[8]; ZERO_STRUCT(chal); -- cgit From 4178f211d1d2d133b96b420361944f5e197ec556 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 2 Jan 2002 23:28:55 +0000 Subject: debug statement fixups. Merge SAFE_FREE fix in tdb from 2.2, and IRIX fix. Jeremy. (This used to be commit eb6607466565bcd5b3800492d0bc1ae8a44da4f6) --- source3/smbd/sesssetup.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 57e0ee2f3a..41a7a657e2 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -792,8 +792,3 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, END_PROFILE(SMBsesssetupX); return chain_reply(inbuf,outbuf,length,bufsize); } - - - - - -- cgit 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/sesssetup.c | 101 ++++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 45 deletions(-) (limited to 'source3/smbd/sesssetup.c') 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 From 341f87090bad76c427bae85bf81798aaea6c659b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Jan 2002 12:04:33 +0000 Subject: Fix up the SPNEGO segfault. (This used to be commit 17b1c83dd02035048bd38b305460c96c6c09343a) --- source3/smbd/sesssetup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 737ecade7d..8b7a29ea86 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -23,7 +23,7 @@ #include "includes.h" uint32 global_client_caps = 0; -static struct auth_context *ntlmssp_auth_context; +static struct auth_context *ntlmssp_auth_context = NULL; /* on a logon error possibly map the error to success if "map to guest" @@ -288,7 +288,7 @@ static int reply_spnego_negotiate(connection_struct *conn, DEBUG(3,("Got neg_flags=%08x\n", neg_flags)); - if (!ntlmssp_auth_context) { + if (ntlmssp_auth_context) { ntlmssp_auth_context->free(&ntlmssp_auth_context); } -- cgit From b283dba09d1ad7bcf14066071cf2df8de95a9b12 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 6 Jan 2002 00:49:23 +0000 Subject: Some more SPNEGO fixes. (This used to be commit 0e564cb32acc70c1fc43f1be5ceb3637f0dc7361) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 8b7a29ea86..c6cb40fcda 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -311,7 +311,7 @@ static int reply_spnego_negotiate(connection_struct *conn, 0, 0x30, /* ?? */ neg_flags, - cryptkey, sizeof(cryptkey), + cryptkey, 8, 0, 0, 0, 0x3000); /* ?? */ -- cgit From b8b228d9615352f552a534c30076032d4e2dd3ef Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 6 Jan 2002 01:37:14 +0000 Subject: Get this code back to where it belongs... Apparently (and I will doublecheck) its legal to do an annoymous session setup when we negoitiated SPNEGO, but we can't do an authenticated one becouse we didn't give a challange. Andrew Bartlett (This used to be commit 08a5c5bf940fac7a779be01db01ae7d97df80f79) --- source3/smbd/sesssetup.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index c6cb40fcda..a159111319 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -681,6 +681,13 @@ 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) { + + /* 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); + } pstrcpy(sub_user, user); } else { pstrcpy(sub_user, lp_guestaccount()); @@ -704,13 +711,6 @@ 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); -- cgit From f5bc0e92a66b418b2bd8f3669a9642b4d46bc8d1 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Wed, 9 Jan 2002 07:52:51 +0000 Subject: Better explanation message for dmalloc. Also more insertion of parenthesis to handle struct members called 'free'. You can now get useful dmalloc output, as long as it is compatible with your C library. On RH7.1 it looks like you have to rebuild dmalloc to allow free(0) by default, because something in libcrypt does that. (sigh) (This used to be commit 391cbb690196537c8b6292b42c2e27408cc7e249) --- source3/smbd/sesssetup.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index a159111319..f809f9ca0c 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -87,12 +87,12 @@ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) } if (!make_user_info_guest(&user_info)) { - auth_context->free(&auth_context); + (auth_context->free)(&auth_context); return NT_STATUS_NO_MEMORY; } nt_status = auth_context->check_ntlm_password(auth_context, user_info, server_info); - auth_context->free(&auth_context); + (auth_context->free)(&auth_context); free_user_info(&user_info); return nt_status; } @@ -289,7 +289,7 @@ static int reply_spnego_negotiate(connection_struct *conn, DEBUG(3,("Got neg_flags=%08x\n", neg_flags)); if (ntlmssp_auth_context) { - ntlmssp_auth_context->free(&ntlmssp_auth_context); + (ntlmssp_auth_context->free)(&ntlmssp_auth_context); } if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&ntlmssp_auth_context))) { @@ -400,7 +400,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, SAFE_FREE(workgroup); SAFE_FREE(machine); - ntlmssp_auth_context->free(&ntlmssp_auth_context); + (ntlmssp_auth_context->free)(&ntlmssp_auth_context); free_user_info(&user_info); @@ -741,7 +741,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, user_info, &server_info); - plaintext_auth_context->free(&plaintext_auth_context); + (plaintext_auth_context->free)(&plaintext_auth_context); } } } -- cgit From 5047a66d39fdd56a5895037de8c519a828a03b19 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 11 Jan 2002 05:29:09 +0000 Subject: Back out the crazy notion that the NTLMSSP flags actually mean anything... Replace this with some flags that *we* define. We can do a mapping later if we actually get some more reliable info about what passwords are actually valid. Andrew Bartlett (This used to be commit 7f7a42c3e4d5798ac87ea16a42e4976c3778a76b) --- source3/smbd/sesssetup.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index f809f9ca0c..519817432d 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -346,6 +346,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, NTSTATUS nt_status; int sess_vuid; BOOL as_guest; + uint32 auth_flags = AUTH_FLAG_NONE; auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; @@ -382,12 +383,22 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, file_save("lmhash1.dat", lmhash.data, lmhash.length); #endif + if (lmhash.length) { + auth_flags |= AUTH_FLAG_LM_RESP; + } + + if (nthash.length == 24) { + auth_flags |= AUTH_FLAG_NTLM_RESP; + } else if (nthash.length > 24) { + auth_flags |= AUTH_FLAG_NTLMv2_RESP; + } + if (!make_user_info_map(&user_info, user, workgroup, machine, lmhash, nthash, plaintext_password, - neg_flags, True)) { + auth_flags, True)) { return ERROR_NT(NT_STATUS_NO_MEMORY); } -- cgit From c311d24ce32d2a8aa244f126bcec67ec03549727 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 17 Jan 2002 08:45:58 +0000 Subject: A nice *big* change to the fundemental way we do things. Samba (ab)uses the returns from getpwnam() a lot - in particular it keeps them around for a long time - often past the next call... This adds a getpwnam_alloc and a getpwuid_alloc to the collection. These function as expected, returning a malloced structure that can be free()ed with passwd_free(&passwd). This patch also cuts down on the number of calls to getpwnam - mostly by taking advantage of the fact that the passdb interface is already case-insensiteve. With this patch most of the recursive cases have been removed (that I know of) and the problems are reduced further by not using the sys_ interface in the new code. This means that pointers to the cache won't be affected. (This is a tempoary HACK, I intend to kill the password cache entirly). The only change I'm a little worried about is the change to rpc_server/srv_samr_nt.c for private groups. In this case we are getting groups from the new group mapping DB. Do we still need to check for private groups? I've toned down the check to a case sensitve match with the new code, but we might be able to kill it entirly. I've also added a make_modifyable_passwd() function, that copies a passwd struct into the form that the old sys_getpw* code provided. As far as I can tell this is only actually used in the pass_check.c crazies, where I moved the final 'special case' for shadow passwords (out of _Get_Pwnam()). The matching case for getpwent() is dealt with already, in lib/util_getent.c Also included in here is a small change to register the [homes] share at vuid creation rather than just in one varient of the session setup. (This picks up the SPNEGO cases). The home directory is now stored on the vuid, and I am hoping this might provide a saner way to do %H substitions. TODO: Kill off remaining Get_Pwnam_Modify calls (they are not needed), change the remaining sys_getpwnam() callers to use getpwnam_alloc() and move Get_Pwnam to return an allocated struct. Andrew Bartlett (This used to be commit 1d86c7f94230bc53daebd4d2cd829da6292e05da) --- source3/smbd/sesssetup.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 519817432d..0e5830fc24 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -782,13 +782,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if (server_info->guest) { SSVAL(outbuf,smb_vwv2,1); - } else { - const char *home_dir = pdb_get_homedir(server_info->sam_account); - const char *username = pdb_get_username(server_info->sam_account); - if ((home_dir && *home_dir) - && (lp_servicenumber(username) < 0)) { - add_home_service(username, home_dir); - } } /* register the name and uid as being validated, so further connections -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/smbd/sesssetup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 0e5830fc24..899c9174b2 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. handle SMBsessionsetup Copyright (C) Andrew Tridgell 1998-2001 Copyright (C) Andrew Bartlett 2001 -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/smbd/sesssetup.c | 88 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 28 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 899c9174b2..867b00ff5c 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -120,7 +120,7 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - ads = ads_init(NULL, NULL, NULL, NULL); + ads = ads_init_simple(); ret = ads_verify_ticket(ads, &ticket, &client, &auth_data); if (!NT_STATUS_IS_OK(ret)) { @@ -235,11 +235,12 @@ static int reply_spnego_negotiate(connection_struct *conn, char *OIDs[ASN1_MAX_OIDS]; DATA_BLOB secblob; int i; - uint32 ntlmssp_command, neg_flags; - DATA_BLOB sess_key, chal, spnego_chal; + uint32 ntlmssp_command, neg_flags, chal_flags; + DATA_BLOB chal, spnego_chal, extra_data; const uint8 *cryptkey; BOOL got_kerberos = False; NTSTATUS nt_status; + extern pstring global_myname; /* parse out the OIDs and the first sec blob */ if (!parse_negTokenTarg(blob1, OIDs, &secblob)) { @@ -274,18 +275,23 @@ static int reply_spnego_negotiate(connection_struct *conn, "NTLMSSP", &ntlmssp_command, &neg_flags, - &sess_key)) { + &extra_data)) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } + + DEBUG(5, ("Extra data: \n")); + dump_data(5, extra_data.data, extra_data.length); data_blob_free(&secblob); - data_blob_free(&sess_key); + data_blob_free(&extra_data); if (ntlmssp_command != NTLMSSP_NEGOTIATE) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - DEBUG(3,("Got neg_flags=%08x\n", neg_flags)); + DEBUG(3,("Got neg_flags=0x%08x\n", neg_flags)); + + debug_ntlmssp_flags(neg_flags); if (ntlmssp_auth_context) { (ntlmssp_auth_context->free)(&ntlmssp_auth_context); @@ -300,22 +306,47 @@ static int reply_spnego_negotiate(connection_struct *conn, /* Give them the challenge. For now, ignore neg_flags and just return the flags we want. Obviously this is not correct */ - neg_flags = NTLMSSP_NEGOTIATE_UNICODE | + chal_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_LM_KEY | - NTLMSSP_NEGOTIATE_NTLM; - - msrpc_gen(&chal, "Cddddbdddd", - "NTLMSSP", - NTLMSSP_CHALLENGE, - 0, - 0x30, /* ?? */ - neg_flags, - cryptkey, 8, - 0, 0, 0, - 0x3000); /* ?? */ + NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_CHAL_TARGET_INFO; + + { + DATA_BLOB domain_blob, netbios_blob, realm_blob; + + msrpc_gen(&domain_blob, + "U", + lp_workgroup()); + + msrpc_gen(&netbios_blob, + "U", + global_myname); + + msrpc_gen(&realm_blob, + "U", + lp_realm()); + + + msrpc_gen(&chal, "CddddbBBBB", + "NTLMSSP", + NTLMSSP_CHALLENGE, + 0, + 0x30, /* ?? */ + chal_flags, + cryptkey, 8, + domain_blob.data, domain_blob.length, + domain_blob.data, domain_blob.length, + netbios_blob.data, netbios_blob.length, + realm_blob.data, realm_blob.length); + + data_blob_free(&domain_blob); + data_blob_free(&netbios_blob); + data_blob_free(&realm_blob); + } if (!spnego_gen_challenge(&spnego_chal, &chal, &chal)) { DEBUG(3,("Failed to generate challenge\n")); + data_blob_free(&chal); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -346,10 +377,15 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, int sess_vuid; BOOL as_guest; uint32 auth_flags = AUTH_FLAG_NONE; - auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; + /* we must have setup the auth context by now */ + if (!ntlmssp_auth_context) { + DEBUG(2,("ntlmssp_auth_context is NULL in reply_spnego_auth\n")); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + if (!spnego_parse_auth(blob1, &auth)) { #if 0 file_save("auth.dat", blob1.data, blob1.length); @@ -606,7 +642,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, plaintext_password.data[passlen1] = 0; } - srvstr_pull(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), -1, STR_TERMINATE); + srvstr_pull_buf(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), STR_TERMINATE); *domain = 0; } else { @@ -669,14 +705,10 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } p += passlen1 + passlen2; - p += srvstr_pull(inbuf, user, p, sizeof(user), -1, - STR_TERMINATE); - p += srvstr_pull(inbuf, domain, p, sizeof(domain), - -1, STR_TERMINATE); - p += srvstr_pull(inbuf, native_os, p, sizeof(native_os), - -1, STR_TERMINATE); - p += srvstr_pull(inbuf, native_lanman, p, sizeof(native_lanman), - -1, STR_TERMINATE); + p += srvstr_pull_buf(inbuf, user, p, sizeof(user), STR_TERMINATE); + p += srvstr_pull_buf(inbuf, domain, p, sizeof(domain), STR_TERMINATE); + p += srvstr_pull_buf(inbuf, native_os, p, sizeof(native_os), STR_TERMINATE); + p += srvstr_pull_buf(inbuf, native_lanman, p, sizeof(native_lanman), STR_TERMINATE); DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n", domain,native_os,native_lanman)); } -- cgit From 127e77e6e334fdc33086bffcbe00d340c0ba0097 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 15:27:10 +0000 Subject: Sync 3.0 branch with head (This used to be commit 42615b945e2e48e53a21ea47f2e45407913a6a1e) --- source3/smbd/sesssetup.c | 119 ++++++++++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 49 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 867b00ff5c..77f93812dd 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -3,6 +3,7 @@ handle SMBsessionsetup Copyright (C) Andrew Tridgell 1998-2001 Copyright (C) Andrew Bartlett 2001 + Copyright (C) Jim McDonough 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -122,6 +123,12 @@ static int reply_spnego_kerberos(connection_struct *conn, ads = ads_init_simple(); + if (!ads) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + + ads->auth.realm = strdup(lp_realm()); + ret = ads_verify_ticket(ads, &ticket, &client, &auth_data); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("Failed to verify incoming ticket!\n")); @@ -139,7 +146,7 @@ static int reply_spnego_kerberos(connection_struct *conn, } *p = 0; - if (strcasecmp(p+1, ads->realm) != 0) { + if (strcasecmp(p+1, ads->auth.realm) != 0) { DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1)); if (!lp_allow_trusted_domains()) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); @@ -200,7 +207,7 @@ static int reply_spnego_kerberos(connection_struct *conn, send a security blob via a session setup reply ****************************************************************************/ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, - DATA_BLOB blob) + DATA_BLOB blob, uint32 errcode) { char *p; @@ -209,7 +216,7 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, /* we set NT_STATUS_MORE_PROCESSING_REQUIRED to tell the other end that we aren't finished yet */ - SIVAL(outbuf, smb_rcls, NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED)); + SIVAL(outbuf, smb_rcls, errcode); SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */ SSVAL(outbuf, smb_vwv3, blob.length); p = smb_buf(outbuf); @@ -236,11 +243,12 @@ static int reply_spnego_negotiate(connection_struct *conn, DATA_BLOB secblob; int i; uint32 ntlmssp_command, neg_flags, chal_flags; - DATA_BLOB chal, spnego_chal, extra_data; + DATA_BLOB chal, spnego_chal; const uint8 *cryptkey; BOOL got_kerberos = False; NTSTATUS nt_status; extern pstring global_myname; + char *cliname=NULL, *domname=NULL; /* parse out the OIDs and the first sec blob */ if (!parse_negTokenTarg(blob1, OIDs, &secblob)) { @@ -258,7 +266,7 @@ static int reply_spnego_negotiate(connection_struct *conn, DEBUG(3,("Got secblob of size %d\n", secblob.length)); #ifdef HAVE_KRB5 - if (got_kerberos) { + if (got_kerberos && (SEC_ADS == lp_security())) { int ret = reply_spnego_kerberos(conn, inbuf, outbuf, length, bufsize, &secblob); data_blob_free(&secblob); @@ -271,19 +279,16 @@ static int reply_spnego_negotiate(connection_struct *conn, file_save("secblob.dat", secblob.data, secblob.length); #endif - if (!msrpc_parse(&secblob, "CddB", + if (!msrpc_parse(&secblob, "CddAA", "NTLMSSP", &ntlmssp_command, &neg_flags, - &extra_data)) { + &cliname, + &domname)) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - DEBUG(5, ("Extra data: \n")); - dump_data(5, extra_data.data, extra_data.length); - data_blob_free(&secblob); - data_blob_free(&extra_data); if (ntlmssp_command != NTLMSSP_NEGOTIATE) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); @@ -307,41 +312,44 @@ static int reply_spnego_negotiate(connection_struct *conn, return the flags we want. Obviously this is not correct */ chal_flags = NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_LM_KEY | + NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_CHAL_TARGET_INFO; { - DATA_BLOB domain_blob, netbios_blob, realm_blob; + DATA_BLOB domain_blob, struct_blob; + fstring dnsname, dnsdomname; msrpc_gen(&domain_blob, "U", lp_workgroup()); - msrpc_gen(&netbios_blob, - "U", - global_myname); - - msrpc_gen(&realm_blob, - "U", - lp_realm()); - + fstrcpy(dnsdomname, lp_realm()); + strlower(dnsdomname); + + fstrcpy(dnsname, global_myname); + fstrcat(dnsname, "."); + fstrcat(dnsname, lp_realm()); + strlower(dnsname); - msrpc_gen(&chal, "CddddbBBBB", + msrpc_gen(&struct_blob, "aaaaa", + 2, lp_workgroup(), + 1, global_myname, + 4, dnsdomname, + 3, dnsname, + 0, ""); + + msrpc_gen(&chal, "CdUdbddB", "NTLMSSP", NTLMSSP_CHALLENGE, - 0, - 0x30, /* ?? */ + lp_workgroup(), chal_flags, cryptkey, 8, - domain_blob.data, domain_blob.length, - domain_blob.data, domain_blob.length, - netbios_blob.data, netbios_blob.length, - realm_blob.data, realm_blob.length); + 0, 0, + struct_blob.data, struct_blob.length); data_blob_free(&domain_blob); - data_blob_free(&netbios_blob); - data_blob_free(&realm_blob); + data_blob_free(&struct_blob); } if (!spnego_gen_challenge(&spnego_chal, &chal, &chal)) { @@ -351,7 +359,7 @@ static int reply_spnego_negotiate(connection_struct *conn, } /* now tell the client to send the auth packet */ - reply_sesssetup_blob(conn, outbuf, spnego_chal); + reply_sesssetup_blob(conn, outbuf, spnego_chal, NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED)); data_blob_free(&chal); data_blob_free(&spnego_chal); @@ -368,7 +376,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, DATA_BLOB blob1) { - DATA_BLOB auth; + DATA_BLOB auth, response; char *workgroup = NULL, *user = NULL, *machine = NULL; DATA_BLOB lmhash, nthash, sess_key; DATA_BLOB plaintext_password = data_blob(NULL, 0); @@ -413,6 +421,13 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, DEBUG(3,("Got user=[%s] workgroup=[%s] machine=[%s] len1=%d len2=%d\n", user, workgroup, machine, lmhash.length, nthash.length)); + /* the client has given us its machine name (which we otherwise would not get on port 445). + we need to possibly reload smb.conf if smb.conf includes depend on the machine name */ + + set_remote_machine_name(machine); + + reload_services(True); + #if 0 file_save("nthash1.dat", nthash.data, nthash.length); file_save("lmhash1.dat", lmhash.data, lmhash.length); @@ -481,8 +496,12 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); - - return chain_reply(inbuf,outbuf,length,bufsize); + + response = spnego_gen_auth_response(); + reply_sesssetup_blob(conn, outbuf, response, 0); + + /* and tell smbd that we have already replied to this packet */ + return -1; } @@ -594,7 +613,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, extern BOOL global_encrypted_passwords_negotiated; extern BOOL global_spnego_negotiated; extern int Protocol; - extern fstring remote_machine; extern userdom_struct current_user_info; extern int max_send; @@ -630,8 +648,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if (Protocol < PROTOCOL_NT1) { uint16 passlen1 = SVAL(inbuf,smb_vwv7); - if (passlen1 > MAX_PASS_LEN) { - return ERROR_DOS(ERRDOS,ERRbuftoosmall); + if ((passlen1 > MAX_PASS_LEN) || (passlen1 > smb_bufrem(inbuf, smb_buf(inbuf)))) { + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } if (doencrypt) { @@ -665,13 +683,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } } - if (passlen1 > MAX_PASS_LEN) { - return ERROR_DOS(ERRDOS,ERRbuftoosmall); - } - - passlen1 = MIN(passlen1, MAX_PASS_LEN); - passlen2 = MIN(passlen2, MAX_PASS_LEN); - if (!doencrypt) { /* both Win95 and WinNT stuff up the password lengths for non-encrypting systems. Uggh. @@ -689,19 +700,29 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, passlen2 = 0; } + /* check for nasty tricks */ + if (passlen1 > MAX_PASS_LEN || passlen1 > smb_bufrem(inbuf, p)) { + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + + if (passlen2 > MAX_PASS_LEN || passlen2 > smb_bufrem(inbuf, p+passlen1)) { + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + /* Save the lanman2 password and the NT md4 password. */ if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) { doencrypt = False; } - + if (doencrypt) { lm_resp = data_blob(p, passlen1); nt_resp = data_blob(p+passlen1, passlen2); } else { - plaintext_password = data_blob(p, passlen1+1); - /* Ensure null termination */ - plaintext_password.data[passlen1] = 0; + pstring pass; + srvstr_pull(inbuf, pass, smb_buf(inbuf), + sizeof(pass), passlen1, STR_TERMINATE); + plaintext_password = data_blob(pass, strlen(pass)+1); } p += passlen1 + passlen2; @@ -720,7 +741,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, remote_machine)); + DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, get_remote_machine_name())); if (*user) { if (global_spnego_negotiated) { -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/smbd/sesssetup.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 77f93812dd..b9af720008 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -160,12 +160,12 @@ static int reply_spnego_kerberos(connection_struct *conn, ads_destroy(&ads); /* the password is good - let them in */ - pw = smb_getpwnam(user,False); + pw = Get_Pwnam(user); if (!pw && !strstr(user, lp_winbind_separator())) { char *user2; /* try it with a winbind domain prefix */ asprintf(&user2, "%s%s%s", lp_workgroup(), lp_winbind_separator(), user); - pw = smb_getpwnam(user2,False); + pw = Get_Pwnam(user2); if (pw) { free(user); user = user2; @@ -177,9 +177,9 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_NO_SUCH_USER); } - if (!make_server_info_pw(&server_info,pw)) { + if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info,pw))) { DEBUG(1,("make_server_info_from_pw failed!\n")); - return ERROR_NT(NT_STATUS_NO_MEMORY); + return ERROR_NT(ret); } sess_vuid = register_vuid(server_info, user); @@ -294,8 +294,6 @@ static int reply_spnego_negotiate(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - DEBUG(3,("Got neg_flags=0x%08x\n", neg_flags)); - debug_ntlmssp_flags(neg_flags); if (ntlmssp_auth_context) { @@ -324,12 +322,12 @@ static int reply_spnego_negotiate(connection_struct *conn, "U", lp_workgroup()); - fstrcpy(dnsdomname, lp_realm()); + fstrcpy(dnsdomname, (SEC_ADS == lp_security())?lp_realm():""); strlower(dnsdomname); fstrcpy(dnsname, global_myname); fstrcat(dnsname, "."); - fstrcat(dnsname, lp_realm()); + fstrcat(dnsname, dnsdomname); strlower(dnsname); msrpc_gen(&struct_blob, "aaaaa", @@ -441,14 +439,14 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, auth_flags |= AUTH_FLAG_NTLM_RESP; } else if (nthash.length > 24) { auth_flags |= AUTH_FLAG_NTLMv2_RESP; - } + }; + + nt_status = make_user_info_map(&user_info, user, workgroup, machine, + lmhash, nthash, plaintext_password, + auth_flags, True); - if (!make_user_info_map(&user_info, - user, workgroup, - machine, - lmhash, nthash, - plaintext_password, - auth_flags, True)) { + /* it looks a bit weird, but this function returns int type... */ + if (!NT_STATUS_IS_OK(nt_status)) { return ERROR_NT(NT_STATUS_NO_MEMORY); } @@ -623,7 +621,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, NTSTATUS nt_status; BOOL doencrypt = global_encrypted_passwords_negotiated; - + START_PROFILE(SMBsesssetupX); ZERO_STRUCT(lm_resp); @@ -736,7 +734,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* don't allow for weird usernames or domains */ alpha_strcpy(user, user, ". _-$", sizeof(user)); - alpha_strcpy(domain, domain, ". _-", sizeof(domain)); + alpha_strcpy(domain, domain, ". _-@", sizeof(domain)); if (strstr(user, "..") || strstr(domain,"..")) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -778,11 +776,9 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, 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)) { - nt_status = NT_STATUS_NO_MEMORY; - } else { + nt_status = make_user_info_for_reply_enc(&user_info, user, domain, + lm_resp, nt_resp); + if (NT_STATUS_IS_OK(nt_status)) { nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context, user_info, &server_info); -- cgit From 2f194322d419350f35a48dff750066894d68eccf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2002 23:20:50 +0000 Subject: Removed global_myworkgroup, global_myname, global_myscope. Added liberal dashes of const. This is a rather large check-in, some things may break. It does compile though :-). Jeremy. (This used to be commit f755711df8f74f9b8e8c1a2b0d07d02a931eeb89) --- source3/smbd/sesssetup.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index b9af720008..4ab1063217 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -247,7 +247,6 @@ static int reply_spnego_negotiate(connection_struct *conn, const uint8 *cryptkey; BOOL got_kerberos = False; NTSTATUS nt_status; - extern pstring global_myname; char *cliname=NULL, *domname=NULL; /* parse out the OIDs and the first sec blob */ @@ -325,14 +324,14 @@ static int reply_spnego_negotiate(connection_struct *conn, fstrcpy(dnsdomname, (SEC_ADS == lp_security())?lp_realm():""); strlower(dnsdomname); - fstrcpy(dnsname, global_myname); + fstrcpy(dnsname, global_myname()); fstrcat(dnsname, "."); fstrcat(dnsname, dnsdomname); strlower(dnsname); msrpc_gen(&struct_blob, "aaaaa", 2, lp_workgroup(), - 1, global_myname, + 1, global_myname(), 4, dnsdomname, 3, dnsname, 0, ""); -- cgit From 91b7ac9fb955124263d0e86801db972590dabfb9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 20 Nov 2002 00:53:24 +0000 Subject: merged the %U changes to 3.0 (This used to be commit 58fa6bfee8ba35cc182c18c980e0a4040ddd7d09) --- source3/smbd/sesssetup.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 4ab1063217..9d708bd5a0 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -159,6 +159,11 @@ static int reply_spnego_kerberos(connection_struct *conn, } ads_destroy(&ads); + /* setup the string used by %U */ + sub_set_smb_name(user); + + reload_services(True); + /* the password is good - let them in */ pw = Get_Pwnam(user); if (!pw && !strstr(user, lp_winbind_separator())) { @@ -423,6 +428,9 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, set_remote_machine_name(machine); + /* setup the string used by %U */ + sub_set_smb_name(user); + reload_services(True); #if 0 @@ -749,6 +757,9 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_NT(NT_STATUS_UNSUCCESSFUL); } pstrcpy(sub_user, user); + + /* setup the string used by %U */ + sub_set_smb_name(user); } else { pstrcpy(sub_user, lp_guestaccount()); } -- cgit From 95ce704fe6aab58ac68940ee3a25fb8e0796caba Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 2 Jan 2003 20:43:17 +0000 Subject: pstring/fstring missmatches found by Andrew Bartlett. Jeremy. (This used to be commit 666861b1e263370f6ba8fa4108842f52a81d8b83) --- source3/smbd/sesssetup.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 9d708bd5a0..f8e8e017e0 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -609,8 +609,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, DATA_BLOB lm_resp; DATA_BLOB nt_resp; DATA_BLOB plaintext_password; - pstring user; - pstring sub_user; /* Sainitised username for substituion */ + fstring user; + fstring sub_user; /* Sainitised username for substituion */ fstring domain; fstring native_os; fstring native_lanman; @@ -756,15 +756,15 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at 'normal' session setup after negotiating spnego.\n")); return ERROR_NT(NT_STATUS_UNSUCCESSFUL); } - pstrcpy(sub_user, user); + fstrcpy(sub_user, user); /* setup the string used by %U */ sub_set_smb_name(user); } else { - pstrcpy(sub_user, lp_guestaccount()); + fstrcpy(sub_user, lp_guestaccount()); } - pstrcpy(current_user_info.smb_name,sub_user); + fstrcpy(current_user_info.smb_name,sub_user); reload_services(True); -- cgit From 1cba0a757970ffd8b81d61c88965010968ab3eff Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 28 Jan 2003 12:07:02 +0000 Subject: Merge from HEAD: - NTLMSSP over SPENGO (sesssion-setup-and-x) cleanup and code refactor. - also consequential changes to the NTLMSSP and SPNEGO parsing functions - and the client code that uses the same functions - Add ntlm_auth, a NTLMSSP authentication interface for use by applications like Squid and Apache. - also consquential changes to use common code for base64 encode/decode. - Winbind changes to support ntlm_auth (I don't want this program to need to read smb.conf, instead getting all it's details over the pipe). - nmbd changes for fstrcat() instead of fstrcpy(). Andrew Bartlett (This used to be commit fbb46da79cf322570a7e3318100c304bbf33409e) --- source3/smbd/sesssetup.c | 371 ++++++++++++++--------------------------------- 1 file changed, 109 insertions(+), 262 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index f8e8e017e0..679f040b2c 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -23,7 +23,8 @@ #include "includes.h" uint32 global_client_caps = 0; -static struct auth_context *ntlmssp_auth_context = NULL; + +static struct auth_ntlmssp_state *global_ntlmssp_state; /* on a logon error possibly map the error to success if "map to guest" @@ -67,6 +68,37 @@ static void add_signature(char *outbuf) set_message_end(outbuf,p); } +/**************************************************************************** +send a security blob via a session setup reply +****************************************************************************/ +static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, + DATA_BLOB blob, NTSTATUS nt_status) +{ + char *p; + + set_message(outbuf,4,0,True); + + /* we set NT_STATUS_MORE_PROCESSING_REQUIRED to tell the other end + that we aren't finished yet */ + + nt_status = nt_status_squash(nt_status); + SIVAL(outbuf, smb_rcls, NT_STATUS_V(nt_status)); + SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */ + SSVAL(outbuf, smb_vwv3, blob.length); + p = smb_buf(outbuf); + + /* should we cap this? */ + memcpy(p, blob.data, blob.length); + p += blob.length; + + p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); + set_message_end(outbuf,p); + + return send_smb(smbd_server_fd(),outbuf); +} + /**************************************************************************** Do a 'guest' logon, getting back the ****************************************************************************/ @@ -209,30 +241,54 @@ static int reply_spnego_kerberos(connection_struct *conn, /**************************************************************************** -send a security blob via a session setup reply -****************************************************************************/ -static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, - DATA_BLOB blob, uint32 errcode) + send a session setup reply, wrapped in SPNEGO. + get vuid and check first. + end the NTLMSSP exchange context if we are OK/complete fail +***************************************************************************/ +static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, + AUTH_NTLMSSP_STATE **auth_ntlmssp_state, + DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status) { - char *p; + BOOL ret; + DATA_BLOB response; + struct auth_serversupplied_info *server_info; + server_info = (*auth_ntlmssp_state)->server_info; - set_message(outbuf,4,0,True); + if (!NT_STATUS_IS_OK(nt_status)) { + nt_status = do_map_to_guest(nt_status, + &server_info, + (*auth_ntlmssp_state)->ntlmssp_state->user, + (*auth_ntlmssp_state)->ntlmssp_state->domain); + } - /* we set NT_STATUS_MORE_PROCESSING_REQUIRED to tell the other end - that we aren't finished yet */ + if (NT_STATUS_IS_OK(nt_status)) { + int sess_vuid; + sess_vuid = register_vuid(server_info, (*auth_ntlmssp_state)->ntlmssp_state->user /* check this for weird */); + + if (sess_vuid == -1) { + nt_status = NT_STATUS_LOGON_FAILURE; + } else { + + set_message(outbuf,4,0,True); + SSVAL(outbuf, smb_vwv3, 0); + + if ((*auth_ntlmssp_state)->server_info->guest) { + SSVAL(outbuf,smb_vwv2,1); + } + + SSVAL(outbuf,smb_uid,sess_vuid); + } + } - SIVAL(outbuf, smb_rcls, errcode); - SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */ - SSVAL(outbuf, smb_vwv3, blob.length); - p = smb_buf(outbuf); - memcpy(p, blob.data, blob.length); - p += blob.length; - p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); - set_message_end(outbuf,p); - - return send_smb(smbd_server_fd(),outbuf); + response = spnego_gen_auth_response(ntlmssp_blob, nt_status); + ret = reply_sesssetup_blob(conn, outbuf, response, nt_status); + data_blob_free(&response); + + if (!ret || !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + auth_ntlmssp_end(&global_ntlmssp_state); + } + + return ret; } /**************************************************************************** @@ -247,12 +303,9 @@ static int reply_spnego_negotiate(connection_struct *conn, char *OIDs[ASN1_MAX_OIDS]; DATA_BLOB secblob; int i; - uint32 ntlmssp_command, neg_flags, chal_flags; - DATA_BLOB chal, spnego_chal; - const uint8 *cryptkey; + DATA_BLOB chal; BOOL got_kerberos = False; NTSTATUS nt_status; - char *cliname=NULL, *domname=NULL; /* parse out the OIDs and the first sec blob */ if (!parse_negTokenTarg(blob1, OIDs, &secblob)) { @@ -278,95 +331,26 @@ static int reply_spnego_negotiate(connection_struct *conn, } #endif - /* parse the NTLMSSP packet */ -#if 0 - file_save("secblob.dat", secblob.data, secblob.length); -#endif - - if (!msrpc_parse(&secblob, "CddAA", - "NTLMSSP", - &ntlmssp_command, - &neg_flags, - &cliname, - &domname)) { - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - - data_blob_free(&secblob); - - if (ntlmssp_command != NTLMSSP_NEGOTIATE) { - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - - debug_ntlmssp_flags(neg_flags); - - if (ntlmssp_auth_context) { - (ntlmssp_auth_context->free)(&ntlmssp_auth_context); + if (global_ntlmssp_state) { + auth_ntlmssp_end(&global_ntlmssp_state); } - if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&ntlmssp_auth_context))) { + nt_status = auth_ntlmssp_start(&global_ntlmssp_state); + if (!NT_STATUS_IS_OK(nt_status)) { return ERROR_NT(nt_status); } - 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 */ - - chal_flags = NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_CHAL_TARGET_INFO; - - { - DATA_BLOB domain_blob, struct_blob; - fstring dnsname, dnsdomname; - - msrpc_gen(&domain_blob, - "U", - lp_workgroup()); - - fstrcpy(dnsdomname, (SEC_ADS == lp_security())?lp_realm():""); - strlower(dnsdomname); - - fstrcpy(dnsname, global_myname()); - fstrcat(dnsname, "."); - fstrcat(dnsname, dnsdomname); - strlower(dnsname); - - msrpc_gen(&struct_blob, "aaaaa", - 2, lp_workgroup(), - 1, global_myname(), - 4, dnsdomname, - 3, dnsname, - 0, ""); - - msrpc_gen(&chal, "CdUdbddB", - "NTLMSSP", - NTLMSSP_CHALLENGE, - lp_workgroup(), - chal_flags, - cryptkey, 8, - 0, 0, - struct_blob.data, struct_blob.length); - - data_blob_free(&domain_blob); - data_blob_free(&struct_blob); - } - - if (!spnego_gen_challenge(&spnego_chal, &chal, &chal)) { - DEBUG(3,("Failed to generate challenge\n")); - data_blob_free(&chal); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } + nt_status = auth_ntlmssp_update(global_ntlmssp_state, + secblob, &chal); - /* now tell the client to send the auth packet */ - reply_sesssetup_blob(conn, outbuf, spnego_chal, NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED)); + data_blob_free(&secblob); + reply_spnego_ntlmssp(conn, outbuf, &global_ntlmssp_state, + &chal, nt_status); + data_blob_free(&chal); - data_blob_free(&spnego_chal); - /* and tell smbd that we have already replied to this packet */ + /* already replied */ return -1; } @@ -378,23 +362,8 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, DATA_BLOB blob1) { - DATA_BLOB auth, response; - char *workgroup = NULL, *user = NULL, *machine = NULL; - DATA_BLOB lmhash, nthash, sess_key; - DATA_BLOB plaintext_password = data_blob(NULL, 0); - uint32 ntlmssp_command, neg_flags; + DATA_BLOB auth, auth_reply; NTSTATUS nt_status; - int sess_vuid; - BOOL as_guest; - uint32 auth_flags = AUTH_FLAG_NONE; - auth_usersupplied_info *user_info = NULL; - auth_serversupplied_info *server_info = NULL; - - /* we must have setup the auth context by now */ - if (!ntlmssp_auth_context) { - DEBUG(2,("ntlmssp_auth_context is NULL in reply_spnego_auth\n")); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } if (!spnego_parse_auth(blob1, &auth)) { #if 0 @@ -403,157 +372,32 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - /* now the NTLMSSP encoded auth hashes */ - if (!msrpc_parse(&auth, "CdBBUUUBd", - "NTLMSSP", - &ntlmssp_command, - &lmhash, - &nthash, - &workgroup, - &user, - &machine, - &sess_key, - &neg_flags)) { - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } + nt_status = auth_ntlmssp_update(global_ntlmssp_state, + auth, &auth_reply); data_blob_free(&auth); - data_blob_free(&sess_key); - - DEBUG(3,("Got user=[%s] workgroup=[%s] machine=[%s] len1=%d len2=%d\n", - user, workgroup, machine, lmhash.length, nthash.length)); - - /* the client has given us its machine name (which we otherwise would not get on port 445). - we need to possibly reload smb.conf if smb.conf includes depend on the machine name */ - - set_remote_machine_name(machine); - - /* setup the string used by %U */ - sub_set_smb_name(user); - - reload_services(True); - -#if 0 - file_save("nthash1.dat", nthash.data, nthash.length); - file_save("lmhash1.dat", lmhash.data, lmhash.length); -#endif - - if (lmhash.length) { - auth_flags |= AUTH_FLAG_LM_RESP; - } - - if (nthash.length == 24) { - auth_flags |= AUTH_FLAG_NTLM_RESP; - } else if (nthash.length > 24) { - auth_flags |= AUTH_FLAG_NTLMv2_RESP; - }; - - nt_status = make_user_info_map(&user_info, user, workgroup, machine, - lmhash, nthash, plaintext_password, - auth_flags, True); - - /* it looks a bit weird, but this function returns int type... */ - if (!NT_STATUS_IS_OK(nt_status)) { - return ERROR_NT(NT_STATUS_NO_MEMORY); - } - - 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); - } - - SAFE_FREE(workgroup); - SAFE_FREE(machine); - - (ntlmssp_auth_context->free)(&ntlmssp_auth_context); - - free_user_info(&user_info); - - data_blob_free(&lmhash); - - data_blob_free(&nthash); - - if (!NT_STATUS_IS_OK(nt_status)) { - SAFE_FREE(user); - return ERROR_NT(nt_status_squash(nt_status)); - } - - as_guest = server_info->guest; - - sess_vuid = register_vuid(server_info, user); - free_server_info(&server_info); - - SAFE_FREE(user); - - if (sess_vuid == -1) { - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - - set_message(outbuf,4,0,True); - SSVAL(outbuf, smb_vwv3, 0); - if (as_guest) { - SSVAL(outbuf,smb_vwv2,1); - } - - add_signature(outbuf); - - SSVAL(outbuf,smb_uid,sess_vuid); - SSVAL(inbuf,smb_uid,sess_vuid); - - response = spnego_gen_auth_response(); - reply_sesssetup_blob(conn, outbuf, response, 0); + reply_spnego_ntlmssp(conn, outbuf, &global_ntlmssp_state, + &auth_reply, nt_status); + + data_blob_free(&auth_reply); /* and tell smbd that we have already replied to this packet */ return -1; } -/**************************************************************************** -reply to a session setup spnego anonymous packet -****************************************************************************/ -static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *outbuf, - int length, int bufsize) -{ - int sess_vuid; - auth_serversupplied_info *server_info = NULL; - NTSTATUS nt_status; - - nt_status = check_guest_password(&server_info); - - if (!NT_STATUS_IS_OK(nt_status)) { - return ERROR_NT(nt_status_squash(nt_status)); - } - - sess_vuid = register_vuid(server_info, lp_guestaccount()); - - free_server_info(&server_info); - - if (sess_vuid == -1) { - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - - set_message(outbuf,4,0,True); - SSVAL(outbuf, smb_vwv3, 0); - add_signature(outbuf); - - SSVAL(outbuf,smb_uid,sess_vuid); - SSVAL(inbuf,smb_uid,sess_vuid); - - return chain_reply(inbuf,outbuf,length,bufsize); -} - - /**************************************************************************** reply to a session setup command ****************************************************************************/ -static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,char *outbuf, +static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, + char *outbuf, int length,int bufsize) { uint8 *p; DATA_BLOB blob1; int ret; + size_t bufrem; DEBUG(3,("Doing spnego session setup\n")); @@ -564,12 +408,13 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf,cha p = (uint8 *)smb_buf(inbuf); if (SVAL(inbuf, smb_vwv7) == 0) { - /* an anonymous request */ - return reply_spnego_anonymous(conn, inbuf, outbuf, length, bufsize); + /* an invalid request */ + return ERROR_NT(NT_STATUS_LOGON_FAILURE); } + bufrem = smb_bufrem(inbuf, p); /* pull the spnego blob */ - blob1 = data_blob(p, SVAL(inbuf, smb_vwv7)); + blob1 = data_blob(p, MIN(bufrem, SVAL(inbuf, smb_vwv7))); #if 0 file_save("negotiate.dat", blob1.data, blob1.length); @@ -786,6 +631,10 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, nt_status = check_guest_password(&server_info); } else if (doencrypt) { + if (!negprot_global_auth_context) { + DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted session setup without negprot denied!\n")); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } nt_status = make_user_info_for_reply_enc(&user_info, user, domain, lm_resp, nt_resp); if (NT_STATUS_IS_OK(nt_status)) { @@ -830,10 +679,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } /* it's ok - setup a reply */ - if (Protocol < PROTOCOL_NT1) { - set_message(outbuf,3,0,True); - } else { - set_message(outbuf,3,0,True); + set_message(outbuf,3,0,True); + if (Protocol >= PROTOCOL_NT1) { add_signature(outbuf); /* perhaps grab OS version here?? */ } -- cgit From 67acaa00264e40f92dc06855a913138df676abe5 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 7 Feb 2003 16:20:42 +0000 Subject: check pointer before dereferencing it (This used to be commit 8712bd1f8eb5321278e7c57bfdc7bdddbdaf1424) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 679f040b2c..bb7d17be56 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -272,7 +272,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, set_message(outbuf,4,0,True); SSVAL(outbuf, smb_vwv3, 0); - if ((*auth_ntlmssp_state)->server_info->guest) { + if ((*auth_ntlmssp_state)->server_info && (*auth_ntlmssp_state)->server_info->guest) { SSVAL(outbuf,smb_vwv2,1); } -- cgit From e72ecdc862804339912325fe848401e8ec57cde7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 02:35:54 +0000 Subject: Merge of server-side authentication changes to 3.0: - user_ok() and user_in_group() now take a list of groups, instead of looking for the user in the members of all groups. - The 'server_info' returned from the authentication is now kept around - in future we won't copy the sesion key, username etc, we will just referece them directly. - rhosts upgraded to use the SAM if possible, otherwise fake up based on getpwnam(). - auth_util code to deal with groups upgraded to deal with non-winbind domain members again. Andrew Bartlett (This used to be commit 74b5436c75114170ce7c780c19226103d0df9060) --- source3/smbd/sesssetup.c | 60 ++++++++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 35 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index bb7d17be56..eafe805aba 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -148,6 +148,7 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB auth_data; auth_serversupplied_info *server_info = NULL; ADS_STRUCT *ads; + BOOL foreign = False; if (!spnego_parse_krb5_wrap(*secblob, &ticket)) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); @@ -168,6 +169,8 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } + data_blob_free(&auth_data); + DEBUG(3,("Ticket name is [%s]\n", client)); p = strchr_m(client, '@'); @@ -183,12 +186,20 @@ static int reply_spnego_kerberos(connection_struct *conn, if (!lp_allow_trusted_domains()) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - /* this gives a fully qualified user name (ie. with full realm). - that leads to very long usernames, but what else can we do? */ - asprintf(&user, "%s%s%s", p+1, lp_winbind_separator(), client); - } else { - user = strdup(client); + foreign = True; + } + + /* this gives a fully qualified user name (ie. with full realm). + that leads to very long usernames, but what else can we do? */ + asprintf(&user, "%s%s%s", p+1, lp_winbind_separator(), client); + + pw = Get_Pwnam(user); + if (!pw && !foreign) { + pw = Get_Pwnam(client); + SAFE_FREE(user); + user = smb_xstrdup(client); } + ads_destroy(&ads); /* setup the string used by %U */ @@ -196,19 +207,6 @@ static int reply_spnego_kerberos(connection_struct *conn, reload_services(True); - /* the password is good - let them in */ - pw = Get_Pwnam(user); - if (!pw && !strstr(user, lp_winbind_separator())) { - char *user2; - /* try it with a winbind domain prefix */ - asprintf(&user2, "%s%s%s", lp_workgroup(), lp_winbind_separator(), user); - pw = Get_Pwnam(user2); - if (pw) { - free(user); - user = user2; - } - } - if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); return ERROR_NT(NT_STATUS_NO_SUCH_USER); @@ -219,10 +217,10 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(ret); } + /* register_vuid keeps the server info */ sess_vuid = register_vuid(server_info, user); free(user); - free_server_info(&server_info); if (sess_vuid == -1) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); @@ -263,8 +261,10 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, if (NT_STATUS_IS_OK(nt_status)) { int sess_vuid; - sess_vuid = register_vuid(server_info, (*auth_ntlmssp_state)->ntlmssp_state->user /* check this for weird */); - + /* register_vuid keeps the server info */ + sess_vuid = register_vuid(server_info, (*auth_ntlmssp_state)->ntlmssp_state->user); + (*auth_ntlmssp_state)->server_info = NULL; + if (sess_vuid == -1) { nt_status = NT_STATUS_LOGON_FAILURE; } else { @@ -272,7 +272,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, set_message(outbuf,4,0,True); SSVAL(outbuf, smb_vwv3, 0); - if ((*auth_ntlmssp_state)->server_info && (*auth_ntlmssp_state)->server_info->guest) { + if (server_info->guest) { SSVAL(outbuf,smb_vwv2,1); } @@ -285,7 +285,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, data_blob_free(&response); if (!ret || !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - auth_ntlmssp_end(&global_ntlmssp_state); + auth_ntlmssp_end(auth_ntlmssp_state); } return ret; @@ -463,7 +463,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, extern BOOL global_encrypted_passwords_negotiated; extern BOOL global_spnego_negotiated; extern int Protocol; - extern userdom_struct current_user_info; extern int max_send; auth_usersupplied_info *user_info = NULL; @@ -584,13 +583,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, domain,native_os,native_lanman)); } - /* don't allow for weird usernames or domains */ - alpha_strcpy(user, user, ". _-$", sizeof(user)); - alpha_strcpy(domain, domain, ". _-@", sizeof(domain)); - if (strstr(user, "..") || strstr(domain,"..")) { - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, get_remote_machine_name())); if (*user) { @@ -609,7 +601,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, fstrcpy(sub_user, lp_guestaccount()); } - fstrcpy(current_user_info.smb_name,sub_user); + sub_set_smb_name(sub_user); reload_services(True); @@ -692,15 +684,13 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* register the name and uid as being validated, so further connections 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); - - free_server_info(&server_info); if (sess_vuid == -1) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); -- cgit From 0d30cdf66c4e186e20a09e1e8b39d501e662ae50 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 27 Feb 2003 21:22:36 +0000 Subject: additional fix for CR 601 * distinguish WinXP from Win2k * add a 1/3 of a second delay in OpenPrinter in order to trigger a LAN/WAN optimization in 2k clients. (This used to be commit c7712fa054d21b4884a78b7ea6c0fb8b3d637c6b) --- source3/smbd/sesssetup.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index eafe805aba..b0ef78f447 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -581,6 +581,21 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, p += srvstr_pull_buf(inbuf, native_lanman, p, sizeof(native_lanman), STR_TERMINATE); DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n", domain,native_os,native_lanman)); + + /* + * we distinguish between 2K and XP by the "Native Lan Manager" string + * WinXP => "Windows 2002 5.1" + * Win2k => "Windows 2000 5.0" + * NT4 => "Windows NT 4.0" + * Win9x => "Windows 4.0" + */ + + if ( ra_type == RA_WIN2K ) { + if ( 0 == strcmp( native_lanman, "Windows 2002 5.1" ) ) + set_remote_arch( RA_WINXP ); + } + + } DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, get_remote_machine_name())); -- cgit From fd56ede2b6c6590616d66b524734dacfaf1a8f1b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 12 Mar 2003 15:41:39 +0000 Subject: adding some initiaial code to sert %a to Win2K3 (using Native LanMan string from .NET RC2) (This used to be commit e074cab810f9299d0b27881cddf8a74f10fe233e) --- source3/smbd/sesssetup.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index b0ef78f447..7e28592eeb 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -593,6 +593,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if ( ra_type == RA_WIN2K ) { if ( 0 == strcmp( native_lanman, "Windows 2002 5.1" ) ) set_remote_arch( RA_WINXP ); + else if ( 0 == strcmp( native_lanman, "Windows .NET 5.2" ) ) + set_remote_arch( RA_WIN2K3 ); } -- cgit From 128e7edaaf7cf6ed590c8b7260303520f7b773a0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 14 Mar 2003 23:06:06 +0000 Subject: fix WinXP & Win2K3 remote_arch and check pointer in ntlmssp code before dereferencing (This used to be commit 7bc5fc729f67ae16e09ea67efa9e2b8e2ba41c8f) --- source3/smbd/sesssetup.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7e28592eeb..7f125de583 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -372,8 +372,10 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - nt_status = auth_ntlmssp_update(global_ntlmssp_state, - auth, &auth_reply); + if ( global_ntlmssp_state ) { + nt_status = auth_ntlmssp_update(global_ntlmssp_state, + auth, &auth_reply); + } data_blob_free(&auth); @@ -398,6 +400,10 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, DATA_BLOB blob1; int ret; size_t bufrem; + fstring native_os, native_lanman; + char *p2; + uint16 data_blob_len = SVAL(inbuf, smb_vwv7); + enum remote_arch_types ra_type = get_remote_arch(); DEBUG(3,("Doing spnego session setup\n")); @@ -407,19 +413,27 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, p = (uint8 *)smb_buf(inbuf); - if (SVAL(inbuf, smb_vwv7) == 0) { + if (data_blob_len == 0) { /* an invalid request */ return ERROR_NT(NT_STATUS_LOGON_FAILURE); } bufrem = smb_bufrem(inbuf, p); /* pull the spnego blob */ - blob1 = data_blob(p, MIN(bufrem, SVAL(inbuf, smb_vwv7))); + blob1 = data_blob(p, MIN(bufrem, data_blob_len)); #if 0 file_save("negotiate.dat", blob1.data, blob1.length); #endif + p2 = inbuf + smb_vwv13 + data_blob_len; + p2 += srvstr_pull_buf(inbuf, native_os, p2, sizeof(native_os), STR_TERMINATE); + p2 += srvstr_pull_buf(inbuf, native_lanman, p2, sizeof(native_lanman), STR_TERMINATE); + DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s]\n", native_os, native_lanman)); + + if ( ra_type == RA_WIN2K ) + ra_lanman_string( native_lanman ); + if (blob1.data[0] == ASN1_APPLICATION(0)) { /* its a negTokenTarg packet */ ret = reply_spnego_negotiate(conn, inbuf, outbuf, length, bufsize, blob1); @@ -582,21 +596,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n", domain,native_os,native_lanman)); - /* - * we distinguish between 2K and XP by the "Native Lan Manager" string - * WinXP => "Windows 2002 5.1" - * Win2k => "Windows 2000 5.0" - * NT4 => "Windows NT 4.0" - * Win9x => "Windows 4.0" - */ - - if ( ra_type == RA_WIN2K ) { - if ( 0 == strcmp( native_lanman, "Windows 2002 5.1" ) ) - set_remote_arch( RA_WINXP ); - else if ( 0 == strcmp( native_lanman, "Windows .NET 5.2" ) ) - set_remote_arch( RA_WIN2K3 ); - } - + if ( ra_type == RA_WIN2K ) + ra_lanman_string( native_lanman ); } -- cgit From ec458fa87e3ee858be39671f575e21a9350674b6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Mar 2003 22:45:16 +0000 Subject: Merge from HEAD - sync up SessionSetup code to HEAD, including Luke Howard's session key and auth verifier patches. Andrew Bartlett (This used to be commit 3f9616a68a855acbae3f405c27ee2358fbe7ba2c) --- source3/smbd/sesssetup.c | 82 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 27 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7f125de583..e36760c148 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 1998-2001 Copyright (C) Andrew Bartlett 2001 Copyright (C) Jim McDonough 2002 + Copyright (C) Luke Howard 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -38,16 +39,14 @@ static NTSTATUS do_map_to_guest(NTSTATUS status, auth_serversupplied_info **serv (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) { DEBUG(3,("No such user %s [%s] - using guest account\n", user, domain)); - make_server_info_guest(server_info); - status = NT_STATUS_OK; + status = make_server_info_guest(server_info); } } if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) { if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) { DEBUG(3,("Registered username %s for guest access\n",user)); - make_server_info_guest(server_info); - status = NT_STATUS_OK; + status = make_server_info_guest(server_info); } } @@ -146,11 +145,14 @@ static int reply_spnego_kerberos(connection_struct *conn, int sess_vuid; NTSTATUS ret; DATA_BLOB auth_data; + DATA_BLOB ap_rep, ap_rep_wrapped, response; auth_serversupplied_info *server_info = NULL; ADS_STRUCT *ads; + uint8 session_key[16]; + uint8 tok_id[2]; BOOL foreign = False; - if (!spnego_parse_krb5_wrap(*secblob, &ticket)) { + if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -162,7 +164,7 @@ static int reply_spnego_kerberos(connection_struct *conn, ads->auth.realm = strdup(lp_realm()); - ret = ads_verify_ticket(ads, &ticket, &client, &auth_data); + ret = ads_verify_ticket(ads, &ticket, &client, &auth_data, &ap_rep, session_key); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("Failed to verify incoming ticket!\n")); ads_destroy(&ads); @@ -177,6 +179,7 @@ static int reply_spnego_kerberos(connection_struct *conn, if (!p) { DEBUG(3,("Doesn't look like a valid principal\n")); ads_destroy(&ads); + data_blob_free(&ap_rep); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -184,6 +187,7 @@ static int reply_spnego_kerberos(connection_struct *conn, if (strcasecmp(p+1, ads->auth.realm) != 0) { DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1)); if (!lp_allow_trusted_domains()) { + data_blob_free(&ap_rep); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } foreign = True; @@ -209,31 +213,51 @@ static int reply_spnego_kerberos(connection_struct *conn, if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); + data_blob_free(&ap_rep); return ERROR_NT(NT_STATUS_NO_SUCH_USER); } if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info,pw))) { DEBUG(1,("make_server_info_from_pw failed!\n")); + data_blob_free(&ap_rep); return ERROR_NT(ret); } - + + /* Copy out the session key from the AP_REQ. */ + memcpy(server_info->session_key, session_key, sizeof(session_key)); + /* register_vuid keeps the server info */ sess_vuid = register_vuid(server_info, user); free(user); if (sess_vuid == -1) { - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + ret = NT_STATUS_LOGON_FAILURE; + } else { + set_message(outbuf,4,0,True); + SSVAL(outbuf, smb_vwv3, 0); + + if (server_info->guest) { + SSVAL(outbuf,smb_vwv2,1); + } + + SSVAL(outbuf, smb_uid, sess_vuid); } - set_message(outbuf,4,0,True); - SSVAL(outbuf, smb_vwv3, 0); - add_signature(outbuf); - - SSVAL(outbuf,smb_uid,sess_vuid); - SSVAL(inbuf,smb_uid,sess_vuid); - - return chain_reply(inbuf,outbuf,length,bufsize); + /* wrap that up in a nice GSS-API wrapping */ + if (NT_STATUS_IS_OK(ret)) { + ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_AP_REP); + } else { + ap_rep_wrapped = data_blob(NULL, 0); + } + response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD); + reply_sesssetup_blob(conn, outbuf, response, ret); + + data_blob_free(&ap_rep); + data_blob_free(&ap_rep_wrapped); + data_blob_free(&response); + + return -1; /* already replied */ } #endif @@ -249,10 +273,11 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, { BOOL ret; DATA_BLOB response; - struct auth_serversupplied_info *server_info; - server_info = (*auth_ntlmssp_state)->server_info; + struct auth_serversupplied_info *server_info = NULL; - if (!NT_STATUS_IS_OK(nt_status)) { + if (NT_STATUS_IS_OK(nt_status)) { + server_info = (*auth_ntlmssp_state)->server_info; + } else { nt_status = do_map_to_guest(nt_status, &server_info, (*auth_ntlmssp_state)->ntlmssp_state->user, @@ -280,7 +305,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, } } - response = spnego_gen_auth_response(ntlmssp_blob, nt_status); + response = spnego_gen_auth_response(ntlmssp_blob, nt_status, OID_NTLMSSP); ret = reply_sesssetup_blob(conn, outbuf, response, nt_status); data_blob_free(&response); @@ -363,19 +388,22 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, DATA_BLOB blob1) { DATA_BLOB auth, auth_reply; - NTSTATUS nt_status; + NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; if (!spnego_parse_auth(blob1, &auth)) { #if 0 file_save("auth.dat", blob1.data, blob1.length); #endif - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - - if ( global_ntlmssp_state ) { - nt_status = auth_ntlmssp_update(global_ntlmssp_state, - auth, &auth_reply); + + if (!global_ntlmssp_state) { + /* auth before negotiatiate? */ + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } + + nt_status = auth_ntlmssp_update(global_ntlmssp_state, + auth, &auth_reply); data_blob_free(&auth); @@ -545,7 +573,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, set_remote_arch( RA_WIN95); } } - + if (!doencrypt) { /* both Win95 and WinNT stuff up the password lengths for non-encrypting systems. Uggh. -- cgit From cb380f13f7957cd0c04f9bad73c42ae9576ed892 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 22 Apr 2003 12:28:30 +0000 Subject: Merge comment with HEAD (This used to be commit 8f8d819d5814c2a538b5b906014ff0c354625450) --- source3/smbd/sesssetup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index e36760c148..25f9d424ab 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -77,9 +77,6 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, set_message(outbuf,4,0,True); - /* we set NT_STATUS_MORE_PROCESSING_REQUIRED to tell the other end - that we aren't finished yet */ - nt_status = nt_status_squash(nt_status); SIVAL(outbuf, smb_rcls, NT_STATUS_V(nt_status)); SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */ @@ -309,6 +306,9 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, ret = reply_sesssetup_blob(conn, outbuf, response, nt_status); data_blob_free(&response); + /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us, + and the other end, that we are not finished yet. */ + if (!ret || !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { auth_ntlmssp_end(auth_ntlmssp_state); } -- cgit From ad9a3848a8288803fa752b86fd2aea1a46cf4a7d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 29 Apr 2003 13:28:48 +0000 Subject: add version back to lanman string in sessetup reply (This used to be commit dade462a168abe721c70022546109074961969b6) --- source3/smbd/sesssetup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 25f9d424ab..3fa3fa411f 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -60,9 +60,13 @@ static NTSTATUS do_map_to_guest(NTSTATUS status, auth_serversupplied_info **serv static void add_signature(char *outbuf) { char *p; + fstring lanman; + + snprintf( lanman, sizeof(lanman), "Samba %s", VERSION ); + p = smb_buf(outbuf); p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE); + p += srvstr_push(outbuf, p, lanman, -1, STR_TERMINATE); p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); set_message_end(outbuf,p); } -- cgit From 269a48fedc03f8351384c7d1eeb89d7fbc4e084e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 May 2003 18:11:24 +0000 Subject: Fix uninitialized blobs reported by Luke Howard. Jeremy. (This used to be commit 8dcc00899977a126d5782e44bdae74175ecc0d93) --- source3/smbd/sesssetup.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 3fa3fa411f..a9842424a5 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -153,6 +153,12 @@ static int reply_spnego_kerberos(connection_struct *conn, uint8 tok_id[2]; BOOL foreign = False; + ZERO_STRUCT(ticket); + ZERO_STRUCT(auth_data); + ZERO_STRUCT(ap_rep); + ZERO_STRUCT(ap_rep_wrapped); + ZERO_STRUCT(response); + if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } -- cgit From 402fbc518a5489b33f1c5eafb8e6acb9ee5addbd Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 14 May 2003 00:46:43 +0000 Subject: spelling (This used to be commit 865c11275685c85124b506c9bbd2a8bde2e760b9) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index a9842424a5..fc223ecf37 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -644,7 +644,7 @@ 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 :-( */ + /* This has to be here, because 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); -- cgit From 273dbfd9c61ddeb2cce87c0bf72cdb0b0e297972 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 20 May 2003 22:54:58 +0000 Subject: really make sure to include the version in the lanman string; tested spnego using smbclient (This used to be commit d7ca85613b6acf60e29cc118435db2c075995edb) --- source3/smbd/sesssetup.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index fc223ecf37..8840d4e759 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -57,18 +57,18 @@ static NTSTATUS do_map_to_guest(NTSTATUS status, auth_serversupplied_info **serv /**************************************************************************** Add the standard 'Samba' signature to the end of the session setup. ****************************************************************************/ -static void add_signature(char *outbuf) +static int add_signature(char *outbuf) { - char *p; + char *p = outbuf; fstring lanman; snprintf( lanman, sizeof(lanman), "Samba %s", VERSION ); - p = smb_buf(outbuf); p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); p += srvstr_push(outbuf, p, lanman, -1, STR_TERMINATE); p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); - set_message_end(outbuf,p); + + return PTR_DIFF(p, outbuf); } /**************************************************************************** @@ -91,9 +91,8 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, memcpy(p, blob.data, blob.length); p += blob.length; - p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, "Samba", -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); + p += add_signature( p ); + set_message_end(outbuf,p); return send_smb(smbd_server_fd(),outbuf); @@ -729,7 +728,9 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* it's ok - setup a reply */ set_message(outbuf,3,0,True); if (Protocol >= PROTOCOL_NT1) { - add_signature(outbuf); + char *p = smb_buf( outbuf ); + p += add_signature( p ); + set_message_end( outbuf, p ); /* perhaps grab OS version here?? */ } -- cgit From c52ee09afe06dce29118356078cc4c26b126afc6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 21 May 2003 16:12:07 +0000 Subject: fix for UNICODE plaintext passwords (bug #59) and fix smbclient to send the unicode plain text password if negoitated (This used to be commit e7d635af80c844f17ff9f34c26c1e9c978951ce1) --- source3/smbd/sesssetup.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 8840d4e759..44131b1752 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -620,8 +620,11 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, nt_resp = data_blob(p+passlen1, passlen2); } else { pstring pass; + BOOL unic; + unic=SVAL(inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS; srvstr_pull(inbuf, pass, smb_buf(inbuf), - sizeof(pass), passlen1, STR_TERMINATE); + sizeof(pass), unic ? passlen2 : passlen1, + STR_TERMINATE); plaintext_password = data_blob(pass, strlen(pass)+1); } -- cgit From 090d70fc3f49c5b79492861227c515dcd899bc08 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 27 May 2003 16:30:02 +0000 Subject: volker's add_signature() fix; must pass the beginning on the outbuf to get the flags field (This used to be commit 48c8211084503172f053ad23b308901628f8a978) --- source3/smbd/sesssetup.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 44131b1752..64984d4809 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -57,9 +57,9 @@ static NTSTATUS do_map_to_guest(NTSTATUS status, auth_serversupplied_info **serv /**************************************************************************** Add the standard 'Samba' signature to the end of the session setup. ****************************************************************************/ -static int add_signature(char *outbuf) +static int add_signature(char *outbuf, char *p) { - char *p = outbuf; + char *start = p; fstring lanman; snprintf( lanman, sizeof(lanman), "Samba %s", VERSION ); @@ -68,7 +68,7 @@ static int add_signature(char *outbuf) p += srvstr_push(outbuf, p, lanman, -1, STR_TERMINATE); p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); - return PTR_DIFF(p, outbuf); + return PTR_DIFF(p, start); } /**************************************************************************** @@ -91,7 +91,7 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, memcpy(p, blob.data, blob.length); p += blob.length; - p += add_signature( p ); + p += add_signature( outbuf, p ); set_message_end(outbuf,p); @@ -732,7 +732,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, set_message(outbuf,3,0,True); if (Protocol >= PROTOCOL_NT1) { char *p = smb_buf( outbuf ); - p += add_signature( p ); + p += add_signature( outbuf, p ); set_message_end( outbuf, p ); /* perhaps grab OS version here?? */ } -- cgit From a11797cda2c1b81771edfdbd467ab36af121b6eb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 May 2003 21:55:10 +0000 Subject: Correct (?) handling for VC = 0. Trying to fix XP logoff leaving resources around. Jeremy. (This used to be commit bf0916e1da442606311c74ac73ccec2e9710d663) --- source3/smbd/sesssetup.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 64984d4809..15d816bd6d 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -493,6 +493,16 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } +/**************************************************************************** + On new VC == 0, shutdown *all* old connections and users. +****************************************************************************/ + +static void setup_new_vc_session(void) +{ + DEBUG(2,("setup_new_vc_session: New VC == 0, closing all old resources.\n")); + conn_close_all(); + invalidate_all_vuids(); +} /**************************************************************************** reply to a session setup command @@ -541,6 +551,9 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_NT(NT_STATUS_UNSUCCESSFUL); } + if (SVAL(inbuf,smb_vwv4) == 0) { + setup_new_vc_session(); + } return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize); } @@ -562,7 +575,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, srvstr_pull_buf(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), STR_TERMINATE); *domain = 0; - + } else { uint16 passlen1 = SVAL(inbuf,smb_vwv7); uint16 passlen2 = SVAL(inbuf,smb_vwv8); @@ -641,6 +654,10 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } + if (SVAL(inbuf,smb_vwv4) == 0) { + setup_new_vc_session(); + } + DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, get_remote_machine_name())); if (*user) { -- cgit From 03f046dd9920b3f3c00e97afc06d1857297583ee Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 May 2003 01:00:58 +0000 Subject: It seems only NT4 does the VC == 0 session drop code. Jeremy. (This used to be commit 30bbf4c8c4cbed0f7980237ea9b78baa785dec3d) --- source3/smbd/sesssetup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 15d816bd6d..2631961739 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -495,13 +495,17 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, /**************************************************************************** On new VC == 0, shutdown *all* old connections and users. + It seems that only NT4.x does this. At W2K and above (XP etc.). + a new session setup with VC==0 is ignored. ****************************************************************************/ static void setup_new_vc_session(void) { - DEBUG(2,("setup_new_vc_session: New VC == 0, closing all old resources.\n")); + DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x compatible we would close all old resources.\n")); +#if 0 conn_close_all(); invalidate_all_vuids(); +#endif } /**************************************************************************** -- cgit From c44a9d25a2bfff9d5ebede80f30e13e41aca797c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Jul 2003 23:05:57 +0000 Subject: Added the "required" keyword to the "client signing" parameter to force it on. Fail if missmatch. Small format tidyups in smbd/sesssetup.c. Preparing to add signing on server side. Jeremy. (This used to be commit c390b3e4cd68cfc233ddf14d139e25d40f050f27) --- source3/smbd/sesssetup.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 2631961739..7d77ed3071 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -53,10 +53,10 @@ static NTSTATUS do_map_to_guest(NTSTATUS status, auth_serversupplied_info **serv return status; } - /**************************************************************************** Add the standard 'Samba' signature to the end of the session setup. ****************************************************************************/ + static int add_signature(char *outbuf, char *p) { char *start = p; @@ -72,8 +72,9 @@ static int add_signature(char *outbuf, char *p) } /**************************************************************************** -send a security blob via a session setup reply + Send a security blob via a session setup reply. ****************************************************************************/ + static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, DATA_BLOB blob, NTSTATUS nt_status) { @@ -101,6 +102,7 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, /**************************************************************************** Do a 'guest' logon, getting back the ****************************************************************************/ + static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) { struct auth_context *auth_context; @@ -267,12 +269,12 @@ static int reply_spnego_kerberos(connection_struct *conn, } #endif - /**************************************************************************** - send a session setup reply, wrapped in SPNEGO. - get vuid and check first. - end the NTLMSSP exchange context if we are OK/complete fail + Send a session setup reply, wrapped in SPNEGO. + Get vuid and check first. + End the NTLMSSP exchange context if we are OK/complete fail ***************************************************************************/ + static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, AUTH_NTLMSSP_STATE **auth_ntlmssp_state, DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status) @@ -326,8 +328,9 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, } /**************************************************************************** -reply to a session setup spnego negotiate packet + Reply to a session setup spnego negotiate packet. ****************************************************************************/ + static int reply_spnego_negotiate(connection_struct *conn, char *inbuf, char *outbuf, @@ -387,11 +390,11 @@ static int reply_spnego_negotiate(connection_struct *conn, /* already replied */ return -1; } - /**************************************************************************** -reply to a session setup spnego auth packet + Reply to a session setup spnego auth packet. ****************************************************************************/ + static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, DATA_BLOB blob1) @@ -425,10 +428,10 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, return -1; } - /**************************************************************************** -reply to a session setup command + Reply to a session setup command. ****************************************************************************/ + static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, char *outbuf, int length,int bufsize) @@ -509,8 +512,9 @@ static void setup_new_vc_session(void) } /**************************************************************************** -reply to a session setup command + Reply to a session setup command. ****************************************************************************/ + int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, int length,int bufsize) { -- cgit From 814e987c6241601fb03335b2ba9a633d65cc5e23 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 18 Jul 2003 00:53:34 +0000 Subject: Signing so far... the client code fails on a SMBtrans2 secondary transaction I think (my changes haven't affected this I believe). Initial support on the server side for smbclient. Still doesn't work for w2k clients I think... Work in progress..... (don't change). Jeremy. (This used to be commit e5714edc233424c2f74edb6d658f32f8e0ec9275) --- source3/smbd/sesssetup.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7d77ed3071..9ec5433b02 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -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,10 @@ static int reply_spnego_kerberos(connection_struct *conn, } SSVAL(outbuf, smb_uid, sess_vuid); + + if (!server_info->guest && !srv_check_sign_mac(inbuf)) { + exit_server("reply_spnego_kerberos: bad smb signature"); + } } /* wrap that up in a nice GSS-API wrapping */ @@ -275,7 +280,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 +299,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 +317,11 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *outbuf, } SSVAL(outbuf,smb_uid,sess_vuid); + + if (!server_info->guest && !srv_check_sign_mac(inbuf)) { + exit_server("reply_spnego_ntlmssp: bad smb signature"); + } + } } @@ -382,7 +394,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 +431,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 +754,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 +761,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 +782,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); -- cgit From 3a5dc7c2ecacecf7dd0cfd71ff1bb298d70b391b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 23 Jul 2003 12:33:59 +0000 Subject: convert snprintf() calls using pstrings & fstrings to pstr_sprintf() and fstr_sprintf() to try to standardize. lots of snprintf() calls were using len-1; some were using len. At least this helps to be consistent. (This used to be commit 9f835b85dd38cbe655eb19021ff763f31886ac00) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 9ec5433b02..767bf84154 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -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); -- cgit From 79e2d7c24ebc06a485d8a26c1e58c684237ef533 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jul 2003 04:25:37 +0000 Subject: Server side NTLM signing works - until the first async packet. Working on this next.... Jeremy. (This used to be commit eff74a1fcc597497a4c70589a44c1b70e93ab549) --- source3/smbd/sesssetup.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 767bf84154..689059a3ca 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -318,8 +318,14 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out SSVAL(outbuf,smb_uid,sess_vuid); - if (!server_info->guest && !srv_check_sign_mac(inbuf)) { - exit_server("reply_spnego_ntlmssp: bad smb signature"); + 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); } } -- cgit From 77373f1f8e3b2f61e9bbcd9fadfb83257d390cf2 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 24 Jul 2003 23:46:27 +0000 Subject: More printf fixes - size_t is long on some architectures. (This used to be commit ba4d334b822248d8ab929c9568533431603d967e) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 689059a3ca..8e02f65951 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -375,7 +375,7 @@ static int reply_spnego_negotiate(connection_struct *conn, } free(OIDs[i]); } - DEBUG(3,("Got secblob of size %d\n", secblob.length)); + DEBUG(3,("Got secblob of size %l\n", secblob.length)); #ifdef HAVE_KRB5 if (got_kerberos && (SEC_ADS == lp_security())) { -- cgit From 7d833de662b83f026b54a236588da27dd8899630 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 25 Jul 2003 04:24:40 +0000 Subject: More printf portability fixes. Got caught out by some gcc'isms last time. )-: (This used to be commit 59dae1da66a5eb7e128263bd578f167d8746e9f0) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 8e02f65951..bc3ac6ac64 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -375,7 +375,7 @@ static int reply_spnego_negotiate(connection_struct *conn, } free(OIDs[i]); } - DEBUG(3,("Got secblob of size %l\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())) { -- cgit From 559439e1f4d3ba3444213cbf64a1ede5f9d51906 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 Jul 2003 23:43:22 +0000 Subject: Start the packet signing engine in the kerberos case in the same place as the ntlmssp case. Jeremy. (This used to be commit 79e0bf829875fc985f1940dc31ee418aad910ed6) --- source3/smbd/sesssetup.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index bc3ac6ac64..ccd7214251 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -252,8 +252,14 @@ static int reply_spnego_kerberos(connection_struct *conn, SSVAL(outbuf, smb_uid, sess_vuid); - if (!server_info->guest && !srv_check_sign_mac(inbuf)) { - exit_server("reply_spnego_kerberos: bad smb signature"); + 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); } } @@ -327,7 +333,6 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out */ srv_check_sign_mac(inbuf); } - } } -- cgit From 0da36b22ff3382f2e4a86f4090ad8097a2dd8a32 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 31 Jul 2003 19:01:22 +0000 Subject: only honor the first OID in the sessetup snego negotiate. Deviates from RFC but I'm smelling a client bug here. /* 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 */ (This used to be commit 731420b03dbc15977822f74047e931dc62284fc0) --- source3/smbd/sesssetup.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index ccd7214251..c585ac1e67 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -371,13 +371,24 @@ 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 %lu\n", (unsigned long)secblob.length)); -- cgit From 8c64504f7c58b05769ec1014242c15a2eb93ca84 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 1 Aug 2003 15:30:44 +0000 Subject: Update my copyrights according to my agreement with IBM (This used to be commit a2bd8f0bfa12f2a1e33c96bc9dabcc0e2171700d) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index c585ac1e67..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 2002 Copyright (C) Luke Howard 2003 This program is free software; you can redistribute it and/or modify -- cgit From bb6dff2cb1599882ed6142c3617560b6e9755841 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 14 Aug 2003 21:07:49 +0000 Subject: In ads_verify_realm, all we use in the ADS_STRUCT is the auth.realm. So directly pass that instead of setting up and tearing down the ADS_STRUCT. Volker (This used to be commit ce5b8d2ec20fe1f4d3d1956020d88272fb84124a) --- source3/smbd/sesssetup.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 88b442215d..0b3d42302a 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -149,7 +149,6 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB auth_data; DATA_BLOB ap_rep, ap_rep_wrapped, response; auth_serversupplied_info *server_info = NULL; - ADS_STRUCT *ads; uint8 session_key[16]; uint8 tok_id[2]; BOOL foreign = False; @@ -165,18 +164,9 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - ads = ads_init_simple(); - - if (!ads) { - return ERROR_NT(NT_STATUS_LOGON_FAILURE); - } - - ads->auth.realm = strdup(lp_realm()); - - ret = ads_verify_ticket(ads, &ticket, &client, &auth_data, &ap_rep, session_key); + ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, session_key); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("Failed to verify incoming ticket!\n")); - ads_destroy(&ads); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -187,13 +177,12 @@ static int reply_spnego_kerberos(connection_struct *conn, p = strchr_m(client, '@'); if (!p) { DEBUG(3,("Doesn't look like a valid principal\n")); - ads_destroy(&ads); data_blob_free(&ap_rep); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } *p = 0; - if (strcasecmp(p+1, ads->auth.realm) != 0) { + if (strcasecmp(p+1, lp_realm()) != 0) { DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1)); if (!lp_allow_trusted_domains()) { data_blob_free(&ap_rep); @@ -213,8 +202,6 @@ static int reply_spnego_kerberos(connection_struct *conn, user = smb_xstrdup(client); } - ads_destroy(&ads); - /* setup the string used by %U */ sub_set_smb_name(user); -- cgit From c9aa836204eb722890cbd4d64248ff7ef1a50e60 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 15 Aug 2003 01:46:09 +0000 Subject: Fix memleaks. Currently I'm compiling against MIT Kerberos 1.2.8. Anthony, you said you have a heimdal installation available. Could you please compile this stuff with krb and check it with valgrind? Thanks, Volker (This used to be commit d8ab44685994b302bb46eed9001c72c194d13dc8) --- source3/smbd/sesssetup.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 0b3d42302a..1435c38c99 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -171,6 +171,7 @@ static int reply_spnego_kerberos(connection_struct *conn, } data_blob_free(&auth_data); + data_blob_free(&ticket); DEBUG(3,("Ticket name is [%s]\n", client)); @@ -178,6 +179,7 @@ static int reply_spnego_kerberos(connection_struct *conn, if (!p) { DEBUG(3,("Doesn't look like a valid principal\n")); data_blob_free(&ap_rep); + SAFE_FREE(client); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -186,6 +188,7 @@ static int reply_spnego_kerberos(connection_struct *conn, DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1)); if (!lp_allow_trusted_domains()) { data_blob_free(&ap_rep); + SAFE_FREE(client); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } foreign = True; @@ -202,6 +205,8 @@ static int reply_spnego_kerberos(connection_struct *conn, user = smb_xstrdup(client); } + SAFE_FREE(client); + /* setup the string used by %U */ sub_set_smb_name(user); -- cgit From c236ac83c8ba6fc8d57542bad5bb4685838948e8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 18 Aug 2003 23:48:03 +0000 Subject: Win2k never returns 'no such user' here, so when we do it, the clients freak out. Return the standard 'logon failure' instead. Andrew Bartlett (This used to be commit a83506802fd331af78d2fd6e6a5cd507b5a40ca3) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 1435c38c99..242b39d8d7 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -215,7 +215,7 @@ static int reply_spnego_kerberos(connection_struct *conn, if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); data_blob_free(&ap_rep); - return ERROR_NT(NT_STATUS_NO_SUCH_USER); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); } if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info,pw))) { -- cgit From 8bfe26b62db2e671b143d93a5428f8fb64a9df05 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 20 Aug 2003 17:13:38 +0000 Subject: metze's autogenerate patch for version.h (This used to be commit ae452e51b02672a56adf18aa7a7e365eeaba9272) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 242b39d8d7..e7fc6254e5 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -62,7 +62,7 @@ static int add_signature(char *outbuf, char *p) char *start = p; fstring lanman; - fstr_sprintf( lanman, "Samba %s", VERSION ); + fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING); p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); p += srvstr_push(outbuf, p, lanman, -1, STR_TERMINATE); -- cgit From f474b7fb4e24b790a64178b044e6a8f7caab9a95 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 25 Aug 2003 09:13:54 +0000 Subject: Fix memleak. (This used to be commit afbf15f94189f50cd447d9bcdebbc4886800b05a) --- source3/smbd/sesssetup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index e7fc6254e5..427caa3ba1 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -165,13 +165,15 @@ static int reply_spnego_kerberos(connection_struct *conn, } ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, session_key); + + data_blob_free(&ticket); + if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("Failed to verify incoming ticket!\n")); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } data_blob_free(&auth_data); - data_blob_free(&ticket); DEBUG(3,("Ticket name is [%s]\n", client)); -- cgit From 3fb80f1926e1770f650bca1485c21cf5ee6b9c4f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 20 Oct 2003 16:49:45 +0000 Subject: more 2.2.x compatibility fixes - allow user looksup in the kerb5 sesssetup to fall back to 'user' instaed of failing is REA.LM\user doesn't exist. also fix include line in smb_acls.h as requested by metze (This used to be commit 62ed2598b3441b3c198872df8eb55e594332807b) --- source3/smbd/sesssetup.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 427caa3ba1..945855b832 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -198,28 +198,25 @@ static int reply_spnego_kerberos(connection_struct *conn, /* this gives a fully qualified user name (ie. with full realm). that leads to very long usernames, but what else can we do? */ - asprintf(&user, "%s%s%s", p+1, lp_winbind_separator(), client); + + asprintf(&user, "%s%c%s", p+1, *lp_winbind_separator(), client); - pw = Get_Pwnam(user); - if (!pw && !foreign) { - pw = Get_Pwnam(client); - SAFE_FREE(user); - user = smb_xstrdup(client); - } - + pw = smb_getpwnam( user ); + + SAFE_FREE(user); SAFE_FREE(client); - /* setup the string used by %U */ - sub_set_smb_name(user); - - reload_services(True); - if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); data_blob_free(&ap_rep); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } + /* setup the string used by %U */ + + sub_set_smb_name(pw->pw_name); + reload_services(True); + if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info,pw))) { DEBUG(1,("make_server_info_from_pw failed!\n")); data_blob_free(&ap_rep); -- cgit From bb0598faf58679a7ad26a1caab8eadb154a07ae2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Oct 2003 23:38:20 +0000 Subject: Put strcasecmp/strncasecmp on the banned list (except for needed calls in iconv.c and nsswitch/). Using them means you're not thinking about multibyte at all and I really want to discourage that. Jeremy. (This used to be commit d7e35dfb9283d560d0ed2ab231f36ed92767dace) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 945855b832..314ffbb4a9 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -186,7 +186,7 @@ static int reply_spnego_kerberos(connection_struct *conn, } *p = 0; - if (strcasecmp(p+1, lp_realm()) != 0) { + if (!strequal(p+1, lp_realm())) { DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1)); if (!lp_allow_trusted_domains()) { data_blob_free(&ap_rep); -- cgit From fcbfc7ad0669009957c65fa61bb20df75a9701b4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Nov 2003 13:19:38 +0000 Subject: Changes all over the shop, but all towards: - NTLM2 support in the server - KEY_EXCH support in the server - variable length session keys. In detail: - NTLM2 is an extension of NTLMv1, that is compatible with existing domain controllers (unlike NTLMv2, which requires a DC upgrade). * This is known as 'NTLMv2 session security' * (This is not yet implemented on the RPC pipes however, so there may well still be issues for PDC setups, particuarly around password changes. We do not fully understand the sign/seal implications of NTLM2 on RPC pipes.) This requires modifications to our authentication subsystem, as we must handle the 'challege' input into the challenge-response algorithm being changed. This also needs to be turned off for 'security=server', which does not support this. - KEY_EXCH is another 'security' mechanism, whereby the session key actually used by the server is sent by the client, rather than being the shared-secret directly or indirectly. - As both these methods change the session key, the auth subsystem needed to be changed, to 'override' session keys provided by the backend. - There has also been a major overhaul of the NTLMSSP subsystem, to merge the 'client' and 'server' functions, so they both operate on a single structure. This should help the SPNEGO implementation. - The 'names blob' in NTLMSSP is always in unicode - never in ascii. Don't make an ascii version ever. - The other big change is to allow variable length session keys. We have always assumed that session keys are 16 bytes long - and padded to this length if shorter. However, Kerberos session keys are 8 bytes long, when the krb5 login uses DES. * This fix allows SMB signging on machines not yet running MIT KRB5 1.3.1. * - Add better DEBUG() messages to ntlm_auth, warning administrators of misconfigurations that prevent access to the privileged pipe. This should help reduce some of the 'it just doesn't work' issues. - Fix data_blob_talloc() to behave the same way data_blob() does when passed a NULL data pointer. (just allocate) REMEMBER to make clean after this commit - I have changed plenty of data structures... (This used to be commit f3bbc87b0dac63426cda6fac7a295d3aad810ecc) --- source3/smbd/sesssetup.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 314ffbb4a9..64c25db2ab 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -149,7 +149,7 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB auth_data; DATA_BLOB ap_rep, ap_rep_wrapped, response; auth_serversupplied_info *server_info = NULL; - uint8 session_key[16]; + DATA_BLOB session_key; uint8 tok_id[2]; BOOL foreign = False; DATA_BLOB nullblob = data_blob(NULL, 0); @@ -164,7 +164,7 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, session_key); + ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, &session_key); data_blob_free(&ticket); @@ -223,11 +223,8 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(ret); } - /* Copy out the session key from the AP_REQ. */ - memcpy(server_info->session_key, session_key, sizeof(session_key)); - /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, nullblob, user); + sess_vuid = register_vuid(server_info, session_key, nullblob, user); free(user); @@ -297,9 +294,10 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out if (NT_STATUS_IS_OK(nt_status)) { int sess_vuid; DATA_BLOB nullblob = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob((*auth_ntlmssp_state)->ntlmssp_state->session_key.data, (*auth_ntlmssp_state)->ntlmssp_state->session_key.length); /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user); + sess_vuid = register_vuid(server_info, session_key, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user); (*auth_ntlmssp_state)->server_info = NULL; if (sess_vuid == -1) { @@ -566,6 +564,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, NTSTATUS nt_status; BOOL doencrypt = global_encrypted_passwords_negotiated; + + DATA_BLOB session_key; START_PROFILE(SMBsesssetupX); @@ -766,18 +766,28 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, free_user_info(&user_info); - data_blob_free(&lm_resp); - data_blob_clear_free(&plaintext_password); - if (!NT_STATUS_IS_OK(nt_status)) { nt_status = do_map_to_guest(nt_status, &server_info, user, domain); } if (!NT_STATUS_IS_OK(nt_status)) { data_blob_free(&nt_resp); + data_blob_free(&lm_resp); + data_blob_clear_free(&plaintext_password); return ERROR_NT(nt_status_squash(nt_status)); } + if (server_info->nt_session_key.data) { + session_key = data_blob(server_info->nt_session_key.data, server_info->nt_session_key.length); + } else if (server_info->lm_session_key.length >= 8 && lm_resp.length == 24) { + session_key = data_blob(NULL, 16); + SMBsesskeygen_lmv1(server_info->lm_session_key.data, lm_resp.data, + session_key.data); + } + + data_blob_free(&lm_resp); + data_blob_clear_free(&plaintext_password); + /* it's ok - setup a reply */ set_message(outbuf,3,0,True); if (Protocol >= PROTOCOL_NT1) { @@ -795,7 +805,7 @@ 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, nt_resp, sub_user); + sess_vuid = register_vuid(server_info, session_key, nt_resp, sub_user); data_blob_free(&nt_resp); if (sess_vuid == -1) { -- cgit From 6bb8f54e018db066d93f960ec0f257a77671b593 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 02:25:56 +0000 Subject: Don't automatically set nt status code flag unless client tells us it can cope. Jeremy. (This used to be commit 0d82ac57a59276adb403f8e023578c2d6d5136e4) --- source3/smbd/sesssetup.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 64c25db2ab..fb0744bb73 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -472,6 +472,11 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, if (global_client_caps == 0) { global_client_caps = IVAL(inbuf,smb_vwv10); + + if (global_client_caps & CAP_STATUS32) { + add_to_common_flags2(FLAGS2_32_BIT_ERROR_CODES); + } + } p = (uint8 *)smb_buf(inbuf); @@ -615,17 +620,22 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, enum remote_arch_types ra_type = get_remote_arch(); char *p = smb_buf(inbuf); - if(global_client_caps == 0) + if(global_client_caps == 0) { global_client_caps = IVAL(inbuf,smb_vwv11); - /* client_caps is used as final determination if client is NT or Win95. - This is needed to return the correct error codes in some - circumstances. - */ + if (global_client_caps & CAP_STATUS32) { + add_to_common_flags2(FLAGS2_32_BIT_ERROR_CODES); + } + + /* client_caps is used as final determination if client is NT or Win95. + This is needed to return the correct error codes in some + circumstances. + */ - if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) { - if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) { - set_remote_arch( RA_WIN95); + if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) { + if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) { + set_remote_arch( RA_WIN95); + } } } @@ -686,7 +696,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, ra_lanman_string( native_lanman ); } - + if (SVAL(inbuf,smb_vwv4) == 0) { setup_new_vc_session(); } -- cgit From 27891bdef10069e70e240bbea53f75359cec78eb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 06:19:17 +0000 Subject: Subtract NT_STATUS from common flag, don't add it... Jeremy. (This used to be commit 4e73faa7b4af7f73bdce9fcc2ee1825249dc7da7) --- source3/smbd/sesssetup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index fb0744bb73..ec01a330ee 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -473,8 +473,8 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, if (global_client_caps == 0) { global_client_caps = IVAL(inbuf,smb_vwv10); - if (global_client_caps & CAP_STATUS32) { - add_to_common_flags2(FLAGS2_32_BIT_ERROR_CODES); + if (!(global_client_caps & CAP_STATUS32)) { + remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); } } @@ -623,8 +623,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if(global_client_caps == 0) { global_client_caps = IVAL(inbuf,smb_vwv11); - if (global_client_caps & CAP_STATUS32) { - add_to_common_flags2(FLAGS2_32_BIT_ERROR_CODES); + if (!(global_client_caps & CAP_STATUS32)) { + remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); } /* client_caps is used as final determination if client is NT or Win95. -- cgit From 4b1e15a4f2a9bac1fd6b3a800dc642dfe69f2d2a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 5 Dec 2003 21:51:51 +0000 Subject: fix %a variable for Windows 2003 -> Win2K3 (This used to be commit 2f43a1c166dfc8679a9d03bd0f3cf9303aafcf74) --- source3/smbd/sesssetup.c | 48 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 9 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index ec01a330ee..da48c81fc1 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -463,7 +463,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, DATA_BLOB blob1; int ret; size_t bufrem; - fstring native_os, native_lanman; + fstring native_os, native_lanman, primary_domain; char *p2; uint16 data_blob_len = SVAL(inbuf, smb_vwv7); enum remote_arch_types ra_type = get_remote_arch(); @@ -497,11 +497,20 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, p2 = inbuf + smb_vwv13 + data_blob_len; p2 += srvstr_pull_buf(inbuf, native_os, p2, sizeof(native_os), STR_TERMINATE); p2 += srvstr_pull_buf(inbuf, native_lanman, p2, sizeof(native_lanman), STR_TERMINATE); - DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s]\n", native_os, native_lanman)); - - if ( ra_type == RA_WIN2K ) - ra_lanman_string( native_lanman ); + p2 += srvstr_pull_buf(inbuf, primary_domain, p2, sizeof(primary_domain), STR_TERMINATE); + DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n", + native_os, native_lanman, primary_domain)); + if ( ra_type == RA_WIN2K ) { + /* Windows 2003 doesn't set the native lanman string, + but does set primary domain which is a bug I think */ + + if ( !strlen(native_lanman) ) + ra_lanman_string( primary_domain ); + else + ra_lanman_string( native_lanman ); + } + if (blob1.data[0] == ASN1_APPLICATION(0)) { /* its a negTokenTarg packet */ ret = reply_spnego_negotiate(conn, inbuf, outbuf, length, bufsize, blob1); @@ -556,6 +565,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, fstring domain; fstring native_os; fstring native_lanman; + fstring primary_domain; static BOOL done_sesssetup = False; extern BOOL global_encrypted_passwords_negotiated; extern BOOL global_spnego_negotiated; @@ -619,6 +629,9 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, uint16 passlen2 = SVAL(inbuf,smb_vwv8); enum remote_arch_types ra_type = get_remote_arch(); char *p = smb_buf(inbuf); + char *save_p = smb_buf(inbuf); + uint16 byte_count; + if(global_client_caps == 0) { global_client_caps = IVAL(inbuf,smb_vwv11); @@ -689,11 +702,28 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, p += srvstr_pull_buf(inbuf, domain, p, sizeof(domain), STR_TERMINATE); p += srvstr_pull_buf(inbuf, native_os, p, sizeof(native_os), STR_TERMINATE); p += srvstr_pull_buf(inbuf, native_lanman, p, sizeof(native_lanman), STR_TERMINATE); - DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n", - domain,native_os,native_lanman)); - if ( ra_type == RA_WIN2K ) - ra_lanman_string( native_lanman ); + /* not documented or decoded by Ethereal but there is one more string + in the extra bytes which is the same as the PrimaryDomain when using + extended security. Windows NT 4 and 2003 use this string to store + the native lanman string. Windows 9x does not include a string here + at all so we have to check if we have any extra bytes left */ + + byte_count = SVAL(inbuf, smb_vwv13); + if ( PTR_DIFF(p, save_p) < byte_count) + p += srvstr_pull_buf(inbuf, primary_domain, p, sizeof(primary_domain), STR_TERMINATE); + else + fstrcpy( primary_domain, "null" ); + + DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n", + domain, native_os, native_lanman, primary_domain)); + + if ( ra_type == RA_WIN2K ) { + if ( strlen(native_lanman) == 0 ) + ra_lanman_string( primary_domain ); + else + ra_lanman_string( native_lanman ); + } } -- cgit From c4f1b6cf3af731750bf0dfe2311514576197e4e2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 12 Dec 2003 22:54:43 +0000 Subject: Fix for bug #815. Make plaintext unicode passwords work with NT4.x Jeremy. (This used to be commit ba0b5b8c9be9bfeba5e0b3f930ca0463d1e78c9c) --- source3/smbd/sesssetup.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index da48c81fc1..e9cfa47d0c 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -689,11 +689,17 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, nt_resp = data_blob(p+passlen1, passlen2); } else { pstring pass; - BOOL unic; - unic=SVAL(inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS; - srvstr_pull(inbuf, pass, smb_buf(inbuf), - sizeof(pass), unic ? passlen2 : passlen1, - STR_TERMINATE); + BOOL unic=SVAL(inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS; + + if ((ra_type == RA_WINNT) && (passlen2 == 0) && unic && passlen1) { + /* NT4.0 stuffs up plaintext unicode password lengths... */ + srvstr_pull(inbuf, pass, smb_buf(inbuf) + 1, + sizeof(pass), passlen1, STR_TERMINATE); + } else { + srvstr_pull(inbuf, pass, smb_buf(inbuf), + sizeof(pass), unic ? passlen2 : passlen1, + STR_TERMINATE); + } plaintext_password = data_blob(pass, strlen(pass)+1); } -- cgit From fd35232584d34c3250094572393b3a64fc87cef9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 4 Jan 2004 11:51:31 +0000 Subject: Commit the translation of the realm to the netbios domain name in the kerberos session setup. After talking to jht and abartlet I made this unconditional, no additional parameter. Jerry: This is a change in behaviour, but I think it is necessary. Volker (This used to be commit 3ce6c9f27368cfb278007fe660a0e44a84d67f8f) --- source3/smbd/sesssetup.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index e9cfa47d0c..2c38cd3eb3 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -141,7 +141,8 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB *secblob) { DATA_BLOB ticket; - char *client, *p; + char *client, *p, *domain; + fstring netbios_domain_name; const struct passwd *pw; char *user; int sess_vuid; @@ -198,8 +199,45 @@ static int reply_spnego_kerberos(connection_struct *conn, /* this gives a fully qualified user name (ie. with full realm). that leads to very long usernames, but what else can we do? */ - - asprintf(&user, "%s%c%s", p+1, *lp_winbind_separator(), client); + + domain = p+1; + + { + /* If we have winbind running, we can (and must) shorten the + username by using the short netbios name. Otherwise we will + have inconsistent user names. With Kerberos, we get the + fully qualified realm, with ntlmssp we get the short + name. And even w2k3 does use ntlmssp if you for example + connect to an ip address. */ + + struct winbindd_request wb_request; + struct winbindd_response wb_response; + NSS_STATUS wb_result; + + ZERO_STRUCT(wb_request); + ZERO_STRUCT(wb_response); + + DEBUG(10, ("Mapping [%s] to short name\n", domain)); + + fstrcpy(wb_request.domain_name, domain); + + wb_result = winbindd_request(WINBINDD_DOMAIN_INFO, + &wb_request, &wb_response); + + if (wb_result == NSS_STATUS_SUCCESS) { + + fstrcpy(netbios_domain_name, + wb_response.data.domain_info.name); + domain = netbios_domain_name; + + DEBUG(10, ("Mapped to [%s]\n", domain)); + } else { + DEBUG(3, ("Could not find short name -- winbind " + "not running?\n")); + } + } + + asprintf(&user, "%s%c%s", domain, *lp_winbind_separator(), client); pw = smb_getpwnam( user ); -- cgit From e41a67a18839ea8a5e1bd5403f3668e7f2b374b7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 7 Jan 2004 19:55:01 +0000 Subject: Fix from Luke Howard for incorrect early free(). Jeremy. (This used to be commit 8e20c06ed31d9ec10ff0155b1624eee3d60cd006) --- source3/smbd/sesssetup.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 2c38cd3eb3..80be9da53b 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -241,11 +241,10 @@ static int reply_spnego_kerberos(connection_struct *conn, pw = smb_getpwnam( user ); - SAFE_FREE(user); - SAFE_FREE(client); - if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); + SAFE_FREE(user); + SAFE_FREE(client); data_blob_free(&ap_rep); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -257,14 +256,17 @@ static int reply_spnego_kerberos(connection_struct *conn, if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info,pw))) { DEBUG(1,("make_server_info_from_pw failed!\n")); + SAFE_FREE(user); + SAFE_FREE(client); data_blob_free(&ap_rep); return ERROR_NT(ret); } /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, session_key, nullblob, user); + sess_vuid = register_vuid(server_info, session_key, nullblob, client); - free(user); + SAFE_FREE(user); + SAFE_FREE(client); if (sess_vuid == -1) { ret = NT_STATUS_LOGON_FAILURE; -- cgit From 55d6877f0f9708c80aeb94d1d145441833cb26b9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 15 Jan 2004 17:17:58 +0000 Subject: reply_spnego_kerberos did not set the domain of the user handed to register_vuid correctly. We ended up with the local netbios name in substitutions for %D later. Volker P.S: Tridge, I can *really* see why you want to get rid of global variables :-) (This used to be commit 3d9931fe291559a907c3e172a66fbce1155497a3) --- source3/smbd/sesssetup.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 80be9da53b..9405c065e1 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -262,6 +262,13 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(ret); } + /* make_server_info_pw does not set the domain. Without this we end up + * with the local netbios name in substitutions for %D. */ + + if (server_info->sam_account != NULL) { + pdb_set_domain(server_info->sam_account, domain, PDB_SET); + } + /* register_vuid keeps the server info */ sess_vuid = register_vuid(server_info, session_key, nullblob, client); -- cgit From c26e4057ae1ada769555079738f09f9cea1614b9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 26 Jan 2004 02:19:44 +0000 Subject: Patch by Luca Bolcioni . Ensure we always initialise the session key. Fixes segfaults with security=server, and encrypt passwords = no. Andrew Bartlett (This used to be commit 493ac5ce98fa3fcddb596139240dd762e70d4ac3) --- source3/smbd/sesssetup.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 9405c065e1..c42a35e809 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -876,6 +876,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, session_key = data_blob(NULL, 16); SMBsesskeygen_lmv1(server_info->lm_session_key.data, lm_resp.data, session_key.data); + } else { + session_key = data_blob(NULL, 0); } data_blob_free(&lm_resp); -- cgit From d24b8a2032a2e92d954781e610ab535361fefd88 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 16 Mar 2004 16:41:54 +0000 Subject: BUG 1165, 1126: Fix bug with secondary groups (security = ads) and winbind use default domain = yes (This used to be commit f2eaa14b1eb7e89c945b2b06a48e17998c75d620) --- source3/smbd/sesssetup.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index c42a35e809..d91aa94728 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -143,7 +143,7 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB ticket; char *client, *p, *domain; fstring netbios_domain_name; - const struct passwd *pw; + struct passwd *pw; char *user; int sess_vuid; NTSTATUS ret; @@ -154,6 +154,7 @@ static int reply_spnego_kerberos(connection_struct *conn, uint8 tok_id[2]; BOOL foreign = False; DATA_BLOB nullblob = data_blob(NULL, 0); + fstring real_username; ZERO_STRUCT(ticket); ZERO_STRUCT(auth_data); @@ -239,7 +240,9 @@ static int reply_spnego_kerberos(connection_struct *conn, asprintf(&user, "%s%c%s", domain, *lp_winbind_separator(), client); - pw = smb_getpwnam( user ); + /* lookup the passwd struct, create a new user if necessary */ + + pw = smb_getpwnam( user, real_username, True ); if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); @@ -251,10 +254,11 @@ static int reply_spnego_kerberos(connection_struct *conn, /* setup the string used by %U */ - sub_set_smb_name(pw->pw_name); + sub_set_smb_name( real_username ); reload_services(True); - if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info,pw))) { + if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info, real_username, pw))) + { DEBUG(1,("make_server_info_from_pw failed!\n")); SAFE_FREE(user); SAFE_FREE(client); -- cgit From c24dccd413c41ed81454bc204c59d1fc17a54a33 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 19 Mar 2004 22:06:54 +0000 Subject: BUG 417: fix %UuGg variables expansion in include lines setging the current_user_info struct in register_vuid() -- shouldn't be any more broken than we were (This used to be commit a90c3bd281e7a62bb8482e42aa3b674eeeb5995a) --- source3/smbd/sesssetup.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index d91aa94728..244db6d2c1 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -282,6 +282,9 @@ static int reply_spnego_kerberos(connection_struct *conn, if (sess_vuid == -1) { ret = NT_STATUS_LOGON_FAILURE; } else { + /* current_user_info is changed on new vuid */ + reload_services( True ); + set_message(outbuf,4,0,True); SSVAL(outbuf, smb_vwv3, 0); @@ -355,6 +358,9 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out nt_status = NT_STATUS_LOGON_FAILURE; } else { + /* current_user_info is changed on new vuid */ + reload_services( True ); + set_message(outbuf,4,0,True); SSVAL(outbuf, smb_vwv3, 0); @@ -911,6 +917,9 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } + /* current_user_info is changed on new vuid */ + reload_services( True ); + if (!server_info->guest && !srv_check_sign_mac(inbuf)) { exit_server("reply_sesssetup_and_X: bad smb signature"); } -- cgit From e9a7e67e01c115328f95690cbf63ca1ef0b4d408 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2004 07:33:59 +0000 Subject: Merge from HEAD the SMB signing patch that I developed a couple of weeks ago. This patch re-adds support for 'optional' SMB signing. It also ensures that we are much more careful about when we enable signing, particularly with on-the-fly smb.conf reloads. The client code will now attempt to use smb signing by default, and disable it if the server doesn't correctly support it. Andrew Bartlett (This used to be commit e27b5cbe75d89ec839dafd52dd33101885a4c263) --- source3/smbd/sesssetup.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 244db6d2c1..b8777be697 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -294,14 +294,14 @@ static int reply_spnego_kerberos(connection_struct *conn, SSVAL(outbuf, smb_uid, sess_vuid); - if (!server_info->guest) { + if (!server_info->guest && !srv_signing_started()) { /* 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); + srv_check_sign_mac(inbuf, False); } } @@ -370,14 +370,15 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out SSVAL(outbuf,smb_uid,sess_vuid); - if (!server_info->guest) { + if (!server_info->guest && !srv_signing_started()) { /* 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); + + srv_check_sign_mac(inbuf, False); } } } @@ -920,7 +921,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* current_user_info is changed on new vuid */ reload_services( True ); - if (!server_info->guest && !srv_check_sign_mac(inbuf)) { + if (!server_info->guest && !srv_signing_started() && !srv_check_sign_mac(inbuf, True)) { exit_server("reply_sesssetup_and_X: bad smb signature"); } -- cgit From 991112a73cf2abd1761c0680b737fa724666820b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Apr 2004 14:27:23 +0000 Subject: r49: Support SMB signing on connections using only the LANMAN password. This also corrects the 'session key' for these connections. (This used to be commit 26d8791ddedb7964c219067480cf4a7d61877765) --- source3/smbd/sesssetup.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index b8777be697..902db2d288 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -881,17 +881,12 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_NT(nt_status_squash(nt_status)); } - if (server_info->nt_session_key.data) { - session_key = data_blob(server_info->nt_session_key.data, server_info->nt_session_key.length); - } else if (server_info->lm_session_key.length >= 8 && lm_resp.length == 24) { - session_key = data_blob(NULL, 16); - SMBsesskeygen_lmv1(server_info->lm_session_key.data, lm_resp.data, - session_key.data); + if (server_info->user_session_key.data) { + session_key = data_blob(server_info->user_session_key.data, server_info->user_session_key.length); } else { session_key = data_blob(NULL, 0); } - data_blob_free(&lm_resp); data_blob_clear_free(&plaintext_password); /* it's ok - setup a reply */ @@ -911,8 +906,9 @@ 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, session_key, nt_resp, sub_user); + sess_vuid = register_vuid(server_info, session_key, nt_resp.data ? nt_resp : lm_resp, sub_user); data_blob_free(&nt_resp); + data_blob_free(&lm_resp); if (sess_vuid == -1) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); -- cgit From a5dde6c5cc2fce655ed1dd7c701fdaf5ed96edfc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 5 Apr 2004 16:57:40 +0000 Subject: r59: revert session key problem (This used to be commit 40b5794ae0919c6c6f1b8a451871dcc95bbab5cc) --- source3/smbd/sesssetup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 902db2d288..abb9c24d41 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -881,8 +881,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_NT(nt_status_squash(nt_status)); } - if (server_info->user_session_key.data) { - session_key = data_blob(server_info->user_session_key.data, server_info->user_session_key.length); + if (server_info->nt_session_key.data) { + session_key = data_blob(server_info->nt_session_key.data, server_info->nt_session_key.length); } else { session_key = data_blob(NULL, 0); } -- cgit From d17425ed52b086b7046708a207e849271cedc804 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Apr 2004 08:11:16 +0000 Subject: r69: Global rename of 'nt_session_key' -> 'user_session_key'. The session key could be anything, and may not be based on anything 'NT'. This is also what microsoft calls it. (This used to be commit 724e8d3f33719543146280062435c69a835c491e) --- source3/smbd/sesssetup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index abb9c24d41..902db2d288 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -881,8 +881,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_NT(nt_status_squash(nt_status)); } - if (server_info->nt_session_key.data) { - session_key = data_blob(server_info->nt_session_key.data, server_info->nt_session_key.length); + if (server_info->user_session_key.data) { + session_key = data_blob(server_info->user_session_key.data, server_info->user_session_key.length); } else { session_key = data_blob(NULL, 0); } -- cgit From 8c0db1bbc469932694ed877eebecffa3d1948abd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 19 May 2004 21:49:58 +0000 Subject: r786: Memory leak fixes in (mostly) error code paths from kawasa_r@itg.hitachi.co.jp. A couple of mem leak fixes in mainline code paths though :-). Jeremy. (This used to be commit 4695cc95fe576b6da0d0cb0686f208fc306b2646) --- source3/smbd/sesssetup.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 902db2d288..8a56478929 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -150,7 +150,7 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB auth_data; DATA_BLOB ap_rep, ap_rep_wrapped, response; auth_serversupplied_info *server_info = NULL; - DATA_BLOB session_key; + DATA_BLOB session_key = data_blob(NULL, 0); uint8 tok_id[2]; BOOL foreign = False; DATA_BLOB nullblob = data_blob(NULL, 0); @@ -183,6 +183,7 @@ static int reply_spnego_kerberos(connection_struct *conn, if (!p) { DEBUG(3,("Doesn't look like a valid principal\n")); data_blob_free(&ap_rep); + data_blob_free(&session_key); SAFE_FREE(client); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -192,6 +193,7 @@ static int reply_spnego_kerberos(connection_struct *conn, DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1)); if (!lp_allow_trusted_domains()) { data_blob_free(&ap_rep); + data_blob_free(&session_key); SAFE_FREE(client); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -249,6 +251,7 @@ static int reply_spnego_kerberos(connection_struct *conn, SAFE_FREE(user); SAFE_FREE(client); data_blob_free(&ap_rep); + data_blob_free(&session_key); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -263,6 +266,7 @@ static int reply_spnego_kerberos(connection_struct *conn, SAFE_FREE(user); SAFE_FREE(client); data_blob_free(&ap_rep); + data_blob_free(&session_key); return ERROR_NT(ret); } @@ -274,6 +278,8 @@ static int reply_spnego_kerberos(connection_struct *conn, } /* register_vuid keeps the server info */ + /* register_vuid takes ownership of session_key, no need to free after this. + A better interface would copy it.... */ sess_vuid = register_vuid(server_info, session_key, nullblob, client); SAFE_FREE(user); -- cgit From 3542b99cf1408b075353efe1cbfb30569104dfba Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 13 Jun 2004 23:13:22 +0000 Subject: r1122: As spotted by lha@stacken.kth.se we don't actually use this variable any more. Andrew Bartlett (This used to be commit 9d5821d5ee5e9f666dfbe75419e97508af9cad5e) --- source3/smbd/sesssetup.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 8a56478929..49acd371a5 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -152,7 +152,6 @@ static int reply_spnego_kerberos(connection_struct *conn, auth_serversupplied_info *server_info = NULL; DATA_BLOB session_key = data_blob(NULL, 0); uint8 tok_id[2]; - BOOL foreign = False; DATA_BLOB nullblob = data_blob(NULL, 0); fstring real_username; @@ -197,7 +196,6 @@ static int reply_spnego_kerberos(connection_struct *conn, SAFE_FREE(client); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - foreign = True; } /* this gives a fully qualified user name (ie. with full realm). -- cgit From 600e904aa1ddf620df2ed6e5a02d0fe00e627dbb Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 6 Jul 2004 21:43:12 +0000 Subject: r1370: BUG 1297 - prevent map_username() from being called twice during logon (This used to be commit e1364ff774b62f46c0f50864695da49972352126) --- source3/smbd/sesssetup.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 49acd371a5..0122b662eb 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -242,6 +242,8 @@ static int reply_spnego_kerberos(connection_struct *conn, /* lookup the passwd struct, create a new user if necessary */ + map_username( user ); + pw = smb_getpwnam( user, real_username, True ); if (!pw) { -- cgit From 482f14871d568a24006fec5af68d722b5fa70a0d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 25 Nov 2004 00:07:01 +0000 Subject: r3946: Fix for bugid #2085 reported by Jason Mader . Use consistent enum type for Protocol extern. Jeremy. (This used to be commit 65dfae7ea45d4c9452b2a08efa09b01d870142f3) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 0122b662eb..cff7d7371c 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -633,7 +633,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, static BOOL done_sesssetup = False; extern BOOL global_encrypted_passwords_negotiated; extern BOOL global_spnego_negotiated; - extern int Protocol; + extern enum protocol_types Protocol; extern int max_send; auth_usersupplied_info *user_info = NULL; -- cgit From 2257618d7f282ebc7b99279728b4f05c6593c02b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Feb 2005 23:46:14 +0000 Subject: r5290: Fix for bug #2323 - plaintext problem with WinXP. Jeremy. (This used to be commit 3e10c36cb50462d1f220029e8fa64c3b6e554e6c) --- source3/smbd/sesssetup.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index cff7d7371c..40ea28a86d 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -755,10 +755,18 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, pstring pass; BOOL unic=SVAL(inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS; +#if 0 + /* This was the previous fix. Not sure if it's still valid. JRA. */ if ((ra_type == RA_WINNT) && (passlen2 == 0) && unic && passlen1) { /* NT4.0 stuffs up plaintext unicode password lengths... */ srvstr_pull(inbuf, pass, smb_buf(inbuf) + 1, sizeof(pass), passlen1, STR_TERMINATE); +#endif + + if (unic && (passlen2 == 0) && passlen1) { + /* Only a ascii plaintext password was sent. */ + srvstr_pull(inbuf, pass, smb_buf(inbuf), sizeof(pass), + passlen1, STR_TERMINATE|STR_ASCII); } else { srvstr_pull(inbuf, pass, smb_buf(inbuf), sizeof(pass), unic ? passlen2 : passlen1, -- cgit From 4b831f8e16d305666b0f2b018c35f5427efc21cc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Mar 2005 15:12:50 +0000 Subject: r5952: BUG 2469: patch from Jason Mader to cleanup compiler warning when not using krb5 (This used to be commit 19a639ac468237b22f16d917c0150fbf10c9623e) --- source3/smbd/sesssetup.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 40ea28a86d..e1fb71d575 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -417,7 +417,9 @@ static int reply_spnego_negotiate(connection_struct *conn, DATA_BLOB secblob; int i; DATA_BLOB chal; - BOOL got_kerberos = False; +#ifdef HAVE_KRB5 + BOOL got_kerberos_mechanism = False; +#endif NTSTATUS nt_status; /* parse out the OIDs and the first sec blob */ @@ -434,11 +436,13 @@ static int reply_spnego_negotiate(connection_struct *conn, server sent back krb5/mskrb5/ntlmssp as mechtypes, but the client (2ksp3) replied with ntlmssp/mskrb5/krb5 and an NTLMSSP mechtoken. --jerry */ - + +#ifdef HAVE_KRB5 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) { - got_kerberos = True; + got_kerberos_mechanism = True; } +#endif for (i=0;OIDs[i];i++) { DEBUG(3,("Got OID %s\n", OIDs[i])); @@ -447,7 +451,7 @@ static int reply_spnego_negotiate(connection_struct *conn, DEBUG(3,("Got secblob of size %lu\n", (unsigned long)secblob.length)); #ifdef HAVE_KRB5 - if (got_kerberos && (SEC_ADS == lp_security())) { + if (got_kerberos_mechanism && (SEC_ADS == lp_security())) { int ret = reply_spnego_kerberos(conn, inbuf, outbuf, length, bufsize, &secblob); data_blob_free(&secblob); -- cgit From 5415480d7eea3ddd319625087e6ed902cd6e04c6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Mar 2005 01:02:52 +0000 Subject: r6020: Never do NT status codes with protocols before NT1 as we don't get client caps. Jeremy. (This used to be commit 4868e4202775c1c0a60828e0c6f6fa23cf8346e1) --- source3/smbd/sesssetup.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index e1fb71d575..48524b472d 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -677,6 +677,10 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if (Protocol < PROTOCOL_NT1) { uint16 passlen1 = SVAL(inbuf,smb_vwv7); + + /* Never do NT status codes with protocols before NT1 as we don't get client caps. */ + remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); + if ((passlen1 > MAX_PASS_LEN) || (passlen1 > smb_bufrem(inbuf, smb_buf(inbuf)))) { return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } -- cgit From 9840db418bad5a39edc4a32a1786f5e2d2c9dff8 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 31 Mar 2005 05:06:04 +0000 Subject: r6149: Fixes bugs #2498 and 2484. 1. using smbc_getxattr() et al, one may now request all access control entities in the ACL without getting all other NT attributes. 2. added the ability to exclude specified attributes from the result set provided by smbc_getxattr() et al, when requesting all attributes, all NT attributes, or all DOS attributes. 3. eliminated all compiler warnings, including when --enable-developer compiler flags are in use. removed -Wcast-qual flag from list, as that is specifically to force warnings in the case of casting away qualifiers. Note: In the process of eliminating compiler warnings, a few nasties were discovered. In the file libads/sasl.c, PRIVATE kerberos interfaces are being used; and in libsmb/clikrb5.c, both PRIAVE and DEPRECATED kerberos interfaces are being used. Someone who knows kerberos should look at these and determine if there is an alternate method of accomplishing the task. (This used to be commit 994694f7f26da5099f071e1381271a70407f33bb) --- source3/smbd/sesssetup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 48524b472d..60867df653 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -313,7 +313,9 @@ static int reply_spnego_kerberos(connection_struct *conn, /* wrap that up in a nice GSS-API wrapping */ if (NT_STATUS_IS_OK(ret)) { - ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_AP_REP); + ap_rep_wrapped = spnego_gen_krb5_wrap( + ap_rep, + CONST_ADD(const uint8 *, TOK_ID_KRB_AP_REP)); } else { ap_rep_wrapped = data_blob(NULL, 0); } -- cgit From 978ca8486031e43754a3c23757f361bf3a85f335 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 6 Apr 2005 16:28:04 +0000 Subject: r6225: get rid of warnings from my compiler about nested externs (This used to be commit efea76ac71412f8622cd233912309e91b9ea52da) --- source3/smbd/sesssetup.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 60867df653..9fbf0b1d51 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -25,6 +25,12 @@ uint32 global_client_caps = 0; +extern BOOL global_encrypted_passwords_negotiated; +extern BOOL global_spnego_negotiated; +extern enum protocol_types Protocol; +extern int max_send; +extern struct auth_context *negprot_global_auth_context; + static struct auth_ntlmssp_state *global_ntlmssp_state; /* @@ -637,13 +643,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, fstring native_lanman; fstring primary_domain; static BOOL done_sesssetup = False; - extern BOOL global_encrypted_passwords_negotiated; - extern BOOL global_spnego_negotiated; - extern enum protocol_types Protocol; - extern int max_send; auth_usersupplied_info *user_info = NULL; - extern struct auth_context *negprot_global_auth_context; auth_serversupplied_info *server_info = NULL; NTSTATUS nt_status; -- cgit From af52df2f1fde76b518bf946e396bc29869aa6964 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 27 May 2005 13:58:04 +0000 Subject: r7020: fixing printer ace values and getting rid of false compiler warning about unitialized variable (This used to be commit 3a91b20e4bcc78c91932e6c4394b3f6f153b2ff5) --- source3/smbd/sesssetup.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 9fbf0b1d51..0209dc2597 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -125,6 +125,7 @@ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) return nt_status; } + if (!make_user_info_guest(&user_info)) { (auth_context->free)(&auth_context); return NT_STATUS_NO_MEMORY; @@ -146,6 +147,7 @@ static int reply_spnego_kerberos(connection_struct *conn, int length, int bufsize, DATA_BLOB *secblob) { + int map_domainuser_to_guest = 0; DATA_BLOB ticket; char *client, *p, *domain; fstring netbios_domain_name; @@ -245,14 +247,19 @@ static int reply_spnego_kerberos(connection_struct *conn, } asprintf(&user, "%s%c%s", domain, *lp_winbind_separator(), client); - /* lookup the passwd struct, create a new user if necessary */ + if (lp_map_to_guest() == MAP_TO_GUEST_ON_VALID_DOMAIN_USER ){ + map_domainuser_to_guest == 1; + fstrcpy(user,lp_guestaccount()); + pw = smb_getpwnam( user, real_username, True ); + } else { map_username( user ); pw = smb_getpwnam( user, real_username, True ); if (!pw) { + } DEBUG(1,("Username %s is invalid on this system\n",user)); SAFE_FREE(user); SAFE_FREE(client); @@ -265,16 +272,20 @@ static int reply_spnego_kerberos(connection_struct *conn, sub_set_smb_name( real_username ); reload_services(True); - - if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info, real_username, pw))) + if (map_domainuser_to_guest == 1) { + make_server_info_guest(&server_info); + }else{ + if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info, real_username, pw))) { DEBUG(1,("make_server_info_from_pw failed!\n")); SAFE_FREE(user); SAFE_FREE(client); data_blob_free(&ap_rep); + data_blob_free(&session_key); return ERROR_NT(ret); } + } /* make_server_info_pw does not set the domain. Without this we end up * with the local netbios name in substitutions for %D. */ -- cgit From cc6df2e9cf5b31f83cf88d21457b32712d90f04b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 27 May 2005 14:19:57 +0000 Subject: r7024: reverting mistaken commit (This used to be commit c70c5c4ee9b14fbdb174f542607aceebe0e88470) --- source3/smbd/sesssetup.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 0209dc2597..9fbf0b1d51 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -125,7 +125,6 @@ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) return nt_status; } - if (!make_user_info_guest(&user_info)) { (auth_context->free)(&auth_context); return NT_STATUS_NO_MEMORY; @@ -147,7 +146,6 @@ static int reply_spnego_kerberos(connection_struct *conn, int length, int bufsize, DATA_BLOB *secblob) { - int map_domainuser_to_guest = 0; DATA_BLOB ticket; char *client, *p, *domain; fstring netbios_domain_name; @@ -247,19 +245,14 @@ static int reply_spnego_kerberos(connection_struct *conn, } asprintf(&user, "%s%c%s", domain, *lp_winbind_separator(), client); + /* lookup the passwd struct, create a new user if necessary */ - if (lp_map_to_guest() == MAP_TO_GUEST_ON_VALID_DOMAIN_USER ){ - map_domainuser_to_guest == 1; - fstrcpy(user,lp_guestaccount()); - pw = smb_getpwnam( user, real_username, True ); - } else { map_username( user ); pw = smb_getpwnam( user, real_username, True ); if (!pw) { - } DEBUG(1,("Username %s is invalid on this system\n",user)); SAFE_FREE(user); SAFE_FREE(client); @@ -272,20 +265,16 @@ static int reply_spnego_kerberos(connection_struct *conn, sub_set_smb_name( real_username ); reload_services(True); - if (map_domainuser_to_guest == 1) { - make_server_info_guest(&server_info); - }else{ - if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info, real_username, pw))) + + if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info, real_username, pw))) { DEBUG(1,("make_server_info_from_pw failed!\n")); SAFE_FREE(user); SAFE_FREE(client); data_blob_free(&ap_rep); - data_blob_free(&session_key); return ERROR_NT(ret); } - } /* make_server_info_pw does not set the domain. Without this we end up * with the local netbios name in substitutions for %D. */ -- cgit From f24d88cf9da46680d52b42b92bd484e7b09ce99b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 31 May 2005 13:46:45 +0000 Subject: r7139: trying to reduce the number of diffs between trunk and 3.0; changing version to 3.0.20pre1 (This used to be commit 9727d05241574042dd3aa8844ae5c701d22e2da1) --- source3/smbd/sesssetup.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 9fbf0b1d51..48524b472d 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -25,12 +25,6 @@ uint32 global_client_caps = 0; -extern BOOL global_encrypted_passwords_negotiated; -extern BOOL global_spnego_negotiated; -extern enum protocol_types Protocol; -extern int max_send; -extern struct auth_context *negprot_global_auth_context; - static struct auth_ntlmssp_state *global_ntlmssp_state; /* @@ -319,9 +313,7 @@ static int reply_spnego_kerberos(connection_struct *conn, /* wrap that up in a nice GSS-API wrapping */ if (NT_STATUS_IS_OK(ret)) { - ap_rep_wrapped = spnego_gen_krb5_wrap( - ap_rep, - CONST_ADD(const uint8 *, TOK_ID_KRB_AP_REP)); + ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_AP_REP); } else { ap_rep_wrapped = data_blob(NULL, 0); } @@ -643,8 +635,13 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, fstring native_lanman; fstring primary_domain; static BOOL done_sesssetup = False; + extern BOOL global_encrypted_passwords_negotiated; + extern BOOL global_spnego_negotiated; + extern enum protocol_types Protocol; + extern int max_send; auth_usersupplied_info *user_info = NULL; + extern struct auth_context *negprot_global_auth_context; auth_serversupplied_info *server_info = NULL; NTSTATUS nt_status; -- cgit From b279ee16e982d419c2205a7f790bd9cb8035d6e5 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 7 Jun 2005 17:52:19 +0000 Subject: r7372: abartet's patch for BUG 2391 (segv caused by free a static pointer) (This used to be commit 4cda2bd035276bd090bf0fbd4e3b2eff657a80cb) --- source3/smbd/sesssetup.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 48524b472d..6f963fc603 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -267,8 +267,10 @@ static int reply_spnego_kerberos(connection_struct *conn, SAFE_FREE(client); data_blob_free(&ap_rep); data_blob_free(&session_key); + passwd_free(&pw); return ERROR_NT(ret); } + passwd_free(&pw); /* make_server_info_pw does not set the domain. Without this we end up * with the local netbios name in substitutions for %D. */ -- cgit From 377f947930f3a3fe69c21d5b9386642cbf8b3df7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 8 Jun 2005 14:23:49 +0000 Subject: r7395: * new feature 'map to guest = bad uid' (based on patch from aruna.prabakar@hp.com). This re-enables the Samba 2.2 behavior where a user that was successfully authenticated by a remote DC would be mapped to the guest account if there was not existing UNIX account for that user and we could not create one. (This used to be commit b7455fbf81f4e47c087c861f70d492a328730a9b) --- source3/smbd/sesssetup.c | 55 ++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 20 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 6f963fc603..5808de9788 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -144,7 +144,7 @@ static int reply_spnego_kerberos(connection_struct *conn, char *client, *p, *domain; fstring netbios_domain_name; struct passwd *pw; - char *user; + fstring user; int sess_vuid; NTSTATUS ret; DATA_BLOB auth_data; @@ -154,6 +154,7 @@ static int reply_spnego_kerberos(connection_struct *conn, uint8 tok_id[2]; DATA_BLOB nullblob = data_blob(NULL, 0); fstring real_username; + BOOL map_domainuser_to_guest = False; ZERO_STRUCT(ticket); ZERO_STRUCT(auth_data); @@ -238,37 +239,52 @@ static int reply_spnego_kerberos(connection_struct *conn, } } - asprintf(&user, "%s%c%s", domain, *lp_winbind_separator(), client); + fstr_sprintf(user, "%s%c%s", domain, *lp_winbind_separator(), client); /* lookup the passwd struct, create a new user if necessary */ map_username( user ); pw = smb_getpwnam( user, real_username, True ); - if (!pw) { - DEBUG(1,("Username %s is invalid on this system\n",user)); - SAFE_FREE(user); - SAFE_FREE(client); - data_blob_free(&ap_rep); - data_blob_free(&session_key); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + + /* this was originally the behavior of Samba 2.2, if a user + did not have a local uid but has been authenticated, then + map them to a guest account */ + + if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID){ + map_domainuser_to_guest = True; + fstrcpy(user,lp_guestaccount()); + pw = smb_getpwnam( user, real_username, True ); + } + + /* extra sanity check that the guest account is valid */ + + if ( !pw ) { + DEBUG(1,("Username %s is invalid on this system\n", user)); + SAFE_FREE(client); + data_blob_free(&ap_rep); + data_blob_free(&session_key); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } } /* setup the string used by %U */ sub_set_smb_name( real_username ); reload_services(True); - - if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info, real_username, pw))) - { - DEBUG(1,("make_server_info_from_pw failed!\n")); - SAFE_FREE(user); - SAFE_FREE(client); - data_blob_free(&ap_rep); - data_blob_free(&session_key); - passwd_free(&pw); - return ERROR_NT(ret); + if ( map_domainuser_to_guest ) { + make_server_info_guest(&server_info); + } else { + ret = make_server_info_pw(&server_info, real_username, pw); + if ( !NT_STATUS_IS_OK(ret) ) { + DEBUG(1,("make_server_info_from_pw failed!\n")); + SAFE_FREE(client); + data_blob_free(&ap_rep); + data_blob_free(&session_key); + passwd_free(&pw); + return ERROR_NT(ret); + } } passwd_free(&pw); @@ -284,7 +300,6 @@ static int reply_spnego_kerberos(connection_struct *conn, A better interface would copy it.... */ sess_vuid = register_vuid(server_info, session_key, nullblob, client); - SAFE_FREE(user); SAFE_FREE(client); if (sess_vuid == -1) { -- cgit From dacdfbc98ccb533626058745f4aacef0b0b36286 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 8 Jun 2005 14:57:37 +0000 Subject: r7398: commiting abartlet's patch for kerberos authentication when using a keytab and security != ads (This used to be commit 3faaa5c3eb3b2057984586e069a47cb210c99140) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 5808de9788..3b33db24e8 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -468,7 +468,7 @@ static int reply_spnego_negotiate(connection_struct *conn, DEBUG(3,("Got secblob of size %lu\n", (unsigned long)secblob.length)); #ifdef HAVE_KRB5 - if (got_kerberos_mechanism && (SEC_ADS == lp_security())) { + if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { int ret = reply_spnego_kerberos(conn, inbuf, outbuf, length, bufsize, &secblob); data_blob_free(&secblob); -- cgit From 19ca97a70f6b7b41d251eaa76e4d3c980c6eedff Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 24 Jun 2005 20:25:18 +0000 Subject: r7882: Looks like a large patch - but what it actually does is make Samba safe for using our headers and linking with C++ modules. Stops us from using C++ reserved keywords in our code. Jeremy (This used to be commit 9506b8e145982b1160a2f0aee5c9b7a54980940a) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 3b33db24e8..95fe571cff 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -223,7 +223,7 @@ static int reply_spnego_kerberos(connection_struct *conn, fstrcpy(wb_request.domain_name, domain); - wb_result = winbindd_request(WINBINDD_DOMAIN_INFO, + wb_result = winbindd_request_response(WINBINDD_DOMAIN_INFO, &wb_request, &wb_response); if (wb_result == NSS_STATUS_SUCCESS) { -- cgit From f2f55d703d0dd549a83809d3e5cc5151569b48d6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 27 Jun 2005 22:53:56 +0000 Subject: r7963: Add aio support to 3.0. Jeremy. (This used to be commit 1de27da47051af08790317f5b48b02719d6b9934) --- source3/smbd/sesssetup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 95fe571cff..1ddd6256b3 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -96,6 +96,7 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, set_message_end(outbuf,p); + show_msg(outbuf); return send_smb(smbd_server_fd(),outbuf); } -- cgit From dae78e57e2341e519a2bb609d827968ac93a2499 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 14 Jul 2005 14:39:27 +0000 Subject: r8472: abartlet's patch for parallel ntlmssp supporttrunk/source/smbd/sesssetup.c (This used to be commit aab17a7095a18b243a271f8f3f824facd6932f23) --- source3/smbd/sesssetup.c | 75 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 17 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 1ddd6256b3..8586ac1324 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -25,8 +25,6 @@ uint32 global_client_caps = 0; -static struct auth_ntlmssp_state *global_ntlmssp_state; - /* on a logon error possibly map the error to success if "map to guest" is set approriately @@ -353,6 +351,7 @@ static int reply_spnego_kerberos(connection_struct *conn, ***************************************************************************/ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *outbuf, + uint16 vuid, AUTH_NTLMSSP_STATE **auth_ntlmssp_state, DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status) { @@ -416,6 +415,8 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out if (!ret || !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { auth_ntlmssp_end(auth_ntlmssp_state); + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); } return ret; @@ -428,8 +429,10 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out static int reply_spnego_negotiate(connection_struct *conn, char *inbuf, char *outbuf, + uint16 vuid, int length, int bufsize, - DATA_BLOB blob1) + DATA_BLOB blob1, + AUTH_NTLMSSP_STATE **auth_ntlmssp_state) { char *OIDs[ASN1_MAX_OIDS]; DATA_BLOB secblob; @@ -442,6 +445,9 @@ static int reply_spnego_negotiate(connection_struct *conn, /* parse out the OIDs and the first sec blob */ if (!parse_negTokenTarg(blob1, OIDs, &secblob)) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -473,25 +479,31 @@ static int reply_spnego_negotiate(connection_struct *conn, int ret = reply_spnego_kerberos(conn, inbuf, outbuf, length, bufsize, &secblob); data_blob_free(&secblob); + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + return ret; } #endif - if (global_ntlmssp_state) { - auth_ntlmssp_end(&global_ntlmssp_state); + if (*auth_ntlmssp_state) { + auth_ntlmssp_end(auth_ntlmssp_state); } - nt_status = auth_ntlmssp_start(&global_ntlmssp_state); + nt_status = auth_ntlmssp_start(auth_ntlmssp_state); if (!NT_STATUS_IS_OK(nt_status)) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + return ERROR_NT(nt_status); } - nt_status = auth_ntlmssp_update(global_ntlmssp_state, + nt_status = auth_ntlmssp_update(*auth_ntlmssp_state, secblob, &chal); data_blob_free(&secblob); - reply_spnego_ntlmssp(conn, inbuf, outbuf, &global_ntlmssp_state, + reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, auth_ntlmssp_state, &chal, nt_status); data_blob_free(&chal); @@ -505,8 +517,10 @@ static int reply_spnego_negotiate(connection_struct *conn, ****************************************************************************/ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, + uint16 vuid, int length, int bufsize, - DATA_BLOB blob1) + DATA_BLOB blob1, + AUTH_NTLMSSP_STATE **auth_ntlmssp_state) { DATA_BLOB auth, auth_reply; NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; @@ -515,20 +529,27 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, #if 0 file_save("auth.dat", blob1.data, blob1.length); #endif + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - if (!global_ntlmssp_state) { + if (!*auth_ntlmssp_state) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + /* auth before negotiatiate? */ return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } - nt_status = auth_ntlmssp_update(global_ntlmssp_state, - auth, &auth_reply); + nt_status = auth_ntlmssp_update(*auth_ntlmssp_state, + auth, &auth_reply); data_blob_free(&auth); - reply_spnego_ntlmssp(conn, inbuf, outbuf, &global_ntlmssp_state, + reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, + auth_ntlmssp_state, &auth_reply, nt_status); data_blob_free(&auth_reply); @@ -553,6 +574,8 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, char *p2; uint16 data_blob_len = SVAL(inbuf, smb_vwv7); enum remote_arch_types ra_type = get_remote_arch(); + int vuid = SVAL(inbuf,smb_uid); + user_struct *vuser = NULL; DEBUG(3,("Doing spnego session setup\n")); @@ -597,16 +620,34 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, ra_lanman_string( native_lanman ); } + vuser = get_partial_auth_user_struct(vuid); + if (!vuser) { + vuid = register_vuid(NULL, data_blob(NULL, 0), data_blob(NULL, 0), NULL); + if (vuid == -1) { + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + + vuser = get_partial_auth_user_struct(vuid); + } + + if (!vuser) { + return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + } + + SSVAL(outbuf,smb_uid,vuid); + if (blob1.data[0] == ASN1_APPLICATION(0)) { /* its a negTokenTarg packet */ - ret = reply_spnego_negotiate(conn, inbuf, outbuf, length, bufsize, blob1); + ret = reply_spnego_negotiate(conn, inbuf, outbuf, vuid, length, bufsize, blob1, + &vuser->auth_ntlmssp_state); data_blob_free(&blob1); return ret; } if (blob1.data[0] == ASN1_CONTEXT(1)) { /* its a auth packet */ - ret = reply_spnego_auth(conn, inbuf, outbuf, length, bufsize, blob1); + ret = reply_spnego_auth(conn, inbuf, outbuf, vuid, length, bufsize, blob1, + &vuser->auth_ntlmssp_state); data_blob_free(&blob1); return ret; } @@ -682,7 +723,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) { if (!global_spnego_negotiated) { DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at SPNEGO session setup when it was not negoitiated.\n")); - return ERROR_NT(NT_STATUS_UNSUCCESSFUL); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); } if (SVAL(inbuf,smb_vwv4) == 0) { @@ -843,7 +884,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* This has to be here, because 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); + return ERROR_NT(NT_STATUS_LOGON_FAILURE); } fstrcpy(sub_user, user); -- cgit From a3947eaa4eb32c40e983993d17178bb9d9b5f151 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 2 Aug 2005 06:36:42 +0000 Subject: r8912: Samba 3.0 was failing from a Vista client, because it was using 'raw' NTLMSSP (not wrapped in SPNEGO). We really should have supported this anyway, but we got away with it for a while... Andrew Bartlett (This used to be commit 78f0640a4b4af8b40c0af251fd06edd97feaf1be) --- source3/smbd/sesssetup.c | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 8586ac1324..6a414acc4c 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -353,7 +353,8 @@ static int reply_spnego_kerberos(connection_struct *conn, static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *outbuf, uint16 vuid, AUTH_NTLMSSP_STATE **auth_ntlmssp_state, - DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status) + DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status, + BOOL wrap) { BOOL ret; DATA_BLOB response; @@ -406,9 +407,16 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out } } - response = spnego_gen_auth_response(ntlmssp_blob, nt_status, OID_NTLMSSP); + if (wrap) { + response = spnego_gen_auth_response(ntlmssp_blob, nt_status, OID_NTLMSSP); + } else { + response = *ntlmssp_blob; + } + ret = reply_sesssetup_blob(conn, outbuf, response, nt_status); - data_blob_free(&response); + if (wrap) { + data_blob_free(&response); + } /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us, and the other end, that we are not finished yet. */ @@ -504,8 +512,8 @@ static int reply_spnego_negotiate(connection_struct *conn, data_blob_free(&secblob); reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, auth_ntlmssp_state, - &chal, nt_status); - + &chal, nt_status, True); + data_blob_free(&chal); /* already replied */ @@ -550,7 +558,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, auth_ntlmssp_state, - &auth_reply, nt_status); + &auth_reply, nt_status, True); data_blob_free(&auth_reply); @@ -652,6 +660,31 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, return ret; } + if (strncmp(blob1.data, "NTLMSSP", 7) == 0) { + DATA_BLOB chal; + NTSTATUS nt_status; + if (!vuser->auth_ntlmssp_state) { + nt_status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state); + if (!NT_STATUS_IS_OK(nt_status)) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + + return ERROR_NT(nt_status); + } + } + + nt_status = auth_ntlmssp_update(vuser->auth_ntlmssp_state, + blob1, &chal); + + data_blob_free(&blob1); + + reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, + &vuser->auth_ntlmssp_state, + &chal, nt_status, False); + data_blob_free(&blob1); + return -1; + } + /* what sort of packet is this? */ DEBUG(1,("Unknown packet in reply_sesssetup_and_X_spnego\n")); -- cgit From f31965b549d5def6d0b25ece6b1ff721fc66bcab Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 2 Aug 2005 07:07:43 +0000 Subject: r8913: Fix memory leak in -r 8912: Free the right thing, rather than blob1 'twice'. Andrew Bartlett (This used to be commit 7adeba4036d9d83a10d8944c81ea3fab0267db21) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 6a414acc4c..bf7287aab9 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -681,7 +681,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, &vuser->auth_ntlmssp_state, &chal, nt_status, False); - data_blob_free(&blob1); + data_blob_free(&chal); return -1; } -- cgit From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: r10656: BIG merge from trunk. Features not copied over * \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3) --- source3/smbd/sesssetup.c | 70 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 13 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index bf7287aab9..fc2d8b4abb 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -139,6 +139,7 @@ static int reply_spnego_kerberos(connection_struct *conn, int length, int bufsize, DATA_BLOB *secblob) { + TALLOC_CTX *mem_ctx; DATA_BLOB ticket; char *client, *p, *domain; fstring netbios_domain_name; @@ -146,7 +147,7 @@ static int reply_spnego_kerberos(connection_struct *conn, fstring user; int sess_vuid; NTSTATUS ret; - DATA_BLOB auth_data; + PAC_DATA *pac_data; DATA_BLOB ap_rep, ap_rep_wrapped, response; auth_serversupplied_info *server_info = NULL; DATA_BLOB session_key = data_blob(NULL, 0); @@ -154,18 +155,24 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB nullblob = data_blob(NULL, 0); fstring real_username; BOOL map_domainuser_to_guest = False; + PAC_LOGON_INFO *logon_info = NULL; + int i; ZERO_STRUCT(ticket); - ZERO_STRUCT(auth_data); + ZERO_STRUCT(pac_data); ZERO_STRUCT(ap_rep); ZERO_STRUCT(ap_rep_wrapped); ZERO_STRUCT(response); + mem_ctx = talloc_init("reply_spnego_kerberos"); + if (mem_ctx == NULL) + return ERROR_NT(NT_STATUS_NO_MEMORY); + if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - ret = ads_verify_ticket(lp_realm(), &ticket, &client, &auth_data, &ap_rep, &session_key); + ret = ads_verify_ticket(mem_ctx, lp_realm(), &ticket, &client, &pac_data, &ap_rep, &session_key); data_blob_free(&ticket); @@ -174,7 +181,18 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - data_blob_free(&auth_data); + if (pac_data) { + + /* get the logon_info */ + for (i=0; i < pac_data->num_buffers; i++) { + + if (pac_data->pac_buffer[i].type != PAC_TYPE_LOGON_INFO) + continue; + + logon_info = pac_data->pac_buffer[i].ctr->pac.logon_info; + break; + } + } DEBUG(3,("Ticket name is [%s]\n", client)); @@ -203,7 +221,14 @@ static int reply_spnego_kerberos(connection_struct *conn, domain = p+1; - { + if (logon_info && logon_info->info3.hdr_logon_dom.uni_str_len) { + + unistr2_to_ascii(netbios_domain_name, &logon_info->info3.uni_logon_dom, -1); + domain = netbios_domain_name; + DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain)); + + } else { + /* If we have winbind running, we can (and must) shorten the username by using the short netbios name. Otherwise we will have inconsistent user names. With Kerberos, we get the @@ -231,7 +256,7 @@ static int reply_spnego_kerberos(connection_struct *conn, wb_response.data.domain_info.name); domain = netbios_domain_name; - DEBUG(10, ("Mapped to [%s]\n", domain)); + DEBUG(10, ("Mapped to [%s] (using Winbind)\n", domain)); } else { DEBUG(3, ("Could not find short name -- winbind " "not running?\n")); @@ -274,8 +299,21 @@ static int reply_spnego_kerberos(connection_struct *conn, reload_services(True); if ( map_domainuser_to_guest ) { make_server_info_guest(&server_info); + } else if (logon_info) { + ret = make_server_info_pac(&server_info, real_username, pw, logon_info); + + if ( !NT_STATUS_IS_OK(ret) ) { + DEBUG(1,("make_server_info_pac failed!\n")); + SAFE_FREE(client); + data_blob_free(&ap_rep); + data_blob_free(&session_key); + passwd_free(&pw); + return ERROR_NT(ret); + } + } else { ret = make_server_info_pw(&server_info, real_username, pw); + if ( !NT_STATUS_IS_OK(ret) ) { DEBUG(1,("make_server_info_from_pw failed!\n")); SAFE_FREE(client); @@ -284,15 +322,17 @@ static int reply_spnego_kerberos(connection_struct *conn, passwd_free(&pw); return ERROR_NT(ret); } + + /* make_server_info_pw does not set the domain. Without this we end up + * with the local netbios name in substitutions for %D. */ + + if (server_info->sam_account != NULL) { + pdb_set_domain(server_info->sam_account, domain, PDB_SET); + } } - passwd_free(&pw); - /* make_server_info_pw does not set the domain. Without this we end up - * with the local netbios name in substitutions for %D. */ - if (server_info->sam_account != NULL) { - pdb_set_domain(server_info->sam_account, domain, PDB_SET); - } + passwd_free(&pw); /* register_vuid keeps the server info */ /* register_vuid takes ownership of session_key, no need to free after this. @@ -339,6 +379,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&ap_rep_wrapped); data_blob_free(&response); + talloc_destroy(mem_ctx); return -1; /* already replied */ } @@ -348,6 +389,8 @@ static int reply_spnego_kerberos(connection_struct *conn, 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 +465,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out 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); @@ -660,7 +704,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, return ret; } - if (strncmp(blob1.data, "NTLMSSP", 7) == 0) { + if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) { DATA_BLOB chal; NTSTATUS nt_status; if (!vuser->auth_ntlmssp_state) { -- cgit From ad93243f2399c2f349434dbbb33ed3766a817a8d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 19 Oct 2005 14:34:17 +0000 Subject: r11183: add small helper function to return a PAC_LOGON_INFO. Guenther (This used to be commit a8d5d6b845efb62e73e281549528376f3ee74211) --- source3/smbd/sesssetup.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index fc2d8b4abb..c875e08b24 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -182,16 +182,7 @@ static int reply_spnego_kerberos(connection_struct *conn, } if (pac_data) { - - /* get the logon_info */ - for (i=0; i < pac_data->num_buffers; i++) { - - if (pac_data->pac_buffer[i].type != PAC_TYPE_LOGON_INFO) - continue; - - logon_info = pac_data->pac_buffer[i].ctr->pac.logon_info; - break; - } + logon_info = get_logon_info_from_pac(pac_data); } DEBUG(3,("Ticket name is [%s]\n", client)); -- cgit From ad7cd4096f73382f3723fb3f4581c6cea4186702 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 20 Oct 2005 08:13:00 +0000 Subject: r11213: Fix the build Guenther (This used to be commit 908ac0c9eccd1ba368a6305fee9673770fc74a53) --- source3/smbd/sesssetup.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index c875e08b24..34b161c92f 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -156,7 +156,6 @@ static int reply_spnego_kerberos(connection_struct *conn, fstring real_username; BOOL map_domainuser_to_guest = False; PAC_LOGON_INFO *logon_info = NULL; - int i; ZERO_STRUCT(ticket); ZERO_STRUCT(pac_data); -- cgit From 9d9fe2d58de24ff7fd7f95bae878d299a1c6d33c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 10 Nov 2005 21:10:24 +0000 Subject: r11655: Two small fixes * remove redundant call to sub_set_smb_name() in session setup code. * Fix lockup when running 'wbinfo -t' on a Samba PDC. Cause was new authenticated session setup from winbindd which resulted in a mangled username (machine_) that was not found in the local files and so was queiued up to nss_winbindd. Deadlock.... So now make sure to keep the trailing '$' for machine account names when calling sub_set_smb_name(). (This used to be commit b0a2d43b603c2e230da6ada73587696605102e8f) --- source3/smbd/sesssetup.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 34b161c92f..9ac258cb5e 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -954,9 +954,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } fstrcpy(sub_user, user); - - /* setup the string used by %U */ - sub_set_smb_name(user); } else { fstrcpy(sub_user, lp_guestaccount()); } -- cgit From a4d729bdfadfc39fece612fcdd68955c3e3845bb Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Nov 2005 03:03:41 +0000 Subject: r11661: Store the INFO3 in the PAC data into the netsamlogon_cache. Also remove the mem_ctx from the netsamlogon_cache_store() API. Guenther, what should we be doing with the other fields in the PAC_LOGON_INFO? (This used to be commit 8bead2d2825015fe41ba7d7401a12c06c29ea7f7) --- source3/smbd/sesssetup.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 9ac258cb5e..2c96760167 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -180,10 +180,6 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_LOGON_FAILURE); } - if (pac_data) { - logon_info = get_logon_info_from_pac(pac_data); - } - DEBUG(3,("Ticket name is [%s]\n", client)); p = strchr_m(client, '@'); @@ -196,6 +192,14 @@ static int reply_spnego_kerberos(connection_struct *conn, } *p = 0; + + /* save the PAC data if we have it */ + + if (pac_data) { + logon_info = get_logon_info_from_pac(pac_data); + netsamlogon_cache_store( client, &logon_info->info3 ); + } + if (!strequal(p+1, lp_realm())) { DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1)); if (!lp_allow_trusted_domains()) { -- cgit From 90603cb3cddcab3c7577cdad81e4a134c39de4ce Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 22 Nov 2005 10:22:59 +0000 Subject: r11846: Destroy the TALLOC_CTX on error in the Kerberos session setup and give a more precise inline comment why PAC verification may fail. Guenther (This used to be commit 43b57715e9b44a0a0c7cc7fe3674a5fd4369e78b) --- source3/smbd/sesssetup.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 2c96760167..8aa046b85a 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -168,6 +168,7 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(NT_STATUS_NO_MEMORY); if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) { + talloc_destroy(mem_ctx); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -177,6 +178,7 @@ static int reply_spnego_kerberos(connection_struct *conn, if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("Failed to verify incoming ticket!\n")); + talloc_destroy(mem_ctx); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -188,6 +190,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); SAFE_FREE(client); + talloc_destroy(mem_ctx); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } @@ -206,6 +209,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); SAFE_FREE(client); + talloc_destroy(mem_ctx); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } } @@ -283,6 +287,7 @@ static int reply_spnego_kerberos(connection_struct *conn, SAFE_FREE(client); data_blob_free(&ap_rep); data_blob_free(&session_key); + talloc_destroy(mem_ctx); return ERROR_NT(NT_STATUS_LOGON_FAILURE); } } @@ -302,6 +307,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); passwd_free(&pw); + talloc_destroy(mem_ctx); return ERROR_NT(ret); } @@ -314,6 +320,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); passwd_free(&pw); + talloc_destroy(mem_ctx); return ERROR_NT(ret); } -- cgit From 1bfb5b734b0d5e1bc093bb43513729ed458fe372 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Nov 2005 12:31:40 +0000 Subject: r11909: Implement 'reset on zero vc'. This kills other connections when a session setup comes in with the vc (virtual connection) field set to zero. This is done by Windows, probably you can tweak that by some registry key. This boolean option controls whether an incoming session setup should kill other connections coming from the same IP. This matches the default Windows 2003 behaviour. Setting this parameter to yes becomes necessary when you have a flaky network and windows decides to reconnect while the old connection still has files with share modes open. These files become inaccessible over the new connection. The client sends a zero VC on the new connection, and Windows 2003 kills all other connections coming from the same IP. This way the locked files are accessible again. Please be aware that enabling this option will kill connections behind a masquerading router. Volker (This used to be commit 5629ca16235f0aa21fea3afd9e414309e4e1374e) --- source3/smbd/sesssetup.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 8aa046b85a..a22a575c76 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -744,6 +744,29 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, a new session setup with VC==0 is ignored. ****************************************************************************/ +static int shutdown_other_smbds(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, + void *p) +{ + struct sessionid *sessionid = (struct sessionid *)dbuf.dptr; + const char *ip = (const char *)p; + + if (!process_exists(pid_to_procid(sessionid->pid))) { + return 0; + } + + if (sessionid->pid == sys_getpid()) { + return 0; + } + + if (strcmp(ip, sessionid->ip_addr) != 0) { + return 0; + } + + message_send_pid(pid_to_procid(sessionid->pid), MSG_SHUTDOWN, + NULL, 0, True); + return 0; +} + static void setup_new_vc_session(void) { DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x compatible we would close all old resources.\n")); @@ -751,6 +774,9 @@ static void setup_new_vc_session(void) conn_close_all(); invalidate_all_vuids(); #endif + if (lp_reset_on_zero_vc()) { + session_traverse(shutdown_other_smbds, client_addr()); + } } /**************************************************************************** -- cgit From 0af1500fc0bafe61019f1b2ab1d9e1d369221240 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 22:19:41 +0000 Subject: r13316: Let the carnage begin.... Sync with trunk as off r13315 (This used to be commit 17e63ac4ed8325c0d44fe62b2442449f3298559f) --- source3/smbd/sesssetup.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index a22a575c76..38e16126e2 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -267,7 +267,7 @@ static int reply_spnego_kerberos(connection_struct *conn, map_username( user ); - pw = smb_getpwnam( user, real_username, True ); + pw = smb_getpwnam( mem_ctx, user, real_username, True ); if (!pw) { /* this was originally the behavior of Samba 2.2, if a user @@ -277,7 +277,7 @@ static int reply_spnego_kerberos(connection_struct *conn, if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID){ map_domainuser_to_guest = True; fstrcpy(user,lp_guestaccount()); - pw = smb_getpwnam( user, real_username, True ); + pw = smb_getpwnam( mem_ctx, user, real_username, True ); } /* extra sanity check that the guest account is valid */ @@ -302,11 +302,11 @@ static int reply_spnego_kerberos(connection_struct *conn, ret = make_server_info_pac(&server_info, real_username, pw, logon_info); if ( !NT_STATUS_IS_OK(ret) ) { - DEBUG(1,("make_server_info_pac failed!\n")); + DEBUG(1,("make_server_info_pac failed: %s!\n", + nt_errstr(ret))); SAFE_FREE(client); data_blob_free(&ap_rep); data_blob_free(&session_key); - passwd_free(&pw); talloc_destroy(mem_ctx); return ERROR_NT(ret); } @@ -315,26 +315,24 @@ static int reply_spnego_kerberos(connection_struct *conn, ret = make_server_info_pw(&server_info, real_username, pw); if ( !NT_STATUS_IS_OK(ret) ) { - DEBUG(1,("make_server_info_from_pw failed!\n")); + DEBUG(1,("make_server_info_pw failed: %s!\n", + nt_errstr(ret))); SAFE_FREE(client); data_blob_free(&ap_rep); data_blob_free(&session_key); - passwd_free(&pw); talloc_destroy(mem_ctx); return ERROR_NT(ret); } - /* make_server_info_pw does not set the domain. Without this we end up - * with the local netbios name in substitutions for %D. */ + /* make_server_info_pw does not set the domain. Without this + * we end up with the local netbios name in substitutions for + * %D. */ if (server_info->sam_account != NULL) { pdb_set_domain(server_info->sam_account, domain, PDB_SET); } } - - passwd_free(&pw); - /* register_vuid keeps the server info */ /* register_vuid takes ownership of session_key, no need to free after this. A better interface would copy it.... */ @@ -1063,6 +1061,16 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_NT(nt_status_squash(nt_status)); } + nt_status = create_local_token(server_info); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(10, ("create_local_token failed: %s\n", + nt_errstr(nt_status))); + data_blob_free(&nt_resp); + data_blob_free(&lm_resp); + data_blob_clear_free(&plaintext_password); + return ERROR_NT(nt_status_squash(nt_status)); + } + if (server_info->user_session_key.data) { session_key = data_blob(server_info->user_session_key.data, server_info->user_session_key.length); } else { -- cgit From 7104002cf87fb2636b0819f386da79a037cc0a4e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Feb 2006 23:21:28 +0000 Subject: r13604: Fix for bug #3512 "use spnego=no" and "server signing=auto" cause client to disconnect after negprot" We missed one case of ignoring "BSRSPYL ". Merge for 3.0.21c. Jeremy. (This used to be commit 7d21cf420fdecaee43408ad5cc192cc0715d95a2) --- source3/smbd/sesssetup.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 38e16126e2..1be117a7d4 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -69,6 +69,23 @@ static int add_signature(char *outbuf, char *p) return PTR_DIFF(p, start); } +/**************************************************************************** + Start the signing engine if needed. Don't fail signing here. +****************************************************************************/ + +static void sessionsetup_start_signing_engine(const auth_serversupplied_info *server_info, char *inbuf) +{ + if (!server_info->guest && !srv_signing_started()) { + /* 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, False); + } +} + /**************************************************************************** Send a security blob via a session setup reply. ****************************************************************************/ @@ -355,15 +372,7 @@ static int reply_spnego_kerberos(connection_struct *conn, SSVAL(outbuf, smb_uid, sess_vuid); - if (!server_info->guest && !srv_signing_started()) { - /* 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, False); - } + sessionsetup_start_signing_engine(server_info, inbuf); } /* wrap that up in a nice GSS-API wrapping */ @@ -436,16 +445,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out SSVAL(outbuf,smb_uid,sess_vuid); - if (!server_info->guest && !srv_signing_started()) { - /* 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, False); - } + sessionsetup_start_signing_engine(server_info, inbuf); } } @@ -1107,9 +1107,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* current_user_info is changed on new vuid */ reload_services( True ); - if (!server_info->guest && !srv_signing_started() && !srv_check_sign_mac(inbuf, True)) { - exit_server("reply_sesssetup_and_X: bad smb signature"); - } + sessionsetup_start_signing_engine(server_info, inbuf); SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); -- cgit From 1de2983de4ea1a482c294a9ecce8437cc35ff7ee Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 9 Mar 2006 22:31:37 +0000 Subject: r14112: * fix checks on return code from register_vuid() which could actually fail and we would still return success in the SMBsesssetup reply :-( * Make sure to create the local token for the server_fino struct in reply_spnego_kerberos() so that register_vuid() does not fail. (how did this ever work?) (This used to be commit 8dafa45b97020d1aceb027a85e18401c965bf402) --- source3/smbd/sesssetup.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 1be117a7d4..1abb800627 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -349,6 +349,21 @@ static int reply_spnego_kerberos(connection_struct *conn, pdb_set_domain(server_info->sam_account, domain, PDB_SET); } } + + /* we need to build the token for the user. make_server_info_guest() + already does this */ + + if ( !server_info->ptok ) { + ret = create_local_token( server_info ); + if ( !NT_STATUS_IS_OK(ret) ) { + SAFE_FREE(client); + data_blob_free(&ap_rep); + data_blob_free(&session_key); + TALLOC_FREE( mem_ctx ); + TALLOC_FREE( server_info ); + return ERROR_NT(ret); + } + } /* register_vuid keeps the server info */ /* register_vuid takes ownership of session_key, no need to free after this. @@ -357,7 +372,7 @@ static int reply_spnego_kerberos(connection_struct *conn, SAFE_FREE(client); - if (sess_vuid == -1) { + if (sess_vuid == UID_FIELD_INVALID ) { ret = NT_STATUS_LOGON_FAILURE; } else { /* current_user_info is changed on new vuid */ @@ -429,7 +444,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out sess_vuid = register_vuid(server_info, session_key, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user); (*auth_ntlmssp_state)->server_info = NULL; - if (sess_vuid == -1) { + if (sess_vuid == UID_FIELD_INVALID ) { nt_status = NT_STATUS_LOGON_FAILURE; } else { @@ -674,7 +689,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, vuser = get_partial_auth_user_struct(vuid); if (!vuser) { vuid = register_vuid(NULL, data_blob(NULL, 0), data_blob(NULL, 0), NULL); - if (vuid == -1) { + if (vuid == UID_FIELD_INVALID ) { return ERROR_NT(NT_STATUS_INVALID_PARAMETER); } @@ -1100,7 +1115,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, data_blob_free(&nt_resp); data_blob_free(&lm_resp); - if (sess_vuid == -1) { + if (sess_vuid == UID_FIELD_INVALID) { return ERROR_NT(NT_STATUS_LOGON_FAILURE); } -- cgit From c077d363a4f14afd2c83d57dcd52e6a2c1a2d42b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 10 Mar 2006 08:43:32 +0000 Subject: r14130: Remove make_server_info_pac alltogether, make_server_info_info3 does already do what we need. Guenther (This used to be commit 773e33c9717ae04f48983ddc49f7619a97523603) --- source3/smbd/sesssetup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 1abb800627..98146561b2 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -316,10 +316,10 @@ static int reply_spnego_kerberos(connection_struct *conn, if ( map_domainuser_to_guest ) { make_server_info_guest(&server_info); } else if (logon_info) { - ret = make_server_info_pac(&server_info, real_username, pw, logon_info); - + ret = make_server_info_info3(mem_ctx, real_username, real_username, domain, + &server_info, &logon_info->info3); if ( !NT_STATUS_IS_OK(ret) ) { - DEBUG(1,("make_server_info_pac failed: %s!\n", + DEBUG(1,("make_server_info_info3 failed: %s!\n", nt_errstr(ret))); SAFE_FREE(client); data_blob_free(&ap_rep); -- cgit From 47a11f8a4c6156965163fd89bef668cd6612b70c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Mar 2006 17:52:41 +0000 Subject: r14168: Fix Coverity #219. I think this is a false coverity warning as it seems to get confused with assignment and comparison. Clarify the code anyway. Jeremy. (This used to be commit 754818f8cc0849bddf84b7a534cd65e8dcd932ac) --- source3/smbd/sesssetup.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 98146561b2..d32ff9fa14 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1044,7 +1044,10 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } else { struct auth_context *plaintext_auth_context = NULL; const uint8 *chal; - if (NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) { + + nt_status = make_auth_context_subsystem(&plaintext_auth_context); + + if (NT_STATUS_IS_OK(nt_status)) { chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context); if (!make_user_info_for_reply(&user_info, -- cgit From 5f224c2c265faa50e5495cc738f1a62c6aa70d56 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Mar 2006 18:32:18 +0000 Subject: r14170: Paranioa fix for sesssetup. Fix Coverity bug #26. Guard against NULL ref. Jeremy. (This used to be commit c0f906ac8de850f4566b6b3be4e3c7d245e6e252) --- source3/smbd/sesssetup.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index d32ff9fa14..fcb778d1fe 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1079,6 +1079,11 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, return ERROR_NT(nt_status_squash(nt_status)); } + /* Ensure we can't possible take a code path leading to a null defref. */ + if (!server_info) { + return ERROR_NT(NT_STATUS_LOGON_FAILURE); + } + nt_status = create_local_token(server_info); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(10, ("create_local_token failed: %s\n", -- cgit From 75c965d3a45b6f72b2d2eeb5937ce19dc33af419 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Mar 2006 23:45:08 +0000 Subject: r14790: Fix possible null deref. Coverity #277. Jeremy. (This used to be commit 2454af392a71989ecddb2dbb17a9217658102523) --- source3/smbd/sesssetup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index fcb778d1fe..3280e2d5fc 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -217,7 +217,9 @@ static int reply_spnego_kerberos(connection_struct *conn, if (pac_data) { logon_info = get_logon_info_from_pac(pac_data); - netsamlogon_cache_store( client, &logon_info->info3 ); + if (logon_info) { + netsamlogon_cache_store( client, &logon_info->info3 ); + } } if (!strequal(p+1, lp_realm())) { -- cgit From 6ca1ba38147403bc5a8a3f1ec560c0671b1f9463 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Apr 2006 03:45:09 +0000 Subject: r15115: Fix error return on sessionsetup. Ensure no data blob is added if the logon call failed. Jeremy. (This used to be commit 71d0191c313e2106ae2bdef3119b3ff6e591ee1b) --- source3/smbd/sesssetup.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 3280e2d5fc..7c90263a5b 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -95,21 +95,25 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, { char *p; - set_message(outbuf,4,0,True); + if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + ERROR_NT(nt_status); + } else { + set_message(outbuf,4,0,True); - nt_status = nt_status_squash(nt_status); - SIVAL(outbuf, smb_rcls, NT_STATUS_V(nt_status)); - SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */ - SSVAL(outbuf, smb_vwv3, blob.length); - p = smb_buf(outbuf); + nt_status = nt_status_squash(nt_status); + SIVAL(outbuf, smb_rcls, NT_STATUS_V(nt_status)); + SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */ + SSVAL(outbuf, smb_vwv3, blob.length); + p = smb_buf(outbuf); - /* should we cap this? */ - memcpy(p, blob.data, blob.length); - p += blob.length; + /* should we cap this? */ + memcpy(p, blob.data, blob.length); + p += blob.length; - p += add_signature( outbuf, p ); + p += add_signature( outbuf, p ); - set_message_end(outbuf,p); + set_message_end(outbuf,p); + } show_msg(outbuf); return send_smb(smbd_server_fd(),outbuf); -- cgit From f2e788ca37b8c812ecaa2e6ccd380ebf68597bf0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 May 2006 23:36:36 +0000 Subject: r15467: Ensure every exit error path calls nt_status_squash. Jeremy. (This used to be commit e9b016ced636dfdfcb1c4d7d4313f89ddb5e7cbc) --- source3/smbd/sesssetup.c | 54 ++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7c90263a5b..295d3875e4 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -96,7 +96,7 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, char *p; if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - ERROR_NT(nt_status); + ERROR_NT(nt_status_squash(nt_status)); } else { set_message(outbuf,4,0,True); @@ -186,11 +186,11 @@ static int reply_spnego_kerberos(connection_struct *conn, mem_ctx = talloc_init("reply_spnego_kerberos"); if (mem_ctx == NULL) - return ERROR_NT(NT_STATUS_NO_MEMORY); + return ERROR_NT(nt_status_squash(NT_STATUS_NO_MEMORY)); if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) { talloc_destroy(mem_ctx); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } ret = ads_verify_ticket(mem_ctx, lp_realm(), &ticket, &client, &pac_data, &ap_rep, &session_key); @@ -200,7 +200,7 @@ static int reply_spnego_kerberos(connection_struct *conn, if (!NT_STATUS_IS_OK(ret)) { DEBUG(1,("Failed to verify incoming ticket!\n")); talloc_destroy(mem_ctx); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } DEBUG(3,("Ticket name is [%s]\n", client)); @@ -212,7 +212,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&session_key); SAFE_FREE(client); talloc_destroy(mem_ctx); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } *p = 0; @@ -233,7 +233,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&session_key); SAFE_FREE(client); talloc_destroy(mem_ctx); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } } @@ -311,7 +311,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); talloc_destroy(mem_ctx); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } } @@ -331,7 +331,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); talloc_destroy(mem_ctx); - return ERROR_NT(ret); + return ERROR_NT(nt_status_squash(ret)); } } else { @@ -344,7 +344,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); talloc_destroy(mem_ctx); - return ERROR_NT(ret); + return ERROR_NT(nt_status_squash(ret)); } /* make_server_info_pw does not set the domain. Without this @@ -367,7 +367,7 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&session_key); TALLOC_FREE( mem_ctx ); TALLOC_FREE( server_info ); - return ERROR_NT(ret); + return ERROR_NT(nt_status_squash(ret)); } } @@ -520,7 +520,7 @@ static int reply_spnego_negotiate(connection_struct *conn, /* Kill the intermediate vuid */ invalidate_vuid(vuid); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } /* only look at the first OID for determining the mechToken -- @@ -567,7 +567,7 @@ static int reply_spnego_negotiate(connection_struct *conn, /* Kill the intermediate vuid */ invalidate_vuid(vuid); - return ERROR_NT(nt_status); + return ERROR_NT(nt_status_squash(nt_status)); } nt_status = auth_ntlmssp_update(*auth_ntlmssp_state, @@ -604,7 +604,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, /* Kill the intermediate vuid */ invalidate_vuid(vuid); - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } if (!*auth_ntlmssp_state) { @@ -612,7 +612,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, invalidate_vuid(vuid); /* auth before negotiatiate? */ - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } nt_status = auth_ntlmssp_update(*auth_ntlmssp_state, @@ -664,7 +664,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, if (data_blob_len == 0) { /* an invalid request */ - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } bufrem = smb_bufrem(inbuf, p); @@ -696,14 +696,14 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, if (!vuser) { vuid = register_vuid(NULL, data_blob(NULL, 0), data_blob(NULL, 0), NULL); if (vuid == UID_FIELD_INVALID ) { - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } vuser = get_partial_auth_user_struct(vuid); } if (!vuser) { - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } SSVAL(outbuf,smb_uid,vuid); @@ -733,7 +733,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, /* Kill the intermediate vuid */ invalidate_vuid(vuid); - return ERROR_NT(nt_status); + return ERROR_NT(nt_status_squash(nt_status)); } } @@ -754,7 +754,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, data_blob_free(&blob1); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } /**************************************************************************** @@ -846,7 +846,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) { if (!global_spnego_negotiated) { DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at SPNEGO session setup when it was not negoitiated.\n")); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } if (SVAL(inbuf,smb_vwv4) == 0) { @@ -864,7 +864,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); if ((passlen1 > MAX_PASS_LEN) || (passlen1 > smb_bufrem(inbuf, smb_buf(inbuf)))) { - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } if (doencrypt) { @@ -925,11 +925,11 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* check for nasty tricks */ if (passlen1 > MAX_PASS_LEN || passlen1 > smb_bufrem(inbuf, p)) { - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } if (passlen2 > MAX_PASS_LEN || passlen2 > smb_bufrem(inbuf, p+passlen1)) { - return ERROR_NT(NT_STATUS_INVALID_PARAMETER); + return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } /* Save the lanman2 password and the NT md4 password. */ @@ -1007,7 +1007,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* This has to be here, because 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_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } fstrcpy(sub_user, user); } else { @@ -1038,7 +1038,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } else if (doencrypt) { if (!negprot_global_auth_context) { DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted session setup without negprot denied!\n")); - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } nt_status = make_user_info_for_reply_enc(&user_info, user, domain, lm_resp, nt_resp); @@ -1087,7 +1087,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* Ensure we can't possible take a code path leading to a null defref. */ if (!server_info) { - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } nt_status = create_local_token(server_info); @@ -1130,7 +1130,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, data_blob_free(&lm_resp); if (sess_vuid == UID_FIELD_INVALID) { - return ERROR_NT(NT_STATUS_LOGON_FAILURE); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } /* current_user_info is changed on new vuid */ -- cgit From 83e4ea7e852e4ae9a4ba6fd187787c76f2d54ef6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 6 May 2006 15:46:53 +0000 Subject: r15472: Remove an unused function parameter (This used to be commit d2f39ae7fe79fd31846c555849655023a2d1cbc7) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 295d3875e4..b13042074a 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -322,7 +322,7 @@ static int reply_spnego_kerberos(connection_struct *conn, if ( map_domainuser_to_guest ) { make_server_info_guest(&server_info); } else if (logon_info) { - ret = make_server_info_info3(mem_ctx, real_username, real_username, domain, + ret = make_server_info_info3(mem_ctx, real_username, domain, &server_info, &logon_info->info3); if ( !NT_STATUS_IS_OK(ret) ) { DEBUG(1,("make_server_info_info3 failed: %s!\n", -- cgit From dc9f30b8b0ace8d6e2c8c0cbed537fde68d1556a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 6 May 2006 19:24:35 +0000 Subject: r15475: Ugly and disgusting patch to fix the username map problem I created by changing the token generation. I *hate* this code! Jerry, you have been looking at this as well, can you double-check that I did not screw it up? Thanks, Volker (This used to be commit 2765c4ff8d44c970db3e075b0a2412662f1936c6) --- source3/smbd/sesssetup.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index b13042074a..b086090bd9 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -176,6 +176,7 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB nullblob = data_blob(NULL, 0); fstring real_username; BOOL map_domainuser_to_guest = False; + BOOL username_was_mapped; PAC_LOGON_INFO *logon_info = NULL; ZERO_STRUCT(ticket); @@ -288,7 +289,7 @@ static int reply_spnego_kerberos(connection_struct *conn, /* lookup the passwd struct, create a new user if necessary */ - map_username( user ); + username_was_mapped = map_username( user ); pw = smb_getpwnam( mem_ctx, user, real_username, True ); if (!pw) { @@ -355,6 +356,8 @@ static int reply_spnego_kerberos(connection_struct *conn, pdb_set_domain(server_info->sam_account, domain, PDB_SET); } } + + server_info->was_mapped |= username_was_mapped; /* we need to build the token for the user. make_server_info_guest() already does this */ -- cgit From f7776975080c88bec9013ccac8185c582e818e54 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 9 May 2006 19:02:26 +0000 Subject: r15523: Honour the time_offset also when verifying kerberos tickets. This prevents a nasty failure condition in winbindd's pam_auth where a tgt and a service ticket could have been succefully retrieved, but just not validated. Guenther (This used to be commit a75dd80c6210d01aff104a86b0a9d39d65f2c348) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index b086090bd9..8fe01a19b3 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -194,7 +194,7 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } - ret = ads_verify_ticket(mem_ctx, lp_realm(), &ticket, &client, &pac_data, &ap_rep, &session_key); + ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket, &client, &pac_data, &ap_rep, &session_key); data_blob_free(&ticket); -- cgit From ee7b4b47cb590dc16ebdf3a40b360b0f0600aa84 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 May 2006 23:05:53 +0000 Subject: r15589: While trying to understand the vuid code I found that security=share is broken right now. r14112 broke it, in 3.0.22 register_vuid for security=share returns UID_FIELD_INVALID which in current 3_0 is turned into an error condition. This makes sure that we only call register_vuid if sec!=share and meanwhile also fixes a little memleak. Then I also found a crash in smbclient with sec=share and hostmsdfs=yes. There's another crash with sec=share when coming from w2k3, but I need sleep now. Someone (jerry,jra?) please review the sesssetup.c change. Thanks, Volker (This used to be commit 8059d0ae395604503cad3d9f197928305923e3f5) --- source3/smbd/sesssetup.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 8fe01a19b3..46acb20bda 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1127,20 +1127,30 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* register the name and uid as being validated, so further connections 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, session_key, nt_resp.data ? nt_resp : lm_resp, sub_user); - data_blob_free(&nt_resp); - data_blob_free(&lm_resp); - - if (sess_vuid == UID_FIELD_INVALID) { - return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); - } + if (lp_security() == SEC_SHARE) { + sess_vuid = UID_FIELD_INVALID; + data_blob_free(&session_key); + TALLOC_FREE(server_info); + } else { + /* register_vuid keeps the server info */ + sess_vuid = register_vuid(server_info, session_key, + nt_resp.data ? nt_resp : lm_resp, + sub_user); + if (sess_vuid == UID_FIELD_INVALID) { + data_blob_free(&nt_resp); + data_blob_free(&lm_resp); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + } - /* current_user_info is changed on new vuid */ - reload_services( True ); + /* current_user_info is changed on new vuid */ + reload_services( True ); - sessionsetup_start_signing_engine(server_info, inbuf); + sessionsetup_start_signing_engine(server_info, inbuf); + } + data_blob_free(&nt_resp); + data_blob_free(&lm_resp); + SSVAL(outbuf,smb_uid,sess_vuid); SSVAL(inbuf,smb_uid,sess_vuid); -- cgit From ce61fb21d948bd8e3c7733d542f8ecae1390cbfc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Jun 2006 02:38:28 +0000 Subject: r16397: Fix Klocwork #11767 and drasticly simplify the logic in smbd/process.c. All interested (Volker, Jerry, James etc). PLEASE REVIEW THIS CHANGE. The logic should be identical but *much* easier to follow and change (and shouldn't confuse Klockwork :-). Jeremy. (This used to be commit d357f8b33594472ffa78d0a112accccc2a8b1fe7) --- source3/smbd/sesssetup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 46acb20bda..fb579707ca 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -635,6 +635,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, /**************************************************************************** Reply to a session setup command. + conn POINTER CAN BE NULL HERE ! ****************************************************************************/ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, -- cgit From 545353b062a82920fa8040f248d55c04da33f735 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 29 Aug 2006 15:42:09 +0000 Subject: r17909: ensure we do not call map_username() twice on Krb5 session setups (This used to be commit 779eba0a7cab3156b8580410cfe288609a288548) --- source3/smbd/sesssetup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index fb579707ca..dd8d9fc852 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -320,10 +320,14 @@ static int reply_spnego_kerberos(connection_struct *conn, sub_set_smb_name( real_username ); reload_services(True); + if ( map_domainuser_to_guest ) { make_server_info_guest(&server_info); } else if (logon_info) { - ret = make_server_info_info3(mem_ctx, real_username, domain, + /* pass the unmapped username here since map_username() + will be called again from inside make_server_info_info3() */ + + ret = make_server_info_info3(mem_ctx, user, domain, &server_info, &logon_info->info3); if ( !NT_STATUS_IS_OK(ret) ) { DEBUG(1,("make_server_info_info3 failed: %s!\n", -- cgit From c432bfc14b18988f1e74a6364340eb1f09084b2e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 11 Sep 2006 21:06:44 +0000 Subject: r18398: Fix bug #4095 - username composed into domain\user twice in spnego path. Jerry please check. Jeremy. (This used to be commit e872bacf2850cfb66be1c57be40484fe8e4c2da5) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index dd8d9fc852..8c8173ef37 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -327,7 +327,7 @@ static int reply_spnego_kerberos(connection_struct *conn, /* pass the unmapped username here since map_username() will be called again from inside make_server_info_info3() */ - ret = make_server_info_info3(mem_ctx, user, domain, + ret = make_server_info_info3(mem_ctx, client, domain, &server_info, &logon_info->info3); if ( !NT_STATUS_IS_OK(ret) ) { DEBUG(1,("make_server_info_info3 failed: %s!\n", -- cgit From 68a2430c526ae4b94ecec9690a64936299808140 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 11 Sep 2006 21:48:30 +0000 Subject: r18403: Revert until we get this sorted out correctly. Jeremy. (This used to be commit d0fdd5eb1e0c8bf135c267d4ff8183899345beaa) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 8c8173ef37..dd8d9fc852 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -327,7 +327,7 @@ static int reply_spnego_kerberos(connection_struct *conn, /* pass the unmapped username here since map_username() will be called again from inside make_server_info_info3() */ - ret = make_server_info_info3(mem_ctx, client, domain, + ret = make_server_info_info3(mem_ctx, user, domain, &server_info, &logon_info->info3); if ( !NT_STATUS_IS_OK(ret) ) { DEBUG(1,("make_server_info_info3 failed: %s!\n", -- cgit From 28800c54dc835d8a3aa97299b1df989ddfd04df2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 25 Sep 2006 20:59:48 +0000 Subject: r18907: W00t. My original fix was correct after all :-). Re-checking it in. Fix bug #4095 - username composed into domain\user twice in spnego path. Jeremy. (This used to be commit 0c770467519e73897462e730c3226e65668d3890) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index dd8d9fc852..8c8173ef37 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -327,7 +327,7 @@ static int reply_spnego_kerberos(connection_struct *conn, /* pass the unmapped username here since map_username() will be called again from inside make_server_info_info3() */ - ret = make_server_info_info3(mem_ctx, user, domain, + ret = make_server_info_info3(mem_ctx, client, domain, &server_info, &logon_info->info3); if ( !NT_STATUS_IS_OK(ret) ) { DEBUG(1,("make_server_info_info3 failed: %s!\n", -- cgit From ef8d6bf5f700dcfeec7919203da9c357c4f21e3f Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 1 Dec 2006 15:04:53 +0000 Subject: r19979: Fix memleak on pw and change talloc_destroy to TALLOC_FREE for mem_ctx (This used to be commit defa0a352b32469984126ec5d47aab9ef8d6b61c) --- source3/smbd/sesssetup.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 8c8173ef37..ae6dd49663 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -335,7 +335,8 @@ static int reply_spnego_kerberos(connection_struct *conn, SAFE_FREE(client); data_blob_free(&ap_rep); data_blob_free(&session_key); - talloc_destroy(mem_ctx); + TALLOC_FREE(mem_ctx); + TALLOC_FREE(pw); return ERROR_NT(nt_status_squash(ret)); } @@ -348,7 +349,8 @@ static int reply_spnego_kerberos(connection_struct *conn, SAFE_FREE(client); data_blob_free(&ap_rep); data_blob_free(&session_key); - talloc_destroy(mem_ctx); + TALLOC_FREE(mem_ctx); + TALLOC_FREE(pw); return ERROR_NT(nt_status_squash(ret)); } @@ -372,6 +374,7 @@ static int reply_spnego_kerberos(connection_struct *conn, SAFE_FREE(client); data_blob_free(&ap_rep); data_blob_free(&session_key); + TALLOC_FREE(pw); TALLOC_FREE( mem_ctx ); TALLOC_FREE( server_info ); return ERROR_NT(nt_status_squash(ret)); @@ -415,7 +418,8 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&ap_rep_wrapped); data_blob_free(&response); - talloc_destroy(mem_ctx); + TALLOC_FREE(mem_ctx); + TALLOC_FREE(pw); return -1; /* already replied */ } -- cgit From cb0402c2d3941a813e33b2b5e07c54b9ff644ca4 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 1 Dec 2006 15:06:34 +0000 Subject: r19980: Implement pam account stack checks when obey pam restrictions is true. It was missing for security=server/domain/ads Simo. (This used to be commit 550f651499c22c3c11594a0a39061a8a9b438d82) --- source3/smbd/sesssetup.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index ae6dd49663..11c5e9bbf9 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -292,6 +292,22 @@ static int reply_spnego_kerberos(connection_struct *conn, username_was_mapped = map_username( user ); pw = smb_getpwnam( mem_ctx, user, real_username, True ); + + if (pw) { + /* if a real user check pam account restrictions */ + /* only really perfomed if "obey pam restriction" is true */ + /* do this before an eventual mappign to guest occurs */ + ret = smb_pam_accountcheck(pw->pw_name); + if ( !NT_STATUS_IS_OK(ret)) { + DEBUG(1, ("PAM account restriction prevents user login\n")); + data_blob_free(&ap_rep); + data_blob_free(&session_key); + talloc_destroy(mem_ctx); + TALLOC_FREE(pw); + return ERROR_NT(nt_status_squash(ret)); + } + } + if (!pw) { /* this was originally the behavior of Samba 2.2, if a user -- cgit From c81c8cb4a7962f5437690a106bd7793b38175af2 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 1 Dec 2006 16:13:06 +0000 Subject: r19984: Must have been drunk yesterday. Freeing memctx is all we need, fix double free stupidity (This used to be commit 2a7454959e93e5bd11161707d0bd16a431b92351) --- source3/smbd/sesssetup.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 11c5e9bbf9..0cf6692e22 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -302,8 +302,7 @@ static int reply_spnego_kerberos(connection_struct *conn, DEBUG(1, ("PAM account restriction prevents user login\n")); data_blob_free(&ap_rep); data_blob_free(&session_key); - talloc_destroy(mem_ctx); - TALLOC_FREE(pw); + TALLOC_FREE(mem_ctx); return ERROR_NT(nt_status_squash(ret)); } } @@ -327,7 +326,7 @@ static int reply_spnego_kerberos(connection_struct *conn, SAFE_FREE(client); data_blob_free(&ap_rep); data_blob_free(&session_key); - talloc_destroy(mem_ctx); + TALLOC_FREE(mem_ctx); return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } } @@ -335,6 +334,8 @@ static int reply_spnego_kerberos(connection_struct *conn, /* setup the string used by %U */ sub_set_smb_name( real_username ); +C_FR +C_FREE reload_services(True); if ( map_domainuser_to_guest ) { @@ -352,7 +353,6 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); TALLOC_FREE(mem_ctx); - TALLOC_FREE(pw); return ERROR_NT(nt_status_squash(ret)); } @@ -366,7 +366,6 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); TALLOC_FREE(mem_ctx); - TALLOC_FREE(pw); return ERROR_NT(nt_status_squash(ret)); } @@ -390,7 +389,6 @@ static int reply_spnego_kerberos(connection_struct *conn, SAFE_FREE(client); data_blob_free(&ap_rep); data_blob_free(&session_key); - TALLOC_FREE(pw); TALLOC_FREE( mem_ctx ); TALLOC_FREE( server_info ); return ERROR_NT(nt_status_squash(ret)); @@ -435,7 +433,6 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep_wrapped); data_blob_free(&response); TALLOC_FREE(mem_ctx); - TALLOC_FREE(pw); return -1; /* already replied */ } -- cgit From dc2ed4c830842a21c205fb453d5b15a8e46d1dbc Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 1 Dec 2006 16:37:25 +0000 Subject: r19986: ooops (This used to be commit 97f150fbbbee4837c15de121b418881241f321e2) --- source3/smbd/sesssetup.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 0cf6692e22..1603490441 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -334,8 +334,6 @@ static int reply_spnego_kerberos(connection_struct *conn, /* setup the string used by %U */ sub_set_smb_name( real_username ); -C_FR -C_FREE reload_services(True); if ( map_domainuser_to_guest ) { -- cgit From 791f48f167de339c8ae371e5c80706511fd10018 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 12 Dec 2006 17:38:42 +0000 Subject: r20124: clean up nested extern declaration warnings (This used to be commit ac3eb7813e33b9a2e78c9158433f7ed62c3b62bb) --- source3/smbd/sesssetup.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 1603490441..4d731f9c59 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -23,6 +23,12 @@ #include "includes.h" +extern struct auth_context *negprot_global_auth_context; +extern BOOL global_encrypted_passwords_negotiated; +extern BOOL global_spnego_negotiated; +extern enum protocol_types Protocol; +extern int max_send; + uint32 global_client_caps = 0; /* @@ -840,13 +846,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, fstring native_lanman; fstring primary_domain; static BOOL done_sesssetup = False; - extern BOOL global_encrypted_passwords_negotiated; - extern BOOL global_spnego_negotiated; - extern enum protocol_types Protocol; - extern int max_send; - auth_usersupplied_info *user_info = NULL; - extern struct auth_context *negprot_global_auth_context; auth_serversupplied_info *server_info = NULL; NTSTATUS nt_status; -- cgit From 685ca94ac24842fddf22e31edc39de40b0729248 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Feb 2007 22:02:42 +0000 Subject: r21128: Fix Vista connecting to Samba in share level security. Vista sends the NTLMv2 blob by default in the tconX packet. Make sure we save off the workgroup the user was logged into on the client in the sessionsetupX and re-use it for the NTLMv2 calc. Jeremy. (This used to be commit 45dcf62960c2815c4d8e0c5f4a2d0af24df83290) --- source3/smbd/sesssetup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 4d731f9c59..6c5e8f678f 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1050,6 +1050,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, map_username(sub_user); add_session_user(sub_user); + add_session_workgroup(domain); /* Then force it to null for the benfit of the code below */ *user = 0; } -- cgit From f77bdcf6c71a9d0274d96298b136300d5bb05bb1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Feb 2007 06:22:20 +0000 Subject: r21460: Fix for server-side processing of SPNEGO auth fragmented into "max xmit" size security blob chunks. Bug #4400. Needs limits adding, and also a client-side version. Jeremy. (This used to be commit aa69f2481aafee5dccc3783b8a6e23ca4eb0dbfa) --- source3/smbd/sesssetup.c | 226 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 216 insertions(+), 10 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 6c5e8f678f..9b9ae4c353 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -658,6 +658,183 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, return -1; } +/**************************************************************************** + List to store partial SPNEGO auth fragments. +****************************************************************************/ + +static struct pending_auth_data *pd_list; + +/**************************************************************************** + Delete an entry on the list. +****************************************************************************/ + +static void delete_partial_auth(struct pending_auth_data *pad) +{ + DLIST_REMOVE(pd_list, pad); + data_blob_free(&pad->partial_data); + SAFE_FREE(pad); +} + +/**************************************************************************** + Search for a partial SPNEGO auth fragment matching an smbpid. +****************************************************************************/ + +static struct pending_auth_data *get_pending_auth_data(uint16 smbpid) +{ + struct pending_auth_data *pad; + + for (pad = pd_list; pad; pad = pad->next) { + if (pad->smbpid == smbpid) { + break; + } + } + return pad; +} + +/**************************************************************************** + Check the size of an SPNEGO blob. If we need more return NT_STATUS_MORE_PROCESSING_REQUIRED, + else return NT_STATUS_OK. +****************************************************************************/ + +static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB *pblob) +{ + struct pending_auth_data *pad; + ASN1_DATA data; + size_t needed_len = 0; + + /* Ensure we have some data. */ + if (pblob->length == 0) { + /* Caller can cope. */ + DEBUG(2,("check_spnego_blob_complete: zero blob length !\n")); + delete_partial_auth(pad); + return NT_STATUS_OK; + } + + pad = get_pending_auth_data(smbpid); + + /* Were we waiting for more data ? */ + if (pad) { + DATA_BLOB tmp_blob; + + /* Integer wrap paranoia.... */ + + if (pad->partial_data.length + pblob->length < pad->partial_data.length || + pad->partial_data.length + pblob->length < pblob->length) { + + DEBUG(2,("check_spnego_blob_complete: integer wrap " + "pad->partial_data.length = %u, " + "pblob->length = %u\n", + (unsigned int)pad->partial_data.length, + (unsigned int)pblob->length )); + + delete_partial_auth(pad); + return NT_STATUS_INVALID_PARAMETER; + } + + DEBUG(10,("check_spnego_blob_complete: " + "pad->partial_data.length = %u, " + "pad->needed_len = %u, " + "pblob->length = %u,\n", + (unsigned int)pad->partial_data.length, + (unsigned int)pad->needed_len, + (unsigned int)pblob->length )); + + tmp_blob = data_blob(NULL, + pad->partial_data.length + pblob->length); + + /* Concatenate the two. */ + memcpy(tmp_blob.data, + pad->partial_data.data, + pad->partial_data.length); + memcpy(tmp_blob.data + pad->partial_data.length, + pblob->data, + pblob->length); + + /* Replace the partial data. */ + data_blob_free(&pad->partial_data); + pad->partial_data = tmp_blob; + ZERO_STRUCT(tmp_blob); + + /* Are we done ? */ + if (pblob->length >= pad->needed_len) { + /* Yes, replace pblob. */ + data_blob_free(pblob); + *pblob = pad->partial_data; + ZERO_STRUCT(pad->partial_data); + delete_partial_auth(pad); + return NT_STATUS_OK; + } + + /* Still need more data. */ + pad->needed_len -= pblob->length; + return NT_STATUS_MORE_PROCESSING_REQUIRED; + } + + if ((pblob->data[0] != ASN1_APPLICATION(0)) && + (pblob->data[0] != ASN1_CONTEXT(1))) { + /* Not something we can determine the + * length of. + */ + return NT_STATUS_OK; + } + + /* This is a new SPNEGO sessionsetup - see if + * the data given in this blob is enough. + */ + + asn1_load(&data, *pblob); + asn1_start_tag(&data, pblob->data[0]); + if (data.has_error || data.nesting == NULL) { + asn1_free(&data); + /* Let caller catch. */ + return NT_STATUS_OK; + } + + /* Integer wrap paranoia.... */ + + if (data.nesting->taglen + data.nesting->start < data.nesting->taglen || + data.nesting->taglen + data.nesting->start < data.nesting->start) { + + DEBUG(2,("check_spnego_blob_complete: integer wrap " + "data.nesting->taglen = %u, " + "data.nesting->start = %u\n", + (unsigned int)data.nesting->taglen, + (unsigned int)data.nesting->start )); + + asn1_free(&data); + return NT_STATUS_INVALID_PARAMETER; + } + + /* Total length of the needed asn1 is the tag length + * plus the current offset. */ + + needed_len = data.nesting->taglen + data.nesting->start; + asn1_free(&data); + + DEBUG(10,("check_spnego_blob_complete: needed_len = %u, " + "pblob->length = %u\n", + (unsigned int)needed_len, + (unsigned int)pblob->length )); + + if (needed_len <= pblob->length) { + /* Nothing to do - blob is complete. */ + return NT_STATUS_OK; + } + + /* We must store this blob until complete. */ + pad = SMB_MALLOC(sizeof(struct pending_auth_data)); + if (!pad) { + return NT_STATUS_NO_MEMORY; + } + pad->needed_len = needed_len - pblob->length; + pad->partial_data = data_blob(pblob->data, pblob->length); + pad->smbpid = smbpid; + pad->vuid = vuid; + DLIST_ADD(pd_list, pad); + + return NT_STATUS_MORE_PROCESSING_REQUIRED; +} + /**************************************************************************** Reply to a session setup command. conn POINTER CAN BE NULL HERE ! @@ -677,6 +854,8 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, enum remote_arch_types ra_type = get_remote_arch(); int vuid = SVAL(inbuf,smb_uid); user_struct *vuser = NULL; + NTSTATUS status = NT_STATUS_OK; + uint16 smbpid = SVAL(inbuf,smb_pid); DEBUG(3,("Doing spnego session setup\n")); @@ -715,16 +894,28 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, /* Windows 2003 doesn't set the native lanman string, but does set primary domain which is a bug I think */ - if ( !strlen(native_lanman) ) + if ( !strlen(native_lanman) ) { ra_lanman_string( primary_domain ); - else + } else { ra_lanman_string( native_lanman ); + } } vuser = get_partial_auth_user_struct(vuid); + if (!vuser) { + struct pending_auth_data *pad = get_pending_auth_data(smbpid); + if (pad) { + DEBUG(10,("reply_sesssetup_and_X_spnego: found pending vuid %u\n", + (unsigned int)pad->vuid )); + vuid = pad->vuid; + vuser = get_partial_auth_user_struct(vuid); + } + } + if (!vuser) { vuid = register_vuid(NULL, data_blob(NULL, 0), data_blob(NULL, 0), NULL); if (vuid == UID_FIELD_INVALID ) { + data_blob_free(&blob1); return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } @@ -732,11 +923,27 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, } if (!vuser) { + data_blob_free(&blob1); return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } SSVAL(outbuf,smb_uid,vuid); - + + /* Large (greater than 4k) SPNEGO blobs are split into multiple + * sessionsetup requests as the Windows limit on the security blob + * field is 4k. Bug #4400. JRA. + */ + + status = check_spnego_blob_complete(smbpid, vuid, &blob1); + if (!NT_STATUS_IS_OK(status)) { + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + /* Real error - kill the intermediate vuid */ + invalidate_vuid(vuid); + } + data_blob_free(&blob1); + return ERROR_NT(nt_status_squash(status)); + } + if (blob1.data[0] == ASN1_APPLICATION(0)) { /* its a negTokenTarg packet */ ret = reply_spnego_negotiate(conn, inbuf, outbuf, vuid, length, bufsize, blob1, @@ -755,25 +962,24 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) { DATA_BLOB chal; - NTSTATUS nt_status; if (!vuser->auth_ntlmssp_state) { - nt_status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state); - if (!NT_STATUS_IS_OK(nt_status)) { + status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state); + if (!NT_STATUS_IS_OK(status)) { /* Kill the intermediate vuid */ invalidate_vuid(vuid); - - return ERROR_NT(nt_status_squash(nt_status)); + data_blob_free(&blob1); + return ERROR_NT(nt_status_squash(status)); } } - nt_status = auth_ntlmssp_update(vuser->auth_ntlmssp_state, + status = auth_ntlmssp_update(vuser->auth_ntlmssp_state, blob1, &chal); data_blob_free(&blob1); reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, &vuser->auth_ntlmssp_state, - &chal, nt_status, False); + &chal, status, False); data_blob_free(&chal); return -1; } -- cgit From b45442e46d595337c17829aed2d846a8c8963e6e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 20 Feb 2007 12:16:20 +0000 Subject: r21461: Not strictly necessary, as data_blob() panics if it can't allocate. But I'd see this as a design flaw in data_blob() and it made me look in that routine. Jeremy, revert or merge please :-) Volker (This used to be commit e7e6b8b5e0b00cc0746db4e9baa2e860074f903a) --- source3/smbd/sesssetup.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 9b9ae4c353..6ca306ac25 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -828,6 +828,10 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB } pad->needed_len = needed_len - pblob->length; pad->partial_data = data_blob(pblob->data, pblob->length); + if (pad->partial_data.data == NULL) { + SAFE_FREE(pad); + return NT_STATUS_NO_MEMORY; + } pad->smbpid = smbpid; pad->vuid = vuid; DLIST_ADD(pd_list, pad); -- cgit From cedcf06b22bb30ca52a8bbb21fd331ec20ef9180 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Feb 2007 23:56:46 +0000 Subject: r21478: Add 65k length limit for split SPNEGO blobs. Jeremy (This used to be commit 6be078da267677e3e558033c28099e3932a17712) --- source3/smbd/sesssetup.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 6ca306ac25..4e27914c0d 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -693,7 +693,7 @@ static struct pending_auth_data *get_pending_auth_data(uint16 smbpid) /**************************************************************************** Check the size of an SPNEGO blob. If we need more return NT_STATUS_MORE_PROCESSING_REQUIRED, - else return NT_STATUS_OK. + else return NT_STATUS_OK. Don't allow the blob to be more than 64k. ****************************************************************************/ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB *pblob) @@ -715,17 +715,18 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB /* Were we waiting for more data ? */ if (pad) { DATA_BLOB tmp_blob; + size_t copy_len = MIN(65536, pblob->length); /* Integer wrap paranoia.... */ - if (pad->partial_data.length + pblob->length < pad->partial_data.length || - pad->partial_data.length + pblob->length < pblob->length) { + if (pad->partial_data.length + copy_len < pad->partial_data.length || + pad->partial_data.length + copy_len < copy_len) { DEBUG(2,("check_spnego_blob_complete: integer wrap " "pad->partial_data.length = %u, " - "pblob->length = %u\n", + "copy_len = %u\n", (unsigned int)pad->partial_data.length, - (unsigned int)pblob->length )); + (unsigned int)copy_len )); delete_partial_auth(pad); return NT_STATUS_INVALID_PARAMETER; @@ -734,21 +735,23 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB DEBUG(10,("check_spnego_blob_complete: " "pad->partial_data.length = %u, " "pad->needed_len = %u, " + "copy_len = %u, " "pblob->length = %u,\n", (unsigned int)pad->partial_data.length, (unsigned int)pad->needed_len, + (unsigned int)copy_len, (unsigned int)pblob->length )); tmp_blob = data_blob(NULL, - pad->partial_data.length + pblob->length); + pad->partial_data.length + copy_len); - /* Concatenate the two. */ + /* Concatenate the two (up to copy_len) bytes. */ memcpy(tmp_blob.data, pad->partial_data.data, pad->partial_data.length); memcpy(tmp_blob.data + pad->partial_data.length, pblob->data, - pblob->length); + copy_len); /* Replace the partial data. */ data_blob_free(&pad->partial_data); @@ -766,7 +769,7 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB } /* Still need more data. */ - pad->needed_len -= pblob->length; + pad->needed_len -= copy_len; return NT_STATUS_MORE_PROCESSING_REQUIRED; } @@ -821,6 +824,13 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB return NT_STATUS_OK; } + /* Refuse the blob if it's bigger than 64k. */ + if (needed_len > 65536) { + DEBUG(2,("check_spnego_blob_complete: needed_len too large (%u)\n", + (unsigned int)needed_len )); + return NT_STATUS_INVALID_PARAMETER; + } + /* We must store this blob until complete. */ pad = SMB_MALLOC(sizeof(struct pending_auth_data)); if (!pad) { -- cgit From ca229b0980b5c78f140180db764b3229d5ccb078 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Feb 2007 02:15:23 +0000 Subject: r21483: Fix use of uninitialized variable. Jeremy. (This used to be commit 4a74d042c9108ed68cc92f27b390c261c0bc8885) --- source3/smbd/sesssetup.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 4e27914c0d..7a5f8be47f 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -670,6 +670,9 @@ static struct pending_auth_data *pd_list; static void delete_partial_auth(struct pending_auth_data *pad) { + if (!pad) { + return; + } DLIST_REMOVE(pd_list, pad); data_blob_free(&pad->partial_data); SAFE_FREE(pad); @@ -698,10 +701,12 @@ static struct pending_auth_data *get_pending_auth_data(uint16 smbpid) static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB *pblob) { - struct pending_auth_data *pad; + struct pending_auth_data *pad = NULL; ASN1_DATA data; size_t needed_len = 0; + pad = get_pending_auth_data(smbpid); + /* Ensure we have some data. */ if (pblob->length == 0) { /* Caller can cope. */ @@ -710,8 +715,6 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB return NT_STATUS_OK; } - pad = get_pending_auth_data(smbpid); - /* Were we waiting for more data ? */ if (pad) { DATA_BLOB tmp_blob; -- cgit From edccfc91928c323f18febb7b90e41e0ddbfd8c7c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Mar 2007 19:18:18 +0000 Subject: r21845: Refactor the sessionsetupX code a little to allow us to return a NT_STATUS_TIME_DIFFERENCE_AT_DC error to a client when there's clock skew. Will help people debug this. Prepare us for being able to return the correct sessionsetupX "NT_STATUS_MORE_PROCESSING_REQUIRED" error with associated krb5 clock skew error to allow clients to re-sync time with us when we're eventually able to be a KDC. Jeremy. (This used to be commit c426340fc79a6b446033433b8de599130adffe28) --- source3/smbd/sesssetup.c | 235 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 193 insertions(+), 42 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7a5f8be47f..e678d959d8 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -158,13 +158,75 @@ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) #ifdef HAVE_KRB5 + +#if 0 +/* Experiment that failed. See "only happens with a KDC" comment below. */ +/**************************************************************************** + Cerate a clock skew error blob for a Windows client. +****************************************************************************/ + +static BOOL make_krb5_skew_error(DATA_BLOB *pblob_out) +{ + krb5_context context = NULL; + krb5_error_code kerr = 0; + krb5_data reply; + krb5_principal host_princ = NULL; + char *host_princ_s = NULL; + BOOL ret = False; + + *pblob_out = data_blob(NULL,0); + + kerr = krb5_init_context(&context); + if (kerr) { + return False; + } + /* Create server principal. */ + asprintf(&host_princ_s, "%s$@%s", global_myname(), lp_realm()); + if (!host_princ_s) { + goto out; + } + strlower_m(host_princ_s); + + kerr = smb_krb5_parse_name(context, host_princ_s, &host_princ); + if (kerr) { + DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed for name %s: Error %s\n", + host_princ_s, error_message(kerr) )); + goto out; + } + + kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW, host_princ, &reply); + if (kerr) { + DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error failed: Error %s\n", + error_message(kerr) )); + goto out; + } + + *pblob_out = data_blob(reply.data, reply.length); + kerberos_free_data_contents(context,&reply); + ret = True; + + out: + + if (host_princ_s) { + SAFE_FREE(host_princ_s); + } + if (host_princ) { + krb5_free_principal(context, host_princ); + } + krb5_free_context(context); + return ret; +} +#endif + /**************************************************************************** -reply to a session setup spnego negotiate packet for kerberos + Reply to a session setup spnego negotiate packet for kerberos. ****************************************************************************/ + static int reply_spnego_kerberos(connection_struct *conn, char *inbuf, char *outbuf, int length, int bufsize, - DATA_BLOB *secblob) + DATA_BLOB *secblob, + BOOL *p_invalidate_vuid) { TALLOC_CTX *mem_ctx; DATA_BLOB ticket; @@ -191,9 +253,13 @@ static int reply_spnego_kerberos(connection_struct *conn, ZERO_STRUCT(ap_rep_wrapped); ZERO_STRUCT(response); + /* Normally we will always invalidate the intermediate vuid. */ + *p_invalidate_vuid = True; + mem_ctx = talloc_init("reply_spnego_kerberos"); - if (mem_ctx == NULL) + if (mem_ctx == NULL) { return ERROR_NT(nt_status_squash(NT_STATUS_NO_MEMORY)); + } if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) { talloc_destroy(mem_ctx); @@ -205,9 +271,50 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ticket); if (!NT_STATUS_IS_OK(ret)) { - DEBUG(1,("Failed to verify incoming ticket!\n")); +#if 0 + /* Experiment that failed. See "only happens with a KDC" comment below. */ + + if (NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) { + + /* + * Windows in this case returns NT_STATUS_MORE_PROCESSING_REQUIRED + * with a negTokenTarg blob containing an krb5_error struct ASN1 encoded + * containing KRB5KRB_AP_ERR_SKEW. The client then fixes its + * clock and continues rather than giving an error. JRA. + * -- Looks like this only happens with a KDC. JRA. + */ + + BOOL ok = make_krb5_skew_error(&ap_rep); + if (!ok) { + talloc_destroy(mem_ctx); + return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + } + ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_ERROR); + response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD); + reply_sesssetup_blob(conn, outbuf, response, NT_STATUS_MORE_PROCESSING_REQUIRED); + + /* + * In this one case we don't invalidate the intermediate vuid. + * as we're expecting the client to re-use it for the next + * sessionsetupX packet. JRA. + */ + + *p_invalidate_vuid = False; + + data_blob_free(&ap_rep); + data_blob_free(&ap_rep_wrapped); + data_blob_free(&response); + talloc_destroy(mem_ctx); + return -1; /* already replied */ + } +#else + if (!NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) { + ret = NT_STATUS_LOGON_FAILURE; + } +#endif + DEBUG(1,("Failed to verify incoming ticket with error %s!\n", nt_errstr(ret))); talloc_destroy(mem_ctx); - return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + return ERROR_NT(nt_status_squash(ret)); } DEBUG(3,("Ticket name is [%s]\n", client)); @@ -523,32 +630,19 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out } /**************************************************************************** - Reply to a session setup spnego negotiate packet. + Is this a krb5 mechanism ? ****************************************************************************/ -static int reply_spnego_negotiate(connection_struct *conn, - char *inbuf, - char *outbuf, - uint16 vuid, - int length, int bufsize, - DATA_BLOB blob1, - AUTH_NTLMSSP_STATE **auth_ntlmssp_state) +static NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, BOOL *p_is_krb5) { char *OIDs[ASN1_MAX_OIDS]; - DATA_BLOB secblob; int i; - DATA_BLOB chal; -#ifdef HAVE_KRB5 - BOOL got_kerberos_mechanism = False; -#endif - NTSTATUS nt_status; - /* parse out the OIDs and the first sec blob */ - if (!parse_negTokenTarg(blob1, OIDs, &secblob)) { - /* Kill the intermediate vuid */ - invalidate_vuid(vuid); + *p_is_krb5 = False; - return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + /* parse out the OIDs and the first sec blob */ + if (!parse_negTokenTarg(blob_in, OIDs, pblob_out)) { + return NT_STATUS_LOGON_FAILURE; } /* only look at the first OID for determining the mechToken -- @@ -564,24 +658,53 @@ static int reply_spnego_negotiate(connection_struct *conn, #ifdef HAVE_KRB5 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) { - got_kerberos_mechanism = True; + *p_is_krb5 = True; } #endif for (i=0;OIDs[i];i++) { - DEBUG(3,("Got OID %s\n", OIDs[i])); + DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i])); free(OIDs[i]); } - DEBUG(3,("Got secblob of size %lu\n", (unsigned long)secblob.length)); + return NT_STATUS_OK; +} + +/**************************************************************************** + Reply to a session setup spnego negotiate packet. +****************************************************************************/ + +static int reply_spnego_negotiate(connection_struct *conn, + char *inbuf, + char *outbuf, + uint16 vuid, + int length, int bufsize, + DATA_BLOB blob1, + AUTH_NTLMSSP_STATE **auth_ntlmssp_state) +{ + DATA_BLOB secblob; + DATA_BLOB chal; + BOOL got_kerberos_mechanism = False; + NTSTATUS status; + + status = parse_spnego_mechanisms(blob1, &secblob, &got_kerberos_mechanism); + if (!NT_STATUS_IS_OK(status)) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + return ERROR_NT(nt_status_squash(status)); + } + + DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length)); #ifdef HAVE_KRB5 if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { + BOOL destroy_vuid = True; int ret = reply_spnego_kerberos(conn, inbuf, outbuf, - length, bufsize, &secblob); + length, bufsize, &secblob, &destroy_vuid); data_blob_free(&secblob); - /* Kill the intermediate vuid */ - invalidate_vuid(vuid); - + if (destroy_vuid) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + } return ret; } #endif @@ -590,28 +713,27 @@ static int reply_spnego_negotiate(connection_struct *conn, auth_ntlmssp_end(auth_ntlmssp_state); } - nt_status = auth_ntlmssp_start(auth_ntlmssp_state); - if (!NT_STATUS_IS_OK(nt_status)) { + status = auth_ntlmssp_start(auth_ntlmssp_state); + if (!NT_STATUS_IS_OK(status)) { /* Kill the intermediate vuid */ invalidate_vuid(vuid); - - return ERROR_NT(nt_status_squash(nt_status)); + return ERROR_NT(nt_status_squash(status)); } - nt_status = auth_ntlmssp_update(*auth_ntlmssp_state, + status = auth_ntlmssp_update(*auth_ntlmssp_state, secblob, &chal); data_blob_free(&secblob); reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, auth_ntlmssp_state, - &chal, nt_status, True); + &chal, status, True); data_blob_free(&chal); /* already replied */ return -1; } - + /**************************************************************************** Reply to a session setup spnego auth packet. ****************************************************************************/ @@ -622,8 +744,10 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, DATA_BLOB blob1, AUTH_NTLMSSP_STATE **auth_ntlmssp_state) { - DATA_BLOB auth, auth_reply; - NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; + DATA_BLOB auth = data_blob(NULL,0); + DATA_BLOB auth_reply = data_blob(NULL,0); + DATA_BLOB secblob = data_blob(NULL,0); + NTSTATUS status = NT_STATUS_INVALID_PARAMETER; if (!spnego_parse_auth(blob1, &auth)) { #if 0 @@ -634,6 +758,33 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } + + if (auth.data[0] == ASN1_APPLICATION(0)) { + /* Might be a second negTokenTarg packet */ + + BOOL got_krb5_mechanism = False; + status = parse_spnego_mechanisms(auth, &secblob, &got_krb5_mechanism); + if (NT_STATUS_IS_OK(status)) { + DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n", (unsigned long)secblob.length)); +#ifdef HAVE_KRB5 + if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { + BOOL destroy_vuid = True; + int ret = reply_spnego_kerberos(conn, inbuf, outbuf, + length, bufsize, &secblob, &destroy_vuid); + data_blob_free(&secblob); + data_blob_free(&auth); + if (destroy_vuid) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + } + return ret; + } +#endif + } + } + + /* If we get here it wasn't a negTokenTarg auth packet. */ + data_blob_free(&secblob); if (!*auth_ntlmssp_state) { /* Kill the intermediate vuid */ @@ -643,14 +794,14 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); } - nt_status = auth_ntlmssp_update(*auth_ntlmssp_state, + status = auth_ntlmssp_update(*auth_ntlmssp_state, auth, &auth_reply); data_blob_free(&auth); reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, auth_ntlmssp_state, - &auth_reply, nt_status, True); + &auth_reply, status, True); data_blob_free(&auth_reply); -- cgit From 7d77dd9db600a4b2ee11913bf8169224c2d9424a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Mar 2007 21:53:53 +0000 Subject: r21847: Fix memory leaks in error paths (and in main code path in one case...) in sasl bind. Wonder why coverity didn't find these ? Jeremy. (This used to be commit 89bdd30e4b2bb9dbc2ab57c54be8c6d01cae5a26) --- source3/smbd/sesssetup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index e678d959d8..ff1b2821cc 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -176,6 +176,7 @@ static BOOL make_krb5_skew_error(DATA_BLOB *pblob_out) *pblob_out = data_blob(NULL,0); + initialize_krb5_error_table(); kerr = krb5_init_context(&context); if (kerr) { return False; -- cgit From 296dcbac5897ad208c890720d3356a3ddc5f7794 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Mar 2007 01:17:47 +0000 Subject: r21882: The server part of the code has to use an AUTH_NTLMSSP struct, not just an NTLMSSP - grr. This complicates the re-use of common client and server code but I think I've got it right. Not turned on of valgrinded yet, but you can see it start to take shape ! Jeremy. (This used to be commit 60fc9c0aedf42dcd9df2ef9f1df07eaf3bca9bce) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index ff1b2821cc..91f4a9e12f 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -634,7 +634,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out Is this a krb5 mechanism ? ****************************************************************************/ -static NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, BOOL *p_is_krb5) +NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, BOOL *p_is_krb5) { char *OIDs[ASN1_MAX_OIDS]; int i; -- cgit From 90dc2613153bb8c865a1cfda0318ae4db3cf212e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 5 Apr 2007 19:56:08 +0000 Subject: r22095: BUG 4484: Add more checks to set %a for Vista clients (based on absence of native OS and Lanman strings in the session setup request) (This used to be commit e5c9fc937d40046030c0d3bcfced505410a14caf) --- source3/smbd/sesssetup.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 91f4a9e12f..7b5528222e 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1060,6 +1060,11 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, native_os, native_lanman, primary_domain)); if ( ra_type == RA_WIN2K ) { + /* Vista sets neither the OS or lanman strings */ + + if ( !strlen(native_os) && !strlen(native_lanman) ) + set_remote_arch(RA_VISTA); + /* Windows 2003 doesn't set the native lanman string, but does set primary domain which is a bug I think */ -- cgit From 0829e1ad1c3646efecf50729f493b9ee72ef0517 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 22:40:32 +0000 Subject: r22391: Looks bigger than it is. Make "inbuf" available to all callers of smb_setlen (via set_message() calls). This will allow the server to reflect back the correct encryption context. Jeremy. (This used to be commit 2d80a96120a5fe2fe726f00746d36d85044c4bdb) --- source3/smbd/sesssetup.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7b5528222e..188b7bfb81 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -96,15 +96,18 @@ static void sessionsetup_start_signing_engine(const auth_serversupplied_info *se Send a security blob via a session setup reply. ****************************************************************************/ -static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, - DATA_BLOB blob, NTSTATUS nt_status) +static BOOL reply_sesssetup_blob(connection_struct *conn, + const char *inbuf, + char *outbuf, + DATA_BLOB blob, + NTSTATUS nt_status) { char *p; if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { ERROR_NT(nt_status_squash(nt_status)); } else { - set_message(outbuf,4,0,True); + set_message(inbuf,outbuf,4,0,True); nt_status = nt_status_squash(nt_status); SIVAL(outbuf, smb_rcls, NT_STATUS_V(nt_status)); @@ -118,7 +121,7 @@ static BOOL reply_sesssetup_blob(connection_struct *conn, char *outbuf, p += add_signature( outbuf, p ); - set_message_end(outbuf,p); + set_message_end(inbuf,outbuf,p); } show_msg(outbuf); @@ -292,7 +295,7 @@ static int reply_spnego_kerberos(connection_struct *conn, } ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_ERROR); response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD); - reply_sesssetup_blob(conn, outbuf, response, NT_STATUS_MORE_PROCESSING_REQUIRED); + reply_sesssetup_blob(conn, inbuf, outbuf, response, NT_STATUS_MORE_PROCESSING_REQUIRED); /* * In this one case we don't invalidate the intermediate vuid. @@ -520,7 +523,7 @@ static int reply_spnego_kerberos(connection_struct *conn, /* current_user_info is changed on new vuid */ reload_services( True ); - set_message(outbuf,4,0,True); + set_message(inbuf,outbuf,4,0,True); SSVAL(outbuf, smb_vwv3, 0); if (server_info->guest) { @@ -539,7 +542,7 @@ static int reply_spnego_kerberos(connection_struct *conn, ap_rep_wrapped = data_blob(NULL, 0); } response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD); - reply_sesssetup_blob(conn, outbuf, response, ret); + reply_sesssetup_blob(conn, inbuf, outbuf, response, ret); data_blob_free(&ap_rep); data_blob_free(&ap_rep_wrapped); @@ -593,7 +596,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out /* current_user_info is changed on new vuid */ reload_services( True ); - set_message(outbuf,4,0,True); + set_message(inbuf,outbuf,4,0,True); SSVAL(outbuf, smb_vwv3, 0); if (server_info->guest) { @@ -612,7 +615,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out response = *ntlmssp_blob; } - ret = reply_sesssetup_blob(conn, outbuf, response, nt_status); + ret = reply_sesssetup_blob(conn, inbuf, outbuf, response, nt_status); if (wrap) { data_blob_free(&response); } @@ -1513,11 +1516,11 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, data_blob_clear_free(&plaintext_password); /* it's ok - setup a reply */ - set_message(outbuf,3,0,True); + set_message(inbuf,outbuf,3,0,True); if (Protocol >= PROTOCOL_NT1) { char *p = smb_buf( outbuf ); p += add_signature( outbuf, p ); - set_message_end( outbuf, p ); + set_message_end(inbuf, outbuf, p ); /* perhaps grab OS version here?? */ } -- cgit From 71921605995fa95d84301534760a6bc2db3fa74b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 May 2007 15:07:49 +0000 Subject: r22747: Fix some C++ warnings (This used to be commit a66a04e9f11f6c4462f2b56b447bae4eca7b177c) --- source3/smbd/sesssetup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 188b7bfb81..7dbf20a189 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -990,8 +990,7 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB } /* We must store this blob until complete. */ - pad = SMB_MALLOC(sizeof(struct pending_auth_data)); - if (!pad) { + if (!(pad = SMB_MALLOC_P(struct pending_auth_data))) { return NT_STATUS_NO_MEMORY; } pad->needed_len = needed_len - pblob->length; -- cgit From 76ce309234adbe0a6a56b849a91714cab148c4a7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 May 2007 15:31:12 +0000 Subject: r22751: Next step for the cluster merge: sessionid.tdb should contain a 'struct server_id' instead of a 'uint32 pid' (This used to be commit be7bac55c37676a8137c59a22dfb2e4c4821ac21) --- source3/smbd/sesssetup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7dbf20a189..d6cdf777d8 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1180,11 +1180,11 @@ static int shutdown_other_smbds(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, struct sessionid *sessionid = (struct sessionid *)dbuf.dptr; const char *ip = (const char *)p; - if (!process_exists(pid_to_procid(sessionid->pid))) { + if (!process_exists(sessionid->pid)) { return 0; } - if (sessionid->pid == sys_getpid()) { + if (procid_is_me(&sessionid->pid)) { return 0; } @@ -1192,7 +1192,7 @@ static int shutdown_other_smbds(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, return 0; } - message_send_pid(pid_to_procid(sessionid->pid), MSG_SHUTDOWN, + message_send_pid(sessionid->pid, MSG_SHUTDOWN, NULL, 0, True); return 0; } -- cgit From b4a7b7a8889737e2891fc1176feabd4ce47f2737 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 May 2007 12:16:20 +0000 Subject: r22844: Introduce const DATA_BLOB data_blob_null = { NULL, 0, NULL }; and replace all data_blob(NULL, 0) calls. (This used to be commit 3d3d61687ef00181f4f04e001d42181d93ac931e) --- source3/smbd/sesssetup.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index d6cdf777d8..dcff27f70c 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -177,7 +177,7 @@ static BOOL make_krb5_skew_error(DATA_BLOB *pblob_out) char *host_princ_s = NULL; BOOL ret = False; - *pblob_out = data_blob(NULL,0); + *pblob_out = data_blob_null; initialize_krb5_error_table(); kerr = krb5_init_context(&context); @@ -243,9 +243,9 @@ static int reply_spnego_kerberos(connection_struct *conn, PAC_DATA *pac_data; DATA_BLOB ap_rep, ap_rep_wrapped, response; auth_serversupplied_info *server_info = NULL; - DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob_null; uint8 tok_id[2]; - DATA_BLOB nullblob = data_blob(NULL, 0); + DATA_BLOB nullblob = data_blob_null; fstring real_username; BOOL map_domainuser_to_guest = False; BOOL username_was_mapped; @@ -539,7 +539,7 @@ static int reply_spnego_kerberos(connection_struct *conn, if (NT_STATUS_IS_OK(ret)) { ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_AP_REP); } else { - ap_rep_wrapped = data_blob(NULL, 0); + ap_rep_wrapped = data_blob_null; } response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD); reply_sesssetup_blob(conn, inbuf, outbuf, response, ret); @@ -582,7 +582,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out if (NT_STATUS_IS_OK(nt_status)) { int sess_vuid; - DATA_BLOB nullblob = data_blob(NULL, 0); + DATA_BLOB nullblob = data_blob_null; DATA_BLOB session_key = data_blob((*auth_ntlmssp_state)->ntlmssp_state->session_key.data, (*auth_ntlmssp_state)->ntlmssp_state->session_key.length); /* register_vuid keeps the server info */ @@ -748,9 +748,9 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, DATA_BLOB blob1, AUTH_NTLMSSP_STATE **auth_ntlmssp_state) { - DATA_BLOB auth = data_blob(NULL,0); - DATA_BLOB auth_reply = data_blob(NULL,0); - DATA_BLOB secblob = data_blob(NULL,0); + DATA_BLOB auth = data_blob_null; + DATA_BLOB auth_reply = data_blob_null; + DATA_BLOB secblob = data_blob_null; NTSTATUS status = NT_STATUS_INVALID_PARAMETER; if (!spnego_parse_auth(blob1, &auth)) { @@ -1089,7 +1089,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, } if (!vuser) { - vuid = register_vuid(NULL, data_blob(NULL, 0), data_blob(NULL, 0), NULL); + vuid = register_vuid(NULL, data_blob_null, data_blob_null, NULL); if (vuid == UID_FIELD_INVALID ) { data_blob_free(&blob1); return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); @@ -1509,7 +1509,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if (server_info->user_session_key.data) { session_key = data_blob(server_info->user_session_key.data, server_info->user_session_key.length); } else { - session_key = data_blob(NULL, 0); + session_key = data_blob_null; } data_blob_clear_free(&plaintext_password); -- cgit From fad7dd8a60e6637598b17fa89ec92d98db51fffe Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 May 2007 20:31:28 +0000 Subject: r22868: Replace some message_send_pid calls with messaging_send_pid calls. More tomorrow. (This used to be commit 74fa57ca5d7fa8eace72bbe948a08a0bca3cc4ca) --- source3/smbd/sesssetup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index dcff27f70c..ccfc22598d 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1192,8 +1192,8 @@ static int shutdown_other_smbds(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, return 0; } - message_send_pid(sessionid->pid, MSG_SHUTDOWN, - NULL, 0, True); + messaging_send(smbd_messaging_context(), sessionid->pid, MSG_SHUTDOWN, + &data_blob_null); return 0; } -- cgit From fff51a9af20b7221844ffb11d7491372bbbcda0e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 28 May 2007 12:39:39 +0000 Subject: r23172: Change shutdown_other_smbds to use connections_traverse instead of session_traverse. (This used to be commit ccb5eb245e962b0264b337c2d0275c22e2a36830) --- source3/smbd/sesssetup.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index ccfc22598d..42a71f8ad7 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1174,25 +1174,26 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, a new session setup with VC==0 is ignored. ****************************************************************************/ -static int shutdown_other_smbds(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, - void *p) +static int shutdown_other_smbds(struct db_record *rec, + const struct connections_key *key, + const struct connections_data *crec, + void *private_data) { - struct sessionid *sessionid = (struct sessionid *)dbuf.dptr; - const char *ip = (const char *)p; + const char *ip = (const char *)private_data; - if (!process_exists(sessionid->pid)) { + if (!process_exists(crec->pid)) { return 0; } - if (procid_is_me(&sessionid->pid)) { + if (procid_is_me(&crec->pid)) { return 0; } - if (strcmp(ip, sessionid->ip_addr) != 0) { + if (strcmp(ip, crec->addr) != 0) { return 0; } - messaging_send(smbd_messaging_context(), sessionid->pid, MSG_SHUTDOWN, + messaging_send(smbd_messaging_context(), crec->pid, MSG_SHUTDOWN, &data_blob_null); return 0; } @@ -1205,7 +1206,7 @@ static void setup_new_vc_session(void) invalidate_all_vuids(); #endif if (lp_reset_on_zero_vc()) { - session_traverse(shutdown_other_smbds, client_addr()); + connections_forall(shutdown_other_smbds, client_addr()); } } -- cgit From 4caefdf348857577343075ae647e29a0ac904ae0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 13 Jun 2007 20:49:20 +0000 Subject: r23474: Here's a small patch that disables the libkrb5.so replay cache when verifying a ticket from winbindd_pam.c. I've found during multiple, fast, automated SSH logins (such as from a cron script) that the replay cache in MIT's krb5 lib will occasionally fail the krb5_rd_req() as a replay attack. There seems to be a small window during which the MIT krb5 libs could reproduce identical time stamps for ctime and cusec in the authenticator since Unix systems only give back milli-seconds rather than the micro-seconds needed by the authenticator. Checked against MIT 1.5.1. Have not researched how Heimdal does it. My thinking is that if someone can spoof the KDC and TDS services we are pretty hopeless anyways. (This used to be commit cbd33da9f78373e29729325bbab1ae9040712b11) --- source3/smbd/sesssetup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 42a71f8ad7..22c598a654 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -270,7 +270,9 @@ static int reply_spnego_kerberos(connection_struct *conn, return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } - ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket, &client, &pac_data, &ap_rep, &session_key); + ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket, + &client, &pac_data, &ap_rep, + &session_key, True); data_blob_free(&ticket); -- cgit From fcda5b589633b96415890c569bf23e3e284e0916 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 5 Jul 2007 16:33:37 +0000 Subject: r23726: Explicitly pass down the FLAGS2 field to srvstr_pull_buf. The next checkin will pull this up to srvstr_get_path. At that point we can get more independent of the inbuf, the base_ptr in pull_string will only be used to satisfy UCS2 alignment constraints. (This used to be commit 836782b07bf133e9b2598c4a089f1c810e4c7754) --- source3/smbd/sesssetup.c | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 22c598a654..3ed338bda7 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1057,9 +1057,12 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, #endif p2 = inbuf + smb_vwv13 + data_blob_len; - p2 += srvstr_pull_buf(inbuf, native_os, p2, sizeof(native_os), STR_TERMINATE); - p2 += srvstr_pull_buf(inbuf, native_lanman, p2, sizeof(native_lanman), STR_TERMINATE); - p2 += srvstr_pull_buf(inbuf, primary_domain, p2, sizeof(primary_domain), STR_TERMINATE); + p2 += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), native_os, p2, + sizeof(native_os), STR_TERMINATE); + p2 += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), native_lanman, p2, + sizeof(native_lanman), STR_TERMINATE); + p2 += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), primary_domain, p2, + sizeof(primary_domain), STR_TERMINATE); DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n", native_os, native_lanman, primary_domain)); @@ -1283,7 +1286,9 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, plaintext_password.data[passlen1] = 0; } - srvstr_pull_buf(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), STR_TERMINATE); + srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), user, + smb_buf(inbuf)+passlen1, sizeof(user), + STR_TERMINATE); *domain = 0; } else { @@ -1363,21 +1368,28 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if (unic && (passlen2 == 0) && passlen1) { /* Only a ascii plaintext password was sent. */ - srvstr_pull(inbuf, pass, smb_buf(inbuf), sizeof(pass), - passlen1, STR_TERMINATE|STR_ASCII); + srvstr_pull(inbuf, SVAL(inbuf, smb_flg2), pass, + smb_buf(inbuf), sizeof(pass), + passlen1, STR_TERMINATE|STR_ASCII); } else { - srvstr_pull(inbuf, pass, smb_buf(inbuf), - sizeof(pass), unic ? passlen2 : passlen1, - STR_TERMINATE); + srvstr_pull(inbuf, SVAL(inbuf, smb_flg2), pass, + smb_buf(inbuf), sizeof(pass), + unic ? passlen2 : passlen1, + STR_TERMINATE); } plaintext_password = data_blob(pass, strlen(pass)+1); } p += passlen1 + passlen2; - p += srvstr_pull_buf(inbuf, user, p, sizeof(user), STR_TERMINATE); - p += srvstr_pull_buf(inbuf, domain, p, sizeof(domain), STR_TERMINATE); - p += srvstr_pull_buf(inbuf, native_os, p, sizeof(native_os), STR_TERMINATE); - p += srvstr_pull_buf(inbuf, native_lanman, p, sizeof(native_lanman), STR_TERMINATE); + p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), user, p, + sizeof(user), STR_TERMINATE); + p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), domain, p, + sizeof(domain), STR_TERMINATE); + p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), native_os, + p, sizeof(native_os), STR_TERMINATE); + p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), + native_lanman, p, sizeof(native_lanman), + STR_TERMINATE); /* not documented or decoded by Ethereal but there is one more string in the extra bytes which is the same as the PrimaryDomain when using @@ -1387,7 +1399,10 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, byte_count = SVAL(inbuf, smb_vwv13); if ( PTR_DIFF(p, save_p) < byte_count) - p += srvstr_pull_buf(inbuf, primary_domain, p, sizeof(primary_domain), STR_TERMINATE); + p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), + primary_domain, p, + sizeof(primary_domain), + STR_TERMINATE); else fstrcpy( primary_domain, "null" ); -- cgit From d3965a2689123cd4618c224a3999fdd7e76f36e0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Jul 2007 23:07:40 +0000 Subject: r23736: Use local variable of smb_flag2 instead of using the macro every time. Jeremy. (This used to be commit 9e1663b1f18d716a7f307bea2b09dadeef392ab8) --- source3/smbd/sesssetup.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 3ed338bda7..e938c0bbac 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1029,6 +1029,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, user_struct *vuser = NULL; NTSTATUS status = NT_STATUS_OK; uint16 smbpid = SVAL(inbuf,smb_pid); + uint16 smb_flag2 = SVAL(inbuf, smb_flg2); DEBUG(3,("Doing spnego session setup\n")); @@ -1057,11 +1058,11 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, #endif p2 = inbuf + smb_vwv13 + data_blob_len; - p2 += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), native_os, p2, + p2 += srvstr_pull_buf(inbuf, smb_flag2, native_os, p2, sizeof(native_os), STR_TERMINATE); - p2 += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), native_lanman, p2, + p2 += srvstr_pull_buf(inbuf, smb_flag2, native_lanman, p2, sizeof(native_lanman), STR_TERMINATE); - p2 += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), primary_domain, p2, + p2 += srvstr_pull_buf(inbuf, smb_flag2, primary_domain, p2, sizeof(primary_domain), STR_TERMINATE); DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n", native_os, native_lanman, primary_domain)); @@ -1236,6 +1237,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, static BOOL done_sesssetup = False; auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; + uint16 smb_flag2 = SVAL(inbuf, smb_flg2); NTSTATUS nt_status; @@ -1249,12 +1251,12 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, ZERO_STRUCT(nt_resp); ZERO_STRUCT(plaintext_password); - DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf, smb_wct), SVAL(inbuf, smb_flg2))); + DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf, smb_wct), smb_flag2)); /* a SPNEGO session setup has 12 command words, whereas a normal NT1 session setup has 13. See the cifs spec. */ if (CVAL(inbuf, smb_wct) == 12 && - (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) { + (smb_flag2 & FLAGS2_EXTENDED_SECURITY)) { if (!global_spnego_negotiated) { DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at SPNEGO session setup when it was not negoitiated.\n")); return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); @@ -1286,7 +1288,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, plaintext_password.data[passlen1] = 0; } - srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), user, + srvstr_pull_buf(inbuf, smb_flag2, user, smb_buf(inbuf)+passlen1, sizeof(user), STR_TERMINATE); *domain = 0; @@ -1356,7 +1358,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, nt_resp = data_blob(p+passlen1, passlen2); } else { pstring pass; - BOOL unic=SVAL(inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS; + BOOL unic= smb_flag2 & FLAGS2_UNICODE_STRINGS; #if 0 /* This was the previous fix. Not sure if it's still valid. JRA. */ @@ -1368,11 +1370,11 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if (unic && (passlen2 == 0) && passlen1) { /* Only a ascii plaintext password was sent. */ - srvstr_pull(inbuf, SVAL(inbuf, smb_flg2), pass, + srvstr_pull(inbuf, smb_flag2, pass, smb_buf(inbuf), sizeof(pass), passlen1, STR_TERMINATE|STR_ASCII); } else { - srvstr_pull(inbuf, SVAL(inbuf, smb_flg2), pass, + srvstr_pull(inbuf, smb_flag2, pass, smb_buf(inbuf), sizeof(pass), unic ? passlen2 : passlen1, STR_TERMINATE); @@ -1381,13 +1383,13 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } p += passlen1 + passlen2; - p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), user, p, + p += srvstr_pull_buf(inbuf, smb_flag2, user, p, sizeof(user), STR_TERMINATE); - p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), domain, p, + p += srvstr_pull_buf(inbuf, smb_flag2, domain, p, sizeof(domain), STR_TERMINATE); - p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), native_os, + p += srvstr_pull_buf(inbuf, smb_flag2, native_os, p, sizeof(native_os), STR_TERMINATE); - p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), + p += srvstr_pull_buf(inbuf, smb_flag2, native_lanman, p, sizeof(native_lanman), STR_TERMINATE); @@ -1399,7 +1401,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, byte_count = SVAL(inbuf, smb_vwv13); if ( PTR_DIFF(p, save_p) < byte_count) - p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), + p += srvstr_pull_buf(inbuf, smb_flag2, primary_domain, p, sizeof(primary_domain), STR_TERMINATE); -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index e938c0bbac..4ec7d5f03a 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/smbd/sesssetup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 4ec7d5f03a..320d283575 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From cc6a41017c577742af73b4bc60993d8d415ea580 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Jul 2007 09:36:09 +0000 Subject: r23997: Check in the infrastructure for getting rid of the global InBuffer/OutBuffer The complete history of this patch can be found under http://www.samba.org/~vlendec/inbuf-checkin/. Jeremy, Jerry: If possible I would like to see this in 3.2.0. I'm only checking into 3_2 at the moment, as it currently will slow down operations for all non-converted (i.e. all at this moment) operations, as it will copy the talloc'ed inbuf over the global InBuffer. It will need quite a bit of effort to convert everything necessary for the normal operations an XP box does. I have patches for negprot, session setup, tcon_and_X, open_and_X, close. More to come, but I would appreciate some help here. Volker (This used to be commit 5594af2b208c860d3f4b453af6a649d9e4295d1c) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 320d283575..eb0d7b3e12 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1582,5 +1582,5 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, done_sesssetup = True; END_PROFILE(SMBsesssetupX); - return chain_reply(inbuf,outbuf,length,bufsize); + return chain_reply(inbuf,&outbuf,length,bufsize); } -- cgit From e29325a6ce6aafb64485f1372ebb4148bffae57b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Jul 2007 20:01:03 +0000 Subject: r24050: Fix a typo (This used to be commit 53027d0ee2dbe15beb2fce5d11a26f4ac0b08b9c) --- source3/smbd/sesssetup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index eb0d7b3e12..70819831f6 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1257,7 +1257,9 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if (CVAL(inbuf, smb_wct) == 12 && (smb_flag2 & FLAGS2_EXTENDED_SECURITY)) { if (!global_spnego_negotiated) { - DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at SPNEGO session setup when it was not negoitiated.\n")); + DEBUG(0, ("reply_sesssetup_and_X: Rejecting attempt " + "at SPNEGO session setup when it was not " + "negotiated.\n")); return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); } -- cgit From 7d2d4ddfa2fbd859f35f8f4e2b8243f52a4ace0e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Jul 2007 16:01:12 +0000 Subject: r24056: Another big one: This converts reply_sesssetup_and_X to the new API. As usual, its history can be found on http://samba.org/~vlendec/sesssetup/. This very obviously needs close review. Volker (This used to be commit 35675a6a33d584e5c3c97d1cb5ca9b0315a5fa92) --- source3/smbd/sesssetup.c | 433 +++++++++++++++++++++++++++-------------------- 1 file changed, 248 insertions(+), 185 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 70819831f6..e9808e0040 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -60,25 +60,43 @@ static NTSTATUS do_map_to_guest(NTSTATUS status, auth_serversupplied_info **serv Add the standard 'Samba' signature to the end of the session setup. ****************************************************************************/ -static int add_signature(char *outbuf, char *p) +static int push_signature(uint8 **outbuf) { - char *start = p; - fstring lanman; + char *lanman; + int result, tmp; - fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING); + result = 0; - p += srvstr_push(outbuf, p, "Unix", -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, lanman, -1, STR_TERMINATE); - p += srvstr_push(outbuf, p, lp_workgroup(), -1, STR_TERMINATE); + tmp = message_push_string(outbuf, "Unix", STR_TERMINATE); - return PTR_DIFF(p, start); + if (tmp == -1) return -1; + result += tmp; + + if (asprintf(&lanman, "Samba %s", SAMBA_VERSION_STRING) != -1) { + tmp = message_push_string(outbuf, lanman, STR_TERMINATE); + SAFE_FREE(lanman); + } + else { + tmp = message_push_string(outbuf, "Samba", STR_TERMINATE); + } + + if (tmp == -1) return -1; + result += tmp; + + tmp = message_push_string(outbuf, lp_workgroup(), STR_TERMINATE); + + if (tmp == -1) return -1; + result += tmp; + + return result; } /**************************************************************************** Start the signing engine if needed. Don't fail signing here. ****************************************************************************/ -static void sessionsetup_start_signing_engine(const auth_serversupplied_info *server_info, char *inbuf) +static void sessionsetup_start_signing_engine(const auth_serversupplied_info *server_info, + const uint8 *inbuf) { if (!server_info->guest && !srv_signing_started()) { /* We need to start the signing engine @@ -87,7 +105,7 @@ static void sessionsetup_start_signing_engine(const auth_serversupplied_info *se * correct one. Subsequent packets will * be correct. */ - srv_check_sign_mac(inbuf, False); + srv_check_sign_mac((char *)inbuf, False); } } @@ -95,36 +113,29 @@ static void sessionsetup_start_signing_engine(const auth_serversupplied_info *se Send a security blob via a session setup reply. ****************************************************************************/ -static BOOL reply_sesssetup_blob(connection_struct *conn, - const char *inbuf, - char *outbuf, - DATA_BLOB blob, - NTSTATUS nt_status) +static void reply_sesssetup_blob(connection_struct *conn, + struct smb_request *req, + DATA_BLOB blob, + NTSTATUS nt_status) { - char *p; - - if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - ERROR_NT(nt_status_squash(nt_status)); + if (!NT_STATUS_IS_OK(nt_status) && + !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + reply_nterror(req, nt_status_squash(nt_status)); } else { - set_message(inbuf,outbuf,4,0,True); - nt_status = nt_status_squash(nt_status); - SIVAL(outbuf, smb_rcls, NT_STATUS_V(nt_status)); - SSVAL(outbuf, smb_vwv0, 0xFF); /* no chaining possible */ - SSVAL(outbuf, smb_vwv3, blob.length); - p = smb_buf(outbuf); - - /* should we cap this? */ - memcpy(p, blob.data, blob.length); - p += blob.length; + SIVAL(req->outbuf, smb_rcls, NT_STATUS_V(nt_status)); + SSVAL(req->outbuf, smb_vwv0, 0xFF); /* no chaining possible */ + SSVAL(req->outbuf, smb_vwv3, blob.length); - p += add_signature( outbuf, p ); - - set_message_end(inbuf,outbuf,p); + if ((message_push_blob(&req->outbuf, blob) == -1) + || (push_signature(&req->outbuf) == -1)) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + } } - show_msg(outbuf); - return send_smb(smbd_server_fd(),outbuf); + show_msg((char *)req->outbuf); + send_smb(smbd_server_fd(),(char *)req->outbuf); + TALLOC_FREE(req->outbuf); } /**************************************************************************** @@ -225,11 +236,11 @@ static BOOL make_krb5_skew_error(DATA_BLOB *pblob_out) Reply to a session setup spnego negotiate packet for kerberos. ****************************************************************************/ -static int reply_spnego_kerberos(connection_struct *conn, - char *inbuf, char *outbuf, - int length, int bufsize, - DATA_BLOB *secblob, - BOOL *p_invalidate_vuid) +static void reply_spnego_kerberos(connection_struct *conn, + struct smb_request *req, + DATA_BLOB *secblob, + uint16 vuid, + BOOL *p_invalidate_vuid) { TALLOC_CTX *mem_ctx; DATA_BLOB ticket; @@ -261,12 +272,14 @@ static int reply_spnego_kerberos(connection_struct *conn, mem_ctx = talloc_init("reply_spnego_kerberos"); if (mem_ctx == NULL) { - return ERROR_NT(nt_status_squash(NT_STATUS_NO_MEMORY)); + reply_nterror(req, nt_status_squash(NT_STATUS_NO_MEMORY)); + return; } if (!spnego_parse_krb5_wrap(*secblob, &ticket, tok_id)) { talloc_destroy(mem_ctx); - return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE)); + return; } ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket, @@ -319,7 +332,8 @@ static int reply_spnego_kerberos(connection_struct *conn, #endif DEBUG(1,("Failed to verify incoming ticket with error %s!\n", nt_errstr(ret))); talloc_destroy(mem_ctx); - return ERROR_NT(nt_status_squash(ret)); + reply_nterror(req, nt_status_squash(ret)); + return; } DEBUG(3,("Ticket name is [%s]\n", client)); @@ -331,7 +345,8 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&session_key); SAFE_FREE(client); talloc_destroy(mem_ctx); - return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + reply_nterror(req,nt_status_squash(NT_STATUS_LOGON_FAILURE)); + return; } *p = 0; @@ -352,7 +367,9 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&session_key); SAFE_FREE(client); talloc_destroy(mem_ctx); - return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + reply_nterror(req, nt_status_squash( + NT_STATUS_LOGON_FAILURE)); + return; } } @@ -421,7 +438,8 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); TALLOC_FREE(mem_ctx); - return ERROR_NT(nt_status_squash(ret)); + reply_nterror(req, nt_status_squash(ret)); + return; } } @@ -445,7 +463,9 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); TALLOC_FREE(mem_ctx); - return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + reply_nterror(req, nt_status_squash( + NT_STATUS_LOGON_FAILURE)); + return; } } @@ -469,7 +489,8 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); TALLOC_FREE(mem_ctx); - return ERROR_NT(nt_status_squash(ret)); + reply_nterror(req, nt_status_squash(ret)); + return; } } else { @@ -482,7 +503,8 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&ap_rep); data_blob_free(&session_key); TALLOC_FREE(mem_ctx); - return ERROR_NT(nt_status_squash(ret)); + reply_nterror(req, nt_status_squash(ret)); + return; } /* make_server_info_pw does not set the domain. Without this @@ -507,7 +529,8 @@ static int reply_spnego_kerberos(connection_struct *conn, data_blob_free(&session_key); TALLOC_FREE( mem_ctx ); TALLOC_FREE( server_info ); - return ERROR_NT(nt_status_squash(ret)); + reply_nterror(req, nt_status_squash(ret)); + return; } } @@ -518,22 +541,24 @@ static int reply_spnego_kerberos(connection_struct *conn, SAFE_FREE(client); + reply_outbuf(req, 4, 0); + SSVAL(req->outbuf,smb_uid,vuid); + if (sess_vuid == UID_FIELD_INVALID ) { ret = NT_STATUS_LOGON_FAILURE; } else { /* current_user_info is changed on new vuid */ reload_services( True ); - set_message(inbuf,outbuf,4,0,True); - SSVAL(outbuf, smb_vwv3, 0); + SSVAL(req->outbuf, smb_vwv3, 0); if (server_info->guest) { - SSVAL(outbuf,smb_vwv2,1); + SSVAL(req->outbuf,smb_vwv2,1); } - SSVAL(outbuf, smb_uid, sess_vuid); + SSVAL(req->outbuf, smb_uid, sess_vuid); - sessionsetup_start_signing_engine(server_info, inbuf); + sessionsetup_start_signing_engine(server_info, req->inbuf); } /* wrap that up in a nice GSS-API wrapping */ @@ -543,15 +568,14 @@ static int reply_spnego_kerberos(connection_struct *conn, ap_rep_wrapped = data_blob_null; } response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD); - reply_sesssetup_blob(conn, inbuf, outbuf, response, ret); + reply_sesssetup_blob(conn, req, response, ret); data_blob_free(&ap_rep); data_blob_free(&ap_rep_wrapped); data_blob_free(&response); TALLOC_FREE(mem_ctx); - - return -1; /* already replied */ } + #endif /**************************************************************************** @@ -562,13 +586,13 @@ static int reply_spnego_kerberos(connection_struct *conn, leg of the NTLM auth steps. ***************************************************************************/ -static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *outbuf, +static void reply_spnego_ntlmssp(connection_struct *conn, + struct smb_request *req, uint16 vuid, AUTH_NTLMSSP_STATE **auth_ntlmssp_state, - DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status, - BOOL wrap) + DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status, + BOOL wrap) { - BOOL ret; DATA_BLOB response; struct auth_serversupplied_info *server_info = NULL; @@ -581,6 +605,10 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out (*auth_ntlmssp_state)->ntlmssp_state->domain); } + reply_outbuf(req, 4, 0); + + SSVAL(req->outbuf, smb_uid, vuid); + if (NT_STATUS_IS_OK(nt_status)) { int sess_vuid; DATA_BLOB nullblob = data_blob_null; @@ -597,16 +625,15 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out /* current_user_info is changed on new vuid */ reload_services( True ); - set_message(inbuf,outbuf,4,0,True); - SSVAL(outbuf, smb_vwv3, 0); + SSVAL(req->outbuf, smb_vwv3, 0); if (server_info->guest) { - SSVAL(outbuf,smb_vwv2,1); + SSVAL(req->outbuf,smb_vwv2,1); } - SSVAL(outbuf,smb_uid,sess_vuid); + SSVAL(req->outbuf,smb_uid,sess_vuid); - sessionsetup_start_signing_engine(server_info, inbuf); + sessionsetup_start_signing_engine(server_info, req->inbuf); } } @@ -616,7 +643,7 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out response = *ntlmssp_blob; } - ret = reply_sesssetup_blob(conn, inbuf, outbuf, response, nt_status); + reply_sesssetup_blob(conn, req, response, nt_status); if (wrap) { data_blob_free(&response); } @@ -624,14 +651,12 @@ static BOOL reply_spnego_ntlmssp(connection_struct *conn, char *inbuf, char *out /* NT_STATUS_MORE_PROCESSING_REQUIRED from our NTLMSSP code tells us, and the other end, that we are not finished yet. */ - if (!ret || !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (!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); } - - return ret; } /**************************************************************************** @@ -678,13 +703,11 @@ NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, BOOL * Reply to a session setup spnego negotiate packet. ****************************************************************************/ -static int reply_spnego_negotiate(connection_struct *conn, - char *inbuf, - char *outbuf, - uint16 vuid, - int length, int bufsize, - DATA_BLOB blob1, - AUTH_NTLMSSP_STATE **auth_ntlmssp_state) +static void reply_spnego_negotiate(connection_struct *conn, + struct smb_request *req, + uint16 vuid, + DATA_BLOB blob1, + AUTH_NTLMSSP_STATE **auth_ntlmssp_state) { DATA_BLOB secblob; DATA_BLOB chal; @@ -695,7 +718,8 @@ static int reply_spnego_negotiate(connection_struct *conn, if (!NT_STATUS_IS_OK(status)) { /* Kill the intermediate vuid */ invalidate_vuid(vuid); - return ERROR_NT(nt_status_squash(status)); + reply_nterror(req, nt_status_squash(status)); + return; } DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length)); @@ -703,14 +727,14 @@ static int reply_spnego_negotiate(connection_struct *conn, #ifdef HAVE_KRB5 if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { BOOL destroy_vuid = True; - int ret = reply_spnego_kerberos(conn, inbuf, outbuf, - length, bufsize, &secblob, &destroy_vuid); + reply_spnego_kerberos(conn, req, &secblob, vuid, + &destroy_vuid); data_blob_free(&secblob); if (destroy_vuid) { /* Kill the intermediate vuid */ invalidate_vuid(vuid); } - return ret; + return; } #endif @@ -722,7 +746,8 @@ static int reply_spnego_negotiate(connection_struct *conn, if (!NT_STATUS_IS_OK(status)) { /* Kill the intermediate vuid */ invalidate_vuid(vuid); - return ERROR_NT(nt_status_squash(status)); + reply_nterror(req, nt_status_squash(status)); + return; } status = auth_ntlmssp_update(*auth_ntlmssp_state, @@ -730,24 +755,24 @@ static int reply_spnego_negotiate(connection_struct *conn, data_blob_free(&secblob); - reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, auth_ntlmssp_state, + reply_spnego_ntlmssp(conn, req, vuid, auth_ntlmssp_state, &chal, status, True); data_blob_free(&chal); /* already replied */ - return -1; + return; } /**************************************************************************** Reply to a session setup spnego auth packet. ****************************************************************************/ -static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, - uint16 vuid, - int length, int bufsize, - DATA_BLOB blob1, - AUTH_NTLMSSP_STATE **auth_ntlmssp_state) +static void reply_spnego_auth(connection_struct *conn, + struct smb_request *req, + uint16 vuid, + DATA_BLOB blob1, + AUTH_NTLMSSP_STATE **auth_ntlmssp_state) { DATA_BLOB auth = data_blob_null; DATA_BLOB auth_reply = data_blob_null; @@ -761,7 +786,9 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, /* Kill the intermediate vuid */ invalidate_vuid(vuid); - return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); + reply_nterror(req, nt_status_squash( + NT_STATUS_INVALID_PARAMETER)); + return; } if (auth.data[0] == ASN1_APPLICATION(0)) { @@ -774,15 +801,15 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, #ifdef HAVE_KRB5 if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { BOOL destroy_vuid = True; - int ret = reply_spnego_kerberos(conn, inbuf, outbuf, - length, bufsize, &secblob, &destroy_vuid); + reply_spnego_kerberos(conn, req, &secblob, + vuid, &destroy_vuid); data_blob_free(&secblob); data_blob_free(&auth); if (destroy_vuid) { /* Kill the intermediate vuid */ invalidate_vuid(vuid); } - return ret; + return; } #endif } @@ -796,7 +823,9 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, invalidate_vuid(vuid); /* auth before negotiatiate? */ - return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); + reply_nterror(req, nt_status_squash( + NT_STATUS_INVALID_PARAMETER)); + return; } status = auth_ntlmssp_update(*auth_ntlmssp_state, @@ -804,14 +833,14 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf, data_blob_free(&auth); - reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, + reply_spnego_ntlmssp(conn, req, vuid, auth_ntlmssp_state, &auth_reply, status, True); data_blob_free(&auth_reply); /* and tell smbd that we have already replied to this packet */ - return -1; + return; } /**************************************************************************** @@ -1012,28 +1041,26 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB conn POINTER CAN BE NULL HERE ! ****************************************************************************/ -static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, - char *outbuf, - int length,int bufsize) +static void reply_sesssetup_and_X_spnego(connection_struct *conn, + struct smb_request *req) { uint8 *p; DATA_BLOB blob1; - int ret; size_t bufrem; fstring native_os, native_lanman, primary_domain; - char *p2; - uint16 data_blob_len = SVAL(inbuf, smb_vwv7); + const char *p2; + uint16 data_blob_len = SVAL(req->inbuf, smb_vwv7); enum remote_arch_types ra_type = get_remote_arch(); - int vuid = SVAL(inbuf,smb_uid); + int vuid = SVAL(req->inbuf,smb_uid); user_struct *vuser = NULL; NTSTATUS status = NT_STATUS_OK; - uint16 smbpid = SVAL(inbuf,smb_pid); - uint16 smb_flag2 = SVAL(inbuf, smb_flg2); + uint16 smbpid = req->smbpid; + uint16 smb_flag2 = req->flags2; DEBUG(3,("Doing spnego session setup\n")); if (global_client_caps == 0) { - global_client_caps = IVAL(inbuf,smb_vwv10); + global_client_caps = IVAL(req->inbuf,smb_vwv10); if (!(global_client_caps & CAP_STATUS32)) { remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); @@ -1041,14 +1068,15 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, } - p = (uint8 *)smb_buf(inbuf); + p = (uint8 *)smb_buf(req->inbuf); if (data_blob_len == 0) { /* an invalid request */ - return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE)); + return; } - bufrem = smb_bufrem(inbuf, p); + bufrem = smb_bufrem(req->inbuf, p); /* pull the spnego blob */ blob1 = data_blob(p, MIN(bufrem, data_blob_len)); @@ -1056,12 +1084,12 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, file_save("negotiate.dat", blob1.data, blob1.length); #endif - p2 = inbuf + smb_vwv13 + data_blob_len; - p2 += srvstr_pull_buf(inbuf, smb_flag2, native_os, p2, + p2 = (char *)req->inbuf + smb_vwv13 + data_blob_len; + p2 += srvstr_pull_buf(req->inbuf, smb_flag2, native_os, p2, sizeof(native_os), STR_TERMINATE); - p2 += srvstr_pull_buf(inbuf, smb_flag2, native_lanman, p2, + p2 += srvstr_pull_buf(req->inbuf, smb_flag2, native_lanman, p2, sizeof(native_lanman), STR_TERMINATE); - p2 += srvstr_pull_buf(inbuf, smb_flag2, primary_domain, p2, + p2 += srvstr_pull_buf(req->inbuf, smb_flag2, primary_domain, p2, sizeof(primary_domain), STR_TERMINATE); DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n", native_os, native_lanman, primary_domain)); @@ -1097,7 +1125,9 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, vuid = register_vuid(NULL, data_blob_null, data_blob_null, NULL); if (vuid == UID_FIELD_INVALID ) { data_blob_free(&blob1); - return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); + reply_nterror(req, nt_status_squash( + NT_STATUS_INVALID_PARAMETER)); + return; } vuser = get_partial_auth_user_struct(vuid); @@ -1105,11 +1135,11 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, if (!vuser) { data_blob_free(&blob1); - return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); + reply_nterror(req, nt_status_squash( + NT_STATUS_INVALID_PARAMETER)); + return; } - SSVAL(outbuf,smb_uid,vuid); - /* Large (greater than 4k) SPNEGO blobs are split into multiple * sessionsetup requests as the Windows limit on the security blob * field is 4k. Bug #4400. JRA. @@ -1122,34 +1152,41 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, invalidate_vuid(vuid); } data_blob_free(&blob1); - return ERROR_NT(nt_status_squash(status)); + reply_nterror(req, nt_status_squash(status)); + return; } if (blob1.data[0] == ASN1_APPLICATION(0)) { + /* its a negTokenTarg packet */ - ret = reply_spnego_negotiate(conn, inbuf, outbuf, vuid, length, bufsize, blob1, - &vuser->auth_ntlmssp_state); + + reply_spnego_negotiate(conn, req, vuid, blob1, + &vuser->auth_ntlmssp_state); data_blob_free(&blob1); - return ret; + return; } if (blob1.data[0] == ASN1_CONTEXT(1)) { + /* its a auth packet */ - ret = reply_spnego_auth(conn, inbuf, outbuf, vuid, length, bufsize, blob1, - &vuser->auth_ntlmssp_state); + + reply_spnego_auth(conn, req, vuid, blob1, + &vuser->auth_ntlmssp_state); data_blob_free(&blob1); - return ret; + return; } if (strncmp((char *)(blob1.data), "NTLMSSP", 7) == 0) { DATA_BLOB chal; + if (!vuser->auth_ntlmssp_state) { status = auth_ntlmssp_start(&vuser->auth_ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { /* Kill the intermediate vuid */ invalidate_vuid(vuid); data_blob_free(&blob1); - return ERROR_NT(nt_status_squash(status)); + reply_nterror(req, nt_status_squash(status)); + return; } } @@ -1158,11 +1195,11 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, data_blob_free(&blob1); - reply_spnego_ntlmssp(conn, inbuf, outbuf, vuid, - &vuser->auth_ntlmssp_state, - &chal, status, False); + reply_spnego_ntlmssp(conn, req, vuid, + &vuser->auth_ntlmssp_state, + &chal, status, False); data_blob_free(&chal); - return -1; + return; } /* what sort of packet is this? */ @@ -1170,7 +1207,7 @@ static int reply_sesssetup_and_X_spnego(connection_struct *conn, char *inbuf, data_blob_free(&blob1); - return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE)); } /**************************************************************************** @@ -1219,8 +1256,7 @@ static void setup_new_vc_session(void) Reply to a session setup command. ****************************************************************************/ -int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, - int length,int bufsize) +void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) { int sess_vuid; int smb_bufsize; @@ -1236,75 +1272,88 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, static BOOL done_sesssetup = False; auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; - uint16 smb_flag2 = SVAL(inbuf, smb_flg2); + uint16 smb_flag2 = req->flags2; NTSTATUS nt_status; BOOL doencrypt = global_encrypted_passwords_negotiated; DATA_BLOB session_key; + + START_PROFILE(SMBsesssetupX); ZERO_STRUCT(lm_resp); ZERO_STRUCT(nt_resp); ZERO_STRUCT(plaintext_password); - DEBUG(3,("wct=%d flg2=0x%x\n", CVAL(inbuf, smb_wct), smb_flag2)); + DEBUG(3,("wct=%d flg2=0x%x\n", req->wct, req->flags2)); /* a SPNEGO session setup has 12 command words, whereas a normal NT1 session setup has 13. See the cifs spec. */ - if (CVAL(inbuf, smb_wct) == 12 && - (smb_flag2 & FLAGS2_EXTENDED_SECURITY)) { + if (req->wct == 12 && + (req->flags2 & FLAGS2_EXTENDED_SECURITY)) { + if (!global_spnego_negotiated) { - DEBUG(0, ("reply_sesssetup_and_X: Rejecting attempt " - "at SPNEGO session setup when it was not " - "negotiated.\n")); - return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt " + "at SPNEGO session setup when it was not " + "negotiated.\n")); + reply_nterror(req, nt_status_squash( + NT_STATUS_LOGON_FAILURE)); + return; } - if (SVAL(inbuf,smb_vwv4) == 0) { + if (SVAL(req->inbuf,smb_vwv4) == 0) { setup_new_vc_session(); } - return reply_sesssetup_and_X_spnego(conn, inbuf, outbuf, length, bufsize); + + reply_sesssetup_and_X_spnego(conn, req); + + return; } - smb_bufsize = SVAL(inbuf,smb_vwv2); + smb_bufsize = SVAL(req->inbuf,smb_vwv2); if (Protocol < PROTOCOL_NT1) { - uint16 passlen1 = SVAL(inbuf,smb_vwv7); + uint16 passlen1 = SVAL(req->inbuf,smb_vwv7); /* Never do NT status codes with protocols before NT1 as we don't get client caps. */ remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); - if ((passlen1 > MAX_PASS_LEN) || (passlen1 > smb_bufrem(inbuf, smb_buf(inbuf)))) { - return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); + if ((passlen1 > MAX_PASS_LEN) + || (passlen1 > smb_bufrem(req->inbuf, + smb_buf(req->inbuf)))) { + reply_nterror(req, nt_status_squash( + NT_STATUS_INVALID_PARAMETER)); + return; } if (doencrypt) { - lm_resp = data_blob(smb_buf(inbuf), passlen1); + lm_resp = data_blob(smb_buf(req->inbuf), passlen1); } else { - plaintext_password = data_blob(smb_buf(inbuf), passlen1+1); + plaintext_password = data_blob(smb_buf(req->inbuf), + passlen1+1); /* Ensure null termination */ plaintext_password.data[passlen1] = 0; } - srvstr_pull_buf(inbuf, smb_flag2, user, - smb_buf(inbuf)+passlen1, sizeof(user), + srvstr_pull_buf(req->inbuf, req->flags2, user, + smb_buf(req->inbuf)+passlen1, sizeof(user), STR_TERMINATE); *domain = 0; } else { - uint16 passlen1 = SVAL(inbuf,smb_vwv7); - uint16 passlen2 = SVAL(inbuf,smb_vwv8); + uint16 passlen1 = SVAL(req->inbuf,smb_vwv7); + uint16 passlen2 = SVAL(req->inbuf,smb_vwv8); enum remote_arch_types ra_type = get_remote_arch(); - char *p = smb_buf(inbuf); - char *save_p = smb_buf(inbuf); + char *p = smb_buf(req->inbuf); + char *save_p = smb_buf(req->inbuf); uint16 byte_count; if(global_client_caps == 0) { - global_client_caps = IVAL(inbuf,smb_vwv11); + global_client_caps = IVAL(req->inbuf,smb_vwv11); if (!(global_client_caps & CAP_STATUS32)) { remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); @@ -1340,12 +1389,18 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } /* check for nasty tricks */ - if (passlen1 > MAX_PASS_LEN || passlen1 > smb_bufrem(inbuf, p)) { - return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); + if (passlen1 > MAX_PASS_LEN + || passlen1 > smb_bufrem(req->inbuf, p)) { + reply_nterror(req, nt_status_squash( + NT_STATUS_INVALID_PARAMETER)); + return; } - if (passlen2 > MAX_PASS_LEN || passlen2 > smb_bufrem(inbuf, p+passlen1)) { - return ERROR_NT(nt_status_squash(NT_STATUS_INVALID_PARAMETER)); + if (passlen2 > MAX_PASS_LEN + || passlen2 > smb_bufrem(req->inbuf, p+passlen1)) { + reply_nterror(req, nt_status_squash( + NT_STATUS_INVALID_PARAMETER)); + return; } /* Save the lanman2 password and the NT md4 password. */ @@ -1371,12 +1426,12 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if (unic && (passlen2 == 0) && passlen1) { /* Only a ascii plaintext password was sent. */ - srvstr_pull(inbuf, smb_flag2, pass, - smb_buf(inbuf), sizeof(pass), + srvstr_pull(req->inbuf, req->flags2, pass, + smb_buf(req->inbuf), sizeof(pass), passlen1, STR_TERMINATE|STR_ASCII); } else { - srvstr_pull(inbuf, smb_flag2, pass, - smb_buf(inbuf), sizeof(pass), + srvstr_pull(req->inbuf, req->flags2, pass, + smb_buf(req->inbuf), sizeof(pass), unic ? passlen2 : passlen1, STR_TERMINATE); } @@ -1384,13 +1439,13 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } p += passlen1 + passlen2; - p += srvstr_pull_buf(inbuf, smb_flag2, user, p, + p += srvstr_pull_buf(req->inbuf, req->flags2, user, p, sizeof(user), STR_TERMINATE); - p += srvstr_pull_buf(inbuf, smb_flag2, domain, p, + p += srvstr_pull_buf(req->inbuf, req->flags2, domain, p, sizeof(domain), STR_TERMINATE); - p += srvstr_pull_buf(inbuf, smb_flag2, native_os, + p += srvstr_pull_buf(req->inbuf, req->flags2, native_os, p, sizeof(native_os), STR_TERMINATE); - p += srvstr_pull_buf(inbuf, smb_flag2, + p += srvstr_pull_buf(req->inbuf, req->flags2, native_lanman, p, sizeof(native_lanman), STR_TERMINATE); @@ -1400,9 +1455,9 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, the native lanman string. Windows 9x does not include a string here at all so we have to check if we have any extra bytes left */ - byte_count = SVAL(inbuf, smb_vwv13); + byte_count = SVAL(req->inbuf, smb_vwv13); if ( PTR_DIFF(p, save_p) < byte_count) - p += srvstr_pull_buf(inbuf, smb_flag2, + p += srvstr_pull_buf(req->inbuf, req->flags2, primary_domain, p, sizeof(primary_domain), STR_TERMINATE); @@ -1421,7 +1476,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } - if (SVAL(inbuf,smb_vwv4) == 0) { + if (SVAL(req->inbuf,smb_vwv4) == 0) { setup_new_vc_session(); } @@ -1433,7 +1488,9 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, /* This has to be here, because 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_squash(NT_STATUS_LOGON_FAILURE)); + reply_nterror(req, nt_status_squash( + NT_STATUS_LOGON_FAILURE)); + return; } fstrcpy(sub_user, user); } else { @@ -1465,7 +1522,9 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, } else if (doencrypt) { if (!negprot_global_auth_context) { DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted session setup without negprot denied!\n")); - return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + reply_nterror(req, nt_status_squash( + NT_STATUS_LOGON_FAILURE)); + return; } nt_status = make_user_info_for_reply_enc(&user_info, user, domain, lm_resp, nt_resp); @@ -1509,12 +1568,14 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, data_blob_free(&nt_resp); data_blob_free(&lm_resp); data_blob_clear_free(&plaintext_password); - return ERROR_NT(nt_status_squash(nt_status)); + reply_nterror(req, nt_status_squash(nt_status)); + return; } /* Ensure we can't possible take a code path leading to a null defref. */ if (!server_info) { - return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE)); + return; } nt_status = create_local_token(server_info); @@ -1524,7 +1585,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, data_blob_free(&nt_resp); data_blob_free(&lm_resp); data_blob_clear_free(&plaintext_password); - return ERROR_NT(nt_status_squash(nt_status)); + reply_nterror(req, nt_status_squash(nt_status)); + return; } if (server_info->user_session_key.data) { @@ -1536,16 +1598,14 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, data_blob_clear_free(&plaintext_password); /* it's ok - setup a reply */ - set_message(inbuf,outbuf,3,0,True); + reply_outbuf(req, 3, 0); if (Protocol >= PROTOCOL_NT1) { - char *p = smb_buf( outbuf ); - p += add_signature( outbuf, p ); - set_message_end(inbuf, outbuf, p ); + push_signature(&req->outbuf); /* perhaps grab OS version here?? */ } if (server_info->guest) { - SSVAL(outbuf,smb_vwv2,1); + SSVAL(req->outbuf,smb_vwv2,1); } /* register the name and uid as being validated, so further connections @@ -1563,20 +1623,22 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, if (sess_vuid == UID_FIELD_INVALID) { data_blob_free(&nt_resp); data_blob_free(&lm_resp); - return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + reply_nterror(req, nt_status_squash( + NT_STATUS_LOGON_FAILURE)); + return; } /* current_user_info is changed on new vuid */ reload_services( True ); - sessionsetup_start_signing_engine(server_info, inbuf); + sessionsetup_start_signing_engine(server_info, req->inbuf); } data_blob_free(&nt_resp); data_blob_free(&lm_resp); - SSVAL(outbuf,smb_uid,sess_vuid); - SSVAL(inbuf,smb_uid,sess_vuid); + SSVAL(req->outbuf,smb_uid,sess_vuid); + SSVAL(req->inbuf,smb_uid,sess_vuid); if (!done_sesssetup) max_send = MIN(max_send,smb_bufsize); @@ -1584,5 +1646,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf, done_sesssetup = True; END_PROFILE(SMBsesssetupX); - return chain_reply(inbuf,&outbuf,length,bufsize); + chain_reply_new(req); + return; } -- cgit From b91704d47b7946d561a0021a08c14f8923d59e3a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 2 Aug 2007 18:28:41 +0000 Subject: r24135: Convert call_trans2open to the new API This itself won't help much, because send_trans2_replies_new still allocates the big buffers, but stay tuned :-) Also add/update my copyright on stuff I recently touched. Volker (This used to be commit 248f15ff143474db2493cef89ba446892342a361) --- source3/smbd/sesssetup.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index e9808e0040..22ad43ff75 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -5,6 +5,7 @@ Copyright (C) Andrew Bartlett 2001 Copyright (C) Jim McDonough 2002 Copyright (C) Luke Howard 2003 + Copyright (C) Volker Lendecke 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From 57e2718e097bba57c96632064956f6ce048d8f28 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Aug 2007 01:43:22 +0000 Subject: r24589: Refactor our vuid code so that we keep the same vuid that was allocated whilst the connection is being constructed and after the connection has been set up. This is what Windows does and at least one client (and HP printer) depends on this behaviour. As it depends on the req struct not yet ported to SAMBA_3_2_0 (Volker, hint hint.... :-) I am not yet adding this to that branch, but will investigate that tomorrow. Jeremy. (This used to be commit a54f2805df92c67e74a6764568eedebe394fd500) --- source3/smbd/sesssetup.c | 122 ++++++++++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 43 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 22ad43ff75..e63511c368 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -249,8 +249,8 @@ static void reply_spnego_kerberos(connection_struct *conn, fstring netbios_domain_name; struct passwd *pw; fstring user; - int sess_vuid; - NTSTATUS ret; + int sess_vuid = SVAL(req->inbuf, smb_uid); + NTSTATUS ret = NT_STATUS_OK; PAC_DATA *pac_data; DATA_BLOB ap_rep, ap_rep_wrapped, response; auth_serversupplied_info *server_info = NULL; @@ -535,18 +535,28 @@ static void reply_spnego_kerberos(connection_struct *conn, } } - /* register_vuid keeps the server info */ - /* register_vuid takes ownership of session_key, no need to free after this. - A better interface would copy it.... */ - sess_vuid = register_vuid(server_info, session_key, nullblob, client); + /* register_existing_vuid keeps the server info */ + /* register_existing_vuid takes ownership of session_key on success, + * no need to free after this on success. A better interface would copy + * it.... */ + + if (!is_partial_auth_vuid(sess_vuid)) { + sess_vuid = register_initial_vuid(); + } + sess_vuid = register_existing_vuid(sess_vuid, + server_info, + session_key, + nullblob, + client); SAFE_FREE(client); reply_outbuf(req, 4, 0); - SSVAL(req->outbuf,smb_uid,vuid); + SSVAL(req->outbuf,smb_uid,sess_vuid); if (sess_vuid == UID_FIELD_INVALID ) { ret = NT_STATUS_LOGON_FAILURE; + data_blob_free(&session_key); } else { /* current_user_info is changed on new vuid */ reload_services( True ); @@ -560,6 +570,8 @@ static void reply_spnego_kerberos(connection_struct *conn, SSVAL(req->outbuf, smb_uid, sess_vuid); sessionsetup_start_signing_engine(server_info, req->inbuf); + /* Successful logon. Keep this vuid. */ + *p_invalidate_vuid = False; } /* wrap that up in a nice GSS-API wrapping */ @@ -611,33 +623,43 @@ static void reply_spnego_ntlmssp(connection_struct *conn, SSVAL(req->outbuf, smb_uid, vuid); if (NT_STATUS_IS_OK(nt_status)) { - int sess_vuid; DATA_BLOB nullblob = data_blob_null; DATA_BLOB session_key = data_blob((*auth_ntlmssp_state)->ntlmssp_state->session_key.data, (*auth_ntlmssp_state)->ntlmssp_state->session_key.length); - /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, session_key, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user); + if (!is_partial_auth_vuid(vuid)) { + data_blob_free(&session_key); + nt_status = NT_STATUS_LOGON_FAILURE; + goto out; + } + /* register_existing_vuid keeps the server info */ + if (register_existing_vuid(vuid, + server_info, + session_key, nullblob, + (*auth_ntlmssp_state)->ntlmssp_state->user) != + vuid) { + data_blob_free(&session_key); + nt_status = NT_STATUS_LOGON_FAILURE; + goto out; + } + (*auth_ntlmssp_state)->server_info = NULL; - if (sess_vuid == UID_FIELD_INVALID ) { - nt_status = NT_STATUS_LOGON_FAILURE; - } else { - - /* current_user_info is changed on new vuid */ - reload_services( True ); + /* current_user_info is changed on new vuid */ + reload_services( True ); - SSVAL(req->outbuf, smb_vwv3, 0); - - if (server_info->guest) { - SSVAL(req->outbuf,smb_vwv2,1); - } - - SSVAL(req->outbuf,smb_uid,sess_vuid); + SSVAL(req->outbuf, smb_vwv3, 0); - sessionsetup_start_signing_engine(server_info, req->inbuf); + if (server_info->guest) { + SSVAL(req->outbuf,smb_vwv2,1); } + + SSVAL(req->outbuf,smb_uid,vuid); + + sessionsetup_start_signing_engine(server_info, req->inbuf); } + out: + if (wrap) { response = spnego_gen_auth_response(ntlmssp_blob, nt_status, OID_NTLMSSP); } else { @@ -655,8 +677,10 @@ static void reply_spnego_ntlmssp(connection_struct *conn, if (!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); + if (!NT_STATUS_IS_OK(nt_status)) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + } } } @@ -1111,36 +1135,36 @@ static void reply_sesssetup_and_X_spnego(connection_struct *conn, } } - vuser = get_partial_auth_user_struct(vuid); - if (!vuser) { + /* Did we get a valid vuid ? */ + if (!is_partial_auth_vuid(vuid)) { + /* No, then try and see if this is an intermediate sessionsetup + * for a large SPNEGO packet. */ struct pending_auth_data *pad = get_pending_auth_data(smbpid); if (pad) { DEBUG(10,("reply_sesssetup_and_X_spnego: found pending vuid %u\n", (unsigned int)pad->vuid )); vuid = pad->vuid; - vuser = get_partial_auth_user_struct(vuid); } } - if (!vuser) { - vuid = register_vuid(NULL, data_blob_null, data_blob_null, NULL); - if (vuid == UID_FIELD_INVALID ) { + /* Do we have a valid vuid now ? */ + if (!is_partial_auth_vuid(vuid)) { + /* No, start a new authentication setup. */ + vuid = register_initial_vuid(); + if (vuid == UID_FIELD_INVALID) { data_blob_free(&blob1); reply_nterror(req, nt_status_squash( NT_STATUS_INVALID_PARAMETER)); return; } - - vuser = get_partial_auth_user_struct(vuid); } + vuser = get_partial_auth_user_struct(vuid); + /* This MUST be valid. */ if (!vuser) { - data_blob_free(&blob1); - reply_nterror(req, nt_status_squash( - NT_STATUS_INVALID_PARAMETER)); - return; + smb_panic("reply_sesssetup_and_X_spnego: invalid vuid."); } - + /* Large (greater than 4k) SPNEGO blobs are split into multiple * sessionsetup requests as the Windows limit on the security blob * field is 4k. Bug #4400. JRA. @@ -1617,13 +1641,25 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) data_blob_free(&session_key); TALLOC_FREE(server_info); } else { - /* register_vuid keeps the server info */ - sess_vuid = register_vuid(server_info, session_key, - nt_resp.data ? nt_resp : lm_resp, - sub_user); + /* Ignore the initial vuid. */ + sess_vuid = register_initial_vuid(); if (sess_vuid == UID_FIELD_INVALID) { data_blob_free(&nt_resp); data_blob_free(&lm_resp); + data_blob_free(&session_key); + reply_nterror(req, nt_status_squash( + NT_STATUS_LOGON_FAILURE)); + } + /* register_existing_vuid keeps the server info */ + sess_vuid = register_existing_vuid(sess_vuid, + server_info, + session_key, + nt_resp.data ? nt_resp : lm_resp, + sub_user); + if (sess_vuid == UID_FIELD_INVALID) { + data_blob_free(&nt_resp); + data_blob_free(&lm_resp); + data_blob_free(&session_key); reply_nterror(req, nt_status_squash( NT_STATUS_LOGON_FAILURE)); return; -- cgit From 644b43d993db7ec709a2bc4e121426e7a27237e8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Aug 2007 02:04:24 +0000 Subject: r24590: Reformatting to coding standards. Added my (C) in places it already should have been :-). Jeremy. (This used to be commit 41611a22ed852bb74e2ef3f45766c0580ffd3a18) --- source3/smbd/sesssetup.c | 421 ++++++++++++++++++++++++++++------------------- 1 file changed, 249 insertions(+), 172 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index e63511c368..4c45806b02 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -6,17 +6,18 @@ Copyright (C) Jim McDonough 2002 Copyright (C) Luke Howard 2003 Copyright (C) Volker Lendecke 2007 + Copyright (C) Jeremy Allison 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -35,11 +36,12 @@ uint32 global_client_caps = 0; on a logon error possibly map the error to success if "map to guest" is set approriately */ -static NTSTATUS do_map_to_guest(NTSTATUS status, auth_serversupplied_info **server_info, +static NTSTATUS do_map_to_guest(NTSTATUS status, + auth_serversupplied_info **server_info, const char *user, const char *domain) { if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)) { - if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || + if ((lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER) || (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) { DEBUG(3,("No such user %s [%s] - using guest account\n", user, domain)); @@ -49,7 +51,8 @@ static NTSTATUS do_map_to_guest(NTSTATUS status, auth_serversupplied_info **serv if (NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) { if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) { - DEBUG(3,("Registered username %s for guest access\n",user)); + DEBUG(3,("Registered username %s for guest access\n", + user)); status = make_server_info_guest(server_info); } } @@ -96,8 +99,9 @@ static int push_signature(uint8 **outbuf) Start the signing engine if needed. Don't fail signing here. ****************************************************************************/ -static void sessionsetup_start_signing_engine(const auth_serversupplied_info *server_info, - const uint8 *inbuf) +static void sessionsetup_start_signing_engine( + const auth_serversupplied_info *server_info, + const uint8 *inbuf) { if (!server_info->guest && !srv_signing_started()) { /* We need to start the signing engine @@ -106,7 +110,7 @@ static void sessionsetup_start_signing_engine(const auth_serversupplied_info *se * correct one. Subsequent packets will * be correct. */ - srv_check_sign_mac((char *)inbuf, False); + srv_check_sign_mac((char *)inbuf, False); } } @@ -140,14 +144,14 @@ static void reply_sesssetup_blob(connection_struct *conn, } /**************************************************************************** - Do a 'guest' logon, getting back the + Do a 'guest' logon, getting back the ****************************************************************************/ -static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) +static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) { struct auth_context *auth_context; auth_usersupplied_info *user_info = NULL; - + NTSTATUS nt_status; unsigned char chal[8]; @@ -155,7 +159,8 @@ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) DEBUG(3,("Got anonymous request\n")); - if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context, chal))) { + if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context, + chal))) { return nt_status; } @@ -163,8 +168,10 @@ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) (auth_context->free)(&auth_context); return NT_STATUS_NO_MEMORY; } - - nt_status = auth_context->check_ntlm_password(auth_context, user_info, server_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; @@ -204,14 +211,17 @@ static BOOL make_krb5_skew_error(DATA_BLOB *pblob_out) kerr = smb_krb5_parse_name(context, host_princ_s, &host_princ); if (kerr) { - DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed for name %s: Error %s\n", + DEBUG(10,("make_krb5_skew_error: smb_krb5_parse_name failed " + "for name %s: Error %s\n", host_princ_s, error_message(kerr) )); goto out; } - - kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW, host_princ, &reply); + + kerr = smb_krb5_mk_error(context, KRB5KRB_AP_ERR_SKEW, + host_princ, &reply); if (kerr) { - DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error failed: Error %s\n", + DEBUG(10,("make_krb5_skew_error: smb_krb5_mk_error " + "failed: Error %s\n", error_message(kerr) )); goto out; } @@ -283,39 +293,46 @@ static void reply_spnego_kerberos(connection_struct *conn, return; } - ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket, - &client, &pac_data, &ap_rep, + ret = ads_verify_ticket(mem_ctx, lp_realm(), 0, &ticket, + &client, &pac_data, &ap_rep, &session_key, True); data_blob_free(&ticket); if (!NT_STATUS_IS_OK(ret)) { #if 0 - /* Experiment that failed. See "only happens with a KDC" comment below. */ + /* Experiment that failed. + * See "only happens with a KDC" comment below. */ if (NT_STATUS_EQUAL(ret, NT_STATUS_TIME_DIFFERENCE_AT_DC)) { /* - * Windows in this case returns NT_STATUS_MORE_PROCESSING_REQUIRED - * with a negTokenTarg blob containing an krb5_error struct ASN1 encoded - * containing KRB5KRB_AP_ERR_SKEW. The client then fixes its - * clock and continues rather than giving an error. JRA. + * Windows in this case returns + * NT_STATUS_MORE_PROCESSING_REQUIRED + * with a negTokenTarg blob containing an krb5_error + * struct ASN1 encoded containing KRB5KRB_AP_ERR_SKEW. + * The client then fixes its clock and continues rather + * than giving an error. JRA. * -- Looks like this only happens with a KDC. JRA. */ BOOL ok = make_krb5_skew_error(&ap_rep); if (!ok) { talloc_destroy(mem_ctx); - return ERROR_NT(nt_status_squash(NT_STATUS_LOGON_FAILURE)); + return ERROR_NT(nt_status_squash( + NT_STATUS_LOGON_FAILURE)); } - ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_ERROR); - response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD); - reply_sesssetup_blob(conn, inbuf, outbuf, response, NT_STATUS_MORE_PROCESSING_REQUIRED); + ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, + TOK_ID_KRB_ERROR); + response = spnego_gen_auth_response(&ap_rep_wrapped, + ret, OID_KERBEROS5_OLD); + reply_sesssetup_blob(conn, inbuf, outbuf, response, + NT_STATUS_MORE_PROCESSING_REQUIRED); /* - * In this one case we don't invalidate the intermediate vuid. - * as we're expecting the client to re-use it for the next - * sessionsetupX packet. JRA. + * In this one case we don't invalidate the + * intermediate vuid as we're expecting the client + * to re-use it for the next sessionsetupX packet. JRA. */ *p_invalidate_vuid = False; @@ -331,7 +348,8 @@ static void reply_spnego_kerberos(connection_struct *conn, ret = NT_STATUS_LOGON_FAILURE; } #endif - DEBUG(1,("Failed to verify incoming ticket with error %s!\n", nt_errstr(ret))); + DEBUG(1,("Failed to verify incoming ticket with error %s!\n", + nt_errstr(ret))); talloc_destroy(mem_ctx); reply_nterror(req, nt_status_squash(ret)); return; @@ -380,8 +398,9 @@ static void reply_spnego_kerberos(connection_struct *conn, domain = p+1; if (logon_info && logon_info->info3.hdr_logon_dom.uni_str_len) { - - unistr2_to_ascii(netbios_domain_name, &logon_info->info3.uni_logon_dom, -1); + unistr2_to_ascii(netbios_domain_name, + &logon_info->info3.uni_logon_dom, + -1); domain = netbios_domain_name; DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain)); @@ -422,7 +441,7 @@ static void reply_spnego_kerberos(connection_struct *conn, } fstr_sprintf(user, "%s%c%s", domain, *lp_winbind_separator(), client); - + /* lookup the passwd struct, create a new user if necessary */ username_was_mapped = map_username( user ); @@ -435,7 +454,8 @@ static void reply_spnego_kerberos(connection_struct *conn, /* do this before an eventual mappign to guest occurs */ ret = smb_pam_accountcheck(pw->pw_name); if ( !NT_STATUS_IS_OK(ret)) { - DEBUG(1, ("PAM account restriction prevents user login\n")); + DEBUG(1,("PAM account restriction " + "prevents user login\n")); data_blob_free(&ap_rep); data_blob_free(&session_key); TALLOC_FREE(mem_ctx); @@ -447,19 +467,20 @@ static void reply_spnego_kerberos(connection_struct *conn, if (!pw) { /* this was originally the behavior of Samba 2.2, if a user - did not have a local uid but has been authenticated, then + did not have a local uid but has been authenticated, then map them to a guest account */ - if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID){ + if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID){ map_domainuser_to_guest = True; fstrcpy(user,lp_guestaccount()); pw = smb_getpwnam( mem_ctx, user, real_username, True ); - } + } /* extra sanity check that the guest account is valid */ if ( !pw ) { - DEBUG(1,("Username %s is invalid on this system\n", user)); + DEBUG(1,("Username %s is invalid on this system\n", + user)); SAFE_FREE(client); data_blob_free(&ap_rep); data_blob_free(&session_key); @@ -471,17 +492,17 @@ static void reply_spnego_kerberos(connection_struct *conn, } /* setup the string used by %U */ - + sub_set_smb_name( real_username ); reload_services(True); if ( map_domainuser_to_guest ) { make_server_info_guest(&server_info); } else if (logon_info) { - /* pass the unmapped username here since map_username() + /* pass the unmapped username here since map_username() will be called again from inside make_server_info_info3() */ - - ret = make_server_info_info3(mem_ctx, client, domain, + + ret = make_server_info_info3(mem_ctx, client, domain, &server_info, &logon_info->info3); if ( !NT_STATUS_IS_OK(ret) ) { DEBUG(1,("make_server_info_info3 failed: %s!\n", @@ -513,15 +534,16 @@ static void reply_spnego_kerberos(connection_struct *conn, * %D. */ if (server_info->sam_account != NULL) { - pdb_set_domain(server_info->sam_account, domain, PDB_SET); + pdb_set_domain(server_info->sam_account, + domain, PDB_SET); } } server_info->was_mapped |= username_was_mapped; - + /* we need to build the token for the user. make_server_info_guest() already does this */ - + if ( !server_info->ptok ) { ret = create_local_token( server_info ); if ( !NT_STATUS_IS_OK(ret) ) { @@ -562,11 +584,11 @@ static void reply_spnego_kerberos(connection_struct *conn, reload_services( True ); SSVAL(req->outbuf, smb_vwv3, 0); - + if (server_info->guest) { SSVAL(req->outbuf,smb_vwv2,1); } - + SSVAL(req->outbuf, smb_uid, sess_vuid); sessionsetup_start_signing_engine(server_info, req->inbuf); @@ -576,11 +598,13 @@ static void reply_spnego_kerberos(connection_struct *conn, /* wrap that up in a nice GSS-API wrapping */ if (NT_STATUS_IS_OK(ret)) { - ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, TOK_ID_KRB_AP_REP); + ap_rep_wrapped = spnego_gen_krb5_wrap(ap_rep, + TOK_ID_KRB_AP_REP); } else { ap_rep_wrapped = data_blob_null; } - response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD); + response = spnego_gen_auth_response(&ap_rep_wrapped, ret, + OID_KERBEROS5_OLD); reply_sesssetup_blob(conn, req, response, ret); data_blob_free(&ap_rep); @@ -612,10 +636,10 @@ static void reply_spnego_ntlmssp(connection_struct *conn, if (NT_STATUS_IS_OK(nt_status)) { server_info = (*auth_ntlmssp_state)->server_info; } else { - nt_status = do_map_to_guest(nt_status, - &server_info, - (*auth_ntlmssp_state)->ntlmssp_state->user, - (*auth_ntlmssp_state)->ntlmssp_state->domain); + nt_status = do_map_to_guest(nt_status, + &server_info, + (*auth_ntlmssp_state)->ntlmssp_state->user, + (*auth_ntlmssp_state)->ntlmssp_state->domain); } reply_outbuf(req, 4, 0); @@ -624,7 +648,10 @@ static void reply_spnego_ntlmssp(connection_struct *conn, if (NT_STATUS_IS_OK(nt_status)) { DATA_BLOB nullblob = data_blob_null; - DATA_BLOB session_key = data_blob((*auth_ntlmssp_state)->ntlmssp_state->session_key.data, (*auth_ntlmssp_state)->ntlmssp_state->session_key.length); + DATA_BLOB session_key = + data_blob( + (*auth_ntlmssp_state)->ntlmssp_state->session_key.data, + (*auth_ntlmssp_state)->ntlmssp_state->session_key.length); if (!is_partial_auth_vuid(vuid)) { data_blob_free(&session_key); @@ -661,7 +688,8 @@ static void reply_spnego_ntlmssp(connection_struct *conn, out: if (wrap) { - response = spnego_gen_auth_response(ntlmssp_blob, nt_status, OID_NTLMSSP); + response = spnego_gen_auth_response(ntlmssp_blob, + nt_status, OID_NTLMSSP); } else { response = *ntlmssp_blob; } @@ -688,7 +716,8 @@ static void reply_spnego_ntlmssp(connection_struct *conn, Is this a krb5 mechanism ? ****************************************************************************/ -NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, BOOL *p_is_krb5) +NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, + BOOL *p_is_krb5) { char *OIDs[ASN1_MAX_OIDS]; int i; @@ -701,22 +730,22 @@ NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, BOOL * } /* 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 + according 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 */ -#ifdef HAVE_KRB5 +#ifdef HAVE_KRB5 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) { *p_is_krb5 = True; } #endif - + for (i=0;OIDs[i];i++) { DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i])); free(OIDs[i]); @@ -739,7 +768,8 @@ static void reply_spnego_negotiate(connection_struct *conn, BOOL got_kerberos_mechanism = False; NTSTATUS status; - status = parse_spnego_mechanisms(blob1, &secblob, &got_kerberos_mechanism); + status = parse_spnego_mechanisms(blob1, &secblob, + &got_kerberos_mechanism); if (!NT_STATUS_IS_OK(status)) { /* Kill the intermediate vuid */ invalidate_vuid(vuid); @@ -747,10 +777,12 @@ static void reply_spnego_negotiate(connection_struct *conn, return; } - DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length)); + DEBUG(3,("reply_spnego_negotiate: Got secblob of size %lu\n", + (unsigned long)secblob.length)); #ifdef HAVE_KRB5 - if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { + if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || + lp_use_kerberos_keytab()) ) { BOOL destroy_vuid = True; reply_spnego_kerberos(conn, req, &secblob, vuid, &destroy_vuid); @@ -775,7 +807,7 @@ static void reply_spnego_negotiate(connection_struct *conn, return; } - status = auth_ntlmssp_update(*auth_ntlmssp_state, + status = auth_ntlmssp_update(*auth_ntlmssp_state, secblob, &chal); data_blob_free(&secblob); @@ -820,11 +852,14 @@ static void reply_spnego_auth(connection_struct *conn, /* Might be a second negTokenTarg packet */ BOOL got_krb5_mechanism = False; - status = parse_spnego_mechanisms(auth, &secblob, &got_krb5_mechanism); + status = parse_spnego_mechanisms(auth, &secblob, + &got_krb5_mechanism); if (NT_STATUS_IS_OK(status)) { - DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n", (unsigned long)secblob.length)); + DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n", + (unsigned long)secblob.length)); #ifdef HAVE_KRB5 - if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { + if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || + lp_use_kerberos_keytab()) ) { BOOL destroy_vuid = True; reply_spnego_kerberos(conn, req, &secblob, vuid, &destroy_vuid); @@ -842,7 +877,7 @@ static void reply_spnego_auth(connection_struct *conn, /* If we get here it wasn't a negTokenTarg auth packet. */ data_blob_free(&secblob); - + if (!*auth_ntlmssp_state) { /* Kill the intermediate vuid */ invalidate_vuid(vuid); @@ -852,8 +887,8 @@ static void reply_spnego_auth(connection_struct *conn, NT_STATUS_INVALID_PARAMETER)); return; } - - status = auth_ntlmssp_update(*auth_ntlmssp_state, + + status = auth_ntlmssp_update(*auth_ntlmssp_state, auth, &auth_reply); data_blob_free(&auth); @@ -861,7 +896,7 @@ static void reply_spnego_auth(connection_struct *conn, reply_spnego_ntlmssp(conn, req, vuid, auth_ntlmssp_state, &auth_reply, status, True); - + data_blob_free(&auth_reply); /* and tell smbd that we have already replied to this packet */ @@ -905,11 +940,13 @@ static struct pending_auth_data *get_pending_auth_data(uint16 smbpid) } /**************************************************************************** - Check the size of an SPNEGO blob. If we need more return NT_STATUS_MORE_PROCESSING_REQUIRED, - else return NT_STATUS_OK. Don't allow the blob to be more than 64k. + Check the size of an SPNEGO blob. If we need more return + NT_STATUS_MORE_PROCESSING_REQUIRED, else return NT_STATUS_OK. Don't allow + the blob to be more than 64k. ****************************************************************************/ -static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB *pblob) +static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, + DATA_BLOB *pblob) { struct pending_auth_data *pad = NULL; ASN1_DATA data; @@ -932,7 +969,8 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB /* Integer wrap paranoia.... */ - if (pad->partial_data.length + copy_len < pad->partial_data.length || + if (pad->partial_data.length + copy_len < + pad->partial_data.length || pad->partial_data.length + copy_len < copy_len) { DEBUG(2,("check_spnego_blob_complete: integer wrap " @@ -1039,7 +1077,8 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, DATA_BLOB /* Refuse the blob if it's bigger than 64k. */ if (needed_len > 65536) { - DEBUG(2,("check_spnego_blob_complete: needed_len too large (%u)\n", + DEBUG(2,("check_spnego_blob_complete: needed_len " + "too large (%u)\n", (unsigned int)needed_len )); return NT_STATUS_INVALID_PARAMETER; } @@ -1092,7 +1131,7 @@ static void reply_sesssetup_and_X_spnego(connection_struct *conn, } } - + p = (uint8 *)smb_buf(req->inbuf); if (data_blob_len == 0) { @@ -1116,7 +1155,7 @@ static void reply_sesssetup_and_X_spnego(connection_struct *conn, sizeof(native_lanman), STR_TERMINATE); p2 += srvstr_pull_buf(req->inbuf, smb_flag2, primary_domain, p2, sizeof(primary_domain), STR_TERMINATE); - DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n", + DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n", native_os, native_lanman, primary_domain)); if ( ra_type == RA_WIN2K ) { @@ -1124,24 +1163,25 @@ static void reply_sesssetup_and_X_spnego(connection_struct *conn, if ( !strlen(native_os) && !strlen(native_lanman) ) set_remote_arch(RA_VISTA); - - /* Windows 2003 doesn't set the native lanman string, + + /* Windows 2003 doesn't set the native lanman string, but does set primary domain which is a bug I think */ - + if ( !strlen(native_lanman) ) { ra_lanman_string( primary_domain ); } else { ra_lanman_string( native_lanman ); } } - + /* Did we get a valid vuid ? */ if (!is_partial_auth_vuid(vuid)) { /* No, then try and see if this is an intermediate sessionsetup * for a large SPNEGO packet. */ struct pending_auth_data *pad = get_pending_auth_data(smbpid); if (pad) { - DEBUG(10,("reply_sesssetup_and_X_spnego: found pending vuid %u\n", + DEBUG(10,("reply_sesssetup_and_X_spnego: found " + "pending vuid %u\n", (unsigned int)pad->vuid )); vuid = pad->vuid; } @@ -1172,7 +1212,8 @@ static void reply_sesssetup_and_X_spnego(connection_struct *conn, status = check_spnego_blob_complete(smbpid, vuid, &blob1); if (!NT_STATUS_IS_OK(status)) { - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (!NT_STATUS_EQUAL(status, + NT_STATUS_MORE_PROCESSING_REQUIRED)) { /* Real error - kill the intermediate vuid */ invalidate_vuid(vuid); } @@ -1217,9 +1258,9 @@ static void reply_sesssetup_and_X_spnego(connection_struct *conn, status = auth_ntlmssp_update(vuser->auth_ntlmssp_state, blob1, &chal); - + data_blob_free(&blob1); - + reply_spnego_ntlmssp(conn, req, vuid, &vuser->auth_ntlmssp_state, &chal, status, False); @@ -1267,7 +1308,8 @@ static int shutdown_other_smbds(struct db_record *rec, static void setup_new_vc_session(void) { - DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x compatible we would close all old resources.\n")); + DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x " + "compatible we would close all old resources.\n")); #if 0 conn_close_all(); invalidate_all_vuids(); @@ -1284,7 +1326,7 @@ static void setup_new_vc_session(void) void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) { int sess_vuid; - int smb_bufsize; + int smb_bufsize; DATA_BLOB lm_resp; DATA_BLOB nt_resp; DATA_BLOB plaintext_password; @@ -1305,8 +1347,6 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) DATA_BLOB session_key; - - START_PROFILE(SMBsesssetupX); ZERO_STRUCT(lm_resp); @@ -1326,6 +1366,7 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) "negotiated.\n")); reply_nterror(req, nt_status_squash( NT_STATUS_LOGON_FAILURE)); + END_PROFILE(SMBsesssetupX); return; } @@ -1334,7 +1375,7 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) } reply_sesssetup_and_X_spnego(conn, req); - + END_PROFILE(SMBsesssetupX); return; } @@ -1343,7 +1384,8 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) if (Protocol < PROTOCOL_NT1) { uint16 passlen1 = SVAL(req->inbuf,smb_vwv7); - /* Never do NT status codes with protocols before NT1 as we don't get client caps. */ + /* Never do NT status codes with protocols before NT1 as we + * don't get client caps. */ remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); if ((passlen1 > MAX_PASS_LEN) @@ -1351,6 +1393,7 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) smb_buf(req->inbuf)))) { reply_nterror(req, nt_status_squash( NT_STATUS_INVALID_PARAMETER)); + END_PROFILE(SMBsesssetupX); return; } @@ -1375,49 +1418,55 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) char *p = smb_buf(req->inbuf); char *save_p = smb_buf(req->inbuf); uint16 byte_count; - + if(global_client_caps == 0) { global_client_caps = IVAL(req->inbuf,smb_vwv11); - + if (!(global_client_caps & CAP_STATUS32)) { - remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); + remove_from_common_flags2( + FLAGS2_32_BIT_ERROR_CODES); } - /* client_caps is used as final determination if client is NT or Win95. - This is needed to return the correct error codes in some - circumstances. + /* client_caps is used as final determination if + * client is NT or Win95. This is needed to return + * the correct error codes in some circumstances. */ - - if(ra_type == RA_WINNT || ra_type == RA_WIN2K || ra_type == RA_WIN95) { - if(!(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))) { + + if(ra_type == RA_WINNT || ra_type == RA_WIN2K || + ra_type == RA_WIN95) { + if(!(global_client_caps & (CAP_NT_SMBS| + CAP_STATUS32))) { set_remote_arch( RA_WIN95); } } } if (!doencrypt) { - /* both Win95 and WinNT stuff up the password lengths for - non-encrypting systems. Uggh. - - if passlen1==24 its a win95 system, and its setting the - password length incorrectly. Luckily it still works with the - default code because Win95 will null terminate the password - anyway - - if passlen1>0 and passlen2>0 then maybe its a NT box and its - setting passlen2 to some random value which really stuffs - things up. we need to fix that one. */ - - if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && passlen2 != 1) + /* both Win95 and WinNT stuff up the password + * lengths for non-encrypting systems. Uggh. + + if passlen1==24 its a win95 system, and its setting + the password length incorrectly. Luckily it still + works with the default code because Win95 will null + terminate the password anyway + + if passlen1>0 and passlen2>0 then maybe its a NT box + and its setting passlen2 to some random value which + really stuffs things up. we need to fix that one. */ + + if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && + passlen2 != 1) { passlen2 = 0; + } } - + /* check for nasty tricks */ if (passlen1 > MAX_PASS_LEN || passlen1 > smb_bufrem(req->inbuf, p)) { reply_nterror(req, nt_status_squash( NT_STATUS_INVALID_PARAMETER)); + END_PROFILE(SMBsesssetupX); return; } @@ -1425,11 +1474,12 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) || passlen2 > smb_bufrem(req->inbuf, p+passlen1)) { reply_nterror(req, nt_status_squash( NT_STATUS_INVALID_PARAMETER)); + END_PROFILE(SMBsesssetupX); return; } /* Save the lanman2 password and the NT md4 password. */ - + if ((doencrypt) && (passlen1 != 0) && (passlen1 != 24)) { doencrypt = False; } @@ -1442,9 +1492,12 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) BOOL unic= smb_flag2 & FLAGS2_UNICODE_STRINGS; #if 0 - /* This was the previous fix. Not sure if it's still valid. JRA. */ - if ((ra_type == RA_WINNT) && (passlen2 == 0) && unic && passlen1) { - /* NT4.0 stuffs up plaintext unicode password lengths... */ + /* This was the previous fix. Not sure if it's still + * valid. JRA. */ + if ((ra_type == RA_WINNT) && (passlen2 == 0) + && unic && passlen1) { + /* NT4.0 stuffs up plaintext unicode password + * lengths... */ srvstr_pull(inbuf, pass, smb_buf(inbuf) + 1, sizeof(pass), passlen1, STR_TERMINATE); #endif @@ -1462,7 +1515,7 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) } plaintext_password = data_blob(pass, strlen(pass)+1); } - + p += passlen1 + passlen2; p += srvstr_pull_buf(req->inbuf, req->flags2, user, p, sizeof(user), STR_TERMINATE); @@ -1474,23 +1527,26 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) native_lanman, p, sizeof(native_lanman), STR_TERMINATE); - /* not documented or decoded by Ethereal but there is one more string - in the extra bytes which is the same as the PrimaryDomain when using - extended security. Windows NT 4 and 2003 use this string to store - the native lanman string. Windows 9x does not include a string here - at all so we have to check if we have any extra bytes left */ - + /* not documented or decoded by Ethereal but there is one more + * string in the extra bytes which is the same as the + * PrimaryDomain when using extended security. Windows NT 4 + * and 2003 use this string to store the native lanman string. + * Windows 9x does not include a string here at all so we have + * to check if we have any extra bytes left */ + byte_count = SVAL(req->inbuf, smb_vwv13); - if ( PTR_DIFF(p, save_p) < byte_count) + if ( PTR_DIFF(p, save_p) < byte_count) { p += srvstr_pull_buf(req->inbuf, req->flags2, primary_domain, p, sizeof(primary_domain), STR_TERMINATE); - else + } else { fstrcpy( primary_domain, "null" ); + } - DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n", - domain, native_os, native_lanman, primary_domain)); + DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] " + "PrimaryDomain=[%s]\n", + domain, native_os, native_lanman, primary_domain)); if ( ra_type == RA_WIN2K ) { if ( strlen(native_lanman) == 0 ) @@ -1505,16 +1561,21 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) setup_new_vc_session(); } - DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, get_remote_machine_name())); + DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", + domain, user, get_remote_machine_name())); if (*user) { if (global_spnego_negotiated) { - - /* This has to be here, because 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")); + + /* This has to be here, because 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")); reply_nterror(req, nt_status_squash( NT_STATUS_LOGON_FAILURE)); + END_PROFILE(SMBsesssetupX); return; } fstrcpy(sub_user, user); @@ -1525,7 +1586,7 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) sub_set_smb_name(sub_user); reload_services(True); - + if (lp_security() == SEC_SHARE) { /* in share level we should ignore any passwords */ @@ -1539,67 +1600,79 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) /* Then force it to null for the benfit of the code below */ *user = 0; } - + if (!*user) { nt_status = check_guest_password(&server_info); } else if (doencrypt) { if (!negprot_global_auth_context) { - DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted session setup without negprot denied!\n")); + DEBUG(0, ("reply_sesssetup_and_X: Attempted encrypted " + "session setup without negprot denied!\n")); reply_nterror(req, nt_status_squash( NT_STATUS_LOGON_FAILURE)); + END_PROFILE(SMBsesssetupX); return; } - nt_status = make_user_info_for_reply_enc(&user_info, user, domain, - lm_resp, nt_resp); + nt_status = make_user_info_for_reply_enc(&user_info, user, + domain, + lm_resp, nt_resp); if (NT_STATUS_IS_OK(nt_status)) { - nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context, - user_info, - &server_info); + nt_status = negprot_global_auth_context->check_ntlm_password( + negprot_global_auth_context, + user_info, + &server_info); } } else { struct auth_context *plaintext_auth_context = NULL; const uint8 *chal; - nt_status = make_auth_context_subsystem(&plaintext_auth_context); + nt_status = make_auth_context_subsystem( + &plaintext_auth_context); if (NT_STATUS_IS_OK(nt_status)) { - chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context); - - if (!make_user_info_for_reply(&user_info, + 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; } - + 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); + 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); - + if (!NT_STATUS_IS_OK(nt_status)) { - nt_status = do_map_to_guest(nt_status, &server_info, user, domain); + nt_status = do_map_to_guest(nt_status, &server_info, + user, domain); } - + if (!NT_STATUS_IS_OK(nt_status)) { data_blob_free(&nt_resp); data_blob_free(&lm_resp); data_blob_clear_free(&plaintext_password); reply_nterror(req, nt_status_squash(nt_status)); + END_PROFILE(SMBsesssetupX); return; } - /* Ensure we can't possible take a code path leading to a null defref. */ + /* Ensure we can't possible take a code path leading to a + * null defref. */ if (!server_info) { reply_nterror(req, nt_status_squash(NT_STATUS_LOGON_FAILURE)); + END_PROFILE(SMBsesssetupX); return; } @@ -1611,24 +1684,26 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) data_blob_free(&lm_resp); data_blob_clear_free(&plaintext_password); reply_nterror(req, nt_status_squash(nt_status)); + END_PROFILE(SMBsesssetupX); return; } if (server_info->user_session_key.data) { - session_key = data_blob(server_info->user_session_key.data, server_info->user_session_key.length); + session_key = data_blob(server_info->user_session_key.data, + server_info->user_session_key.length); } else { session_key = data_blob_null; } data_blob_clear_free(&plaintext_password); - + /* it's ok - setup a reply */ reply_outbuf(req, 3, 0); if (Protocol >= PROTOCOL_NT1) { push_signature(&req->outbuf); /* perhaps grab OS version here?? */ } - + if (server_info->guest) { SSVAL(req->outbuf,smb_vwv2,1); } @@ -1647,6 +1722,7 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) data_blob_free(&nt_resp); data_blob_free(&lm_resp); data_blob_free(&session_key); + END_PROFILE(SMBsesssetupX); reply_nterror(req, nt_status_squash( NT_STATUS_LOGON_FAILURE)); } @@ -1662,6 +1738,7 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) data_blob_free(&session_key); reply_nterror(req, nt_status_squash( NT_STATUS_LOGON_FAILURE)); + END_PROFILE(SMBsesssetupX); return; } @@ -1673,15 +1750,15 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) data_blob_free(&nt_resp); data_blob_free(&lm_resp); - + SSVAL(req->outbuf,smb_uid,sess_vuid); SSVAL(req->inbuf,smb_uid,sess_vuid); - + if (!done_sesssetup) max_send = MIN(max_send,smb_bufsize); - + done_sesssetup = True; - + END_PROFILE(SMBsesssetupX); chain_reply_new(req); return; -- cgit From a689f6082b2c8ee82a794e742f904a990702859a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Aug 2007 21:34:08 +0000 Subject: r24638: Remove redundent setting of vuid. Jeremy (This used to be commit fd682c3f397714ebdaf4af3f6d1cbcbab6a2f572) --- source3/smbd/sesssetup.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 4c45806b02..4405b69475 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. handle SMBsessionsetup Copyright (C) Andrew Tridgell 1998-2001 @@ -680,8 +680,6 @@ static void reply_spnego_ntlmssp(connection_struct *conn, SSVAL(req->outbuf,smb_vwv2,1); } - SSVAL(req->outbuf,smb_uid,vuid); - sessionsetup_start_signing_engine(server_info, req->inbuf); } -- cgit From 7bd8ad3c92839b07fd5f5a3ed0f4eb4c571c24ac Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 26 Aug 2007 10:50:39 +0000 Subject: r24661: Fix some obvious diffs between 3_2 and 3_2_0 Jeremy, there are two remaining diffs in sesssetup.c which I don't really know which one is right. Can you take a look? Thanks, Volker (This used to be commit d82f35448763eacd564836f34c9aa450b15ea582) --- source3/smbd/sesssetup.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 4405b69475..0cfe672a82 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -259,7 +259,7 @@ static void reply_spnego_kerberos(connection_struct *conn, fstring netbios_domain_name; struct passwd *pw; fstring user; - int sess_vuid = SVAL(req->inbuf, smb_uid); + int sess_vuid = req->vuid; NTSTATUS ret = NT_STATUS_OK; PAC_DATA *pac_data; DATA_BLOB ap_rep, ap_rep_wrapped, response; @@ -680,7 +680,8 @@ static void reply_spnego_ntlmssp(connection_struct *conn, SSVAL(req->outbuf,smb_vwv2,1); } - sessionsetup_start_signing_engine(server_info, req->inbuf); + sessionsetup_start_signing_engine(server_info, + (uint8 *)req->inbuf); } out: @@ -1720,9 +1721,10 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) data_blob_free(&nt_resp); data_blob_free(&lm_resp); data_blob_free(&session_key); - END_PROFILE(SMBsesssetupX); reply_nterror(req, nt_status_squash( NT_STATUS_LOGON_FAILURE)); + END_PROFILE(SMBsesssetupX); + return; } /* register_existing_vuid keeps the server info */ sess_vuid = register_existing_vuid(sess_vuid, -- cgit From b578db69e91a088f158c1cd78a71d00045fc1da6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 27 Aug 2007 12:04:09 +0000 Subject: r24702: Remove the old API pointers (This used to be commit 17df313db42199e26d7d2044f6a1d845aacd1a90) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 0cfe672a82..520835bef7 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1760,6 +1760,6 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) done_sesssetup = True; END_PROFILE(SMBsesssetupX); - chain_reply_new(req); + chain_reply(req); return; } -- cgit From 30fc6400578a55ff4fad1ee9d292cbeb54aee744 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 21 Sep 2007 11:58:25 +0000 Subject: r25286: Fix one more caller of unistr2_to_ascii() that passed in -1 for maxlen. Michael (This used to be commit cd3d652d0d7609fc369ed0743c1fc54c87558438) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 520835bef7..20021ec7f7 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -400,7 +400,7 @@ static void reply_spnego_kerberos(connection_struct *conn, if (logon_info && logon_info->info3.hdr_logon_dom.uni_str_len) { unistr2_to_ascii(netbios_domain_name, &logon_info->info3.uni_logon_dom, - -1); + sizeof(netbios_domain_name)); domain = netbios_domain_name; DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain)); -- cgit From cb5436bcc3b55e0c221fb6b3fa3133f149a64384 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Oct 2007 15:36:13 -0700 Subject: Add const to the get_peer_addr() and get_socket_addr() calls. Use the IPv6 varient for get_peer_addr(). Jeremy. (This used to be commit baf1f52e34ae2465a7a34be1065da29ed97e7bea) --- source3/smbd/sesssetup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 20021ec7f7..a2f24c66d2 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1314,7 +1314,8 @@ static void setup_new_vc_session(void) invalidate_all_vuids(); #endif if (lp_reset_on_zero_vc()) { - connections_forall(shutdown_other_smbds, client_addr()); + connections_forall(shutdown_other_smbds, + CONST_DISCARD(void *,client_addr())); } } -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/smbd/sesssetup.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index a2f24c66d2..bc298d11f7 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -25,8 +25,8 @@ #include "includes.h" extern struct auth_context *negprot_global_auth_context; -extern BOOL global_encrypted_passwords_negotiated; -extern BOOL global_spnego_negotiated; +extern bool global_encrypted_passwords_negotiated; +extern bool global_spnego_negotiated; extern enum protocol_types Protocol; extern int max_send; @@ -186,14 +186,14 @@ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) Cerate a clock skew error blob for a Windows client. ****************************************************************************/ -static BOOL make_krb5_skew_error(DATA_BLOB *pblob_out) +static bool make_krb5_skew_error(DATA_BLOB *pblob_out) { krb5_context context = NULL; krb5_error_code kerr = 0; krb5_data reply; krb5_principal host_princ = NULL; char *host_princ_s = NULL; - BOOL ret = False; + bool ret = False; *pblob_out = data_blob_null; @@ -251,7 +251,7 @@ static void reply_spnego_kerberos(connection_struct *conn, struct smb_request *req, DATA_BLOB *secblob, uint16 vuid, - BOOL *p_invalidate_vuid) + bool *p_invalidate_vuid) { TALLOC_CTX *mem_ctx; DATA_BLOB ticket; @@ -268,8 +268,8 @@ static void reply_spnego_kerberos(connection_struct *conn, uint8 tok_id[2]; DATA_BLOB nullblob = data_blob_null; fstring real_username; - BOOL map_domainuser_to_guest = False; - BOOL username_was_mapped; + bool map_domainuser_to_guest = False; + bool username_was_mapped; PAC_LOGON_INFO *logon_info = NULL; ZERO_STRUCT(ticket); @@ -316,7 +316,7 @@ static void reply_spnego_kerberos(connection_struct *conn, * -- Looks like this only happens with a KDC. JRA. */ - BOOL ok = make_krb5_skew_error(&ap_rep); + bool ok = make_krb5_skew_error(&ap_rep); if (!ok) { talloc_destroy(mem_ctx); return ERROR_NT(nt_status_squash( @@ -628,7 +628,7 @@ static void reply_spnego_ntlmssp(connection_struct *conn, uint16 vuid, AUTH_NTLMSSP_STATE **auth_ntlmssp_state, DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status, - BOOL wrap) + bool wrap) { DATA_BLOB response; struct auth_serversupplied_info *server_info = NULL; @@ -716,7 +716,7 @@ static void reply_spnego_ntlmssp(connection_struct *conn, ****************************************************************************/ NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, - BOOL *p_is_krb5) + bool *p_is_krb5) { char *OIDs[ASN1_MAX_OIDS]; int i; @@ -764,7 +764,7 @@ static void reply_spnego_negotiate(connection_struct *conn, { DATA_BLOB secblob; DATA_BLOB chal; - BOOL got_kerberos_mechanism = False; + bool got_kerberos_mechanism = False; NTSTATUS status; status = parse_spnego_mechanisms(blob1, &secblob, @@ -782,7 +782,7 @@ static void reply_spnego_negotiate(connection_struct *conn, #ifdef HAVE_KRB5 if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { - BOOL destroy_vuid = True; + bool destroy_vuid = True; reply_spnego_kerberos(conn, req, &secblob, vuid, &destroy_vuid); data_blob_free(&secblob); @@ -850,7 +850,7 @@ static void reply_spnego_auth(connection_struct *conn, if (auth.data[0] == ASN1_APPLICATION(0)) { /* Might be a second negTokenTarg packet */ - BOOL got_krb5_mechanism = False; + bool got_krb5_mechanism = False; status = parse_spnego_mechanisms(auth, &secblob, &got_krb5_mechanism); if (NT_STATUS_IS_OK(status)) { @@ -859,7 +859,7 @@ static void reply_spnego_auth(connection_struct *conn, #ifdef HAVE_KRB5 if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { - BOOL destroy_vuid = True; + bool destroy_vuid = True; reply_spnego_kerberos(conn, req, &secblob, vuid, &destroy_vuid); data_blob_free(&secblob); @@ -1336,14 +1336,14 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) fstring native_os; fstring native_lanman; fstring primary_domain; - static BOOL done_sesssetup = False; + static bool done_sesssetup = False; auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; uint16 smb_flag2 = req->flags2; NTSTATUS nt_status; - BOOL doencrypt = global_encrypted_passwords_negotiated; + bool doencrypt = global_encrypted_passwords_negotiated; DATA_BLOB session_key; @@ -1489,7 +1489,7 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) nt_resp = data_blob(p+passlen1, passlen2); } else { pstring pass; - BOOL unic= smb_flag2 & FLAGS2_UNICODE_STRINGS; + bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS; #if 0 /* This was the previous fix. Not sure if it's still -- cgit From 6658165d5e9cd186fea74e1581091233e8990e9b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2007 18:15:45 -0700 Subject: Stop get_peer_addr() and client_addr() from using global statics. Part of my library cleanups. Jeremy. (This used to be commit e848506c858bd16706c1d7f6b4b032005512b8ac) --- source3/smbd/sesssetup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index bc298d11f7..35efbc009f 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1307,6 +1307,8 @@ static int shutdown_other_smbds(struct db_record *rec, static void setup_new_vc_session(void) { + char addr[INET6_ADDRSTRLEN]; + DEBUG(2,("setup_new_vc_session: New VC == 0, if NT4.x " "compatible we would close all old resources.\n")); #if 0 @@ -1315,7 +1317,7 @@ static void setup_new_vc_session(void) #endif if (lp_reset_on_zero_vc()) { connections_forall(shutdown_other_smbds, - CONST_DISCARD(void *,client_addr())); + CONST_DISCARD(void *,client_addr(addr))); } } -- cgit From 25074433f412c4dd2531fd268d51be8753ddc11b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2007 18:41:26 -0700 Subject: I can't get away without a 'length' arg. :-). Jeremy. (This used to be commit 95d01279a5def709d0a5d5ae7224d6286006d120) --- source3/smbd/sesssetup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 35efbc009f..87cb3b435b 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1317,7 +1317,8 @@ static void setup_new_vc_session(void) #endif if (lp_reset_on_zero_vc()) { connections_forall(shutdown_other_smbds, - CONST_DISCARD(void *,client_addr(addr))); + CONST_DISCARD(void *, + client_addr(addr,sizeof(addr)))); } } -- cgit From 5b0b4f23ef5fec3d1ad518237f973d4e014b5766 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2007 23:20:10 -0700 Subject: Remove most of the remaining globals out of lib/util_sock.c. I have a plan for dealing with the remaining..... Watch this space. Jeremy. (This used to be commit 963fc7685212689f02b3adcc05b4273ee5c382d4) --- source3/smbd/sesssetup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 87cb3b435b..0e8483c81e 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1317,8 +1317,8 @@ static void setup_new_vc_session(void) #endif if (lp_reset_on_zero_vc()) { connections_forall(shutdown_other_smbds, - CONST_DISCARD(void *, - client_addr(addr,sizeof(addr)))); + CONST_DISCARD(void *, + client_addr(get_client_fd(),addr,sizeof(addr)))); } } -- cgit From 41ae2a0a17d3f67252e81a6db730f87ce26fb939 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 10 Nov 2007 15:36:47 -0800 Subject: Remove last pstring from sesssetup.c Jeremy. (This used to be commit 9ed12bfc48fe7f9b1863a9dd88e881974083053c) --- source3/smbd/sesssetup.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 0e8483c81e..8ca012ff24 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1491,30 +1491,32 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) lm_resp = data_blob(p, passlen1); nt_resp = data_blob(p+passlen1, passlen2); } else { - pstring pass; + char *pass = NULL; bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS; -#if 0 - /* This was the previous fix. Not sure if it's still - * valid. JRA. */ - if ((ra_type == RA_WINNT) && (passlen2 == 0) - && unic && passlen1) { - /* NT4.0 stuffs up plaintext unicode password - * lengths... */ - srvstr_pull(inbuf, pass, smb_buf(inbuf) + 1, - sizeof(pass), passlen1, STR_TERMINATE); -#endif - if (unic && (passlen2 == 0) && passlen1) { /* Only a ascii plaintext password was sent. */ - srvstr_pull(req->inbuf, req->flags2, pass, - smb_buf(req->inbuf), sizeof(pass), - passlen1, STR_TERMINATE|STR_ASCII); + (void)srvstr_pull_talloc(talloc_tos(), + req->inbuf, + req->flags2, + &pass, + smb_buf(req->inbuf), + passlen1, + STR_TERMINATE|STR_ASCII); } else { - srvstr_pull(req->inbuf, req->flags2, pass, - smb_buf(req->inbuf), sizeof(pass), - unic ? passlen2 : passlen1, - STR_TERMINATE); + (void)srvstr_pull_talloc(talloc_tos(), + req->inbuf, + req->flags2, + &pass, + smb_buf(req->inbuf), + unic ? passlen2 : passlen1, + STR_TERMINATE); + } + if (!pass) { + reply_nterror(req, nt_status_squash( + NT_STATUS_INVALID_PARAMETER)); + END_PROFILE(SMBsesssetupX); + return; } plaintext_password = data_blob(pass, strlen(pass)+1); } -- cgit From 9254bb4ef1c3c3a52ea8e935edb0e7a86ec3ea7a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Jan 2008 12:56:23 -0800 Subject: Refactor the crypto code after a very helpful conversation with Volker. Mostly making sure we have data on the incoming packet type, not stored in the smb header. Jeremy. (This used to be commit c4e5a505043965eec77b5bb9bc60957e8f3b97c8) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 8ca012ff24..e44a540554 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -139,7 +139,7 @@ static void reply_sesssetup_blob(connection_struct *conn, } show_msg((char *)req->outbuf); - send_smb(smbd_server_fd(),(char *)req->outbuf); + srv_send_smb(smbd_server_fd(),(char *)req->outbuf,req->encrypted); TALLOC_FREE(req->outbuf); } -- cgit From 29562987c393ef7e908aa02ee7ba00a83f3db520 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Jan 2008 15:37:24 -0800 Subject: Now conn is part of smb_request, we don't need it as an extra parameter. This cleans up quite a few places we were passing it around without needing it. Jeremy. (This used to be commit 8f36def18e9f980e8db522e1de41e80cfd5f466e) --- source3/smbd/sesssetup.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index e44a540554..167682ede2 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -118,8 +118,7 @@ static void sessionsetup_start_signing_engine( Send a security blob via a session setup reply. ****************************************************************************/ -static void reply_sesssetup_blob(connection_struct *conn, - struct smb_request *req, +static void reply_sesssetup_blob(struct smb_request *req, DATA_BLOB blob, NTSTATUS nt_status) { @@ -247,8 +246,7 @@ static bool make_krb5_skew_error(DATA_BLOB *pblob_out) Reply to a session setup spnego negotiate packet for kerberos. ****************************************************************************/ -static void reply_spnego_kerberos(connection_struct *conn, - struct smb_request *req, +static void reply_spnego_kerberos(struct smb_request *req, DATA_BLOB *secblob, uint16 vuid, bool *p_invalidate_vuid) @@ -605,7 +603,7 @@ static void reply_spnego_kerberos(connection_struct *conn, } response = spnego_gen_auth_response(&ap_rep_wrapped, ret, OID_KERBEROS5_OLD); - reply_sesssetup_blob(conn, req, response, ret); + reply_sesssetup_blob(req, response, ret); data_blob_free(&ap_rep); data_blob_free(&ap_rep_wrapped); @@ -623,8 +621,7 @@ static void reply_spnego_kerberos(connection_struct *conn, leg of the NTLM auth steps. ***************************************************************************/ -static void reply_spnego_ntlmssp(connection_struct *conn, - struct smb_request *req, +static void reply_spnego_ntlmssp(struct smb_request *req, uint16 vuid, AUTH_NTLMSSP_STATE **auth_ntlmssp_state, DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status, @@ -693,7 +690,7 @@ static void reply_spnego_ntlmssp(connection_struct *conn, response = *ntlmssp_blob; } - reply_sesssetup_blob(conn, req, response, nt_status); + reply_sesssetup_blob(req, response, nt_status); if (wrap) { data_blob_free(&response); } @@ -756,8 +753,7 @@ NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, Reply to a session setup spnego negotiate packet. ****************************************************************************/ -static void reply_spnego_negotiate(connection_struct *conn, - struct smb_request *req, +static void reply_spnego_negotiate(struct smb_request *req, uint16 vuid, DATA_BLOB blob1, AUTH_NTLMSSP_STATE **auth_ntlmssp_state) @@ -783,7 +779,7 @@ static void reply_spnego_negotiate(connection_struct *conn, if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { bool destroy_vuid = True; - reply_spnego_kerberos(conn, req, &secblob, vuid, + reply_spnego_kerberos(req, &secblob, vuid, &destroy_vuid); data_blob_free(&secblob); if (destroy_vuid) { @@ -811,7 +807,7 @@ static void reply_spnego_negotiate(connection_struct *conn, data_blob_free(&secblob); - reply_spnego_ntlmssp(conn, req, vuid, auth_ntlmssp_state, + reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state, &chal, status, True); data_blob_free(&chal); @@ -824,8 +820,7 @@ static void reply_spnego_negotiate(connection_struct *conn, Reply to a session setup spnego auth packet. ****************************************************************************/ -static void reply_spnego_auth(connection_struct *conn, - struct smb_request *req, +static void reply_spnego_auth(struct smb_request *req, uint16 vuid, DATA_BLOB blob1, AUTH_NTLMSSP_STATE **auth_ntlmssp_state) @@ -860,7 +855,7 @@ static void reply_spnego_auth(connection_struct *conn, if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { bool destroy_vuid = True; - reply_spnego_kerberos(conn, req, &secblob, + reply_spnego_kerberos(req, &secblob, vuid, &destroy_vuid); data_blob_free(&secblob); data_blob_free(&auth); @@ -892,7 +887,7 @@ static void reply_spnego_auth(connection_struct *conn, data_blob_free(&auth); - reply_spnego_ntlmssp(conn, req, vuid, + reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state, &auth_reply, status, True); @@ -1104,8 +1099,7 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, conn POINTER CAN BE NULL HERE ! ****************************************************************************/ -static void reply_sesssetup_and_X_spnego(connection_struct *conn, - struct smb_request *req) +static void reply_sesssetup_and_X_spnego(struct smb_request *req) { uint8 *p; DATA_BLOB blob1; @@ -1225,7 +1219,7 @@ static void reply_sesssetup_and_X_spnego(connection_struct *conn, /* its a negTokenTarg packet */ - reply_spnego_negotiate(conn, req, vuid, blob1, + reply_spnego_negotiate(req, vuid, blob1, &vuser->auth_ntlmssp_state); data_blob_free(&blob1); return; @@ -1235,7 +1229,7 @@ static void reply_sesssetup_and_X_spnego(connection_struct *conn, /* its a auth packet */ - reply_spnego_auth(conn, req, vuid, blob1, + reply_spnego_auth(req, vuid, blob1, &vuser->auth_ntlmssp_state); data_blob_free(&blob1); return; @@ -1260,7 +1254,7 @@ static void reply_sesssetup_and_X_spnego(connection_struct *conn, data_blob_free(&blob1); - reply_spnego_ntlmssp(conn, req, vuid, + reply_spnego_ntlmssp(req, vuid, &vuser->auth_ntlmssp_state, &chal, status, False); data_blob_free(&chal); @@ -1326,7 +1320,7 @@ static void setup_new_vc_session(void) Reply to a session setup command. ****************************************************************************/ -void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) +void reply_sesssetup_and_X(struct smb_request *req) { int sess_vuid; int smb_bufsize; @@ -1377,7 +1371,7 @@ void reply_sesssetup_and_X(connection_struct *conn, struct smb_request *req) setup_new_vc_session(); } - reply_sesssetup_and_X_spnego(conn, req); + reply_sesssetup_and_X_spnego(req); END_PROFILE(SMBsesssetupX); return; } -- cgit From d5bd2e7000592b8256b837415c40e20f319fb07b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Jan 2008 22:56:06 -0800 Subject: Can't use logical operations on boolean values. Jeremy. (This used to be commit 34cd9b5b51a4209b4d970eb90bf1db0eb24a60bb) --- source3/smbd/sesssetup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 167682ede2..bc1d26faca 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -537,7 +537,9 @@ static void reply_spnego_kerberos(struct smb_request *req, } } - server_info->was_mapped |= username_was_mapped; + if (username_was_mapped) { + server_info->was_mapped = username_was_mapped; + } /* we need to build the token for the user. make_server_info_guest() already does this */ -- cgit From 43717a16e2fca8b196d4a89e33b05fefc0cb02d2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Jan 2008 23:53:27 -0800 Subject: Fix CID 476. Ensure a valid pac_data pointer is always passed to ads_verify_ticket as it's always derefed. Jeremy. (This used to be commit 0599d57efff0f417f75510e8b08c3cb7b4bcfcd8) --- source3/smbd/sesssetup.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index bc1d26faca..aee8e498e9 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -259,7 +259,7 @@ static void reply_spnego_kerberos(struct smb_request *req, fstring user; int sess_vuid = req->vuid; NTSTATUS ret = NT_STATUS_OK; - PAC_DATA *pac_data; + PAC_DATA *pac_data = NULL; DATA_BLOB ap_rep, ap_rep_wrapped, response; auth_serversupplied_info *server_info = NULL; DATA_BLOB session_key = data_blob_null; @@ -271,7 +271,6 @@ static void reply_spnego_kerberos(struct smb_request *req, PAC_LOGON_INFO *logon_info = NULL; ZERO_STRUCT(ticket); - ZERO_STRUCT(pac_data); ZERO_STRUCT(ap_rep); ZERO_STRUCT(ap_rep_wrapped); ZERO_STRUCT(response); -- cgit From de48cd925a11414063cae7ead89fa060c280352a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 4 Feb 2008 13:47:15 +0100 Subject: smbd: use make usage of wbcDomainInfo() metze (This used to be commit 9d6b43ea106df188b51060a8055fe5168220c314) --- source3/smbd/sesssetup.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index aee8e498e9..1e4e208951 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -410,30 +410,24 @@ static void reply_spnego_kerberos(struct smb_request *req, name. And even w2k3 does use ntlmssp if you for example connect to an ip address. */ - struct winbindd_request wb_request; - struct winbindd_response wb_response; - NSS_STATUS wb_result; - - ZERO_STRUCT(wb_request); - ZERO_STRUCT(wb_response); + wbcErr wbc_status; + struct wbcDomainInfo *info = NULL; DEBUG(10, ("Mapping [%s] to short name\n", domain)); - fstrcpy(wb_request.domain_name, domain); - - wb_result = winbindd_request_response(WINBINDD_DOMAIN_INFO, - &wb_request, &wb_response); + wbc_status = wbcDomainInfo(domain, &info); - if (wb_result == NSS_STATUS_SUCCESS) { + if (WBC_ERROR_IS_OK(wbc_status)) { fstrcpy(netbios_domain_name, - wb_response.data.domain_info.name); - domain = netbios_domain_name; + info->short_name); + wbcFreeMemory(info); + domain = netbios_domain_name; DEBUG(10, ("Mapped to [%s] (using Winbind)\n", domain)); } else { - DEBUG(3, ("Could not find short name -- winbind " - "not running?\n")); + DEBUG(3, ("Could not find short name: %s\n", + wbcErrorString(wbc_status))); } } -- cgit From 4754c2bafe0ac5dc176c1e1d371bbc15165a7447 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 14 Feb 2008 18:10:50 -0800 Subject: Correctly use SPNEGO to negotiate down from krb5 to NTLMSSP. Previously we didn't implement the 'NEGO' part of SPNEGO :-). Jeremy. (This used to be commit 8767a0dab95c544878b4187157e494e740974bb8) --- source3/smbd/sesssetup.c | 109 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 81 insertions(+), 28 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 1e4e208951..3e04da35df 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -620,6 +620,7 @@ static void reply_spnego_ntlmssp(struct smb_request *req, uint16 vuid, AUTH_NTLMSSP_STATE **auth_ntlmssp_state, DATA_BLOB *ntlmssp_blob, NTSTATUS nt_status, + const char *OID, bool wrap) { DATA_BLOB response; @@ -680,7 +681,7 @@ static void reply_spnego_ntlmssp(struct smb_request *req, if (wrap) { response = spnego_gen_auth_response(ntlmssp_blob, - nt_status, OID_NTLMSSP); + nt_status, OID); } else { response = *ntlmssp_blob; } @@ -744,6 +745,28 @@ NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, return NT_STATUS_OK; } +/**************************************************************************** + Fall back from krb5 to NTLMSSP. +****************************************************************************/ + +static void reply_spnego_downgrade_to_ntlmssp(struct smb_request *req, + uint16 vuid) +{ + DATA_BLOB response; + + reply_outbuf(req, 4, 0); + SSVAL(req->outbuf,smb_uid,vuid); + + DEBUG(3,("reply_spnego_downgrade_to_ntlmssp: Got krb5 ticket in SPNEGO " + "but set to downgrade to NTLMSSP\n")); + + response = spnego_gen_auth_response(NULL, + NT_STATUS_MORE_PROCESSING_REQUIRED, + OID_NTLMSSP); + reply_sesssetup_blob(req, response, NT_STATUS_MORE_PROCESSING_REQUIRED); + data_blob_free(&response); +} + /**************************************************************************** Reply to a session setup spnego negotiate packet. ****************************************************************************/ @@ -789,6 +812,15 @@ static void reply_spnego_negotiate(struct smb_request *req, auth_ntlmssp_end(auth_ntlmssp_state); } + if (got_kerberos_mechanism) { + data_blob_free(&secblob); + /* The mechtoken is a krb5 ticket, but + * we need to fall back to NTLM. */ + reply_spnego_downgrade_to_ntlmssp(req, + vuid); + return; + } + status = auth_ntlmssp_start(auth_ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { /* Kill the intermediate vuid */ @@ -803,7 +835,7 @@ static void reply_spnego_negotiate(struct smb_request *req, data_blob_free(&secblob); reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state, - &chal, status, True); + &chal, status, OID_NTLMSSP, true); data_blob_free(&chal); @@ -823,7 +855,7 @@ static void reply_spnego_auth(struct smb_request *req, DATA_BLOB auth = data_blob_null; DATA_BLOB auth_reply = data_blob_null; DATA_BLOB secblob = data_blob_null; - NTSTATUS status = NT_STATUS_INVALID_PARAMETER; + NTSTATUS status = NT_STATUS_LOGON_FAILURE; if (!spnego_parse_auth(blob1, &auth)) { #if 0 @@ -833,7 +865,7 @@ static void reply_spnego_auth(struct smb_request *req, invalidate_vuid(vuid); reply_nterror(req, nt_status_squash( - NT_STATUS_INVALID_PARAMETER)); + NT_STATUS_LOGON_FAILURE)); return; } @@ -843,24 +875,43 @@ static void reply_spnego_auth(struct smb_request *req, bool got_krb5_mechanism = False; status = parse_spnego_mechanisms(auth, &secblob, &got_krb5_mechanism); - if (NT_STATUS_IS_OK(status)) { - DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n", - (unsigned long)secblob.length)); + + if (!NT_STATUS_IS_OK(status)) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + reply_nterror(req, nt_status_squash(status)); + return; + } + + DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n", + (unsigned long)secblob.length)); #ifdef HAVE_KRB5 - if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || - lp_use_kerberos_keytab()) ) { - bool destroy_vuid = True; - reply_spnego_kerberos(req, &secblob, - vuid, &destroy_vuid); - data_blob_free(&secblob); - data_blob_free(&auth); - if (destroy_vuid) { - /* Kill the intermediate vuid */ - invalidate_vuid(vuid); - } - return; + if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || + lp_use_kerberos_keytab()) ) { + bool destroy_vuid = True; + reply_spnego_kerberos(req, &secblob, + vuid, &destroy_vuid); + data_blob_free(&secblob); + data_blob_free(&auth); + if (destroy_vuid) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); } + return; + } #endif + /* Can't blunder into NTLMSSP auth if we have + * a krb5 ticket. */ + + if (got_krb5_mechanism) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + DEBUG(3,("reply_spnego_auth: network " + "misconfiguration, client sent us a " + "krb5 ticket and kerberos security " + "not enabled")); + reply_nterror(req, nt_status_squash( + NT_STATUS_LOGON_FAILURE)); } } @@ -868,13 +919,13 @@ static void reply_spnego_auth(struct smb_request *req, data_blob_free(&secblob); if (!*auth_ntlmssp_state) { - /* Kill the intermediate vuid */ - invalidate_vuid(vuid); - - /* auth before negotiatiate? */ - reply_nterror(req, nt_status_squash( - NT_STATUS_INVALID_PARAMETER)); - return; + status = auth_ntlmssp_start(auth_ntlmssp_state); + if (!NT_STATUS_IS_OK(status)) { + /* Kill the intermediate vuid */ + invalidate_vuid(vuid); + reply_nterror(req, nt_status_squash(status)); + return; + } } status = auth_ntlmssp_update(*auth_ntlmssp_state, @@ -882,9 +933,11 @@ static void reply_spnego_auth(struct smb_request *req, data_blob_free(&auth); + /* Don't send the mechid as we've already sent this (RFC4178). */ + reply_spnego_ntlmssp(req, vuid, auth_ntlmssp_state, - &auth_reply, status, True); + &auth_reply, status, NULL, true); data_blob_free(&auth_reply); @@ -1251,7 +1304,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req) reply_spnego_ntlmssp(req, vuid, &vuser->auth_ntlmssp_state, - &chal, status, False); + &chal, status, OID_NTLMSSP, false); data_blob_free(&chal); return; } -- cgit From 65fc3ae0701dba3d8c336abd236716413b1f634d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 16 Feb 2008 18:55:08 +0100 Subject: Use new structs in reply_spnego_kerberos(). Guenther (This used to be commit c55160f8e866d9b24a4dad234af78ae46c236a37) --- source3/smbd/sesssetup.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 3e04da35df..9baa02977a 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -259,7 +259,7 @@ static void reply_spnego_kerberos(struct smb_request *req, fstring user; int sess_vuid = req->vuid; NTSTATUS ret = NT_STATUS_OK; - PAC_DATA *pac_data = NULL; + struct PAC_DATA *pac_data = NULL; DATA_BLOB ap_rep, ap_rep_wrapped, response; auth_serversupplied_info *server_info = NULL; DATA_BLOB session_key = data_blob_null; @@ -268,7 +268,7 @@ static void reply_spnego_kerberos(struct smb_request *req, fstring real_username; bool map_domainuser_to_guest = False; bool username_was_mapped; - PAC_LOGON_INFO *logon_info = NULL; + struct PAC_LOGON_INFO *logon_info = NULL; ZERO_STRUCT(ticket); ZERO_STRUCT(ap_rep); @@ -394,10 +394,9 @@ static void reply_spnego_kerberos(struct smb_request *req, domain = p+1; - if (logon_info && logon_info->info3.hdr_logon_dom.uni_str_len) { - unistr2_to_ascii(netbios_domain_name, - &logon_info->info3.uni_logon_dom, - sizeof(netbios_domain_name)); + if (logon_info && logon_info->info3.base.domain.string) { + fstrcpy(netbios_domain_name, + logon_info->info3.base.domain.string); domain = netbios_domain_name; DEBUG(10, ("Mapped to [%s] (using PAC)\n", domain)); -- cgit From 23cd8e5ea7f2aac6cfdcb52666ba4e925740f63f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 6 Mar 2008 12:24:37 +0100 Subject: Be more verbose why create local token has failed during NTLMSSP and Kerberos session setup Guenther (This used to be commit 18b8c2c19e50aee8fc900c7507244cb95014a4fa) --- source3/smbd/sesssetup.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 9baa02977a..5578dafd85 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -539,6 +539,8 @@ static void reply_spnego_kerberos(struct smb_request *req, if ( !server_info->ptok ) { ret = create_local_token( server_info ); if ( !NT_STATUS_IS_OK(ret) ) { + DEBUG(10,("failed to create local token: %s\n", + nt_errstr(ret))); SAFE_FREE(client); data_blob_free(&ap_rep); data_blob_free(&session_key); -- cgit From be2fab1fefa5cc2f0b6d0f880215e09405e0bb29 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 20 Mar 2008 16:50:52 +0100 Subject: smbd: fix session setup with security = share. Broken by pstring removal in 9ed12bfc48fe7f9b1863a9dd88e881974083053c. Jeremy, please check. Thanks to Yannick Bergeron for noting this. Michael (This used to be commit 008c4bdbe5de064b4469fc1f7c7173290f35b3ef) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 5578dafd85..cf90c7183a 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1533,7 +1533,7 @@ void reply_sesssetup_and_X(struct smb_request *req) if (doencrypt) { lm_resp = data_blob(p, passlen1); nt_resp = data_blob(p+passlen1, passlen2); - } else { + } else if (lp_security() != SEC_SHARE) { char *pass = NULL; bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS; -- cgit From 7752494cf199d6edcce021baa81f2148e3c7ba4d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Mar 2008 16:08:39 -0700 Subject: Fix up the comments on security=share to explain we're ignoring passwords. Jeremy. (This used to be commit e7b6ea46532a26611dfd9d9e2727d52ba6a9cf50) --- source3/smbd/sesssetup.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index cf90c7183a..e0739ef992 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1534,6 +1534,10 @@ void reply_sesssetup_and_X(struct smb_request *req) lm_resp = data_blob(p, passlen1); nt_resp = data_blob(p+passlen1, passlen2); } else if (lp_security() != SEC_SHARE) { + /* + * In share level we should ignore any passwords, so + * only read them if we're not. + */ char *pass = NULL; bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS; @@ -1636,7 +1640,7 @@ void reply_sesssetup_and_X(struct smb_request *req) reload_services(True); if (lp_security() == SEC_SHARE) { - /* in share level we should ignore any passwords */ + /* In share level we should ignore any passwords */ data_blob_free(&lm_resp); data_blob_free(&nt_resp); -- cgit From f700ee6418c7b861efdb0f8eaa61b99ad598b7c3 Mon Sep 17 00:00:00 2001 From: Bill Ricker Date: Mon, 7 Apr 2008 15:02:56 -0700 Subject: Fix Kerberos interop with Mac OS X 10.5 clients. Ignore optional req_flags. Use the Kerberos mechanism OID negotiated with the client rather than hardcoding OID_KERBEROS5_OLD. (This used to be commit 59a2bcf30fef14ecc826271862b645dd3a61cb48) --- source3/smbd/sesssetup.c | 49 +++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index e0739ef992..33a54dd0de 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -248,6 +248,7 @@ static bool make_krb5_skew_error(DATA_BLOB *pblob_out) static void reply_spnego_kerberos(struct smb_request *req, DATA_BLOB *secblob, + const char *mechOID, uint16 vuid, bool *p_invalidate_vuid) { @@ -598,7 +599,7 @@ static void reply_spnego_kerberos(struct smb_request *req, ap_rep_wrapped = data_blob_null; } response = spnego_gen_auth_response(&ap_rep_wrapped, ret, - OID_KERBEROS5_OLD); + mechOID); reply_sesssetup_blob(req, response, ret); data_blob_free(&ap_rep); @@ -709,13 +710,15 @@ static void reply_spnego_ntlmssp(struct smb_request *req, Is this a krb5 mechanism ? ****************************************************************************/ -NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, - bool *p_is_krb5) +NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, + DATA_BLOB *pblob_out, + char **kerb_mechOID) { char *OIDs[ASN1_MAX_OIDS]; int i; + NTSTATUS ret = NT_STATUS_OK; - *p_is_krb5 = False; + *kerb_mechOID = NULL; /* parse out the OIDs and the first sec blob */ if (!parse_negTokenTarg(blob_in, OIDs, pblob_out)) { @@ -735,7 +738,10 @@ NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, #ifdef HAVE_KRB5 if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) { - *p_is_krb5 = True; + *kerb_mechOID = SMB_STRDUP(OIDs[0]); + if (*kerb_mechOID == NULL) { + ret = NT_STATUS_NO_MEMORY; + } } #endif @@ -743,7 +749,7 @@ NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, DATA_BLOB *pblob_out, DEBUG(5,("parse_spnego_mechanisms: Got OID %s\n", OIDs[i])); free(OIDs[i]); } - return NT_STATUS_OK; + return ret; } /**************************************************************************** @@ -779,11 +785,10 @@ static void reply_spnego_negotiate(struct smb_request *req, { DATA_BLOB secblob; DATA_BLOB chal; - bool got_kerberos_mechanism = False; + char *kerb_mech = NULL; NTSTATUS status; - status = parse_spnego_mechanisms(blob1, &secblob, - &got_kerberos_mechanism); + status = parse_spnego_mechanisms(blob1, &secblob, &kerb_mech); if (!NT_STATUS_IS_OK(status)) { /* Kill the intermediate vuid */ invalidate_vuid(vuid); @@ -795,16 +800,17 @@ static void reply_spnego_negotiate(struct smb_request *req, (unsigned long)secblob.length)); #ifdef HAVE_KRB5 - if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || + if (kerb_mech && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { bool destroy_vuid = True; - reply_spnego_kerberos(req, &secblob, vuid, - &destroy_vuid); + reply_spnego_kerberos(req, &secblob, kerb_mech, + vuid, &destroy_vuid); data_blob_free(&secblob); if (destroy_vuid) { /* Kill the intermediate vuid */ invalidate_vuid(vuid); } + SAFE_FREE(kerb_mech); return; } #endif @@ -813,12 +819,12 @@ static void reply_spnego_negotiate(struct smb_request *req, auth_ntlmssp_end(auth_ntlmssp_state); } - if (got_kerberos_mechanism) { + if (kerb_mech) { data_blob_free(&secblob); /* The mechtoken is a krb5 ticket, but * we need to fall back to NTLM. */ - reply_spnego_downgrade_to_ntlmssp(req, - vuid); + reply_spnego_downgrade_to_ntlmssp(req, vuid); + SAFE_FREE(kerb_mech); return; } @@ -872,10 +878,9 @@ static void reply_spnego_auth(struct smb_request *req, if (auth.data[0] == ASN1_APPLICATION(0)) { /* Might be a second negTokenTarg packet */ + char *kerb_mech = NULL; - bool got_krb5_mechanism = False; - status = parse_spnego_mechanisms(auth, &secblob, - &got_krb5_mechanism); + status = parse_spnego_mechanisms(auth, &secblob, &kerb_mech); if (!NT_STATUS_IS_OK(status)) { /* Kill the intermediate vuid */ @@ -887,10 +892,10 @@ static void reply_spnego_auth(struct smb_request *req, DEBUG(3,("reply_spnego_auth: Got secblob of size %lu\n", (unsigned long)secblob.length)); #ifdef HAVE_KRB5 - if ( got_krb5_mechanism && ((lp_security()==SEC_ADS) || + if (kerb_mech && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { bool destroy_vuid = True; - reply_spnego_kerberos(req, &secblob, + reply_spnego_kerberos(req, &secblob, kerb_mech, vuid, &destroy_vuid); data_blob_free(&secblob); data_blob_free(&auth); @@ -898,13 +903,14 @@ static void reply_spnego_auth(struct smb_request *req, /* Kill the intermediate vuid */ invalidate_vuid(vuid); } + SAFE_FREE(kerb_mech); return; } #endif /* Can't blunder into NTLMSSP auth if we have * a krb5 ticket. */ - if (got_krb5_mechanism) { + if (kerb_mech) { /* Kill the intermediate vuid */ invalidate_vuid(vuid); DEBUG(3,("reply_spnego_auth: network " @@ -913,6 +919,7 @@ static void reply_spnego_auth(struct smb_request *req, "not enabled")); reply_nterror(req, nt_status_squash( NT_STATUS_LOGON_FAILURE)); + SAFE_FREE(kerb_mech); } } -- cgit From 82d2f07dae5d69fc1635a4ed326a2af6632d8a97 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 30 Apr 2008 14:26:16 +0200 Subject: Remove "session_key" from "struct user_struct" This one took a bit -- I hope I covered all data paths (This used to be commit 74c88a44422f88d6e2f2cdbfdfa0bafe0dbe06c4) --- source3/smbd/sesssetup.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 33a54dd0de..99bf0dcbb9 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -560,9 +560,13 @@ static void reply_spnego_kerberos(struct smb_request *req, if (!is_partial_auth_vuid(sess_vuid)) { sess_vuid = register_initial_vuid(); } + + data_blob_free(&server_info->user_session_key); + server_info->user_session_key = session_key; + session_key = data_blob_null; + sess_vuid = register_existing_vuid(sess_vuid, server_info, - session_key, nullblob, client); @@ -573,7 +577,6 @@ static void reply_spnego_kerberos(struct smb_request *req, if (sess_vuid == UID_FIELD_INVALID ) { ret = NT_STATUS_LOGON_FAILURE; - data_blob_free(&session_key); } else { /* current_user_info is changed on new vuid */ reload_services( True ); @@ -649,14 +652,19 @@ static void reply_spnego_ntlmssp(struct smb_request *req, (*auth_ntlmssp_state)->ntlmssp_state->session_key.length); if (!is_partial_auth_vuid(vuid)) { - data_blob_free(&session_key); nt_status = NT_STATUS_LOGON_FAILURE; goto out; } + + data_blob_free(&server_info->user_session_key); + server_info->user_session_key = + data_blob( + (*auth_ntlmssp_state)->ntlmssp_state->session_key.data, + (*auth_ntlmssp_state)->ntlmssp_state->session_key.length); + /* register_existing_vuid keeps the server info */ if (register_existing_vuid(vuid, - server_info, - session_key, nullblob, + server_info, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user) != vuid) { data_blob_free(&session_key); @@ -1398,8 +1406,6 @@ void reply_sesssetup_and_X(struct smb_request *req) bool doencrypt = global_encrypted_passwords_negotiated; - DATA_BLOB session_key; - START_PROFILE(SMBsesssetupX); ZERO_STRUCT(lm_resp); @@ -1747,13 +1753,6 @@ void reply_sesssetup_and_X(struct smb_request *req) return; } - if (server_info->user_session_key.data) { - session_key = data_blob(server_info->user_session_key.data, - server_info->user_session_key.length); - } else { - session_key = data_blob_null; - } - data_blob_clear_free(&plaintext_password); /* it's ok - setup a reply */ @@ -1772,7 +1771,6 @@ void reply_sesssetup_and_X(struct smb_request *req) if (lp_security() == SEC_SHARE) { sess_vuid = UID_FIELD_INVALID; - data_blob_free(&session_key); TALLOC_FREE(server_info); } else { /* Ignore the initial vuid. */ @@ -1780,7 +1778,6 @@ void reply_sesssetup_and_X(struct smb_request *req) if (sess_vuid == UID_FIELD_INVALID) { data_blob_free(&nt_resp); data_blob_free(&lm_resp); - data_blob_free(&session_key); reply_nterror(req, nt_status_squash( NT_STATUS_LOGON_FAILURE)); END_PROFILE(SMBsesssetupX); @@ -1789,13 +1786,11 @@ void reply_sesssetup_and_X(struct smb_request *req) /* register_existing_vuid keeps the server info */ sess_vuid = register_existing_vuid(sess_vuid, server_info, - session_key, nt_resp.data ? nt_resp : lm_resp, sub_user); if (sess_vuid == UID_FIELD_INVALID) { data_blob_free(&nt_resp); data_blob_free(&lm_resp); - data_blob_free(&session_key); reply_nterror(req, nt_status_squash( NT_STATUS_LOGON_FAILURE)); END_PROFILE(SMBsesssetupX); -- cgit From 0636236eec5e73b08b28511ea6dc27d20aa35629 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 30 Apr 2008 12:58:40 +0200 Subject: Fix typo (This used to be commit 8047a1991a09191fec254815f3bfc85a2c36674a) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 99bf0dcbb9..b9219ab302 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -442,7 +442,7 @@ static void reply_spnego_kerberos(struct smb_request *req, if (pw) { /* if a real user check pam account restrictions */ /* only really perfomed if "obey pam restriction" is true */ - /* do this before an eventual mappign to guest occurs */ + /* do this before an eventual mapping to guest occurs */ ret = smb_pam_accountcheck(pw->pw_name); if ( !NT_STATUS_IS_OK(ret)) { DEBUG(1,("PAM account restriction " -- cgit From 64ddd381b74ca94e8ff8ae62d8f019a9b5290a80 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 6 May 2008 17:37:00 +0200 Subject: Rename server_info->was_mapped to server_info->nss_token "nss_token" from my point of view much better reflects what this flag actually represents (This used to be commit b121a5acb2ef0bb3067d953b028696175432f10d) --- source3/smbd/sesssetup.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index b9219ab302..9076949a81 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -530,9 +530,7 @@ static void reply_spnego_kerberos(struct smb_request *req, } } - if (username_was_mapped) { - server_info->was_mapped = username_was_mapped; - } + server_info->nss_token |= username_was_mapped; /* we need to build the token for the user. make_server_info_guest() already does this */ -- cgit From 0283e95a7c20bb0aeedbdd0b657a1293e449a62d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 6 May 2008 17:26:49 +0200 Subject: Add a mem_ctx argument to make_server_info_guest() (This used to be commit e4a9492967f3d2b64f27943f99414608e0c03d21) --- source3/smbd/sesssetup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 9076949a81..0f0a0d5f31 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -45,7 +45,7 @@ static NTSTATUS do_map_to_guest(NTSTATUS status, (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD)) { DEBUG(3,("No such user %s [%s] - using guest account\n", user, domain)); - status = make_server_info_guest(server_info); + status = make_server_info_guest(NULL, server_info); } } @@ -53,7 +53,7 @@ static NTSTATUS do_map_to_guest(NTSTATUS status, if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD) { DEBUG(3,("Registered username %s for guest access\n", user)); - status = make_server_info_guest(server_info); + status = make_server_info_guest(NULL, server_info); } } @@ -488,7 +488,7 @@ static void reply_spnego_kerberos(struct smb_request *req, reload_services(True); if ( map_domainuser_to_guest ) { - make_server_info_guest(&server_info); + make_server_info_guest(NULL, &server_info); } else if (logon_info) { /* pass the unmapped username here since map_username() will be called again from inside make_server_info_info3() */ -- cgit From 4f9b325fb2e9872e4c306791306cd08eb7ac6ef6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 10 May 2008 23:27:21 +0200 Subject: Fix a memleak (This used to be commit 9891c7c30858a3bea9adbea1c5bfa5c6b1b85221) --- source3/smbd/sesssetup.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 0f0a0d5f31..7cff422507 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -644,10 +644,6 @@ static void reply_spnego_ntlmssp(struct smb_request *req, if (NT_STATUS_IS_OK(nt_status)) { DATA_BLOB nullblob = data_blob_null; - DATA_BLOB session_key = - data_blob( - (*auth_ntlmssp_state)->ntlmssp_state->session_key.data, - (*auth_ntlmssp_state)->ntlmssp_state->session_key.length); if (!is_partial_auth_vuid(vuid)) { nt_status = NT_STATUS_LOGON_FAILURE; @@ -665,7 +661,6 @@ static void reply_spnego_ntlmssp(struct smb_request *req, server_info, nullblob, (*auth_ntlmssp_state)->ntlmssp_state->user) != vuid) { - data_blob_free(&session_key); nt_status = NT_STATUS_LOGON_FAILURE; goto out; } -- cgit From 6b6bb484a8049c5acf88b94f9106e40d96bf56ae Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 11 May 2008 00:23:01 +0200 Subject: Fix a memleak in new auth_serversupplied code (This used to be commit f23e970848b6e6655453fa65f6f160f624acfcff) --- source3/smbd/sesssetup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 7cff422507..5b00403140 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -652,7 +652,8 @@ static void reply_spnego_ntlmssp(struct smb_request *req, data_blob_free(&server_info->user_session_key); server_info->user_session_key = - data_blob( + data_blob_talloc( + server_info, (*auth_ntlmssp_state)->ntlmssp_state->session_key.data, (*auth_ntlmssp_state)->ntlmssp_state->session_key.length); -- cgit From bdcc7ddc1ec692a9c8420426b8b2413bf0f7e1a2 Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Tue, 20 May 2008 11:09:06 +0200 Subject: sesssetup.c: Add debug message. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Log when we kill other smbd sessions like when we hit the VC == 0 case. This one fixes BUG #5476. Initial patch from Björn Jacke . Karolin (This used to be commit 1429f3b7cf293994b334052428fcdadcee162dea) --- source3/smbd/sesssetup.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 5b00403140..f6aec7dddc 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1352,6 +1352,9 @@ static int shutdown_other_smbds(struct db_record *rec, return 0; } + DEBUG(0,("shutdown_other_smbds: shutting down pid %d " + "(IP %s)\n", crec->pid, ip)); + messaging_send(smbd_messaging_context(), crec->pid, MSG_SHUTDOWN, &data_blob_null); return 0; -- cgit From c38a1e06b5ada7325ba0fcebd7254475ae84a4de Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 20 May 2008 23:08:42 +0200 Subject: Fix type error in debug message (This used to be commit eb281532b1721ded39c39bb00c26202080dcd735) --- source3/smbd/sesssetup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index f6aec7dddc..041596b953 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1353,7 +1353,7 @@ static int shutdown_other_smbds(struct db_record *rec, } DEBUG(0,("shutdown_other_smbds: shutting down pid %d " - "(IP %s)\n", crec->pid, ip)); + "(IP %s)\n", procid_to_pid(&crec->pid), ip)); messaging_send(smbd_messaging_context(), crec->pid, MSG_SHUTDOWN, &data_blob_null); -- cgit From 4a5ccfb91f8d427fe9fa83cab992587fe6ce70c7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 22 Aug 2008 13:49:46 -0700 Subject: Don't re-initialize a token when we already have one. This fixes the build farm failures when winbindd connects as guest. This one took a *lot* of tracking down :-). Jeremy. (This used to be commit dca827791276906436452c650062164eb819dfe0) --- source3/smbd/sesssetup.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'source3/smbd/sesssetup.c') diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 041596b953..9c9d0a97bc 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1738,16 +1738,19 @@ void reply_sesssetup_and_X(struct smb_request *req) return; } - nt_status = create_local_token(server_info); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(10, ("create_local_token failed: %s\n", - nt_errstr(nt_status))); - data_blob_free(&nt_resp); - data_blob_free(&lm_resp); - data_blob_clear_free(&plaintext_password); - reply_nterror(req, nt_status_squash(nt_status)); - END_PROFILE(SMBsesssetupX); - return; + if (!server_info->ptok) { + nt_status = create_local_token(server_info); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(10, ("create_local_token failed: %s\n", + nt_errstr(nt_status))); + data_blob_free(&nt_resp); + data_blob_free(&lm_resp); + data_blob_clear_free(&plaintext_password); + reply_nterror(req, nt_status_squash(nt_status)); + END_PROFILE(SMBsesssetupX); + return; + } } data_blob_clear_free(&plaintext_password); -- cgit