static struct npa_state *npa_state_init(TALLOC_CTX *mem_ctx) { struct npa_state *npa; npa = talloc_zero(mem_ctx, struct npa_state); if (npa == NULL) { return NULL; } npa->read_queue = tevent_queue_create(npa, "npa_cli_read"); if (npa->read_queue == NULL) { DEBUG(0, ("tevent_queue_create failed\n")); goto fail; } npa->write_queue = tevent_queue_create(npa, "npa_cli_write"); if (npa->write_queue == NULL) { DEBUG(0, ("tevent_queue_create failed\n")); goto fail; } return npa; fail: talloc_free(npa); return NULL; }
struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx, const char* dir) { struct wb_context *result; result = talloc_zero(mem_ctx, struct wb_context); if (result == NULL) { return NULL; } result->queue = tevent_queue_create(result, "wb_trans"); if (result->queue == NULL) { TALLOC_FREE(result); return NULL; } result->fd = -1; result->is_priv = false; if (dir != NULL) { result->dir = talloc_strdup(result, dir); } else { result->dir = winbindd_socket_dir(); } if (result->dir == NULL) { TALLOC_FREE(result); return NULL; } return result; }
static void named_pipe_accept_done(struct tevent_req *subreq) { struct auth_session_info_transport *session_info_transport; struct named_pipe_client *npc = tevent_req_callback_data(subreq, struct named_pipe_client); int error; int ret; ret = tstream_npa_accept_existing_recv(subreq, &error, npc, &npc->tstream, &npc->client, &npc->client_name, &npc->server, &npc->server_name, &session_info_transport); npc->session_info = talloc_move(npc, &session_info_transport->session_info); TALLOC_FREE(subreq); if (ret != 0) { DEBUG(2, ("Failed to accept named pipe connection! (%s)\n", strerror(error))); TALLOC_FREE(npc); return; } ret = make_server_pipes_struct(npc, npc->msg_ctx, npc->pipe_name, NCACN_NP, false, npc->server, npc->client, npc->session_info, &npc->p, &error); if (ret != 0) { DEBUG(2, ("Failed to create pipes_struct! (%s)\n", strerror(error))); goto fail; } npc->write_queue = tevent_queue_create(npc, "np_server_write_queue"); if (!npc->write_queue) { DEBUG(2, ("Failed to set up write queue!\n")); goto fail; } /* And now start receiving and processing packets */ subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream); if (!subreq) { DEBUG(2, ("Failed to start receving packets\n")); goto fail; } tevent_req_set_callback(subreq, named_pipe_packet_process, npc); return; fail: DEBUG(2, ("Fatal error. Terminating client(%s) connection!\n", npc->client_name)); /* terminate client connection */ talloc_free(npc); return; }
/* called when we get a new connection */ static void kdc_tcp_accept(struct stream_connection *conn) { struct kdc_socket *kdc_socket; struct kdc_tcp_connection *kdc_conn; struct tevent_req *subreq; int rc; kdc_conn = talloc_zero(conn, struct kdc_tcp_connection); if (kdc_conn == NULL) { stream_terminate_connection(conn, "kdc_tcp_accept: out of memory"); return; } kdc_conn->send_queue = tevent_queue_create(conn, "kdc_tcp_accept"); if (kdc_conn->send_queue == NULL) { stream_terminate_connection(conn, "kdc_tcp_accept: out of memory"); return; } kdc_socket = talloc_get_type(conn->private_data, struct kdc_socket); TALLOC_FREE(conn->event.fde); rc = tstream_bsd_existing_socket(kdc_conn, socket_get_fd(conn->socket), &kdc_conn->tstream); if (rc < 0) { stream_terminate_connection(conn, "kdc_tcp_accept: out of memory"); return; } kdc_conn->conn = conn; kdc_conn->kdc_socket = kdc_socket; conn->private_data = kdc_conn; /* * The krb5 tcp pdu's has the length as 4 byte (initial_read_size), * packet_full_request_u32 provides the pdu length then. */ subreq = tstream_read_pdu_blob_send(kdc_conn, kdc_conn->conn->event.ctx, kdc_conn->tstream, 4, /* initial_read_size */ packet_full_request_u32, kdc_conn); if (subreq == NULL) { kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_accept: " "no memory for tstream_read_pdu_blob_send"); return; } tevent_req_set_callback(subreq, kdc_tcp_call_loop, kdc_conn); }
static void wbsrv_accept(struct stream_connection *conn) { struct wbsrv_listen_socket *wbsrv_socket = talloc_get_type(conn->private_data, struct wbsrv_listen_socket); struct wbsrv_connection *wbsrv_conn; struct tevent_req *subreq; int rc; wbsrv_conn = talloc_zero(conn, struct wbsrv_connection); if (wbsrv_conn == NULL) { stream_terminate_connection(conn, "wbsrv_accept: out of memory"); return; } wbsrv_conn->send_queue = tevent_queue_create(conn, "wbsrv_accept"); if (wbsrv_conn->send_queue == NULL) { stream_terminate_connection(conn, "wbsrv_accept: out of memory"); return; } TALLOC_FREE(conn->event.fde); rc = tstream_bsd_existing_socket(wbsrv_conn, socket_get_fd(conn->socket), &wbsrv_conn->tstream); if (rc < 0) { stream_terminate_connection(conn, "wbsrv_accept: out of memory"); return; } wbsrv_conn->conn = conn; wbsrv_conn->listen_socket = wbsrv_socket; wbsrv_conn->lp_ctx = wbsrv_socket->service->task->lp_ctx; conn->private_data = wbsrv_conn; /* * The winbind pdu's has the length as 4 byte (initial_read_size), * wbsrv_samba3_packet_full_request provides the pdu length then. */ subreq = tstream_read_pdu_blob_send(wbsrv_conn, wbsrv_conn->conn->event.ctx, wbsrv_conn->tstream, 4, /* initial_read_size */ wbsrv_samba3_packet_full_request, wbsrv_conn); if (subreq == NULL) { wbsrv_terminate_connection(wbsrv_conn, "wbsrv_accept: " "no memory for tstream_read_pdu_blob_send"); return; } tevent_req_set_callback(subreq, wbsrv_call_loop, wbsrv_conn); }
struct tevent_req *ctdb_conn_init_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *sock) { struct tevent_req *req, *subreq; struct ctdb_conn_init_state *state; req = tevent_req_create(mem_ctx, &state, struct ctdb_conn_init_state); if (req == NULL) { return NULL; } if (!lp_clustering()) { tevent_req_error(req, ENOSYS); return tevent_req_post(req, ev); } if (strlen(sock) >= sizeof(state->addr.sun_path)) { tevent_req_error(req, ENAMETOOLONG); return tevent_req_post(req, ev); } state->conn = talloc(state, struct ctdb_conn); if (tevent_req_nomem(state->conn, req)) { return tevent_req_post(req, ev); } state->conn->outqueue = tevent_queue_create( state->conn, "ctdb outqueue"); if (tevent_req_nomem(state->conn->outqueue, req)) { return tevent_req_post(req, ev); } state->conn->fd = socket(AF_UNIX, SOCK_STREAM, 0); if (state->conn->fd == -1) { tevent_req_error(req, errno); return tevent_req_post(req, ev); } talloc_set_destructor(state->conn, ctdb_conn_destructor); state->addr.sun_family = AF_UNIX; strncpy(state->addr.sun_path, sock, sizeof(state->addr.sun_path)); subreq = async_connect_send(state, ev, state->conn->fd, (struct sockaddr *)&state->addr, sizeof(state->addr), before_connect_cb, after_connect_cb, NULL); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } tevent_req_set_callback(subreq, ctdb_conn_init_done, req); return req; }
struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx) { struct wb_context *result; result = talloc(mem_ctx, struct wb_context); if (result == NULL) { return NULL; } result->queue = tevent_queue_create(result, "wb_trans"); if (result->queue == NULL) { TALLOC_FREE(result); return NULL; } result->fd = -1; return result; }
NTSTATUS make_internal_rpc_pipe_socketpair( TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, const char *pipe_name, const struct ndr_syntax_id *syntax, const struct tsocket_address *remote_address, const struct tsocket_address *local_address, const struct auth_session_info *session_info, struct npa_state **pnpa) { TALLOC_CTX *tmp_ctx = talloc_stackframe(); struct named_pipe_client *npc; struct tevent_req *subreq; struct npa_state *npa; NTSTATUS status; int error; int rc; DEBUG(4, ("Create of internal pipe %s requested\n", pipe_name)); npa = npa_state_init(tmp_ctx); if (npa == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } npa->file_type = FILE_TYPE_MESSAGE_MODE_PIPE; npa->device_state = 0xff | 0x0400 | 0x0100; npa->allocation_size = 4096; npc = named_pipe_client_init(npa, ev_ctx, msg_ctx, pipe_name, NULL, /* term_fn */ npa->file_type, npa->device_state, npa->allocation_size, NULL); /* private_data */ if (npc == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } npa->private_data = (void*) npc; rc = tstream_npa_socketpair(npa->file_type, npa, &npa->stream, npc, &npc->tstream); if (rc == -1) { status = map_nt_error_from_unix(errno); goto out; } npc->remote_client_addr = tsocket_address_copy(remote_address, npc); if (npc->remote_client_addr == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } npc->remote_client_name = tsocket_address_inet_addr_string(npc->remote_client_addr, npc); if (npc->remote_client_name == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } npc->local_server_addr = tsocket_address_copy(local_address, npc); if (npc->local_server_addr == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } npc->local_server_name = tsocket_address_inet_addr_string( npc->local_server_addr, npc); if (npc->local_server_name == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } npc->session_info = copy_session_info(npc, session_info); if (npc->session_info == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } rc = make_server_pipes_struct(npc, npc->msg_ctx, npc->pipe_name, NCACN_NP, npc->remote_client_addr, npc->local_server_addr, npc->session_info, &npc->p, &error); if (rc == -1) { status = map_nt_error_from_unix(error); goto out; } npc->write_queue = tevent_queue_create(npc, "npa_server_write_queue"); if (npc->write_queue == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } subreq = dcerpc_read_ncacn_packet_send(npc, npc->ev, npc->tstream); if (subreq == NULL) { DEBUG(2, ("Failed to start receiving packets\n")); status = NT_STATUS_PIPE_BROKEN; goto out; } tevent_req_set_callback(subreq, named_pipe_packet_process, npc); *pnpa = talloc_steal(mem_ctx, npa); status = NT_STATUS_OK; out: talloc_free(tmp_ctx); return status; }
/* initialise a cldap_sock */ NTSTATUS cldap_socket_init(TALLOC_CTX *mem_ctx, const struct tsocket_address *local_addr, const struct tsocket_address *remote_addr, struct cldap_socket **_cldap) { struct cldap_socket *c = NULL; struct tsocket_address *any = NULL; NTSTATUS status; int ret; const char *fam = NULL; if (local_addr == NULL && remote_addr == NULL) { return NT_STATUS_INVALID_PARAMETER_MIX; } if (remote_addr) { bool is_ipv4; bool is_ipv6; is_ipv4 = tsocket_address_is_inet(remote_addr, "ipv4"); is_ipv6 = tsocket_address_is_inet(remote_addr, "ipv6"); if (is_ipv4) { fam = "ipv4"; } else if (is_ipv6) { fam = "ipv6"; } else { return NT_STATUS_INVALID_ADDRESS; } } c = talloc_zero(mem_ctx, struct cldap_socket); if (!c) { goto nomem; } if (!local_addr) { /* * Here we know the address family of the remote address. */ if (fam == NULL) { return NT_STATUS_INVALID_PARAMETER_MIX; } ret = tsocket_address_inet_from_strings(c, fam, NULL, 0, &any); if (ret != 0) { status = map_nt_error_from_unix_common(errno); goto nterror; } local_addr = any; } c->searches.idr = idr_init(c); if (!c->searches.idr) { goto nomem; } ret = tdgram_inet_udp_socket(local_addr, remote_addr, c, &c->sock); if (ret != 0) { status = map_nt_error_from_unix_common(errno); goto nterror; } talloc_free(any); if (remote_addr) { c->connected = true; } c->send_queue = tevent_queue_create(c, "cldap_send_queue"); if (!c->send_queue) { goto nomem; } talloc_set_destructor(c, cldap_socket_destructor); *_cldap = c; return NT_STATUS_OK; nomem: status = NT_STATUS_NO_MEMORY; nterror: talloc_free(c); return status; }
/* called when we get a new connection */ static void wreplsrv_accept(struct stream_connection *conn) { struct wreplsrv_service *service = talloc_get_type(conn->private_data, struct wreplsrv_service); struct wreplsrv_in_connection *wrepl_conn; struct tsocket_address *peer_addr; char *peer_ip; struct tevent_req *subreq; int rc; wrepl_conn = talloc_zero(conn, struct wreplsrv_in_connection); if (wrepl_conn == NULL) { stream_terminate_connection(conn, "wreplsrv_accept: out of memory"); return; } wrepl_conn->send_queue = tevent_queue_create(conn, "wrepl_accept"); if (wrepl_conn->send_queue == NULL) { stream_terminate_connection(conn, "wrepl_accept: out of memory"); return; } TALLOC_FREE(conn->event.fde); rc = tstream_bsd_existing_socket(wrepl_conn, socket_get_fd(conn->socket), &wrepl_conn->tstream); if (rc < 0) { stream_terminate_connection(conn, "wrepl_accept: out of memory"); return; } socket_set_flags(conn->socket, SOCKET_FLAG_NOCLOSE); wrepl_conn->conn = conn; wrepl_conn->service = service; peer_addr = conn->remote_address; if (!tsocket_address_is_inet(peer_addr, "ipv4")) { DEBUG(0,("wreplsrv_accept: non ipv4 peer addr '%s'\n", tsocket_address_string(peer_addr, wrepl_conn))); wreplsrv_terminate_in_connection(wrepl_conn, "wreplsrv_accept: " "invalid peer IP"); return; } peer_ip = tsocket_address_inet_addr_string(peer_addr, wrepl_conn); if (peer_ip == NULL) { wreplsrv_terminate_in_connection(wrepl_conn, "wreplsrv_accept: " "could not convert peer IP into a string"); return; } wrepl_conn->partner = wreplsrv_find_partner(service, peer_ip); irpc_add_name(conn->msg_ctx, "wreplsrv_connection"); /* * The wrepl pdu's has the length as 4 byte (initial_read_size), * packet_full_request_u32 provides the pdu length then. */ subreq = tstream_read_pdu_blob_send(wrepl_conn, wrepl_conn->conn->event.ctx, wrepl_conn->tstream, 4, /* initial_read_size */ packet_full_request_u32, wrepl_conn); if (subreq == NULL) { wreplsrv_terminate_in_connection(wrepl_conn, "wrepl_accept: " "no memory for tstream_read_pdu_blob_send"); return; } tevent_req_set_callback(subreq, wreplsrv_call_loop, wrepl_conn); }
/* called when we get a new connection */ NTSTATUS wreplsrv_in_connection_merge(struct wreplsrv_partner *partner, uint32_t peer_assoc_ctx, struct tstream_context **stream, struct wreplsrv_in_connection **_wrepl_in) { struct wreplsrv_service *service = partner->service; struct wreplsrv_in_connection *wrepl_in; const struct model_ops *model_ops; struct stream_connection *conn; struct tevent_req *subreq; NTSTATUS status; /* within the wrepl task we want to be a single process, so ask for the single process model ops and pass these to the stream_setup_socket() call. */ model_ops = process_model_startup("single"); if (!model_ops) { DEBUG(0,("Can't find 'single' process model_ops")); return NT_STATUS_INTERNAL_ERROR; } wrepl_in = talloc_zero(partner, struct wreplsrv_in_connection); NT_STATUS_HAVE_NO_MEMORY(wrepl_in); wrepl_in->service = service; wrepl_in->partner = partner; wrepl_in->tstream = talloc_move(wrepl_in, stream); wrepl_in->assoc_ctx.peer_ctx = peer_assoc_ctx; status = stream_new_connection_merge(service->task->event_ctx, service->task->lp_ctx, model_ops, &wreplsrv_stream_ops, service->task->msg_ctx, wrepl_in, &conn); NT_STATUS_NOT_OK_RETURN(status); /* * make the wreplsrv_in_connection structure a child of the * stream_connection, to match the hierarchy of wreplsrv_accept */ wrepl_in->conn = conn; talloc_steal(conn, wrepl_in); wrepl_in->send_queue = tevent_queue_create(wrepl_in, "wreplsrv_in_connection_merge"); if (wrepl_in->send_queue == NULL) { stream_terminate_connection(conn, "wreplsrv_in_connection_merge: out of memory"); return NT_STATUS_NO_MEMORY; } /* * The wrepl pdu's has the length as 4 byte (initial_read_size), * packet_full_request_u32 provides the pdu length then. */ subreq = tstream_read_pdu_blob_send(wrepl_in, wrepl_in->conn->event.ctx, wrepl_in->tstream, 4, /* initial_read_size */ packet_full_request_u32, wrepl_in); if (subreq == NULL) { wreplsrv_terminate_in_connection(wrepl_in, "wreplsrv_in_connection_merge: " "no memory for tstream_read_pdu_blob_send"); return NT_STATUS_NO_MEMORY; } tevent_req_set_callback(subreq, wreplsrv_call_loop, wrepl_in); *_wrepl_in = wrepl_in; return NT_STATUS_OK; }
/* initialise a server_context from a open socket and register a event handler for reading from that socket */ static void ldapsrv_accept(struct stream_connection *c, struct auth_session_info *session_info, bool is_privileged) { struct ldapsrv_service *ldapsrv_service = talloc_get_type(c->private_data, struct ldapsrv_service); struct ldapsrv_connection *conn; struct cli_credentials *server_credentials; struct socket_address *socket_address; NTSTATUS status; int port; int ret; struct tevent_req *subreq; struct timeval endtime; conn = talloc_zero(c, struct ldapsrv_connection); if (!conn) { stream_terminate_connection(c, "ldapsrv_accept: out of memory"); return; } conn->is_privileged = is_privileged; conn->sockets.send_queue = tevent_queue_create(conn, "ldapsev send queue"); if (conn->sockets.send_queue == NULL) { stream_terminate_connection(c, "ldapsrv_accept: tevent_queue_create failed"); return; } TALLOC_FREE(c->event.fde); ret = tstream_bsd_existing_socket(conn, socket_get_fd(c->socket), &conn->sockets.raw); if (ret == -1) { stream_terminate_connection(c, "ldapsrv_accept: out of memory"); return; } socket_set_flags(c->socket, SOCKET_FLAG_NOCLOSE); conn->connection = c; conn->service = ldapsrv_service; conn->lp_ctx = ldapsrv_service->task->lp_ctx; c->private_data = conn; socket_address = socket_get_my_addr(c->socket, conn); if (!socket_address) { ldapsrv_terminate_connection(conn, "ldapsrv_accept: failed to obtain local socket address!"); return; } port = socket_address->port; talloc_free(socket_address); if (port == 3268 || port == 3269) /* Global catalog */ { conn->global_catalog = true; } server_credentials = cli_credentials_init(conn); if (!server_credentials) { stream_terminate_connection(c, "Failed to init server credentials\n"); return; } cli_credentials_set_conf(server_credentials, conn->lp_ctx); status = cli_credentials_set_machine_account(server_credentials, conn->lp_ctx); if (!NT_STATUS_IS_OK(status)) { stream_terminate_connection(c, talloc_asprintf(conn, "Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status))); return; } conn->server_credentials = server_credentials; conn->session_info = session_info; if (!NT_STATUS_IS_OK(ldapsrv_backend_Init(conn))) { ldapsrv_terminate_connection(conn, "backend Init failed"); return; } /* load limits from the conf partition */ ldapsrv_load_limits(conn); /* should we fail on error ? */ /* register the server */ irpc_add_name(c->msg_ctx, "ldap_server"); conn->sockets.active = conn->sockets.raw; if (port != 636 && port != 3269) { ldapsrv_call_read_next(conn); return; } endtime = timeval_current_ofs(conn->limits.conn_idle_time, 0); subreq = tstream_tls_accept_send(conn, conn->connection->event.ctx, conn->sockets.raw, conn->service->tls_params); if (subreq == NULL) { ldapsrv_terminate_connection(conn, "ldapsrv_accept: " "no memory for tstream_tls_accept_send"); return; } tevent_req_set_endtime(subreq, conn->connection->event.ctx, endtime); tevent_req_set_callback(subreq, ldapsrv_accept_tls_done, conn); }
struct cli_state *cli_initialise_ex(int signing_state) { struct cli_state *cli = NULL; bool allow_smb_signing = false; bool mandatory_signing = false; /* Check the effective uid - make sure we are not setuid */ if (is_setuid_root()) { DEBUG(0,("libsmb based programs must *NOT* be setuid root.\n")); return NULL; } cli = TALLOC_ZERO_P(NULL, struct cli_state); if (!cli) { return NULL; } cli->dfs_mountpoint = talloc_strdup(cli, ""); if (!cli->dfs_mountpoint) { goto error; } cli->port = 0; cli->fd = -1; cli->cnum = -1; cli->pid = (uint16)sys_getpid(); cli->mid = 1; cli->vuid = UID_FIELD_INVALID; cli->protocol = PROTOCOL_NT1; cli->timeout = 20000; /* Timeout is in milliseconds. */ cli->bufsize = CLI_BUFFER_SIZE+4; cli->max_xmit = cli->bufsize; cli->outbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->seqnum = 0; cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; cli->case_sensitive = false; cli->smb_rw_error = SMB_READ_OK; cli->use_spnego = lp_client_use_spnego(); cli->capabilities = CAP_UNICODE | CAP_STATUS32 | CAP_DFS; /* Set the CLI_FORCE_DOSERR environment variable to test client routines using DOS errors instead of STATUS32 ones. This intended only as a temporary hack. */ if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = true; if (lp_client_signing()) { allow_smb_signing = true; } if (lp_client_signing() == Required) { mandatory_signing = true; } if (signing_state != Undefined) { allow_smb_signing = true; } if (signing_state == false) { allow_smb_signing = false; mandatory_signing = false; } if (signing_state == Required) { mandatory_signing = true; } if (!cli->outbuf || !cli->inbuf) goto error; memset(cli->outbuf, 0, cli->bufsize); memset(cli->inbuf, 0, cli->bufsize); #if defined(DEVELOPER) /* just because we over-allocate, doesn't mean it's right to use it */ clobber_region(FUNCTION_MACRO, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN); clobber_region(FUNCTION_MACRO, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN); #endif /* initialise signing */ cli->signing_state = smb_signing_init(cli, allow_smb_signing, mandatory_signing); if (!cli->signing_state) { goto error; } cli->outgoing = tevent_queue_create(cli, "cli_outgoing"); if (cli->outgoing == NULL) { goto error; } cli->pending = NULL; cli->initialised = 1; return cli; /* Clean up after malloc() error */ error: SAFE_FREE(cli->inbuf); SAFE_FREE(cli->outbuf); TALLOC_FREE(cli); return NULL; }
struct composite_context *wb_init_domain_send(TALLOC_CTX *mem_ctx, struct wbsrv_service *service, struct wb_dom_info *dom_info) { struct composite_context *result, *ctx; struct init_domain_state *state; result = composite_create(mem_ctx, service->task->event_ctx); if (result == NULL) goto failed; state = talloc_zero(result, struct init_domain_state); if (state == NULL) goto failed; state->ctx = result; result->private_data = state; state->service = service; state->domain = talloc(state, struct wbsrv_domain); if (state->domain == NULL) goto failed; state->domain->service = service; state->domain->info = talloc_reference(state->domain, dom_info); if (state->domain->info == NULL) goto failed; state->domain->dc_name = dom_info->dc->name; state->domain->dc_address = dom_info->dc->address; state->domain->libnet_ctx = libnet_context_init(service->task->event_ctx, service->task->lp_ctx); if (state->domain->libnet_ctx == NULL) goto failed; talloc_steal(state->domain, state->domain->libnet_ctx); /* Create a credentials structure */ state->domain->libnet_ctx->cred = cli_credentials_init(state->domain); if (state->domain->libnet_ctx->cred == NULL) goto failed; cli_credentials_set_conf(state->domain->libnet_ctx->cred, service->task->lp_ctx); /* Connect the machine account to the credentials */ state->ctx->status = cli_credentials_set_machine_account(state->domain->libnet_ctx->cred, state->domain->libnet_ctx->lp_ctx); if (!NT_STATUS_IS_OK(state->ctx->status)) goto failed; state->domain->netlogon_binding = init_domain_binding(state, &ndr_table_netlogon); state->domain->netlogon_pipe = NULL; state->domain->netlogon_queue = tevent_queue_create(state->domain, "netlogon_queue"); if (state->domain->netlogon_queue == NULL) goto failed; /* We start the queue when the connection is usable */ tevent_queue_stop(state->domain->netlogon_queue); if ((!cli_credentials_is_anonymous(state->domain->libnet_ctx->cred)) && ((lpcfg_server_role(service->task->lp_ctx) == ROLE_DOMAIN_MEMBER) || (lpcfg_server_role(service->task->lp_ctx) == ROLE_ACTIVE_DIRECTORY_DC)) && (dom_sid_equal(state->domain->info->sid, state->service->primary_sid))) { uint32_t flags = DCERPC_SCHANNEL | DCERPC_SCHANNEL_AUTO; /* For debugging, it can be a real pain if all the traffic is encrypted */ if (lpcfg_winbind_sealed_pipes(service->task->lp_ctx)) { flags |= DCERPC_SIGN | DCERPC_SEAL; } else { flags |= DCERPC_SIGN; } state->ctx->status = dcerpc_binding_set_flags(state->domain->netlogon_binding, flags, 0); if (!NT_STATUS_IS_OK(state->ctx->status)) goto failed; } /* No encryption on anonymous pipes */ ctx = dcerpc_pipe_connect_b_send(state, state->domain->netlogon_binding, &ndr_table_netlogon, state->domain->libnet_ctx->cred, service->task->event_ctx, service->task->lp_ctx); if (composite_nomem(ctx, state->ctx)) { goto failed; } composite_continue(state->ctx, ctx, init_domain_recv_netlogonpipe, state); return result; failed: talloc_free(result); return NULL; }
/* initialise a cldap_sock */ NTSTATUS cldap_socket_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const struct tsocket_address *local_addr, const struct tsocket_address *remote_addr, struct cldap_socket **_cldap) { struct cldap_socket *c = NULL; struct tsocket_address *any = NULL; NTSTATUS status; int ret; c = talloc_zero(mem_ctx, struct cldap_socket); if (!c) { goto nomem; } if (!ev) { ev = tevent_context_init(c); if (!ev) { goto nomem; } c->event.allow_poll = true; } c->event.ctx = ev; if (!local_addr) { ret = tsocket_address_inet_from_strings(c, "ipv4", NULL, 0, &any); if (ret != 0) { status = map_nt_error_from_unix(errno); goto nterror; } local_addr = any; } c->searches.idr = idr_init(c); if (!c->searches.idr) { goto nomem; } ret = tdgram_inet_udp_socket(local_addr, remote_addr, c, &c->sock); if (ret != 0) { status = map_nt_error_from_unix(errno); goto nterror; } talloc_free(any); if (remote_addr) { c->connected = true; } c->send_queue = tevent_queue_create(c, "cldap_send_queue"); if (!c->send_queue) { goto nomem; } talloc_set_destructor(c, cldap_socket_destructor); *_cldap = c; return NT_STATUS_OK; nomem: status = NT_STATUS_NO_MEMORY; nterror: talloc_free(c); return status; }