s4:librpc/rpc: remove unused dcerpc_smb_fnum()
[mat/samba.git] / source4 / librpc / rpc / dcerpc_smb.c
index 5a404556c8fbc959190e07b369f5a5aec21373ea..71faeb4b3feed3a3cf33167fa506390fe657fc19 100644 (file)
 #include "librpc/rpc/dcerpc.h"
 #include "librpc/rpc/dcerpc_proto.h"
 #include "librpc/rpc/rpc_common.h"
+#include "../libcli/smb/smbXcli_base.h"
 
 /* transport private information used by SMB pipe transport */
 struct smb_private {
        uint16_t fnum;
        struct smbcli_tree *tree;
+       DATA_BLOB session_key;
        const char *server_name;
        bool dead;
 };
@@ -39,7 +41,7 @@ struct smb_private {
 /*
   tell the dcerpc layer that the transport is dead
 */
-static void pipe_dead(struct dcerpc_connection *c, NTSTATUS status)
+static void pipe_dead(struct dcecli_connection *c, NTSTATUS status)
 {
        struct smb_private *smb = (struct smb_private *)c->transport.private_data;
 
@@ -67,7 +69,7 @@ static void pipe_dead(struct dcerpc_connection *c, NTSTATUS status)
    this holds the state of an in-flight call
 */
 struct smb_read_state {
-       struct dcerpc_connection *c;
+       struct dcecli_connection *c;
        struct smbcli_request *req;
        size_t received;
        DATA_BLOB data;
@@ -79,6 +81,7 @@ struct smb_read_state {
 */
 static void smb_read_callback(struct smbcli_request *req)
 {
+       struct dcecli_connection *c;
        struct smb_private *smb;
        struct smb_read_state *state;
        union smb_read *io;
@@ -88,11 +91,12 @@ static void smb_read_callback(struct smbcli_request *req)
        state = talloc_get_type(req->async.private_data, struct smb_read_state);
        smb = talloc_get_type(state->c->transport.private_data, struct smb_private);
        io = state->io;
+       c = state->c;
 
        status = smb_raw_read_recv(state->req, io);
        if (NT_STATUS_IS_ERR(status)) {
-               pipe_dead(state->c, status);
                talloc_free(state);
+               pipe_dead(c, status);
                return;
        }
 
@@ -101,8 +105,8 @@ static void smb_read_callback(struct smbcli_request *req)
        if (state->received < 16) {
                DEBUG(0,("dcerpc_smb: short packet (length %d) in read callback!\n",
                         (int)state->received));
-               pipe_dead(state->c, NT_STATUS_INFO_LENGTH_MISMATCH);
                talloc_free(state);
+               pipe_dead(c, NT_STATUS_INFO_LENGTH_MISMATCH);
                return;
        }
 
@@ -110,7 +114,6 @@ static void smb_read_callback(struct smbcli_request *req)
 
        if (frag_length <= state->received) {
                DATA_BLOB data = state->data;
-               struct dcerpc_connection *c = state->c;
                data.length = state->received;
                talloc_steal(state->c, data.data);
                talloc_free(state);
@@ -128,8 +131,8 @@ static void smb_read_callback(struct smbcli_request *req)
 
        state->req = smb_raw_read_send(smb->tree, io);
        if (state->req == NULL) {
-               pipe_dead(state->c, NT_STATUS_NO_MEMORY);
                talloc_free(state);
+               pipe_dead(c, NT_STATUS_NO_MEMORY);
                return;
        }
 
@@ -141,7 +144,7 @@ static void smb_read_callback(struct smbcli_request *req)
   trigger a read request from the server, possibly with some initial
   data in the read buffer
 */
-static NTSTATUS send_read_request_continue(struct dcerpc_connection *c, DATA_BLOB *blob)
+static NTSTATUS send_read_request_continue(struct dcecli_connection *c, DATA_BLOB *blob)
 {
        struct smb_private *smb = (struct smb_private *)c->transport.private_data;
        union smb_read *io;
@@ -197,7 +200,7 @@ static NTSTATUS send_read_request_continue(struct dcerpc_connection *c, DATA_BLO
 /*
   trigger a read request from the server
 */
-static NTSTATUS send_read_request(struct dcerpc_connection *c)
+static NTSTATUS send_read_request(struct dcecli_connection *c)
 {
        struct smb_private *smb = (struct smb_private *)c->transport.private_data;
 
@@ -212,7 +215,7 @@ static NTSTATUS send_read_request(struct dcerpc_connection *c)
    this holds the state of an in-flight trans call
 */
 struct smb_trans_state {
-       struct dcerpc_connection *c;
+       struct dcecli_connection *c;
        struct smbcli_request *req;
        struct smb_trans2 *trans;
 };
@@ -223,7 +226,7 @@ struct smb_trans_state {
 static void smb_trans_callback(struct smbcli_request *req)
 {
        struct smb_trans_state *state = (struct smb_trans_state *)req->async.private_data;
-       struct dcerpc_connection *c = state->c;
+       struct dcecli_connection *c = state->c;
        NTSTATUS status;
 
        status = smb_raw_trans_recv(req, state, state->trans);
@@ -249,7 +252,7 @@ static void smb_trans_callback(struct smbcli_request *req)
 /*
   send a SMBtrans style request
 */
-static NTSTATUS smb_send_trans_request(struct dcerpc_connection *c, DATA_BLOB *blob)
+static NTSTATUS smb_send_trans_request(struct dcecli_connection *c, DATA_BLOB *blob)
 {
         struct smb_private *smb = (struct smb_private *)c->transport.private_data;
         struct smb_trans2 *trans;
@@ -257,7 +260,7 @@ static NTSTATUS smb_send_trans_request(struct dcerpc_connection *c, DATA_BLOB *b
        struct smb_trans_state *state;
        uint16_t max_data;
 
-       state = talloc(smb, struct smb_trans_state);
+       state = talloc(c, struct smb_trans_state);
        if (state == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -306,20 +309,25 @@ static NTSTATUS smb_send_trans_request(struct dcerpc_connection *c, DATA_BLOB *b
 */
 static void smb_write_callback(struct smbcli_request *req)
 {
-       struct dcerpc_connection *c = (struct dcerpc_connection *)req->async.private_data;
+       struct dcecli_connection *c = (struct dcecli_connection *)req->async.private_data;
+       union smb_write io;
+       NTSTATUS status;
 
-       if (!NT_STATUS_IS_OK(req->status)) {
-               DEBUG(0,("dcerpc_smb: write callback error\n"));
-               pipe_dead(c, req->status);
-       }
+       ZERO_STRUCT(io);
+       io.generic.level = RAW_WRITE_WRITEX;
 
-       smbcli_request_destroy(req);
+       status = smb_raw_write_recv(req, &io);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("dcerpc_smb: write callback error: %s\n",
+                       nt_errstr(status)));
+               pipe_dead(c, status);
+       }
 }
 
 /* 
    send a packet to the server
 */
-static NTSTATUS smb_send_request(struct dcerpc_connection *c, DATA_BLOB *blob, 
+static NTSTATUS smb_send_request(struct dcecli_connection *c, DATA_BLOB *blob, 
                                 bool trigger_read)
 {
        struct smb_private *smb = (struct smb_private *)c->transport.private_data;
@@ -354,10 +362,6 @@ static NTSTATUS smb_send_request(struct dcerpc_connection *c, DATA_BLOB *blob,
        req->async.fn = smb_write_callback;
        req->async.private_data = c;
 
-       if (trigger_read) {
-               send_read_request(c);
-       }
-
        return NT_STATUS_OK;
 }
 
@@ -370,7 +374,7 @@ static void free_request(struct smbcli_request *req)
 /* 
    shutdown SMB pipe connection
 */
-static NTSTATUS smb_shutdown_pipe(struct dcerpc_connection *c, NTSTATUS status)
+static NTSTATUS smb_shutdown_pipe(struct dcecli_connection *c, NTSTATUS status)
 {
        struct smb_private *smb = (struct smb_private *)c->transport.private_data;
        union smb_close io;
@@ -397,7 +401,7 @@ static NTSTATUS smb_shutdown_pipe(struct dcerpc_connection *c, NTSTATUS status)
 /*
   return SMB server name (called name)
 */
-static const char *smb_peer_name(struct dcerpc_connection *c)
+static const char *smb_peer_name(struct dcecli_connection *c)
 {
        struct smb_private *smb = (struct smb_private *)c->transport.private_data;
        if (smb == NULL) return "";
@@ -407,31 +411,33 @@ static const char *smb_peer_name(struct dcerpc_connection *c)
 /*
   return remote name we make the actual connection (good for kerberos) 
 */
-static const char *smb_target_hostname(struct dcerpc_connection *c)
+static const char *smb_target_hostname(struct dcecli_connection *c)
 {
        struct smb_private *smb = talloc_get_type(c->transport.private_data, struct smb_private);
        if (smb == NULL) return "";
-       return smb->tree->session->transport->socket->hostname;
+       return smbXcli_conn_remote_name(smb->tree->session->transport->conn);
 }
 
 /*
   fetch the user session key 
 */
-static NTSTATUS smb_session_key(struct dcerpc_connection *c, DATA_BLOB *session_key)
+static NTSTATUS smb_session_key(struct dcecli_connection *c, DATA_BLOB *session_key)
 {
        struct smb_private *smb = (struct smb_private *)c->transport.private_data;
 
        if (smb == NULL) return NT_STATUS_CONNECTION_DISCONNECTED;
-       if (smb->tree->session->user_session_key.data) {
-               *session_key = smb->tree->session->user_session_key;
-               return NT_STATUS_OK;
+
+       if (smb->session_key.length == 0) {
+               return NT_STATUS_NO_USER_SESSION_KEY;
        }
-       return NT_STATUS_NO_USER_SESSION_KEY;
+
+       *session_key = smb->session_key;
+       return NT_STATUS_OK;
 }
 
 struct pipe_open_smb_state {
        union smb_open *open;
-       struct dcerpc_connection *c;
+       struct dcecli_connection *c;
        struct smbcli_tree *tree;
        struct composite_context *ctx;
 };
@@ -445,14 +451,15 @@ struct composite_context *dcerpc_pipe_open_smb_send(struct dcerpc_pipe *p,
        struct composite_context *ctx;
        struct pipe_open_smb_state *state;
        struct smbcli_request *req;
-       struct dcerpc_connection *c = p->conn;
+       struct dcecli_connection *c = p->conn;
 
        /* if we don't have a binding on this pipe yet, then create one */
        if (p->binding == NULL) {
                NTSTATUS status;
+               const char *r = smbXcli_conn_remote_name(tree->session->transport->conn);
                char *s;
-               SMB_ASSERT(tree->session->transport->socket->hostname != NULL);
-               s = talloc_asprintf(p, "ncacn_np:%s", tree->session->transport->socket->hostname);
+               SMB_ASSERT(r != NULL);
+               s = talloc_asprintf(p, "ncacn_np:%s", r);
                if (s == NULL) return NULL;
                status = dcerpc_parse_binding(p, s, &p->binding);
                talloc_free(s);
@@ -515,7 +522,7 @@ static void pipe_open_recv(struct smbcli_request *req)
        struct pipe_open_smb_state *state = talloc_get_type(req->async.private_data,
                                            struct pipe_open_smb_state);
        struct composite_context *ctx = state->ctx;
-       struct dcerpc_connection *c = state->c;
+       struct dcecli_connection *c = state->c;
        struct smb_private *smb;
        
        ctx->status = smb_raw_open_recv(req, state, state->open);
@@ -543,10 +550,18 @@ static void pipe_open_recv(struct smbcli_request *req)
        smb->fnum       = state->open->ntcreatex.out.file.fnum;
        smb->tree       = talloc_reference(smb, state->tree);
        smb->server_name= strupper_talloc(smb,
-                         state->tree->session->transport->called.name);
+               smbXcli_conn_remote_name(state->tree->session->transport->conn));
        if (composite_nomem(smb->server_name, ctx)) return;
        smb->dead       = false;
 
+       ctx->status = smbXcli_session_application_key(state->tree->session->smbXcli,
+                                                     smb, &smb->session_key);
+       if (NT_STATUS_EQUAL(ctx->status, NT_STATUS_NO_USER_SESSION_KEY)) {
+               smb->session_key = data_blob_null;
+               ctx->status = NT_STATUS_OK;
+       }
+       if (!composite_is_ok(ctx)) return;
+
        c->transport.private_data = smb;
 
        composite_done(ctx);
@@ -571,7 +586,7 @@ _PUBLIC_ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe *p,
 /*
   return the SMB tree used for a dcerpc over SMB pipe
 */
-_PUBLIC_ struct smbcli_tree *dcerpc_smb_tree(struct dcerpc_connection *c)
+_PUBLIC_ struct smbcli_tree *dcerpc_smb_tree(struct dcecli_connection *c)
 {
        struct smb_private *smb;
 
@@ -582,18 +597,3 @@ _PUBLIC_ struct smbcli_tree *dcerpc_smb_tree(struct dcerpc_connection *c)
 
        return smb->tree;
 }
-
-/*
-  return the SMB fnum used for a dcerpc over SMB pipe (hack for torture operations)
-*/
-_PUBLIC_ uint16_t dcerpc_smb_fnum(struct dcerpc_connection *c)
-{
-       struct smb_private *smb;
-
-       if (c->transport.transport != NCACN_NP) return 0;
-
-       smb = talloc_get_type(c->transport.private_data, struct smb_private);
-       if (!smb) return 0;
-
-       return smb->fnum;
-}