dcerpc_binding_set_smbXcli_pointers
authorStefan Metzmacher <metze@samba.org>
Mon, 22 Sep 2014 14:41:51 +0000 (16:41 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 4 Jun 2019 10:43:20 +0000 (12:43 +0200)
source4/librpc/rpc/dcerpc_connect.c

index c23e85e7cb1933307b888645681db9dc114ec401..71c8170eb4f7d40a2ae4d3c8162132951ea6176e 100644 (file)
@@ -55,6 +55,175 @@ struct dcerpc_pipe_connect {
        } smb;
 };
 
+struct dcerpc_binding_smbXcli_pointers_ref;
+
+struct dcerpc_binding_smbXcli_pointers {
+       struct smbXcli_conn *conn;
+       struct dcerpc_binding_smbXcli_pointers_ref *conn_ref;
+       struct smbXcli_session *sess;
+       struct dcerpc_binding_smbXcli_pointers_ref *sess_ref;
+       struct smbXcli_tcon *tcon;
+       struct dcerpc_binding_smbXcli_pointers_ref *tcon_ref;
+};
+
+struct dcerpc_binding_smbXcli_pointers_ref {
+       struct dcerpc_binding_smbXcli_pointers *p;
+};
+
+static int dcerpc_binding_smbXcli_pointers_ref_destructor(
+       struct dcerpc_binding_smbXcli_pointers_ref *ref)
+{
+       struct dcerpc_binding_smbXcli_pointers *p;
+
+       if (ref->p == NULL) {
+               return 0;
+       }
+
+       p = ref->p;
+
+       p->conn_ref->p = NULL;
+       p->sess_ref->p = NULL;
+       p->tcon_ref->p = NULL;
+
+       if (p->conn_ref != ref) {
+               talloc_free(p->conn_ref);
+       }
+
+       if (p->sess_ref != ref) {
+               talloc_free(p->sess_ref);
+       }
+
+       if (p->tcon_ref != ref) {
+               talloc_free(p->tcon_ref);
+       }
+
+       ZERO_STRUCTP(p);
+       return 0;
+}
+
+static int dcerpc_binding_smbXcli_pointers_destructor(
+       struct dcerpc_binding_smbXcli_pointers *p)
+{
+       if (p->conn_ref != NULL) {
+               p->conn_ref->p = NULL;
+       }
+
+       if (p->sess_ref != NULL) {
+               p->sess_ref->p = NULL;
+       }
+
+       if (p->tcon_ref != NULL) {
+               p->tcon_ref->p = NULL;
+       }
+
+       talloc_free(p->conn_ref);
+       talloc_free(p->sess_ref);
+       talloc_free(p->tcon_ref);
+
+       ZERO_STRUCTP(p);
+       return 0;
+}
+
+NTSTATUS dcerpc_binding_set_smbXcli_pointers(struct dcerpc_binding *b,
+                                            struct smbXcli_conn *conn,
+                                            struct smbXcli_session *sess,
+                                            struct smbXcli_tcon *tcon)
+{
+       struct dcerpc_binding_smbXcli_pointers *p;
+       struct dcerpc_binding_smbXcli_pointers_ref *r;
+       NTSTATUS status;
+
+       if (!smbXcli_conn_is_connected(conn)) {
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+
+       if (sess == NULL) {
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+
+       if (tcon == NULL) {
+               return NT_STATUS_INVALID_PARAMETER_MIX;
+       }
+
+       p = talloc_zero(b, struct dcerpc_binding_smbXcli_pointers);
+       if (p == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       talloc_set_destructor(p, dcerpc_binding_smbXcli_pointers_destructor);
+
+       r = talloc_zero(conn, struct dcerpc_binding_smbXcli_pointers_ref);
+       if (r == NULL) {
+               TALLOC_FREE(p);
+               return NT_STATUS_NO_MEMORY;
+       }
+       talloc_set_destructor(r, dcerpc_binding_smbXcli_pointers_ref_destructor);
+       r->p = p;
+       p->conn_ref = r;
+
+       r = talloc_zero(sess, struct dcerpc_binding_smbXcli_pointers_ref);
+       if (r == NULL) {
+               TALLOC_FREE(p);
+               return NT_STATUS_NO_MEMORY;
+       }
+       talloc_set_destructor(r, dcerpc_binding_smbXcli_pointers_ref_destructor);
+       r->p = p;
+       p->sess_ref = r;
+
+       r = talloc_zero(tcon, struct dcerpc_binding_smbXcli_pointers_ref);
+       if (r == NULL) {
+               TALLOC_FREE(p);
+               return NT_STATUS_NO_MEMORY;
+       }
+       talloc_set_destructor(r, dcerpc_binding_smbXcli_pointers_ref_destructor);
+       r->p = p;
+       p->tcon_ref = r;
+
+       p->conn = conn;
+       p->sess = sess;
+       p->tcon = tcon;
+
+       status = dcerpc_binding_set_pointer_option(b, "connection",
+                               struct dcerpc_binding_smbXcli_pointers, p);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(p);
+               return status;
+       }
+
+       return NT_STATUS_OK;
+}
+
+NTSTATUS dcerpc_binding_get_smbXcli_pointers(const struct dcerpc_binding *b,
+                                            struct smbXcli_conn **conn,
+                                            struct smbXcli_session **sess,
+                                            struct smbXcli_tcon **tcon)
+{
+       struct dcerpc_binding_smbXcli_pointers *p;
+
+       p = dcerpc_binding_get_pointer_option(b, "connection",
+                               struct dcerpc_binding_smbXcli_pointers);
+       if (p == NULL) {
+               return NT_STATUS_CONNECTION_DISCONNECTED;
+       }
+
+       if (!smbXcli_conn_is_connected(p->conn)) {
+               return NT_STATUS_CONNECTION_DISCONNECTED;
+       }
+
+       if (p->sess == NULL) {
+               return NT_STATUS_CONNECTION_DISCONNECTED;
+       }
+
+       if (p->tcon == NULL) {
+               return NT_STATUS_CONNECTION_DISCONNECTED;
+       }
+
+       *conn = p->conn;
+       *sess = p->sess;
+       *tcon = p->tcon;
+
+       return NT_STATUS_OK;
+}
+
 struct pipe_np_smb_state {
        struct smb_composite_connect conn;
        struct dcerpc_pipe_connect io;