r4080: missing file from the last commit
[samba.git] / source4 / libcli / raw / clisession.c
index dcf32c84856335d68a08910c38819ed7b07d2168..4f77145d4d73bf93a95589c68119cc66c647130c 100644 (file)
 */
 
 #include "includes.h"
+#include "libcli/raw/libcliraw.h"
+#include "auth/auth.h"
 
 #define SETUP_REQUEST_SESSION(cmd, wct, buflen) do { \
        req = smbcli_request_setup_session(session, cmd, wct, buflen); \
        if (!req) return NULL; \
 } while (0)
 
+
 /****************************************************************************
  Initialize the session context
 ****************************************************************************/
 struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport)
 {
        struct smbcli_session *session;
+       uint16_t flags2;
+       uint32_t capabilities;
 
-       session = talloc_named(NULL, sizeof(*session), "smbcli_session");
+       session = talloc_p(transport, struct smbcli_session);
        if (!session) {
                return NULL;
        }
 
        ZERO_STRUCTP(session);
-       session->transport = transport;
+       session->transport = talloc_reference(session, transport);
        session->pid = (uint16_t)getpid();
        session->vuid = UID_FIELD_INVALID;
-       session->transport->reference_count++;
 
-       return session;
-}
+       
+       capabilities = transport->negotiate.capabilities;
 
-/****************************************************************************
-reduce reference_count and destroy is <= 0
-****************************************************************************/
-void smbcli_session_close(struct smbcli_session *session)
-{
-       session->reference_count--;
-       if (session->reference_count <= 0) {
-               smbcli_transport_close(session->transport);
-               talloc_free(session);
+       flags2 = FLAGS2_LONG_PATH_COMPONENTS;
+
+       if (capabilities & CAP_UNICODE) {
+               flags2 |= FLAGS2_UNICODE_STRINGS;
        }
+       if (capabilities & CAP_STATUS32) {
+               flags2 |= FLAGS2_32_BIT_ERROR_CODES;
+       }
+       if (capabilities & CAP_EXTENDED_SECURITY) {
+               flags2 |= FLAGS2_EXTENDED_SECURITY;
+       }
+       if (session->transport->negotiate.sign_info.doing_signing) {
+               flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
+       }
+
+       session->flags2 = flags2;
+
+       return session;
 }
 
 /****************************************************************************
@@ -80,6 +92,7 @@ struct smbcli_request *smb_raw_session_setup_send(struct smbcli_session *session
                SSVAL(req->out.vwv,VWV(4),parms->old.in.vc_num);
                SIVAL(req->out.vwv,VWV(5),parms->old.in.sesskey);
                SSVAL(req->out.vwv,VWV(7),parms->old.in.password.length);
+               SIVAL(req->out.vwv,VWV(8), 0); /* reserved */
                smbcli_req_append_blob(req, &parms->old.in.password);
                smbcli_req_append_string(req, parms->old.in.user, STR_TERMINATE);
                smbcli_req_append_string(req, parms->old.in.domain, STR_TERMINATE|STR_UPPER);
@@ -142,7 +155,7 @@ NTSTATUS smb_raw_session_setup_recv(struct smbcli_request *req,
                                    union smb_sesssetup *parms) 
 {
        uint16_t len;
-       char *p;
+       uint8_t *p;
 
        if (!smbcli_request_receive(req)) {
                return smbcli_request_destroy(req);
@@ -274,8 +287,8 @@ static NTSTATUS smb_raw_session_setup_generic_old(struct smbcli_session *session
 
        /* use the old interface */
        s2.generic.level = RAW_SESSSETUP_OLD;
-       s2.old.in.bufsize = ~0;
-       s2.old.in.mpx_max = 50;
+       s2.old.in.bufsize = session->transport->options.max_xmit;
+       s2.old.in.mpx_max = session->transport->options.max_mux;
        s2.old.in.vc_num = 1;
        s2.old.in.sesskey = parms->generic.in.sesskey;
        s2.old.in.domain = parms->generic.in.domain;
@@ -322,8 +335,8 @@ static NTSTATUS smb_raw_session_setup_generic_nt1(struct smbcli_session *session
        union smb_sesssetup s2;
 
        s2.generic.level = RAW_SESSSETUP_NT1;
-       s2.nt1.in.bufsize = ~0;
-       s2.nt1.in.mpx_max = 50;
+       s2.nt1.in.bufsize = session->transport->options.max_xmit;
+       s2.nt1.in.mpx_max = session->transport->options.max_mux;
        s2.nt1.in.vc_num = 1;
        s2.nt1.in.sesskey = parms->generic.in.sesskey;
        s2.nt1.in.capabilities = parms->generic.in.capabilities;
@@ -379,11 +392,11 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess
        union smb_sesssetup s2;
        DATA_BLOB session_key = data_blob(NULL, 0);
        DATA_BLOB null_data_blob = data_blob(NULL, 0);
-       const char *chosen_oid;
+       const char *chosen_oid = NULL;
 
        s2.generic.level = RAW_SESSSETUP_SPNEGO;
-       s2.spnego.in.bufsize = ~0;
-       s2.spnego.in.mpx_max = 50;
+       s2.spnego.in.bufsize = session->transport->options.max_xmit;
+       s2.spnego.in.mpx_max = session->transport->options.max_mux;
        s2.spnego.in.vc_num = 1;
        s2.spnego.in.sesskey = parms->generic.in.sesskey;
        s2.spnego.in.capabilities = parms->generic.in.capabilities;
@@ -394,13 +407,13 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess
 
        smbcli_temp_set_signing(session->transport);
 
-       status = gensec_client_start(&session->gensec);
+       status = gensec_client_start(session, &session->gensec);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status)));
                goto done;
        }
 
-       gensec_want_feature(session->gensec, GENSEC_WANT_SESSION_KEY);
+       gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY);
 
        status = gensec_set_domain(session->gensec, parms->generic.in.domain);
        if (!NT_STATUS_IS_OK(status)) {
@@ -431,10 +444,10 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess
        }
 
        if (session->transport->negotiate.secblob.length) {
-               chosen_oid = OID_SPNEGO;
+               chosen_oid = GENSEC_OID_SPNEGO;
        } else {
                /* without a sec blob, means raw NTLMSSP */
-               chosen_oid = OID_NTLMSSP;
+               chosen_oid = GENSEC_OID_NTLMSSP;
        }
 
        status = gensec_start_mech_by_oid(session->gensec, chosen_oid);
