Merge branch 'master' of /home/tridge/samba/git/combined
[ira/wip.git] / source4 / librpc / rpc / dcerpc_smb.c
index 6b43de3358ace0020b7c7bfd0ceec5398bcaa338..f4e6b8c3dd3bb697a8c8ba7165c1008614c0f15c 100644 (file)
@@ -24,6 +24,7 @@
 #include "libcli/raw/libcliraw.h"
 #include "libcli/composite/composite.h"
 #include "librpc/rpc/dcerpc.h"
+#include "librpc/rpc/dcerpc_proto.h"
 
 /* transport private information used by SMB pipe transport */
 struct smb_private {
@@ -39,7 +40,7 @@ struct smb_private {
 */
 static void pipe_dead(struct dcerpc_connection *c, NTSTATUS status)
 {
-       struct smb_private *smb = c->transport.private_data;
+       struct smb_private *smb = (struct smb_private *)c->transport.private_data;
 
        if (smb->dead) {
                return;
@@ -83,7 +84,7 @@ static void smb_read_callback(struct smbcli_request *req)
        uint16_t frag_length;
        NTSTATUS status;
 
-       state = talloc_get_type(req->async.private, struct smb_read_state);
+       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;
 
@@ -132,7 +133,7 @@ static void smb_read_callback(struct smbcli_request *req)
        }
 
        state->req->async.fn = smb_read_callback;
-       state->req->async.private = state;
+       state->req->async.private_data = state;
 }
 
 /*
@@ -141,7 +142,7 @@ static void smb_read_callback(struct smbcli_request *req)
 */
 static NTSTATUS send_read_request_continue(struct dcerpc_connection *c, DATA_BLOB *blob)
 {
-       struct smb_private *smb = c->transport.private_data;
+       struct smb_private *smb = (struct smb_private *)c->transport.private_data;
        union smb_read *io;
        struct smb_read_state *state;
        struct smbcli_request *req;
@@ -176,7 +177,7 @@ static NTSTATUS send_read_request_continue(struct dcerpc_connection *c, DATA_BLO
        io->readx.in.maxcnt = io->readx.in.mincnt;
        io->readx.in.offset = 0;
        io->readx.in.remaining = 0;
-       io->readx.in.read_for_execute = False;
+       io->readx.in.read_for_execute = false;
        io->readx.out.data = state->data.data + state->received;
        req = smb_raw_read_send(smb->tree, io);
        if (req == NULL) {
@@ -184,7 +185,7 @@ static NTSTATUS send_read_request_continue(struct dcerpc_connection *c, DATA_BLO
        }
 
        req->async.fn = smb_read_callback;
-       req->async.private = state;
+       req->async.private_data = state;
 
        state->req = req;
 
@@ -197,7 +198,7 @@ static NTSTATUS send_read_request_continue(struct dcerpc_connection *c, DATA_BLO
 */
 static NTSTATUS send_read_request(struct dcerpc_connection *c)
 {
-       struct smb_private *smb = c->transport.private_data;
+       struct smb_private *smb = (struct smb_private *)c->transport.private_data;
 
        if (smb->dead) {
                return NT_STATUS_CONNECTION_DISCONNECTED;
@@ -220,7 +221,7 @@ struct smb_trans_state {
 */
 static void smb_trans_callback(struct smbcli_request *req)
 {
-       struct smb_trans_state *state = req->async.private;
+       struct smb_trans_state *state = (struct smb_trans_state *)req->async.private_data;
        struct dcerpc_connection *c = state->c;
        NTSTATUS status;
 
@@ -249,10 +250,11 @@ static void smb_trans_callback(struct smbcli_request *req)
 */
 static NTSTATUS smb_send_trans_request(struct dcerpc_connection *c, DATA_BLOB *blob)
 {
-        struct smb_private *smb = c->transport.private_data;
+        struct smb_private *smb = (struct smb_private *)c->transport.private_data;
         struct smb_trans2 *trans;
         uint16_t setup[2];
        struct smb_trans_state *state;
+       uint16_t max_data;
 
        state = talloc(smb, struct smb_trans_state);
        if (state == NULL) {
@@ -269,8 +271,14 @@ static NTSTATUS smb_send_trans_request(struct dcerpc_connection *c, DATA_BLOB *b
         setup[0] = TRANSACT_DCERPCCMD;
         setup[1] = smb->fnum;
 
+       if (c->srv_max_xmit_frag > 0) {
+               max_data = MIN(UINT16_MAX, c->srv_max_xmit_frag);
+       } else {
+               max_data = UINT16_MAX;
+       }
+
         trans->in.max_param = 0;
-        trans->in.max_data = smb_raw_max_trans_data(smb->tree, 0);
+        trans->in.max_data = max_data;
         trans->in.max_setup = 0;
         trans->in.setup_count = 2;
         trans->in.flags = 0;
@@ -285,7 +293,7 @@ static NTSTATUS smb_send_trans_request(struct dcerpc_connection *c, DATA_BLOB *b
        }
 
        state->req->async.fn = smb_trans_callback;
-       state->req->async.private = state;
+       state->req->async.private_data = state;
 
        talloc_steal(state, state->req);
 
@@ -297,7 +305,7 @@ 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 = req->async.private;
+       struct dcerpc_connection *c = (struct dcerpc_connection *)req->async.private_data;
 
        if (!NT_STATUS_IS_OK(req->status)) {
                DEBUG(0,("dcerpc_smb: write callback error\n"));
@@ -310,13 +318,14 @@ static void smb_write_callback(struct smbcli_request *req)
 /* 
    send a packet to the server
 */
-static NTSTATUS smb_send_request(struct dcerpc_connection *c, DATA_BLOB *blob, BOOL trigger_read)
+static NTSTATUS smb_send_request(struct dcerpc_connection *c, DATA_BLOB *blob, 
+                                bool trigger_read)
 {
-       struct smb_private *smb = c->transport.private_data;
+       struct smb_private *smb = (struct smb_private *)c->transport.private_data;
        union smb_write io;
        struct smbcli_request *req;
 
-       if (smb->dead) {
+       if (!smb || smb->dead) {
                return NT_STATUS_CONNECTION_DISCONNECTED;
        }
 
@@ -342,7 +351,7 @@ static NTSTATUS smb_send_request(struct dcerpc_connection *c, DATA_BLOB *blob, B
        }
 
        req->async.fn = smb_write_callback;
-       req->async.private = c;
+       req->async.private_data = c;
 
        if (trigger_read) {
                send_read_request(c);
@@ -351,12 +360,18 @@ static NTSTATUS smb_send_request(struct dcerpc_connection *c, DATA_BLOB *blob, B
        return NT_STATUS_OK;
 }
 
+
+static void free_request(struct smbcli_request *req)
+{
+       talloc_free(req);
+}
+
 /* 
    shutdown SMB pipe connection
 */
 static NTSTATUS smb_shutdown_pipe(struct dcerpc_connection *c, NTSTATUS status)
 {
-       struct smb_private *smb = c->transport.private_data;
+       struct smb_private *smb = (struct smb_private *)c->transport.private_data;
        union smb_close io;
        struct smbcli_request *req;
 
@@ -369,10 +384,11 @@ static NTSTATUS smb_shutdown_pipe(struct dcerpc_connection *c, NTSTATUS status)
        req = smb_raw_close_send(smb->tree, &io);
        if (req != NULL) {
                /* we don't care if this fails, so just free it if it succeeds */
-               req->async.fn = (void (*)(struct smbcli_request *))talloc_free;
+               req->async.fn = free_request;
        }
 
        talloc_free(smb);
+       c->transport.private_data = NULL;
 
        return status;
 }
@@ -382,7 +398,8 @@ static NTSTATUS smb_shutdown_pipe(struct dcerpc_connection *c, NTSTATUS status)
 */
 static const char *smb_peer_name(struct dcerpc_connection *c)
 {
-       struct smb_private *smb = c->transport.private_data;
+       struct smb_private *smb = (struct smb_private *)c->transport.private_data;
+       if (smb == NULL) return "";
        return smb->server_name;
 }
 
@@ -392,6 +409,7 @@ static const char *smb_peer_name(struct dcerpc_connection *c)
 static const char *smb_target_hostname(struct dcerpc_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;
 }
 
@@ -400,8 +418,9 @@ static const char *smb_target_hostname(struct dcerpc_connection *c)
 */
 static NTSTATUS smb_session_key(struct dcerpc_connection *c, DATA_BLOB *session_key)
 {
-       struct smb_private *smb = c->transport.private_data;
+       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;
@@ -430,7 +449,9 @@ struct composite_context *dcerpc_pipe_open_smb_send(struct dcerpc_pipe *p,
        /* if we don't have a binding on this pipe yet, then create one */
        if (p->binding == NULL) {
                NTSTATUS status;
-               char *s = talloc_asprintf(p, "ncacn_np:%s", tree->session->transport->socket->hostname);
+               char *s;
+               SMB_ASSERT(tree->session->transport->socket->hostname != NULL);
+               s = talloc_asprintf(p, "ncacn_np:%s", tree->session->transport->socket->hostname);
                if (s == NULL) return NULL;
                status = dcerpc_parse_binding(p, s, &p->binding);
                talloc_free(s);
@@ -490,7 +511,7 @@ struct composite_context *dcerpc_pipe_open_smb_send(struct dcerpc_pipe *p,
 
 static void pipe_open_recv(struct smbcli_request *req)
 {
-       struct pipe_open_smb_state *state = talloc_get_type(req->async.private,
+       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;
@@ -537,7 +558,7 @@ NTSTATUS dcerpc_pipe_open_smb_recv(struct composite_context *c)
        return status;
 }
 
-NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe *p,
+_PUBLIC_ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe *p,
                              struct smbcli_tree *tree,
                              const char *pipe_name)
 {
@@ -549,7 +570,7 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe *p,
 /*
   return the SMB tree used for a dcerpc over SMB pipe
 */
-struct smbcli_tree *dcerpc_smb_tree(struct dcerpc_connection *c)
+_PUBLIC_ struct smbcli_tree *dcerpc_smb_tree(struct dcerpc_connection *c)
 {
        struct smb_private *smb;
 
@@ -564,7 +585,7 @@ struct smbcli_tree *dcerpc_smb_tree(struct dcerpc_connection *c)
 /*
   return the SMB fnum used for a dcerpc over SMB pipe (hack for torture operations)
 */
-uint16_t dcerpc_smb_fnum(struct dcerpc_connection *c)
+_PUBLIC_ uint16_t dcerpc_smb_fnum(struct dcerpc_connection *c)
 {
        struct smb_private *smb;