int make_base_pipes_struct(TALLOC_CTX *mem_ctx, struct messaging_context *msg_ctx, const char *pipe_name, enum dcerpc_transport_t transport, bool endian, bool ncalrpc_as_system, const struct tsocket_address *remote_address, const struct tsocket_address *local_address, struct pipes_struct **_p) { struct pipes_struct *p; p = talloc_zero(mem_ctx, struct pipes_struct); if (!p) { return ENOMEM; } p->mem_ctx = talloc_named(p, 0, "pipe %s %p", pipe_name, p); if (!p->mem_ctx) { talloc_free(p); return ENOMEM; } p->msg_ctx = msg_ctx; p->transport = transport; p->endian = endian; p->ncalrpc_as_system = ncalrpc_as_system; p->remote_address = tsocket_address_copy(remote_address, p); if (p->remote_address == NULL) { talloc_free(p); return ENOMEM; } if (local_address) { p->local_address = tsocket_address_copy(local_address, p); if (p->local_address == NULL) { talloc_free(p); return ENOMEM; } } DLIST_ADD(InternalPipes, p); talloc_set_destructor(p, close_internal_rpc_pipe_hnd); *_p = p; return 0; }
struct pipes_struct *make_internal_rpc_pipe_p(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *syntax, const struct tsocket_address *remote_address, const struct auth_serversupplied_info *session_info, struct messaging_context *msg_ctx) { struct pipes_struct *p; struct pipe_rpc_fns *context_fns; DEBUG(4,("Create pipe requested %s\n", get_pipe_name_from_syntax(talloc_tos(), syntax))); p = talloc_zero(mem_ctx, struct pipes_struct); if (!p) { DEBUG(0,("ERROR! no memory for pipes_struct!\n")); return NULL; } p->mem_ctx = talloc_named(p, 0, "pipe %s %p", get_pipe_name_from_syntax(talloc_tos(), syntax), p); if (p->mem_ctx == NULL) { DEBUG(0,("open_rpc_pipe_p: talloc_init failed.\n")); TALLOC_FREE(p); return NULL; } if (!init_pipe_handles(p, syntax)) { DEBUG(0,("open_rpc_pipe_p: init_pipe_handles failed.\n")); TALLOC_FREE(p); return NULL; } p->session_info = copy_serverinfo(p, session_info); if (p->session_info == NULL) { DEBUG(0, ("open_rpc_pipe_p: copy_serverinfo failed\n")); close_policy_by_pipe(p); TALLOC_FREE(p); return NULL; } p->msg_ctx = msg_ctx; DLIST_ADD(InternalPipes, p); p->remote_address = tsocket_address_copy(remote_address, p); if (p->remote_address == NULL) { return false; } p->endian = RPC_LITTLE_ENDIAN; p->transport = NCALRPC; context_fns = SMB_MALLOC_P(struct pipe_rpc_fns); if (context_fns == NULL) { DEBUG(0,("malloc() failed!\n")); return False; } context_fns->next = context_fns->prev = NULL; context_fns->n_cmds = rpc_srv_get_pipe_num_cmds(syntax); context_fns->cmds = rpc_srv_get_pipe_cmds(syntax); context_fns->context_id = 0; context_fns->syntax = *syntax; /* add to the list of open contexts */ DLIST_ADD(p->contexts, context_fns); DEBUG(4,("Created internal pipe %s\n", get_pipe_name_from_syntax(talloc_tos(), syntax))); talloc_set_destructor(p, close_internal_rpc_pipe_hnd); return p; }
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; }
/* Creates a pipes_struct and initializes it with the information * sent from the client */ static int make_server_pipes_struct(TALLOC_CTX *mem_ctx, const char *pipe_name, enum dcerpc_transport_t transport, bool ncalrpc_as_system, const struct tsocket_address *local_address, const struct tsocket_address *remote_address, struct auth_session_info *session_info, struct pipes_struct **_p, int *perrno) { struct netr_SamInfo3 *info3; struct auth_user_info_dc *auth_user_info_dc; struct pipes_struct *p; struct auth_serversupplied_info *server_info; NTSTATUS status; p = talloc_zero(mem_ctx, struct pipes_struct); if (!p) { *perrno = ENOMEM; return -1; } p->transport = transport; p->ncalrpc_as_system = ncalrpc_as_system; p->mem_ctx = talloc_named(p, 0, "pipe %s %p", pipe_name, p); if (!p->mem_ctx) { TALLOC_FREE(p); *perrno = ENOMEM; return -1; } data_blob_free(&p->in_data.data); data_blob_free(&p->in_data.pdu); p->endian = RPC_LITTLE_ENDIAN; /* Fake up an auth_user_info_dc for now, to make an info3, to make the session_info structure */ auth_user_info_dc = talloc_zero(p, struct auth_user_info_dc); if (!auth_user_info_dc) { TALLOC_FREE(p); *perrno = ENOMEM; return -1; } auth_user_info_dc->num_sids = session_info->security_token->num_sids; auth_user_info_dc->sids = session_info->security_token->sids; auth_user_info_dc->info = session_info->info; auth_user_info_dc->user_session_key = session_info->session_key; /* This creates the input structure that make_server_info_info3 is looking for */ status = auth_convert_user_info_dc_saminfo3(p, auth_user_info_dc, &info3); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to convert auth_user_info_dc into netr_SamInfo3\n")); TALLOC_FREE(p); *perrno = EINVAL; return -1; } status = make_server_info_info3(p, info3->base.account_name.string, info3->base.domain.string, &server_info, info3); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to init server info\n")); TALLOC_FREE(p); *perrno = EINVAL; return -1; } /* * Some internal functions need a local token to determine access to * resoutrces. */ status = create_local_token(p, server_info, &session_info->session_key, &p->session_info); talloc_free(server_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to init local auth token\n")); TALLOC_FREE(p); *perrno = EINVAL; return -1; } /* Now override the session_info->security_token with the exact * security_token we were given from the other side, * regardless of what we just calculated */ p->session_info->security_token = talloc_move(p->session_info, &session_info->security_token); p->remote_address = tsocket_address_copy(remote_address, p); if (p->remote_address == NULL) { TALLOC_FREE(p); *perrno = ENOMEM; return -1; } if (local_address != NULL) { p->local_address = tsocket_address_copy(local_address, p); if (p->local_address == NULL) { TALLOC_FREE(p); *perrno = ENOMEM; return -1; } } talloc_set_destructor(p, close_internal_rpc_pipe_hnd); *_p = p; return 0; }
NTSTATUS auth_ntlmssp_start(const struct tsocket_address *remote_address, struct auth_ntlmssp_state **auth_ntlmssp_state) { NTSTATUS nt_status; bool is_standalone; const char *netbios_name; const char *netbios_domain; const char *dns_name; char *dns_domain; struct auth_ntlmssp_state *ans; struct auth_context *auth_context; if ((enum server_role)lp_server_role() == ROLE_STANDALONE) { is_standalone = true; } else { is_standalone = false; } netbios_name = lp_netbios_name(); netbios_domain = lp_workgroup(); /* This should be a 'netbios domain -> DNS domain' mapping */ dns_domain = get_mydnsdomname(talloc_tos()); if (dns_domain) { strlower_m(dns_domain); } dns_name = get_mydnsfullname(); ans = talloc_zero(NULL, struct auth_ntlmssp_state); if (!ans) { DEBUG(0,("auth_ntlmssp_start: talloc failed!\n")); return NT_STATUS_NO_MEMORY; } ans->remote_address = tsocket_address_copy(remote_address, ans); if (ans->remote_address == NULL) { DEBUG(0,("auth_ntlmssp_start: talloc failed!\n")); return NT_STATUS_NO_MEMORY; } nt_status = ntlmssp_server_start(ans, is_standalone, netbios_name, netbios_domain, dns_name, dns_domain, &ans->ntlmssp_state); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } nt_status = make_auth_context_subsystem(talloc_tos(), &auth_context); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } ans->auth_context = talloc_steal(ans, auth_context); ans->ntlmssp_state->callback_private = ans; ans->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge; ans->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge; ans->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge; ans->ntlmssp_state->check_password = auth_ntlmssp_check_password; talloc_set_destructor((TALLOC_CTX *)ans, auth_ntlmssp_state_destructor); *auth_ntlmssp_state = ans; return NT_STATUS_OK; }