@@ -445,8 +458,8 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct smbcli_session *sess
        }
        
        status = gensec_update(session->gensec, mem_ctx,
-                                      session->transport->negotiate.secblob,
-                                      &s2.spnego.in.secblob);
+                              session->transport->negotiate.secblob,
+                              &s2.spnego.in.secblob);
 
        while(1) {
                if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) {
@@ -492,6 +505,7 @@ done:
                parms->generic.out.lanman = s2.spnego.out.lanman;
                parms->generic.out.domain = s2.spnego.out.domain;
        } else {
+               gensec_end(&session->gensec);
                DEBUG(1, ("Failed to login with %s: %s\n", gensec_get_name_by_oid(chosen_oid), nt_errstr(status)));
                return status;
        }
@@ -589,16 +603,27 @@ NTSTATUS smb_raw_ulogoff(struct smbcli_session *session)
 
 
 /****************************************************************************
- Send a SMBexit
-****************************************************************************/
-NTSTATUS smb_raw_exit(struct smbcli_session *session)
+ Send a exit (async send)
+*****************************************************************************/
+struct smbcli_request *smb_raw_exit_send(struct smbcli_session *session)
 {
        struct smbcli_request *req;
 
-       req = smbcli_request_setup_session(session, SMBexit, 0, 0);
+       SETUP_REQUEST_SESSION(SMBexit, 0, 0);
 
-       if (smbcli_request_send(req)) {
-               smbcli_request_receive(req);
+       if (!smbcli_request_send(req)) {
+               smbcli_request_destroy(req);
+               return NULL;
        }
-       return smbcli_request_destroy(req);
+
+       return req;
+}
+
+/****************************************************************************
+ Send a exit (sync interface)
+*****************************************************************************/
+NTSTATUS smb_raw_exit(struct smbcli_session *session)
+{
+       struct smbcli_request *req = smb_raw_exit_send(session);
+       return smbcli_request_simple_recv(req);
 }