} 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;