Merge branch 'v3-2-test' of ssh://git.samba.org/data/git/samba into v3-2-test
[ira/wip.git] / source3 / smbd / sesssetup.c
index 4c45806b0234f44e23f419cae1d11ec845a92474..aee8e498e9d258d906aae384a36d8e49bc41be84 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    handle SMBsessionsetup
    Copyright (C) Andrew Tridgell 1998-2001
@@ -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;
 
@@ -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)
 {
@@ -139,7 +138,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);
 }
 
@@ -186,14 +185,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;
 
@@ -247,11 +246,10 @@ 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)
+                                 bool *p_invalidate_vuid)
 {
        TALLOC_CTX *mem_ctx;
        DATA_BLOB ticket;
@@ -259,21 +257,20 @@ 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;
+       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;
        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);
-       ZERO_STRUCT(pac_data);
        ZERO_STRUCT(ap_rep);
        ZERO_STRUCT(ap_rep_wrapped);
        ZERO_STRUCT(response);
@@ -316,7 +313,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(
@@ -400,7 +397,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));
 
@@ -539,7 +536,9 @@ static void reply_spnego_kerberos(connection_struct *conn,
                }
        }
 
-       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 */
@@ -605,7 +604,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,12 +622,11 @@ 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,
-                                BOOL wrap)
+                                bool wrap)
 {
        DATA_BLOB response;
        struct auth_serversupplied_info *server_info = NULL;
@@ -680,9 +678,8 @@ 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);
+               sessionsetup_start_signing_engine(server_info,
+                                                 (uint8 *)req->inbuf);
        }
 
   out:
@@ -694,7 +691,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);
        }
@@ -717,7 +714,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;
@@ -757,15 +754,14 @@ 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)
 {
        DATA_BLOB secblob;
        DATA_BLOB chal;
-       BOOL got_kerberos_mechanism = False;
+       bool got_kerberos_mechanism = False;
        NTSTATUS status;
 
        status = parse_spnego_mechanisms(blob1, &secblob,
@@ -783,8 +779,8 @@ 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;
-               reply_spnego_kerberos(conn, req, &secblob, vuid,
+               bool destroy_vuid = True;
+               reply_spnego_kerberos(req, &secblob, vuid,
                                      &destroy_vuid);
                data_blob_free(&secblob);
                if (destroy_vuid) {
@@ -812,7 +808,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);
@@ -825,8 +821,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)
@@ -851,7 +846,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)) {
@@ -860,8 +855,8 @@ 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;
-                               reply_spnego_kerberos(conn, req, &secblob,
+                               bool destroy_vuid = True;
+                               reply_spnego_kerberos(req, &secblob,
                                                      vuid, &destroy_vuid);
                                data_blob_free(&secblob);
                                data_blob_free(&auth);
@@ -893,7 +888,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);
 
@@ -1105,8 +1100,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;
@@ -1226,7 +1220,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;
@@ -1236,7 +1230,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;
@@ -1261,7 +1255,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);
@@ -1308,6 +1302,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 +1311,9 @@ 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(get_client_fd(),addr,sizeof(addr))));
        }
 }
 
@@ -1323,7 +1321,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;
@@ -1336,14 +1334,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;
 
@@ -1374,7 +1372,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;
        }
@@ -1488,30 +1486,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;
-                       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
+                       char *pass = NULL;
+                       bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
 
                        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);
                }
@@ -1722,9 +1722,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,
@@ -1760,6 +1761,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;
 }