From: Volker Lendecke Date: Tue, 8 Jun 2021 07:10:05 +0000 (+0200) Subject: s3:rpc_server: Delete unused code and doc references X-Git-Tag: tdb-1.4.6~350 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=730f7dfd615ed9997cdf2e7e418605b28826e310;p=thirdparty%2Fsamba.git s3:rpc_server: Delete unused code and doc references Signed-off-by: Volker Lendecke Reviewed-by: Samuel Cabrero Reviewed-by: Jeremy Allison Reviewed-by: Stefan Metzmacher --- diff --git a/docs-xml/manpages/vfs_btrfs.8.xml b/docs-xml/manpages/vfs_btrfs.8.xml index 60013f9be9a..c617a276e5b 100644 --- a/docs-xml/manpages/vfs_btrfs.8.xml +++ b/docs-xml/manpages/vfs_btrfs.8.xml @@ -107,7 +107,6 @@ - fork yes registry diff --git a/docs-xml/manpages/vfs_shell_snap.8.xml b/docs-xml/manpages/vfs_shell_snap.8.xml index d6206e152f6..319d825cfaf 100644 --- a/docs-xml/manpages/vfs_shell_snap.8.xml +++ b/docs-xml/manpages/vfs_shell_snap.8.xml @@ -128,7 +128,6 @@ - fork yes registry diff --git a/docs-xml/manpages/vfs_snapper.8.xml b/docs-xml/manpages/vfs_snapper.8.xml index 053da7f5270..9663ece0b0c 100644 --- a/docs-xml/manpages/vfs_snapper.8.xml +++ b/docs-xml/manpages/vfs_snapper.8.xml @@ -70,7 +70,6 @@ - fork yes registry diff --git a/docs-xml/smbdotconf/misc/rpcdaemon.xml b/docs-xml/smbdotconf/misc/rpcdaemon.xml deleted file mode 100644 index d3e3e52c59b..00000000000 --- a/docs-xml/smbdotconf/misc/rpcdaemon.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - - Defines whether to use the embedded code or start a separate daemon - for the defined rpc services. - The rpc_daemon prefix must be followed by the server name, and a value. - - - - Two possible values are currently supported: - - disabled - fork - - - - - The classic method is to run rpc services as internal daemons - embedded in smbd, therefore the external daemons are - disabled by default. - - - - Choosing the fork option will cause samba to fork - a separate process for each daemon configured this way. Each daemon may - in turn fork a number of children used to handle requests from multiple - smbds and direct tcp/ip connections (if the Endpoint Mapper is - enabled). Communication with smbd happens over named pipes and require - that said pipes are forward to the external daemon (see ). - - - - Forked RPC Daemons support dynamically forking children to handle - connections. The heuristics about how many children to keep around and - how fast to allow them to fork and also how many clients each child is - allowed to handle concurrently is defined by parametrical options named - after the daemon. - Five options are currently supported: - - prefork_min_children - prefork_max_children - prefork_spawn_rate - prefork_max_allowed_clients - prefork_child_min_life - - - To set one of these options use the following syntax: - - daemonname:prefork_min_children = 5 - - - - - Samba includes separate daemons for spoolss, lsarpc/lsass, - netlogon, samr, FSRVP and mdssvc(Spotlight). Currently five - daemons are available and they are called: - - epmd - lsasd - spoolssd - fssd - mdssd - - Example: - - rpc_daemon:spoolssd = fork - - - - -disabled - diff --git a/docs-xml/smbdotconf/misc/rpcserver.xml b/docs-xml/smbdotconf/misc/rpcserver.xml deleted file mode 100644 index 434e5ec49ee..00000000000 --- a/docs-xml/smbdotconf/misc/rpcserver.xml +++ /dev/null @@ -1,94 +0,0 @@ - - - - With this option you can define if a rpc service should be - running internal/embedded in smbd or should be redirected to an - external daemon like Samba4, the endpoint mapper daemon, the - spoolss daemon or the new LSA service daemon. The rpc_server - prefix must be followed by the pipe name, and a value. - - - - This option can be set for each available rpc service in Samba. - The following list shows all available pipe names services you - can modify with this option. - - - - epmapper - Endpoint Mapper - winreg - Remote Registry Service - srvsvc - Remote Server Services - lsarpc - Local Security Authority - samr - Security Account Management - netlogon - Netlogon Remote Protocol - netdfs - Settings for Distributed File System - dssetup - Active Directory Setup - wkssvc - Workstation Services - spoolss - Network Printing Spooler - svcctl - Service Control - ntsvcs - Plug and Play Services - eventlog - Event Logger - initshutdown - Init Shutdown Service - mdssvc - Spotlight - - - - Three possible values currently supported are: - embedded - external - disabled - - - - The classic method is to run every pipe as an internal function - embedded in smbd. The defaults may vary - depending on the service. - - - - Choosing the external option allows one to run - a separate daemon or even a completely independent (3rd party) - server capable of interfacing with samba via the MS-RPC - interface over named pipes. - - - - Currently in Samba3 we support four daemons, spoolssd, epmd, - lsasd and mdssd. These daemons can be enabled using the - rpc_daemon option. For spoolssd you have - to enable the daemon and proxy the named pipe with: - - - - Examples: - - rpc_daemon:lsasd = fork - rpc_server:lsarpc = external - rpc_server:samr = external - rpc_server:netlogon = external - - rpc_server:spoolss = external - rpc_server:epmapper = disabled - - rpc_daemon:mdssd = fork - rpc_server:mdssvc = external - - - - - There is one special option which allows you to enable rpc - services to listen for ncacn_ip_tcp connections too. Currently - this is only used for testing and doesn't scale! - - - rpc_server:tcpip = yes - - - - - -embedded - diff --git a/docs-xml/smbdotconf/misc/spotlight.xml b/docs-xml/smbdotconf/misc/spotlight.xml index 95e9d9beb94..04631d3a771 100644 --- a/docs-xml/smbdotconf/misc/spotlight.xml +++ b/docs-xml/smbdotconf/misc/spotlight.xml @@ -18,11 +18,6 @@ Samba must be configured and built with Spotlight support. - - The mdssvc RPC service must be - enabled, see below. - - Tracker integration must be setup and the share must be indexed by Tracker. @@ -31,26 +26,6 @@ url="https://wiki.samba.org/index.php/Spotlight">https://wiki.samba.org/index.php/Spotlight. - - The Spotlight RPC service can either be enabled as embedded - RPC service: - - - - -embedded - - - - Or it can be run in a separate RPC service daemon: - - - - -fork -external - - no diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index 2178c7dbd3a..7385b755273 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1697,7 +1697,6 @@ sub setup_fileserver my $ip4 = Samba::get_ipv4_addr("FILESERVER"); my $fileserver_options = " kernel change notify = yes - rpc_server:mdssvc = embedded spotlight backend = elasticsearch elasticsearch:address = $ip4 elasticsearch:port = 8080 diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index aafe183dced..da6b2de488b 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -1335,15 +1335,6 @@ winbindd:use external pipes = true server signing = enabled raw NTLMv2 auth = yes -rpc_server:default = external -rpc_server:svcctl = embedded -rpc_server:srvsvc = embedded -rpc_server:eventlog = embedded -rpc_server:ntsvcs = embedded -rpc_server:winreg = embedded -rpc_server:spoolss = embedded -rpc_daemon:spoolssd = embedded -rpc_server:tcpip = no # override the new SMB2 only default client min protocol = CORE server min protocol = LANMAN1 diff --git a/source3/lib/server_prefork.c b/source3/lib/server_prefork.c deleted file mode 100644 index 2fb13c90fee..00000000000 --- a/source3/lib/server_prefork.c +++ /dev/null @@ -1,698 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Common server globals - - Copyright (C) Simo Sorce 2011 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "serverid.h" -#include "messages.h" -#include "system/time.h" -#include "system/shmem.h" -#include "system/filesys.h" -#include "server_prefork.h" -#include "../lib/util/samba_util.h" -#include "../lib/util/tevent_unix.h" - -struct prefork_pool { - int listen_fd_size; - struct pf_listen_fd *listen_fds; - - prefork_main_fn_t *main_fn; - void *private_data; - - int pool_size; - struct pf_worker_data *pool; - - int allowed_clients; - - prefork_sigchld_fn_t *sigchld_fn; - void *sigchld_data; -}; - -static bool prefork_setup_sigchld_handler(struct tevent_context *ev_ctx, - struct prefork_pool *pfp); - -static int prefork_pool_destructor(struct prefork_pool *pfp) -{ - anonymous_shared_free(pfp->pool); - return 0; -} - -bool prefork_create_pool(TALLOC_CTX *mem_ctx, - struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - int listen_fd_size, struct pf_listen_fd *listen_fds, - int min_children, int max_children, - prefork_main_fn_t *main_fn, void *private_data, - struct prefork_pool **pf_pool) -{ - struct prefork_pool *pfp = NULL; - pid_t pid; - time_t now = time(NULL); - size_t data_size; - int ret; - int i; - bool ok; - - pfp = talloc_zero(mem_ctx, struct prefork_pool); - if (!pfp) { - DEBUG(1, ("Out of memory!\n")); - goto fail; - } - pfp->listen_fd_size = listen_fd_size; - pfp->listen_fds = talloc_array(pfp, struct pf_listen_fd, - listen_fd_size); - if (!pfp->listen_fds) { - DEBUG(1, ("Out of memory!\n")); - goto fail; - } - for (i = 0; i < listen_fd_size; i++) { - pfp->listen_fds[i] = listen_fds[i]; - /* force sockets in non-blocking mode */ - ret = set_blocking(listen_fds[i].fd, false); - if (ret < 0) { - DBG_WARNING("Failed to set sockets to non-blocking!\n"); - goto fail; - } - } - pfp->main_fn = main_fn; - pfp->private_data = private_data; - - pfp->pool_size = max_children; - data_size = sizeof(struct pf_worker_data) * max_children; - - pfp->pool = (struct pf_worker_data *)anonymous_shared_allocate( - data_size); - if (pfp->pool == NULL) { - DEBUG(1, ("Failed to mmap memory for prefork pool!\n")); - goto fail; - } - talloc_set_destructor(pfp, prefork_pool_destructor); - - for (i = 0; i < min_children; i++) { - - pfp->pool[i].allowed_clients = 1; - pfp->pool[i].started = now; - - pid = fork(); - switch (pid) { - case -1: - DEBUG(1, ("Failed to prefork child n. %d !\n", i)); - break; - - case 0: /* THE CHILD */ - - pfp->pool[i].status = PF_WORKER_ALIVE; - ret = pfp->main_fn(ev_ctx, msg_ctx, - &pfp->pool[i], i + 1, - pfp->listen_fd_size, - pfp->listen_fds, - pfp->private_data); - exit(ret); - - default: /* THE PARENT */ - pfp->pool[i].pid = pid; - break; - } - } - - ok = prefork_setup_sigchld_handler(ev_ctx, pfp); - if (!ok) { - DEBUG(1, ("Failed to setup SIGCHLD Handler!\n")); - goto fail; - } - - *pf_pool = pfp; - return true; -fail: - TALLOC_FREE(pfp); - return false; -} - -/* Provide the new max children number in new_max - * (must be larger than current max). - * Returns: 0 if all fine - * ENOSPC if mremap fails to expand - * EINVAL if new_max is invalid - */ -int prefork_expand_pool(struct prefork_pool *pfp, int new_max) -{ - struct prefork_pool *pool = NULL; - size_t old_size; - size_t new_size; - int ret; - - if (new_max <= pfp->pool_size) { - return EINVAL; - } - - old_size = sizeof(struct pf_worker_data) * pfp->pool_size; - new_size = sizeof(struct pf_worker_data) * new_max; - - pool = (struct prefork_pool *)anonymous_shared_resize( - &pfp->pool, new_size, false); - if (pool == NULL) { - ret = errno; - DEBUG(3, ("Failed to mremap memory (%d: %s)!\n", - ret, strerror(ret))); - return ret; - } - - memset(&pool[pfp->pool_size], 0, new_size - old_size); - - pfp->pool_size = new_max; - - return 0; -} - -int prefork_add_children(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct prefork_pool *pfp, - int num_children) -{ - pid_t pid; - time_t now = time(NULL); - int ret; - int i, j; - - for (i = 0, j = 0; i < pfp->pool_size && j < num_children; i++) { - - if (pfp->pool[i].status != PF_WORKER_NONE) { - continue; - } - - pfp->pool[i].allowed_clients = 1; - pfp->pool[i].started = now; - - pid = fork(); - switch (pid) { - case -1: - DEBUG(1, ("Failed to prefork child n. %d !\n", j)); - break; - - case 0: /* THE CHILD */ - - pfp->pool[i].status = PF_WORKER_ALIVE; - ret = pfp->main_fn(ev_ctx, msg_ctx, - &pfp->pool[i], i + 1, - pfp->listen_fd_size, - pfp->listen_fds, - pfp->private_data); - - pfp->pool[i].status = PF_WORKER_EXITING; - exit(ret); - - default: /* THE PARENT */ - pfp->pool[i].pid = pid; - j++; - break; - } - } - - DEBUG(5, ("Added %d children!\n", j)); - - return j; -} - -struct prefork_oldest { - int num; - time_t started; -}; - -/* sort in inverse order */ -static int prefork_sort_oldest(const void *ap, const void *bp) -{ - const struct prefork_oldest *a = (const struct prefork_oldest *)ap; - const struct prefork_oldest *b = (const struct prefork_oldest *)bp; - - if (a->started == b->started) { - return 0; - } - if (a->started < b->started) { - return 1; - } - return -1; -} - -int prefork_retire_children(struct messaging_context *msg_ctx, - struct prefork_pool *pfp, - int num_children, time_t age_limit) -{ - const DATA_BLOB ping = data_blob_null; - time_t now = time(NULL); - struct prefork_oldest *oldest = NULL; - int i, j; - - oldest = talloc_array(pfp, struct prefork_oldest, pfp->pool_size); - if (!oldest) { - return -1; - } - - for (i = 0; i < pfp->pool_size; i++) { - oldest[i].num = i; - if (pfp->pool[i].status == PF_WORKER_ALIVE || - pfp->pool[i].status == PF_WORKER_ACCEPTING) { - oldest[i].started = pfp->pool[i].started; - } else { - oldest[i].started = now; - } - } - - qsort(oldest, pfp->pool_size, - sizeof(struct prefork_oldest), - prefork_sort_oldest); - - for (i = 0, j = 0; i < pfp->pool_size && j < num_children; i++) { - if (((pfp->pool[i].status == PF_WORKER_ALIVE) && - (pfp->pool[i].num_clients < 1)) && - (pfp->pool[i].started <= age_limit)) { - /* tell the child it's time to give up */ - DEBUG(5, ("Retiring pid %u!\n", (unsigned int)pfp->pool[i].pid)); - pfp->pool[i].cmds = PF_SRV_MSG_EXIT; - messaging_send(msg_ctx, - pid_to_procid(pfp->pool[i].pid), - MSG_PREFORK_PARENT_EVENT, &ping); - j++; - } - } - - return j; -} - -int prefork_count_children(struct prefork_pool *pfp, int *active) -{ - int i, a, t; - - a = 0; - t = 0; - for (i = 0; i < pfp->pool_size; i++) { - if (pfp->pool[i].status == PF_WORKER_NONE) { - continue; - } - - t++; - - if ((pfp->pool[i].status == PF_WORKER_EXITING) || - (pfp->pool[i].num_clients <= 0)) { - continue; - } - - a++; - } - - if (active) { - *active = a; - } - return t; -} - -static void prefork_cleanup_loop(struct prefork_pool *pfp) -{ - int status; - pid_t pid; - int i; - - /* TODO: should we use a process group id wait instead of looping ? */ - for (i = 0; i < pfp->pool_size; i++) { - if (pfp->pool[i].status == PF_WORKER_NONE || - pfp->pool[i].pid == 0) { - continue; - } - - pid = waitpid(pfp->pool[i].pid, &status, WNOHANG); - if (pid > 0) { - - if (pfp->pool[i].status != PF_WORKER_EXITING) { - DEBUG(3, ("Child (%d) terminated abnormally:" - " %d\n", (int)pid, status)); - } else { - DEBUG(10, ("Child (%d) terminated with status:" - " %d\n", (int)pid, status)); - } - - /* reset all fields, - * this makes status = PF_WORK_NONE */ - memset(&pfp->pool[i], 0, - sizeof(struct pf_worker_data)); - } - } - -} - -int prefork_count_allowed_connections(struct prefork_pool *pfp) -{ - int c; - int i; - - c = 0; - for (i = 0; i < pfp->pool_size; i++) { - if (pfp->pool[i].status == PF_WORKER_NONE || - pfp->pool[i].status == PF_WORKER_EXITING) { - continue; - } - - if (pfp->pool[i].num_clients < 0) { - continue; - } - - c += pfp->pool[i].allowed_clients - pfp->pool[i].num_clients; - } - - return c; -} - -void prefork_increase_allowed_clients(struct prefork_pool *pfp, int max) -{ - int i; - - for (i = 0; i < pfp->pool_size; i++) { - if (pfp->pool[i].status == PF_WORKER_NONE || - pfp->pool[i].status == PF_WORKER_EXITING) { - continue; - } - - if (pfp->pool[i].num_clients < 0) { - continue; - } - - if (pfp->pool[i].allowed_clients < max) { - pfp->pool[i].allowed_clients++; - } - } -} - -void prefork_decrease_allowed_clients(struct prefork_pool *pfp) -{ - int i; - - for (i = 0; i < pfp->pool_size; i++) { - if (pfp->pool[i].status == PF_WORKER_NONE || - pfp->pool[i].status == PF_WORKER_EXITING) { - continue; - } - - if (pfp->pool[i].num_clients < 0) { - continue; - } - - if (pfp->pool[i].allowed_clients > 1) { - pfp->pool[i].allowed_clients--; - } - } -} - -void prefork_reset_allowed_clients(struct prefork_pool *pfp) -{ - int i; - - for (i = 0; i < pfp->pool_size; i++) { - pfp->pool[i].allowed_clients = 1; - } -} - -void prefork_send_signal_to_all(struct prefork_pool *pfp, int signal_num) -{ - int i; - - for (i = 0; i < pfp->pool_size; i++) { - if (pfp->pool[i].status == PF_WORKER_NONE) { - continue; - } - - kill(pfp->pool[i].pid, signal_num); - } -} - -void prefork_warn_active_children(struct messaging_context *msg_ctx, - struct prefork_pool *pfp) -{ - const DATA_BLOB ping = data_blob_null; - int i; - - for (i = 0; i < pfp->pool_size; i++) { - if (pfp->pool[i].status == PF_WORKER_NONE) { - continue; - } - - messaging_send(msg_ctx, - pid_to_procid(pfp->pool[i].pid), - MSG_PREFORK_PARENT_EVENT, &ping); - } -} - -static void prefork_sigchld_handler(struct tevent_context *ev_ctx, - struct tevent_signal *se, - int signum, int count, - void *siginfo, void *pvt) -{ - struct prefork_pool *pfp = talloc_get_type_abort( - pvt, struct prefork_pool); - - /* run the cleanup function to make sure all dead children are - * properly and timely retired. */ - prefork_cleanup_loop(pfp); - - if (pfp->sigchld_fn) { - pfp->sigchld_fn(ev_ctx, pfp, pfp->sigchld_data); - } -} - -static bool prefork_setup_sigchld_handler(struct tevent_context *ev_ctx, - struct prefork_pool *pfp) -{ - struct tevent_signal *se = NULL; - - se = tevent_add_signal(ev_ctx, pfp, SIGCHLD, 0, - prefork_sigchld_handler, pfp); - if (!se) { - DEBUG(0, ("Failed to setup SIGCHLD handler!\n")); - return false; - } - - return true; -} - -void prefork_set_sigchld_callback(struct prefork_pool *pfp, - prefork_sigchld_fn_t *sigchld_fn, - void *private_data) -{ - pfp->sigchld_fn = sigchld_fn; - pfp->sigchld_data = private_data; -} - -/* ==== Functions used by children ==== */ - -struct pf_listen_state { - struct tevent_context *ev; - struct pf_worker_data *pf; - - int listen_fd_size; - struct pf_listen_fd *listen_fds; - - struct pf_listen_fd accept; - - struct tsocket_address *srv_addr; - struct tsocket_address *cli_addr; - - int error; -}; - -struct pf_listen_ctx { - TALLOC_CTX *fde_ctx; - struct tevent_req *req; - int listen_fd; - void *listen_fd_data; -}; - -static void prefork_listen_accept_handler(struct tevent_context *ev, - struct tevent_fd *fde, - uint16_t flags, void *pvt); - -struct tevent_req *prefork_listen_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct pf_worker_data *pf, - int listen_fd_size, - struct pf_listen_fd *listen_fds) -{ - struct tevent_req *req = NULL; - struct pf_listen_state *state = NULL; - struct pf_listen_ctx *ctx = NULL; - struct tevent_fd *fde = NULL; - TALLOC_CTX *fde_ctx = NULL; - int i; - - req = tevent_req_create(mem_ctx, &state, struct pf_listen_state); - if (!req) { - return NULL; - } - - state->ev = ev; - state->pf = pf; - state->listen_fd_size = listen_fd_size; - state->listen_fds = listen_fds; - state->accept.fd = -1; - state->accept.fd_data = NULL; - state->error = 0; - - fde_ctx = talloc_new(state); - if (tevent_req_nomem(fde_ctx, req)) { - return tevent_req_post(req, ev); - } - - /* race on accept */ - for (i = 0; i < state->listen_fd_size; i++) { - ctx = talloc(fde_ctx, struct pf_listen_ctx); - if (tevent_req_nomem(ctx, req)) { - return tevent_req_post(req, ev); - } - ctx->fde_ctx = fde_ctx; - ctx->req = req; - ctx->listen_fd = state->listen_fds[i].fd; - ctx->listen_fd_data = state->listen_fds[i].fd_data; - - fde = tevent_add_fd(state->ev, fde_ctx, - ctx->listen_fd, TEVENT_FD_READ, - prefork_listen_accept_handler, ctx); - if (tevent_req_nomem(fde, req)) { - return tevent_req_post(req, ev); - } - } - - pf->status = PF_WORKER_ACCEPTING; - - return req; -} - -static void prefork_listen_accept_handler(struct tevent_context *ev, - struct tevent_fd *fde, - uint16_t flags, void *pvt) -{ - struct pf_listen_ctx *ctx = talloc_get_type_abort( - pvt, struct pf_listen_ctx); - struct tevent_req *req = ctx->req; - struct pf_listen_state *state = tevent_req_data( - ctx->req, struct pf_listen_state); - struct sockaddr_storage addr = { .ss_family = 0 }; - socklen_t addrlen = sizeof(addr); - int soerr = 0; - socklen_t solen = sizeof(soerr); - int sd = -1; - int ret; - - if ((state->pf->cmds == PF_SRV_MSG_EXIT) && - (state->pf->num_clients <= 0)) { - /* We have been asked to exit, so drop here and the next - * child will pick it up */ - state->pf->status = PF_WORKER_EXITING; - state->error = EINTR; - goto done; - } - - /* before proceeding check that the listening fd is ok */ - ret = getsockopt(ctx->listen_fd, SOL_SOCKET, SO_ERROR, &soerr, &solen); - if (ret == -1) { - /* this is a fatal error, we cannot continue listening */ - state->error = EBADF; - goto done; - } - if (soerr != 0) { - /* this is a fatal error, we cannot continue listening */ - state->error = soerr; - goto done; - } - - sd = accept(ctx->listen_fd, (struct sockaddr *)&addr, &addrlen); - if (sd == -1) { - state->error = errno; - DEBUG(6, ("Accept failed! (%d, %s)\n", - state->error, strerror(state->error))); - goto done; - } - smb_set_close_on_exec(sd); - - state->accept.fd = sd; - state->accept.fd_data = ctx->listen_fd_data; - - ret = tsocket_address_bsd_from_sockaddr(state, - (struct sockaddr *)(void *)&addr, - addrlen, &state->cli_addr); - if (ret < 0) { - state->error = errno; - goto done; - } - - ZERO_STRUCT(addr); - addrlen = sizeof(addr); - ret = getsockname(sd, (struct sockaddr *)(void *)&addr, &addrlen); - if (ret < 0) { - state->error = errno; - goto done; - } - - ret = tsocket_address_bsd_from_sockaddr(state, - (struct sockaddr *)(void *)&addr, - addrlen, &state->srv_addr); - if (ret < 0) { - state->error = errno; - goto done; - } - -done: - /* do not track the listen fds anymore */ - talloc_free(ctx->fde_ctx); - tevent_req_done(req); -} - -int prefork_listen_recv(struct tevent_req *req, - TALLOC_CTX *mem_ctx, int *fd, - void **fd_data, - struct tsocket_address **srv_addr, - struct tsocket_address **cli_addr) -{ - struct pf_listen_state *state = tevent_req_data( - req, struct pf_listen_state); - int ret = 0; - - if (state->error) { - ret = state->error; - } else { - if (!tevent_req_is_unix_error(req, &ret)) { - ret = 0; - } - } - - if (ret) { - if (state->accept.fd != -1) { - close(state->accept.fd); - } - } else { - *fd = state->accept.fd; - if (fd_data != NULL) { - *fd_data = state->accept.fd_data; - } - *srv_addr = talloc_move(mem_ctx, &state->srv_addr); - *cli_addr = talloc_move(mem_ctx, &state->cli_addr); - state->pf->num_clients++; - } - if (state->pf->status == PF_WORKER_ACCEPTING) { - state->pf->status = PF_WORKER_ALIVE; - } - - tevent_req_received(req); - return ret; -} diff --git a/source3/lib/server_prefork.h b/source3/lib/server_prefork.h deleted file mode 100644 index 106ffdb3729..00000000000 --- a/source3/lib/server_prefork.h +++ /dev/null @@ -1,312 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Common server globals - - Copyright (C) Simo Sorce 2011 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef _SOURCE3_LIB_SERVER_PREFORK_H_ -#define _SOURCE3_LIB_SERVER_PREFORK_H_ - -#include "system/network.h" -#include -#include "lib/tsocket/tsocket.h" - -struct prefork_pool; - -enum pf_worker_status { - PF_WORKER_NONE = 0, - PF_WORKER_ALIVE, - PF_WORKER_ACCEPTING, - PF_WORKER_EXITING -}; - -enum pf_server_cmds { - PF_SRV_MSG_NONE = 0, - PF_SRV_MSG_EXIT -}; - -/** - * @brief This structure contains a socket listening for clients and a - * private pointer with any data associated to that particular - * socket. - */ -struct pf_listen_fd { - /* The socket to listen on */ - int fd; - - /* The socket associated data */ - void *fd_data; -}; - -/** -* @brief This structure is shared between the controlling parent and the -* the child. The parent can only write to the 'cmds' and -* 'allowed_clients' variables, while a child is running. -* The child can change 'status', and 'num_clients'. -* All other variables are initialized by the parent before forking the -* child. -*/ -struct pf_worker_data { - pid_t pid; - enum pf_worker_status status; - time_t started; - time_t last_used; - int num_clients; - - enum pf_server_cmds cmds; - int allowed_clients; -}; - -/** -* @brief This is the 'main' function called by a child right after the fork. -* It is daemon specific and should initialize and perform whatever -* operation the child is meant to do. Returning from this function will -* cause the termination of the child. -* -* @param ev The event context -* @param msg_ctx The messaging context -* @param pf The mmaped area used to communicate with parent -* @param listen_fd_size The number of file descriptors to monitor -* @param listen_fds The array of file descriptors -* @param private_data Private data that needs to be passed to the main -* function from the calling parent. -* -* @return Returns the exit status to be reported to the parent via exit() -*/ -typedef int (prefork_main_fn_t)(struct tevent_context *ev, - struct messaging_context *msg_ctx, - struct pf_worker_data *pf, - int child_id, - int listen_fd_size, - struct pf_listen_fd *pf_listen_fds, - void *private_data); - -/** -* @brief Callback function for parents that also want to be called on sigchld -* -* @param ev_ctx The event context -* @param pool The pool handler -* @param private_data Data private to the parent -*/ -typedef void (prefork_sigchld_fn_t)(struct tevent_context *ev_ctx, - struct prefork_pool *pool, - void *private_data); - -/* ==== Functions used by controlling process ==== */ - -/** -* @brief Creates the first pool of preforked processes -* -* @param mem_ctx The memory context used to hold the pool structure -* @param ev_ctx The event context -* @param msg_ctx The messaging context -* @param listen_fd_size The number of file descriptors to monitor -* @param listen_fds The array of file descriptors to monitor -* @param min_children Minimum number of children that must be available at -* any given time -* @param max_children Maximum number of children that can be started. Also -* determines the initial size of the pool. -* @param main_fn The children 'main' function to be called after fork -* @param private_data The children private data. -* @param pf_pool The allocated pool. -* -* @return True if it was successful, False otherwise. -* -* NOTE: each listen_fd is forced to non-blocking mode once handed over. -* You should not touch listen_fds once you hand them to the prefork library. -*/ -bool prefork_create_pool(TALLOC_CTX *mem_ctx, - struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - int listen_fd_size, struct pf_listen_fd *listen_fds, - int min_children, int max_children, - prefork_main_fn_t *main_fn, void *private_data, - struct prefork_pool **pf_pool); -/** -* @brief Function used to attempt to expand the size of children. -* -* @param pfp The pool structure. -* @param new_max The new max number of children. -* -* @return 0 if operation was successful -* ENOSPC if the mmap area could not be grown to the requested size -* EINVAL if the new max is invalid. -* -* NOTE: this function can easily fail if the mmap area cannot be enlarged. -* A well behaving parent MUST NOT error out if this happen. -*/ -int prefork_expand_pool(struct prefork_pool *pfp, int new_max); - -/** -* @brief Used to prefork a number of new children -* -* @param ev_ctx The event context -* @param msg_ctx The messaging context -* @param pfp The pool structure -* @param num_children The number of children to be started -* -* @return The number of new children effectively forked. -* -* NOTE: This method does not expand the pool, if the max number of children -* has already been forked it will do nothing. -*/ -int prefork_add_children(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct prefork_pool *pfp, - int num_children); -/** -* @brief Commands a number of children to stop and exit -* -* @param msg_ctx The messaging context. -* @param pfp The pool. -* @param num_children The number of children we need to retire. -* @param age_limit The minimum age a child has been active to be -* considered for retirement. (Compared against the -* 'started' value in the pf_worker_data structure of the -* children. -* -* @return Number of children that were signaled to stop -* -* NOTE: Only children that have no attached clients can be stopped. -* If all the available children are too young or are busy then it -* is possible that none will be asked to stop. -*/ -int prefork_retire_children(struct messaging_context *msg_ctx, - struct prefork_pool *pfp, - int num_children, time_t age_limit); -/** -* @brief Count the number of children -* -* @param pfp The pool. -* @param active Number of children currently active if not NULL -* -* @return The total number of children. -*/ -int prefork_count_children(struct prefork_pool *pfp, int *active); - -/** -* @brief Count the number of actual connections currently allowed -* -* @param pfp The pool. -* -* @return The number of connections that can still be opened by clients -* with the current pool of children. -*/ -int prefork_count_allowed_connections(struct prefork_pool *pfp); - -/** -* @brief Increase the amount of clients each child is allowed to handle -* simultaneaously. It will allow each child to handle more than -* one client at a time, up to 'max' (currently set to 100). -* -* @param pfp The pool. -* @param max Max number of allowed connections per child -*/ -void prefork_increase_allowed_clients(struct prefork_pool *pfp, int max); - -/** -* @brief Decrease the amount of clients each child is allowed to handle. -* Min is 1. -* -* @param pfp The pool. -*/ -void prefork_decrease_allowed_clients(struct prefork_pool *pfp); - -/** -* @brief Reset the maximum allowed clients per child to 1. -* Does not reduce the number of clients actually beeing served by -* any given child, but prevents children from overcommitting from -* now on. -* -* @param pfp The pool. -*/ -void prefork_reset_allowed_clients(struct prefork_pool *pfp); - -/** -* @brief Send a specific signal to all children. -* Used to send SIGHUP when a reload of the configuration is needed -* for example. -* -* @param pfp The pool. -* @param signal_num The signal number to be sent. -*/ -void prefork_send_signal_to_all(struct prefork_pool *pfp, int signal_num); - -/** -* @brief Send a message to all children that the server changed something -* in the pool and they may want to take action. -* -* @param msg_ctx The messaging context. -* @param pfp The pool. -*/ -void prefork_warn_active_children(struct messaging_context *msg_ctx, - struct prefork_pool *pfp); - -/** -* @brief Sets the SIGCHLD callback -* -* @param pfp The pool handler. -* @param sigchld_fn The callback function (pass NULL to unset). -* @param private_data Private data for the callback function. -*/ -void prefork_set_sigchld_callback(struct prefork_pool *pfp, - prefork_sigchld_fn_t *sigchld_fn, - void *private_data); - -/* ==== Functions used by children ==== */ - -/** -* @brief Try to listen and accept on one of the listening sockets. -* Asynchronously tries to grab the lock and perform an accept. -* Will automatically update the 'status' of the child and handle -* all the locking/unlocking/timingout as necessary. -* Changes behavior depending on whether the child already has other -* client connections. If not it blocks on the lock call for periods of -* time. Otherwise it loops on the lock using a timer in order to allow -* processing of the other clients requests. -* -* @param mem_ctx The memory context on whic to allocate the request -* @param ev The event context -* @param pf The child/parent shared structure -* @param listen_fd_size The number of listening file descriptors -* @param listen_fds The array of listening file descriptors -* -* @return The tevent request pointer or NULL on allocation errors. -*/ -struct tevent_req *prefork_listen_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct pf_worker_data *pf, - int listen_fd_size, - struct pf_listen_fd *listen_fds); -/** -* @brief Returns the file descriptor after the new client connection has -* been accepted. -* -* @param req The request -* @param mem_ctx The memory context for cli_addr and srv_addr -* @param fd The new file descriptor. -* @param srv_addr The server address in tsocket_address format -* @param cli_addr The client address in tsocket_address format -* -* @return The error in case the operation failed. -*/ -int prefork_listen_recv(struct tevent_req *req, - TALLOC_CTX *mem_ctx, int *fd, void **fd_data, - struct tsocket_address **srv_addr, - struct tsocket_address **cli_addr); - -#endif /* _SOURCE3_LIB_SERVER_PREFORK_H_ */ diff --git a/source3/lib/server_prefork_util.c b/source3/lib/server_prefork_util.c deleted file mode 100644 index c5954a14a1d..00000000000 --- a/source3/lib/server_prefork_util.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Prefork Helpers - Copyright (C) Simo Sorce 2011 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "lib/server_prefork.h" -#include "lib/server_prefork_util.h" - -void pfh_daemon_config(const char *daemon_name, - struct pf_daemon_config *cfg, - const struct pf_daemon_config *default_cfg) -{ - int min, max, rate, allow, life; - - min = lp_parm_int(GLOBAL_SECTION_SNUM, - daemon_name, - "prefork_min_children", - default_cfg->min_children); - max = lp_parm_int(GLOBAL_SECTION_SNUM, - daemon_name, - "prefork_max_children", - default_cfg->max_children); - rate = lp_parm_int(GLOBAL_SECTION_SNUM, - daemon_name, - "prefork_spawn_rate", - default_cfg->spawn_rate); - allow = lp_parm_int(GLOBAL_SECTION_SNUM, - daemon_name, - "prefork_max_allowed_clients", - default_cfg->max_allowed_clients); - life = lp_parm_int(GLOBAL_SECTION_SNUM, - daemon_name, - "prefork_child_min_life", - default_cfg->child_min_life); - - if (max > cfg->max_children && cfg->max_children != 0) { - cfg->prefork_status |= PFH_NEW_MAX; - } - - cfg->min_children = min; - cfg->max_children = max; - cfg->spawn_rate = rate; - cfg->max_allowed_clients = allow; - cfg->child_min_life = life; -} - -void pfh_manage_pool(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct pf_daemon_config *cfg, - struct prefork_pool *pool) -{ - time_t now = time(NULL); - int total, avail; - int ret, n; - bool msg = false; - - if ((cfg->prefork_status & PFH_NEW_MAX) && - !(cfg->prefork_status & PFH_ENOSPC)) { - ret = prefork_expand_pool(pool, cfg->max_children); - if (ret == ENOSPC) { - cfg->prefork_status |= PFH_ENOSPC; - } - cfg->prefork_status &= ~PFH_NEW_MAX; - } - - total = prefork_count_children(pool, NULL); - avail = prefork_count_allowed_connections(pool); - DEBUG(10, ("(Pre)Stats: children: %d, allowed connections: %d\n", - total, avail)); - - if ((total < cfg->max_children) && (avail < cfg->spawn_rate)) { - n = prefork_add_children(ev_ctx, msg_ctx, - pool, cfg->spawn_rate); - if (n < cfg->spawn_rate) { - DEBUG(10, ("Attempted to add %d children but only " - "%d were actually added!\n", - cfg->spawn_rate, n)); - } - } else if ((avail - cfg->min_children) >= cfg->spawn_rate) { - /* be a little slower in retiring children, to allow for - * double spikes of traffic to be handled more gracefully */ - n = (cfg->spawn_rate / 2) + 1; - if (n > cfg->spawn_rate) { - n = cfg->spawn_rate; - } - if ((total - n) < cfg->min_children) { - n = total - cfg->min_children; - } - if (n >= 0) { - prefork_retire_children(msg_ctx, pool, n, - now - cfg->child_min_life); - } - } - - /* total/avail may have just been changed in the above if/else */ - total = prefork_count_children(pool, NULL); - avail = prefork_count_allowed_connections(pool); - if ((total == cfg->max_children) && (avail < cfg->spawn_rate)) { - n = avail; - while (avail < cfg->spawn_rate) { - prefork_increase_allowed_clients(pool, - cfg->max_allowed_clients); - avail = prefork_count_allowed_connections(pool); - /* if avail didn't change do not loop forever */ - if (n == avail) break; - n = avail; - } - msg = true; - } else if (avail > total + cfg->spawn_rate) { - n = avail; - while (avail > total + cfg->spawn_rate) { - prefork_decrease_allowed_clients(pool); - avail = prefork_count_allowed_connections(pool); - /* if avail didn't change do not loop forever */ - if (n == avail) break; - n = avail; - } - } - - /* send message to all children when we change maximum allowed - * connections, so that they can decide to start again to listen to - * sockets if they were already topping the number of allowed - * clients. Useful only when we increase allowed clients */ - if (msg) { - prefork_warn_active_children(msg_ctx, pool); - } - - DEBUG(10, ("Stats: children: %d, allowed connections: %d\n", - prefork_count_children(pool, NULL), - prefork_count_allowed_connections(pool))); -} - -void pfh_client_terminated(struct pf_worker_data *pf) -{ - if (pf->num_clients >= 0) { - pf->num_clients--; - } else { - if (pf->status != PF_WORKER_EXITING) { - DEBUG(1, ("Invalid num clients, stopping!\n")); - } - pf->status = PF_WORKER_EXITING; - pf->num_clients = -1; - } -} - -bool pfh_child_allowed_to_accept(struct pf_worker_data *pf) -{ - if (pf->status == PF_WORKER_EXITING || - pf->status == PF_WORKER_ACCEPTING) { - return false; - } - - return (pf->num_clients < pf->allowed_clients); -} diff --git a/source3/lib/server_prefork_util.h b/source3/lib/server_prefork_util.h deleted file mode 100644 index 22297120353..00000000000 --- a/source3/lib/server_prefork_util.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Prefork Helpers. - - Copyright (C) Simo Sorce 2011 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef _SERVER_PREFORK_UTIL_H_ -#define _SERVER_PREFORK_UTIL_H_ - -struct tevent_context; -struct messaging_context; - -#define PFH_INIT 0x00 -#define PFH_NEW_MAX 0x01 -#define PFH_ENOSPC 0x02 - -struct pf_daemon_config { - int prefork_status; - int min_children; - int max_children; - int spawn_rate; - int max_allowed_clients; - int child_min_life; -}; - -void pfh_daemon_config(const char *daemon_name, - struct pf_daemon_config *cfg, - const struct pf_daemon_config *default_cfg); - -void pfh_manage_pool(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct pf_daemon_config *cfg, - struct prefork_pool *pool); - -void pfh_client_terminated(struct pf_worker_data *pf); -bool pfh_child_allowed_to_accept(struct pf_worker_data *pf); - -#endif /* _SERVER_PREFORK_UTIL_H_ */ diff --git a/source3/librpc/rpc/dcerpc_ep.c b/source3/librpc/rpc/dcerpc_ep.c deleted file mode 100644 index 66b8b975d75..00000000000 --- a/source3/librpc/rpc/dcerpc_ep.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Endpoint Mapper Functions - * DCERPC local endpoint mapper client routines - * Copyright (c) 2010-2011 Andreas Schneider. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include "includes.h" -#include "librpc/rpc/dcerpc.h" -#include "librpc/rpc/dcerpc_ep.h" -#include "../librpc/gen_ndr/ndr_epmapper_c.h" -#include "rpc_client/cli_pipe.h" -#include "auth.h" -#include "rpc_server/rpc_ncacn_np.h" -#include "../lib/tsocket/tsocket.h" - -#include "librpc/rpc/dcesrv_core.h" -#include "rpc_server/rpc_config.h" - -#define EPM_MAX_ANNOTATION_SIZE 64 - -static NTSTATUS ep_register(TALLOC_CTX *mem_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - const struct dcesrv_interface *iface, - const struct GUID *object_guid, - const char *annotation, - uint32_t replace, - uint32_t unregister, - struct dcerpc_binding_handle **pbh) -{ - struct rpc_pipe_client *cli = NULL; - struct dcerpc_binding_handle *h; - struct pipe_auth_data *auth; - enum rpc_service_mode_e epmd_mode; - struct epm_entry_t *entries = NULL; - uint32_t i = 0; - TALLOC_CTX *tmp_ctx; - uint32_t result = EPMAPPER_STATUS_OK; - NTSTATUS status; - struct dcesrv_endpoint *ep; - bool found = false; - - if (iface == NULL) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (dce_ctx == NULL || iface == NULL) { - return NT_STATUS_INVALID_PARAMETER; - } - - /* Check if interface is registered */ - for (ep = dce_ctx->endpoint_list; ep; ep = ep->next) { - struct dcesrv_if_list *ifl; - for (ifl = ep->interface_list; ifl; ifl = ifl->next) { - if (ndr_syntax_id_equal(&ifl->iface->syntax_id, - &iface->syntax_id)) { - found = true; - break; - } - } - if (found) { - break; - } - } - if (!found) { - DBG_ERR("Failed to register interface '%s' in the endpoint " - "mapper as it is not registered in any endpoint\n", - iface->name); - return NT_STATUS_INVALID_PARAMETER; - } - - tmp_ctx = talloc_stackframe(); - - epmd_mode = rpc_epmapper_mode(); - - if (epmd_mode == RPC_SERVICE_MODE_EMBEDDED) { - struct tsocket_address *local; - int rc; - - rc = tsocket_address_inet_from_strings(tmp_ctx, - "ip", - "127.0.0.1", - 0, - &local); - if (rc < 0) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - - status = rpcint_binding_handle(tmp_ctx, - &ndr_table_epmapper, - local, - NULL, - get_session_info_system(), - msg_ctx, - &h); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("dcerpc_ep_register: Could not connect to " - "epmapper (%s)", nt_errstr(status))); - goto done; - } - } else if (epmd_mode == RPC_SERVICE_MODE_EXTERNAL) { - /* Connect to the endpoint mapper locally */ - status = rpc_pipe_open_ncalrpc(tmp_ctx, - &ndr_table_epmapper, - &cli); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = rpccli_ncalrpc_bind_data(cli, &auth); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Failed to initialize anonymous bind.\n")); - goto done; - } - - status = rpc_pipe_bind(cli, auth); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("Failed to bind ncalrpc socket.\n")); - goto done; - } - - h = cli->binding_handle; - } else { - status = NT_STATUS_INVALID_PARAMETER; - goto done; - } - - for (i = 0, ep = dce_ctx->endpoint_list; ep; i++, ep = ep->next) { - struct dcerpc_binding *map_binding; - struct epm_twr_t *map_tower; - struct dcesrv_if_list *ifl; - - for (ifl = ep->interface_list; ifl; ifl = ifl->next) { - if (!ndr_syntax_id_equal(&ifl->iface->syntax_id, - &iface->syntax_id)) { - continue; - } - } - - /* The interface is registered in this endpoint, add it */ - entries = talloc_realloc(tmp_ctx, entries, struct epm_entry_t, - i + 1); - if (entries == NULL) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - - map_binding = dcerpc_binding_dup(entries, ep->ep_description); - if (map_binding == NULL) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - - status = dcerpc_binding_set_abstract_syntax(map_binding, - &iface->syntax_id); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - map_tower = talloc_zero(entries, struct epm_twr_t); - if (map_tower == NULL) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - - status = dcerpc_binding_build_tower(entries, - map_binding, - &map_tower->tower); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - TALLOC_FREE(map_binding); - - entries[i].tower = map_tower; - if (annotation == NULL) { - entries[i].annotation = talloc_strdup(entries, ""); - } else { - entries[i].annotation = talloc_strndup(entries, - annotation, - EPM_MAX_ANNOTATION_SIZE); - } - if (entries[i].annotation == NULL) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - - if (object_guid != NULL) { - entries[i].object = *object_guid; - } else { - ZERO_STRUCT(entries[i].object); - } - } - - if (unregister) { - status = dcerpc_epm_Delete(h, - tmp_ctx, - i, - entries, - &result); - } else { - status = dcerpc_epm_Insert(h, - tmp_ctx, - i, - entries, - replace, - &result); - } - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("dcerpc_ep_register: Could not insert tower (%s)\n", - nt_errstr(status))); - goto done; - } - if (result != EPMAPPER_STATUS_OK) { - DEBUG(0, ("dcerpc_ep_register: Could not insert tower (0x%.8x)\n", - result)); - status = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (pbh != NULL) { - talloc_steal(h, cli); - *pbh = talloc_move(mem_ctx, &h); - } - -done: - talloc_free(tmp_ctx); - - return status; -} - -NTSTATUS dcerpc_ep_register(TALLOC_CTX *mem_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - const struct dcesrv_interface *iface, - const struct GUID *object_guid, - const char *annotation, - struct dcerpc_binding_handle **ph) -{ - return ep_register(mem_ctx, - msg_ctx, - dce_ctx, - iface, - object_guid, - annotation, - 1, - 0, - ph); -} - -NTSTATUS dcerpc_ep_register_noreplace(TALLOC_CTX *mem_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - const struct dcesrv_interface *iface, - const struct GUID *object_guid, - const char *annotation, - struct dcerpc_binding_handle **ph) -{ - return ep_register(mem_ctx, - msg_ctx, - dce_ctx, - iface, - object_guid, - annotation, - 0, - 0, - ph); -} - -NTSTATUS dcerpc_ep_unregister(struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - const struct dcesrv_interface *iface, - const struct GUID *object_guid) -{ - return ep_register(NULL, - msg_ctx, - dce_ctx, - iface, - object_guid, - NULL, - 0, - 1, - NULL); -} - -/* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */ diff --git a/source3/librpc/rpc/dcerpc_ep.h b/source3/librpc/rpc/dcerpc_ep.h deleted file mode 100644 index f8437953225..00000000000 --- a/source3/librpc/rpc/dcerpc_ep.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Endpoint Mapper Functions - * DCERPC local endpoint mapper client routines - * Copyright (c) 2010-2011 Andreas Schneider. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef _DCERPC_EP_H_ -#define _DCERPC_EP_H_ - -struct dcesrv_context; -struct dcesrv_interface; - -/** - * @brief Adds server address information in the local endpoint map. - * - * @param[in] mem_ctx The memory context to use for the binding handle. - * - * @param[in] dce_ctx The dcerpc server context - * - * @param[in] iface The interface to register in the endpoint mapper - * - * @param[in] object_guid The object GUID that the server offers. The server - * application constructs this vector. - * - * @param[in] annotation Defines a character string comment applied to the - * element added to the local endpoint map. The string - * can be up to 64 characters long, including the null - * terminating character. Strings longer than 64 - * characters are truncated. The application supplies - * the value NULL or the string "" to indicate an empty - * annotation string. - * - * When replacing elements, the annotation string - * supplied, including an empty annotation string, - * replaces any existing annotation string. - * - * @param[out] ph A pointer to store the binding handle. The memory - * context will be the give one. If you free this handle - * then the connection will be closed. - * - * @return An NTSTATUS error code. - */ -NTSTATUS dcerpc_ep_register(TALLOC_CTX *mem_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - const struct dcesrv_interface *iface, - const struct GUID *object_guid, - const char *annotation, - struct dcerpc_binding_handle **ph); - -NTSTATUS dcerpc_ep_register_noreplace(TALLOC_CTX *mem_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - const struct dcesrv_interface *iface, - const struct GUID *object_guid, - const char *annotation, - struct dcerpc_binding_handle **ph); - -NTSTATUS dcerpc_ep_unregister(struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - const struct dcesrv_interface *iface, - const struct GUID *object_guid); - -#endif /* _DCERPC_EP_H_ */ diff --git a/source3/printing/spoolssd.c b/source3/printing/spoolssd.c deleted file mode 100644 index 6eb1a82627f..00000000000 --- a/source3/printing/spoolssd.c +++ /dev/null @@ -1,822 +0,0 @@ -/* - Unix SMB/Netbios implementation. - SPOOLSS Daemon - Copyright (C) Simo Sorce 2010-2011 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -#include "includes.h" -#include "locking/share_mode_lock.h" -#include "smbd/smbd.h" - -#include "messages.h" -#include "include/printing.h" -#include "printing/nt_printing_migrate_internal.h" -#include "printing/queue_process.h" -#include "printing/pcap.h" -#include "printing/load.h" -#include "printing/spoolssd.h" -#include "ntdomain.h" -#include "librpc/gen_ndr/ndr_winreg_scompat.h" -#include "librpc/gen_ndr/ndr_spoolss_scompat.h" -#include "rpc_server/rpc_server.h" -#include "rpc_server/rpc_service_setup.h" -#include "rpc_server/rpc_ep_register.h" -#include "rpc_server/rpc_config.h" -#include "rpc_server/spoolss/srv_spoolss_nt.h" -#include "librpc/rpc/dcerpc_ep.h" -#include "librpc/rpc/dcesrv_core.h" -#include "lib/server_prefork.h" -#include "lib/server_prefork_util.h" -#include "lib/global_contexts.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -#define DAEMON_NAME "spoolssd" - -static struct server_id parent_id; -static struct prefork_pool *spoolss_pool = NULL; -static int spoolss_child_id = 0; - -static const struct pf_daemon_config default_pf_spoolss_cfg = { - .prefork_status = PFH_INIT, - .min_children = 5, - .max_children = 25, - .spawn_rate = 5, - .max_allowed_clients = 100, - .child_min_life = 60 /* 1 minute minimum life time */ -}; -static struct pf_daemon_config pf_spoolss_cfg = { 0 }; - -static void spoolss_reopen_logs(int child_id) -{ - const struct loadparm_substitution *lp_sub = - loadparm_s3_global_substitution(); - char *lfile = lp_logfile(talloc_tos(), lp_sub); - char *ext; - int rc; - - if (child_id) { - rc = asprintf(&ext, "%s.%d", DAEMON_NAME, child_id); - } else { - rc = asprintf(&ext, "%s", DAEMON_NAME); - } - - if (rc == -1) { - return; - } - - rc = 0; - if (lfile == NULL || lfile[0] == '\0') { - rc = asprintf(&lfile, "%s/log.%s", - get_dyn_LOGFILEBASE(), ext); - } else { - if (strstr(lfile, ext) == NULL) { - if (child_id) { - rc = asprintf(&lfile, "%s.%d", - lp_logfile(talloc_tos(), lp_sub), - child_id); - } else { - rc = asprintf(&lfile, "%s.%s", - lp_logfile(talloc_tos(), lp_sub), - ext); - } - } - } - - if (rc > 0) { - lp_set_logfile(lfile); - SAFE_FREE(lfile); - } - - SAFE_FREE(ext); - - reopen_logs(); -} - -static void update_conf(struct tevent_context *ev, - struct messaging_context *msg) -{ - change_to_root_user(); - lp_load_global(get_dyn_CONFIGFILE()); - load_printers(); - - spoolss_reopen_logs(spoolss_child_id); - if (spoolss_child_id == 0) { - pfh_daemon_config(DAEMON_NAME, - &pf_spoolss_cfg, - &default_pf_spoolss_cfg); - pfh_manage_pool(ev, msg, &pf_spoolss_cfg, spoolss_pool); - } -} - -static void smb_conf_updated(struct messaging_context *msg, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data) -{ - struct tevent_context *ev_ctx = talloc_get_type_abort(private_data, - struct tevent_context); - - DEBUG(10, ("Got message saying smb.conf was updated. Reloading.\n")); - update_conf(ev_ctx, msg); -} - -static void spoolss_sig_term_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *private_data) -{ - exit_server_cleanly("termination signal"); -} - -static void spoolss_setup_sig_term_handler(struct tevent_context *ev_ctx) -{ - struct tevent_signal *se; - - se = tevent_add_signal(ev_ctx, - ev_ctx, - SIGTERM, 0, - spoolss_sig_term_handler, - NULL); - if (!se) { - exit_server("failed to setup SIGTERM handler"); - } -} - -static void spoolss_sig_hup_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *pvt) -{ - struct messaging_context *msg_ctx; - - msg_ctx = talloc_get_type_abort(pvt, struct messaging_context); - - DEBUG(1,("Reloading printers after SIGHUP\n")); - update_conf(ev, msg_ctx); - - /* relay to all children */ - if (spoolss_pool) { - prefork_send_signal_to_all(spoolss_pool, SIGHUP); - } -} - -static void spoolss_setup_sig_hup_handler(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - struct tevent_signal *se; - - se = tevent_add_signal(ev_ctx, - ev_ctx, - SIGHUP, 0, - spoolss_sig_hup_handler, - msg_ctx); - if (!se) { - exit_server("failed to setup SIGHUP handler"); - } -} - -/* Children */ - -static void spoolss_chld_sig_hup_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *pvt) -{ - change_to_root_user(); - DEBUG(1,("Reloading printers after SIGHUP\n")); - load_printers(); - spoolss_reopen_logs(spoolss_child_id); -} - -static bool spoolss_setup_chld_hup_handler(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct pf_worker_data *pf) -{ - struct tevent_signal *se; - - se = tevent_add_signal(ev_ctx, - ev_ctx, - SIGHUP, 0, - spoolss_chld_sig_hup_handler, - msg_ctx); - if (!se) { - DEBUG(1, ("failed to setup SIGHUP handler")); - return false; - } - - return true; -} - -static void parent_ping(struct messaging_context *msg_ctx, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data) -{ - - /* The fact we received this message is enough to let make the event - * loop if it was idle. spoolss_children_main will cycle through - * spoolss_next_client at least once. That function will take whatever - * action is necessary */ - - DEBUG(10, ("Got message that the parent changed status.\n")); - return; -} - -static bool spoolss_child_init(struct tevent_context *ev_ctx, - int child_id, struct pf_worker_data *pf) -{ - NTSTATUS status; - struct messaging_context *msg_ctx = global_messaging_context(); - bool ok; - - status = reinit_after_fork(msg_ctx, ev_ctx, true, "spoolssd-child"); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("reinit_after_fork() failed\n")); - smb_panic("reinit_after_fork() failed"); - } - - spoolss_child_id = child_id; - spoolss_reopen_logs(child_id); - - ok = spoolss_setup_chld_hup_handler(ev_ctx, msg_ctx, pf); - if (!ok) { - return false; - } - - if (!locking_init()) { - return false; - } - - messaging_register(msg_ctx, ev_ctx, - MSG_SMB_CONF_UPDATED, smb_conf_updated); - messaging_register(msg_ctx, ev_ctx, - MSG_PREFORK_PARENT_EVENT, parent_ping); - - /* As soon as messaging is up check if pcap has been loaded already. - * If so then we probably missed a message and should load_printers() - * ourselves. If pcap has not been loaded yet, then ignore, we will get - * a message as soon as the bq process completes the reload. */ - load_printers(); - - return true; -} - -struct spoolss_children_data { - struct tevent_context *ev_ctx; - struct messaging_context *msg_ctx; - struct dcesrv_context *dce_ctx; - struct pf_worker_data *pf; - int listen_fd_size; - struct pf_listen_fd *listen_fds; -}; - -static void spoolss_next_client(void *pvt); - -static int spoolss_children_main(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct pf_worker_data *pf, - int child_id, - int listen_fd_size, - struct pf_listen_fd *listen_fds, - void *private_data) -{ - struct spoolss_children_data *data; - bool ok; - int ret = 0; - struct dcesrv_context *dce_ctx = NULL; - - dce_ctx = talloc_get_type_abort(private_data, struct dcesrv_context); - - ok = spoolss_child_init(ev_ctx, child_id, pf); - if (!ok) { - return 1; - } - - data = talloc(ev_ctx, struct spoolss_children_data); - if (!data) { - return 1; - } - data->pf = pf; - data->ev_ctx = ev_ctx; - data->msg_ctx = msg_ctx; - data->dce_ctx = dce_ctx; - data->listen_fd_size = listen_fd_size; - data->listen_fds = listen_fds; - - /* loop until it is time to exit */ - while (pf->status != PF_WORKER_EXITING) { - /* try to see if it is time to schedule the next client */ - spoolss_next_client(data); - - ret = tevent_loop_once(ev_ctx); - if (ret != 0) { - DEBUG(0, ("tevent_loop_once() exited with %d: %s\n", - ret, strerror(errno))); - pf->status = PF_WORKER_EXITING; - } - } - - return ret; -} - -static void spoolss_client_terminated(struct dcesrv_connection *conn, - void *pvt) -{ - struct spoolss_children_data *data; - - data = talloc_get_type_abort(pvt, struct spoolss_children_data); - - pfh_client_terminated(data->pf); - - spoolss_next_client(pvt); -} - -struct spoolss_new_client { - struct spoolss_children_data *data; -}; - -static void spoolss_handle_client(struct tevent_req *req); - -static void spoolss_next_client(void *pvt) -{ - struct tevent_req *req; - struct spoolss_children_data *data; - struct spoolss_new_client *next; - - data = talloc_get_type_abort(pvt, struct spoolss_children_data); - - if (!pfh_child_allowed_to_accept(data->pf)) { - /* nothing to do for now we are already listening - * or we are not allowed to listen further */ - return; - } - - next = talloc_zero(data, struct spoolss_new_client); - if (!next) { - DEBUG(1, ("Out of memory!?\n")); - return; - } - next->data = data; - - req = prefork_listen_send(next, data->ev_ctx, data->pf, - data->listen_fd_size, - data->listen_fds); - if (!req) { - DEBUG(1, ("Failed to make listening request!?\n")); - talloc_free(next); - return; - } - tevent_req_set_callback(req, spoolss_handle_client, next); -} - -static void spoolss_handle_client(struct tevent_req *req) -{ - struct spoolss_children_data *data; - struct spoolss_new_client *client; - const DATA_BLOB ping = data_blob_null; - int ret; - int sd; - struct tsocket_address *srv_addr = NULL; - struct tsocket_address *cli_addr = NULL; - void *listen_fd_data = NULL; - struct dcesrv_endpoint *ep = NULL; - - client = tevent_req_callback_data(req, struct spoolss_new_client); - data = client->data; - - ret = prefork_listen_recv(req, data, &sd, &listen_fd_data, - &srv_addr, &cli_addr); - - /* this will free the request too */ - talloc_free(client); - - if (ret != 0) { - DEBUG(6, ("No client connection was available after all!\n")); - return; - } - - ep = talloc_get_type_abort(listen_fd_data, struct dcesrv_endpoint); - - /* Warn parent that our status changed */ - messaging_send(data->msg_ctx, parent_id, - MSG_PREFORK_CHILD_EVENT, &ping); - - DEBUG(2, ("Spoolss preforked child %d got client connection!\n", - (int)(data->pf->pid))); - - dcerpc_ncacn_accept(data->ev_ctx, - data->msg_ctx, - data->dce_ctx, - ep, - &cli_addr, - &srv_addr, - sd, - spoolss_client_terminated, - data); -} - -/* ==== Main Process Functions ==== */ - -extern pid_t background_lpq_updater_pid; -static char *bq_logfile; - -static void check_updater_child(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - int status; - pid_t pid; - - if (background_lpq_updater_pid == -1) { - return; - } - - pid = waitpid(background_lpq_updater_pid, &status, WNOHANG); - if (pid > 0) { - DEBUG(2, ("The background queue child died... Restarting!\n")); - pid = start_background_queue(ev_ctx, msg_ctx, bq_logfile); - background_lpq_updater_pid = pid; - } -} - -static void child_ping(struct messaging_context *msg_ctx, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data) -{ - struct tevent_context *ev_ctx; - - ev_ctx = talloc_get_type_abort(private_data, struct tevent_context); - - DEBUG(10, ("Got message that a child changed status.\n")); - pfh_manage_pool(ev_ctx, msg_ctx, &pf_spoolss_cfg, spoolss_pool); -} - -static bool spoolssd_schedule_check(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct timeval current_time); -static void spoolssd_check_children(struct tevent_context *ev_ctx, - struct tevent_timer *te, - struct timeval current_time, - void *pvt); - -static void spoolssd_sigchld_handler(struct tevent_context *ev_ctx, - struct prefork_pool *pfp, - void *pvt) -{ - struct messaging_context *msg_ctx; - - msg_ctx = talloc_get_type_abort(pvt, struct messaging_context); - - /* run pool management so we can fork/retire or increase - * the allowed connections per child based on load */ - pfh_manage_pool(ev_ctx, msg_ctx, &pf_spoolss_cfg, spoolss_pool); - - /* also check if the updater child is alive and well */ - check_updater_child(ev_ctx, msg_ctx); -} - -static bool spoolssd_setup_children_monitor(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - bool ok; - - /* add our oun sigchld callback */ - prefork_set_sigchld_callback(spoolss_pool, - spoolssd_sigchld_handler, msg_ctx); - - ok = spoolssd_schedule_check(ev_ctx, msg_ctx, - tevent_timeval_current()); - return ok; -} - -static bool spoolssd_schedule_check(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct timeval current_time) -{ - struct tevent_timer *te; - struct timeval next_event; - - /* check situation again in 10 seconds */ - next_event = tevent_timeval_current_ofs(10, 0); - - /* TODO: check when the socket becomes readable, so that children - * are checked only when there is some activity ? */ - te = tevent_add_timer(ev_ctx, spoolss_pool, next_event, - spoolssd_check_children, msg_ctx); - if (!te) { - DEBUG(2, ("Failed to set up children monitoring!\n")); - return false; - } - - return true; -} - -static void spoolssd_check_children(struct tevent_context *ev_ctx, - struct tevent_timer *te, - struct timeval current_time, - void *pvt) -{ - struct messaging_context *msg_ctx; - - msg_ctx = talloc_get_type_abort(pvt, struct messaging_context); - - pfh_manage_pool(ev_ctx, msg_ctx, &pf_spoolss_cfg, spoolss_pool); - - spoolssd_schedule_check(ev_ctx, msg_ctx, current_time); -} - -static void print_queue_forward(struct messaging_context *msg, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data) -{ - send_to_bgqd(msg, msg_type, data->data, data->length); -} - -static char *get_bq_logfile(void) -{ - const struct loadparm_substitution *lp_sub = - loadparm_s3_global_substitution(); - char *lfile = lp_logfile(talloc_tos(), lp_sub); - int rc; - - if (lfile == NULL || lfile[0] == '\0') { - rc = asprintf(&lfile, "%s/log.%s.bq", - get_dyn_LOGFILEBASE(), DAEMON_NAME); - } else { - rc = asprintf(&lfile, "%s.bq", lp_logfile(talloc_tos(), lp_sub)); - } - if (rc == -1) { - lfile = NULL; - } - return lfile; -} - -static NTSTATUS spoolssd_create_sockets(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - TALLOC_CTX *mem_ctx, - struct pf_listen_fd **plisten_fds, - size_t *pnum_listen_fds) -{ - NTSTATUS status; - int rc; - enum rpc_service_mode_e epm_mode = rpc_epmapper_mode(); - size_t i, num_fds; - struct pf_listen_fd *fds = NULL; - struct dcesrv_endpoint *e = dce_ctx->endpoint_list; - - DBG_INFO("Initializing DCE/RPC connection endpoints\n"); - - status = dcesrv_create_endpoint_list_pf_listen_fds( - ev_ctx, msg_ctx, dce_ctx, e, mem_ctx, &num_fds, &fds); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - for (i = 0; i < num_fds; i++) { - rc = listen(fds[i].fd, pf_spoolss_cfg.max_allowed_clients); - if (rc == -1) { - char *ep_string = NULL; - e = fds[i].fd_data; - - ep_string = dcerpc_binding_string(dce_ctx, - e->ep_description); - DBG_ERR("Failed to listen on endpoint '%s': %s\n", - ep_string, strerror(errno)); - status = map_nt_error_from_unix(errno); - TALLOC_FREE(ep_string); - goto done; - } - } - - if (epm_mode != RPC_SERVICE_MODE_DISABLED && - (lp_parm_bool(-1, "rpc_server", "register_embedded_np", false))) { - for (e = dce_ctx->endpoint_list; e; e = e->next) { - struct dcesrv_if_list *ifl = NULL; - for (ifl = e->interface_list; ifl; ifl = ifl->next) { - status = rpc_ep_register(ev_ctx, - msg_ctx, - dce_ctx, - ifl->iface); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register interface" - " in endpoint mapper: %s\n", - nt_errstr(status)); - goto done; - } - } - } - } - - *plisten_fds = fds; - *pnum_listen_fds = num_fds; - - status = NT_STATUS_OK; -done: - return status; -} - -pid_t start_spoolssd(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx) -{ - pid_t pid; - NTSTATUS status; - struct pf_listen_fd *listen_fds = NULL; - size_t listen_fds_size = 0; - int ret; - bool ok; - const struct dcesrv_endpoint_server *ep_server = NULL; - const char *ep_servers[] = { "winreg", "spoolss", NULL }; - - DEBUG(1, ("Forking SPOOLSS Daemon\n")); - - /* - * Block signals before forking child as it will have to - * set its own handlers. Child will re-enable SIGHUP as - * soon as the handlers are set up. - */ - BlockSignals(true, SIGTERM); - BlockSignals(true, SIGHUP); - - pid = fork(); - - if (pid == -1) { - DEBUG(0, ("Failed to fork SPOOLSS [%s]\n", - strerror(errno))); - exit(1); - } - - /* parent or error */ - if (pid != 0) { - - /* Re-enable SIGHUP before returnig */ - BlockSignals(false, SIGTERM); - BlockSignals(false, SIGHUP); - return pid; - } - - status = smbd_reinit_after_fork(msg_ctx, ev_ctx, true, - "spoolssd-master"); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("reinit_after_fork() failed\n")); - smb_panic("reinit_after_fork() failed"); - } - - /* save the parent process id so the children can use it later */ - parent_id = messaging_server_id(msg_ctx); - - spoolss_reopen_logs(0); - pfh_daemon_config(DAEMON_NAME, - &pf_spoolss_cfg, - &default_pf_spoolss_cfg); - - spoolss_setup_sig_term_handler(ev_ctx); - spoolss_setup_sig_hup_handler(ev_ctx, msg_ctx); - - BlockSignals(false, SIGTERM); - BlockSignals(false, SIGHUP); - - /* always start the backgroundqueue listner in spoolssd */ - bq_logfile = get_bq_logfile(); - pid = start_background_queue(ev_ctx, msg_ctx, bq_logfile); - if (pid > 0) { - background_lpq_updater_pid = pid; - } - - DBG_INFO("Registering DCE/RPC endpoint servers\n"); - - ep_server = winreg_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'winreg' endpoint server\n"); - exit(1); - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status) && - !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { - DBG_ERR("Failed to register 'winreg' endpoint server: %s\n", - nt_errstr(status)); - exit(1); - } - - ep_server = spoolss_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'spoolss' endpoint server\n"); - exit(1); - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register 'spoolss' endpoint server: %s\n", - nt_errstr(status)); - exit(1); - } - - DBG_INFO("Reinitializing DCE/RPC server context\n"); - - status = dcesrv_reinit_context(dce_ctx); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to reinit DCE/RPC context: %s\n", - nt_errstr(status)); - exit(1); - } - - DBG_INFO("Initializing DCE/RPC registered endpoint servers\n"); - - /* Init ep servers */ - status = dcesrv_init_ep_servers(dce_ctx, ep_servers); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to init DCE/RPC endpoint server: %s\n", - nt_errstr(status)); - exit(1); - } - - /* the listening fd must be created before the children are actually - * forked out. */ - status = spoolssd_create_sockets(ev_ctx, - msg_ctx, - dce_ctx, - dce_ctx, - &listen_fds, - &listen_fds_size); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to create sockets: %s\n", - nt_errstr(status)); - exit(1); - } - - /* start children before any more initialization is done */ - ok = prefork_create_pool(ev_ctx, /* mem_ctx */ - ev_ctx, msg_ctx, - listen_fds_size, listen_fds, - pf_spoolss_cfg.min_children, - pf_spoolss_cfg.max_children, - &spoolss_children_main, dce_ctx, - &spoolss_pool); - TALLOC_FREE(listen_fds); - if (!ok) { - exit(1); - } - - if (!locking_init()) { - exit(1); - } - - messaging_register(msg_ctx, ev_ctx, - MSG_SMB_CONF_UPDATED, smb_conf_updated); - messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE, - print_queue_forward); - messaging_register(msg_ctx, ev_ctx, - MSG_PREFORK_CHILD_EVENT, child_ping); - - /* - * As soon as messaging is up check if pcap has been loaded already. - * If pcap has not been loaded yet, then ignore, as we will reload on - * client enumeration anyway. - */ - load_printers(); - - ok = spoolssd_setup_children_monitor(ev_ctx, msg_ctx); - if (!ok) { - DEBUG(0, ("Failed to setup children monitoring!\n")); - exit(1); - } - - DEBUG(1, ("SPOOLSS Daemon Started (%u)\n", (unsigned int)getpid())); - - pfh_manage_pool(ev_ctx, msg_ctx, &pf_spoolss_cfg, spoolss_pool); - - /* loop forever */ - ret = tevent_loop_wait(ev_ctx); - - /* should not be reached */ - DEBUG(0,("spoolssd tevent_loop_wait() exited with %d - %s\n", - ret, (ret == 0) ? "out of events" : strerror(errno))); - exit(1); -} diff --git a/source3/printing/spoolssd.h b/source3/printing/spoolssd.h deleted file mode 100644 index 6d59b513cb9..00000000000 --- a/source3/printing/spoolssd.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - Unix SMB/Netbios implementation. - SPOOLSS Daemon - Copyright (C) Simo Sorce 2010-2011 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef _SOURCE3_PRINTING_SPOOLSSD_H_ -#define _SOURCE3_PRINTING_SPOOLSSD_H_ - -#include "replace.h" -#include "messages.h" - -struct dcesrv_context; - -pid_t start_spoolssd(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx); - -#endif /* _SOURCE3_PRINTING_SPOOLSSD_H_ */ diff --git a/source3/rpc_server/epmapper/srv_epmapper.c b/source3/rpc_server/epmapper/srv_epmapper.c index 7b3a3051d0a..b2b8935af15 100644 --- a/source3/rpc_server/epmapper/srv_epmapper.c +++ b/source3/rpc_server/epmapper/srv_epmapper.c @@ -72,13 +72,6 @@ struct dcesrv_epm_endpoint { struct dcesrv_iface_list *iface_list; }; -struct dcesrv_ep_entry_list { - struct dcesrv_ep_entry_list *next, *prev; - - uint32_t num_ents; - struct epm_entry_t *entries; -}; - struct rpc_eps { struct dcesrv_ep_iface *e; uint32_t count; diff --git a/source3/rpc_server/epmd.c b/source3/rpc_server/epmd.c deleted file mode 100644 index f9b80a03510..00000000000 --- a/source3/rpc_server/epmd.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * SMBD RPC service callbacks - * - * Copyright (c) 2011 Andreas Schneider - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include "includes.h" - -#include "ntdomain.h" -#include "messages.h" - -#include "librpc/rpc/dcerpc_ep.h" - -#include "librpc/rpc/dcesrv_core.h" -#include "librpc/gen_ndr/ndr_epmapper_scompat.h" - -#include "rpc_server/rpc_server.h" -#include "rpc_server/rpc_service_setup.h" -#include "rpc_server/rpc_sock_helper.h" -#include "rpc_server/epmd.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -#define DAEMON_NAME "epmd" - -static void epmd_reopen_logs(void) -{ - const struct loadparm_substitution *lp_sub = - loadparm_s3_global_substitution(); - char *lfile = lp_logfile(talloc_tos(), lp_sub); - int rc; - - if (lfile == NULL || lfile[0] == '\0') { - rc = asprintf(&lfile, "%s/log.%s", get_dyn_LOGFILEBASE(), DAEMON_NAME); - if (rc > 0) { - lp_set_logfile(lfile); - SAFE_FREE(lfile); - } - } else { - if (strstr(lfile, DAEMON_NAME) == NULL) { - rc = asprintf(&lfile, "%s.%s", - lp_logfile(talloc_tos(), lp_sub), DAEMON_NAME); - if (rc > 0) { - lp_set_logfile(lfile); - SAFE_FREE(lfile); - } - } - } - - reopen_logs(); -} - -static void epmd_smb_conf_updated(struct messaging_context *msg, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data) -{ - DEBUG(10, ("Got message saying smb.conf was updated. Reloading.\n")); - change_to_root_user(); - epmd_reopen_logs(); -} - -static void epmd_sig_term_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *private_data) -{ - exit_server_cleanly("termination signal"); -} - -static void epmd_setup_sig_term_handler(struct tevent_context *ev_ctx) -{ - struct tevent_signal *se; - - se = tevent_add_signal(ev_ctx, - ev_ctx, - SIGTERM, 0, - epmd_sig_term_handler, - NULL); - if (se == NULL) { - exit_server("failed to setup SIGTERM handler"); - } -} - -static void epmd_sig_hup_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *private_data) -{ - change_to_root_user(); - - DEBUG(1,("Reloading printers after SIGHUP\n")); - epmd_reopen_logs(); -} - -static void epmd_setup_sig_hup_handler(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - struct tevent_signal *se; - - se = tevent_add_signal(ev_ctx, - ev_ctx, - SIGHUP, 0, - epmd_sig_hup_handler, - msg_ctx); - if (se == NULL) { - exit_server("failed to setup SIGHUP handler"); - } -} - -void start_epmd(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx) -{ - NTSTATUS status; - pid_t pid; - int rc; - const struct dcesrv_endpoint_server *ep_server = NULL; - struct dcesrv_endpoint *e = NULL; - - DEBUG(1, ("Forking Endpoint Mapper Daemon\n")); - - pid = fork(); - - if (pid == -1) { - DEBUG(0, ("Failed to fork Endpoint Mapper [%s], aborting ...\n", - strerror(errno))); - exit(1); - } - - if (pid) { - /* parent */ - return; - } - - status = smbd_reinit_after_fork(msg_ctx, ev_ctx, true, "epmd"); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("reinit_after_fork() failed\n")); - smb_panic("reinit_after_fork() failed"); - } - - epmd_reopen_logs(); - - epmd_setup_sig_term_handler(ev_ctx); - epmd_setup_sig_hup_handler(ev_ctx, msg_ctx); - - messaging_register(msg_ctx, - ev_ctx, - MSG_SMB_CONF_UPDATED, - epmd_smb_conf_updated); - - DBG_INFO("Registering DCE/RPC endpoint servers\n"); - - /* Register the endpoint server in DCERPC core */ - ep_server = epmapper_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'epmapper' endpoint server\n"); - exit(1); - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register 'epmapper' endpoint server: %s\n", - nt_errstr(status)); - exit(1); - } - - DBG_INFO("Reinitializing DCE/RPC server context\n"); - - status = dcesrv_reinit_context(dce_ctx); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to reinit DCE/RPC context: %s\n", - nt_errstr(status)); - exit(1); - } - - DBG_INFO("Initializing DCE/RPC registered endpoint servers\n"); - - status = dcesrv_init_ep_server(dce_ctx, "epmapper"); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to init DCE/RPC endpoint server: %s\n", - nt_errstr(status)); - exit(1); - } - - DBG_INFO("Initializing DCE/RPC connection endpoints\n"); - - for (e = dce_ctx->endpoint_list; e; e = e->next) { - enum dcerpc_transport_t transport = - dcerpc_binding_get_transport(e->ep_description); - dcerpc_ncacn_termination_fn term_fn = NULL; - - if (transport == NCACN_HTTP) { - continue; - } - - status = dcesrv_setup_endpoint_sockets(ev_ctx, - msg_ctx, - dce_ctx, - e, - term_fn, - NULL); /* termination_data */ - if (!NT_STATUS_IS_OK(status)) { - char *ep_string = dcerpc_binding_string( - dce_ctx, e->ep_description); - DBG_ERR("Failed to setup endpoint '%s': %s\n", - ep_string, nt_errstr(status)); - TALLOC_FREE(ep_string); - exit(1); - } - } - - DEBUG(1, ("Endpoint Mapper Daemon Started (%u)\n", (unsigned int)getpid())); - - /* loop forever */ - rc = tevent_loop_wait(ev_ctx); - - /* should not be reached */ - DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n", - rc, (rc == 0) ? "out of events" : strerror(errno))); - - exit(1); -} - -/* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */ diff --git a/source3/rpc_server/epmd.h b/source3/rpc_server/epmd.h deleted file mode 100644 index 882213ebbf2..00000000000 --- a/source3/rpc_server/epmd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * EPMD header file - * - * Copyright (c) 2018 Volker Lendecke - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef __RPC_SERVER_EPMD_H__ -#define __RPC_SERVER_EPMD_H__ - -#include "replace.h" -#include "messages.h" - -struct dcesrv_context; - -void start_epmd(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx); - -#endif diff --git a/source3/rpc_server/fssd.c b/source3/rpc_server/fssd.c deleted file mode 100644 index eaec70d230f..00000000000 --- a/source3/rpc_server/fssd.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * File Server Shadow-Copy Daemon - * - * Copyright (C) David Disseldorp 2012-2015 - * - * Based on epmd.c: - * Copyright (c) 2011 Andreas Schneider - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include "includes.h" - -#include "ntdomain.h" -#include "messages.h" - -#include "librpc/rpc/dcerpc_ep.h" - -#include "librpc/rpc/dcesrv_core.h" -#include "librpc/gen_ndr/ndr_fsrvp_scompat.h" - -#include "rpc_server/rpc_server.h" -#include "rpc_server/rpc_service_setup.h" -#include "rpc_server/rpc_sock_helper.h" -#include "rpc_server/fssd.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -#define DAEMON_NAME "fssd" - -static void fssd_reopen_logs(void) -{ - const struct loadparm_substitution *lp_sub = - loadparm_s3_global_substitution(); - char *lfile = lp_logfile(NULL, lp_sub); - int rc; - - if (lfile == NULL || lfile[0] == '\0') { - rc = asprintf(&lfile, "%s/log.%s", get_dyn_LOGFILEBASE(), DAEMON_NAME); - if (rc > 0) { - lp_set_logfile(lfile); - SAFE_FREE(lfile); - } - } else { - if (strstr(lfile, DAEMON_NAME) == NULL) { - rc = asprintf(&lfile, "%s.%s", lp_logfile(NULL, lp_sub), DAEMON_NAME); - if (rc > 0) { - lp_set_logfile(lfile); - SAFE_FREE(lfile); - } - } - } - - reopen_logs(); -} - -static void fssd_smb_conf_updated(struct messaging_context *msg, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data) -{ - DEBUG(10, ("Got message saying smb.conf was updated. Reloading.\n")); - change_to_root_user(); - fssd_reopen_logs(); -} - -static void fssd_sig_term_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *private_data) -{ - exit_server_cleanly("termination signal"); -} - -static void fssd_setup_sig_term_handler(struct tevent_context *ev_ctx) -{ - struct tevent_signal *se; - - se = tevent_add_signal(ev_ctx, - ev_ctx, - SIGTERM, 0, - fssd_sig_term_handler, - NULL); - if (se == NULL) { - exit_server("failed to setup SIGTERM handler"); - } -} - -static void fssd_sig_hup_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *private_data) -{ - change_to_root_user(); - - DEBUG(1,("reopening logs after SIGHUP\n")); - fssd_reopen_logs(); -} - -static void fssd_setup_sig_hup_handler(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - struct tevent_signal *se; - - se = tevent_add_signal(ev_ctx, - ev_ctx, - SIGHUP, 0, - fssd_sig_hup_handler, - msg_ctx); - if (se == NULL) { - exit_server("failed to setup SIGHUP handler"); - } -} - -void start_fssd(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx) -{ - NTSTATUS status; - pid_t pid; - int rc; - const struct dcesrv_endpoint_server *ep_server = NULL; - struct dcesrv_endpoint *e = NULL; - - DEBUG(1, ("Forking File Server Shadow-copy Daemon\n")); - - pid = fork(); - - if (pid == -1) { - DEBUG(0, ("failed to fork file server shadow-copy daemon [%s], " - "aborting ...\n", strerror(errno))); - exit(1); - } - - if (pid) { - /* parent */ - return; - } - - /* child */ - status = smbd_reinit_after_fork(msg_ctx, ev_ctx, true, NULL); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("reinit_after_fork() failed\n")); - smb_panic("reinit_after_fork() failed"); - } - - fssd_reopen_logs(); - - fssd_setup_sig_term_handler(ev_ctx); - fssd_setup_sig_hup_handler(ev_ctx, msg_ctx); - - messaging_register(msg_ctx, - ev_ctx, - MSG_SMB_CONF_UPDATED, - fssd_smb_conf_updated); - - DBG_INFO("Registering DCE/RPC endpoint servers\n"); - - ep_server = FileServerVssAgent_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'FileServerVssAgent' endpoint " - "server\n"); - exit(1); - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register 'FileServerVssAgent' endpoint " - "server: %s\n", nt_errstr(status)); - exit(1); - } - - DBG_INFO("Reinitializing DCE/RPC server context\n"); - - status = dcesrv_reinit_context(dce_ctx); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to reinit DCE/RPC context: %s\n", - nt_errstr(status)); - exit(1); - } - - DBG_INFO("Initializing DCE/RPC registered endpoint servers\n"); - - status = dcesrv_init_ep_server(dce_ctx, "FileServerVssAgent"); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to init DCE/RPC endpoint server: %s\n", - nt_errstr(status)); - exit(1); - } - - DBG_INFO("Initializing DCE/RPC connection endpoints\n"); - - for (e = dce_ctx->endpoint_list; e; e = e->next) { - status = dcesrv_setup_endpoint_sockets(ev_ctx, - msg_ctx, - dce_ctx, - e, - NULL, /* termination function */ - NULL); /* termination data */ - if (!NT_STATUS_IS_OK(status)) { - char *ep_string = dcerpc_binding_string( - dce_ctx, e->ep_description); - DBG_ERR("Failed to setup endpoint '%s': %s\n", - ep_string, nt_errstr(status)); - TALLOC_FREE(ep_string); - exit(1); - } - } - - DEBUG(1, ("File Server Shadow-copy Daemon Started (%d)\n", - (int)getpid())); - - /* loop forever */ - rc = tevent_loop_wait(ev_ctx); - - /* should not be reached */ - DEBUG(0,("tevent_loop_wait() exited with %d - %s\n", - rc, (rc == 0) ? "out of events" : strerror(errno))); - - exit(1); -} diff --git a/source3/rpc_server/fssd.h b/source3/rpc_server/fssd.h deleted file mode 100644 index 1a8318860cf..00000000000 --- a/source3/rpc_server/fssd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * FSSD header file - * - * Copyright (c) 2018 Volker Lendecke - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef __RPC_SERVER_FSSD_H__ -#define __RPC_SERVER_FSSD_H__ - -#include "replace.h" -#include "messages.h" - -struct dcesrv_context; - -void start_fssd(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx); - -#endif diff --git a/source3/rpc_server/lsasd.c b/source3/rpc_server/lsasd.c deleted file mode 100644 index 93317688ce8..00000000000 --- a/source3/rpc_server/lsasd.c +++ /dev/null @@ -1,775 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * LSA service daemon - * - * Copyright (c) 2011 Andreas Schneider - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include "includes.h" -#include "messages.h" -#include "ntdomain.h" -#include "passdb.h" - -#include "lib/id_cache.h" - -#include "../lib/tsocket/tsocket.h" -#include "lib/server_prefork.h" -#include "lib/server_prefork_util.h" -#include "librpc/rpc/dcerpc_ep.h" -#include "librpc/rpc/dcesrv_core.h" - -#include "rpc_server/rpc_server.h" -#include "rpc_server/rpc_ep_register.h" -#include "rpc_server/rpc_sock_helper.h" -#include "rpc_server/rpc_service_setup.h" - -#include "rpc_server/lsasd.h" - -#include "librpc/gen_ndr/ndr_lsa_scompat.h" -#include "librpc/gen_ndr/ndr_samr_scompat.h" -#include "librpc/gen_ndr/ndr_netlogon_scompat.h" -#include "lib/global_contexts.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -#define DAEMON_NAME "lsasd" - -static struct server_id parent_id; -static struct prefork_pool *lsasd_pool = NULL; -static int lsasd_child_id = 0; - -static const struct pf_daemon_config default_pf_lsasd_cfg = { - .prefork_status = PFH_INIT, - .min_children = 5, - .max_children = 25, - .spawn_rate = 5, - .max_allowed_clients = 100, - .child_min_life = 60 /* 1 minute minimum life time */ -}; -static struct pf_daemon_config pf_lsasd_cfg = { 0 }; - -static void lsasd_reopen_logs(int child_id) -{ - const struct loadparm_substitution *lp_sub = - loadparm_s3_global_substitution(); - char *lfile = lp_logfile(talloc_tos(), lp_sub); - char *extension; - int rc; - - if (child_id) { - rc = asprintf(&extension, "%s.%d", DAEMON_NAME, child_id); - } else { - rc = asprintf(&extension, "%s", DAEMON_NAME); - } - if (rc == -1) { - return; - } - - rc = 0; - if (lfile == NULL || lfile[0] == '\0') { - rc = asprintf(&lfile, "%s/log.%s", - get_dyn_LOGFILEBASE(), extension); - } else { - if (strstr(lfile, extension) == NULL) { - if (child_id) { - rc = asprintf(&lfile, "%s.%d", - lp_logfile(talloc_tos(), lp_sub), - child_id); - } else { - rc = asprintf(&lfile, "%s.%s", - lp_logfile(talloc_tos(), lp_sub), - extension); - } - } - } - - if (rc > 0) { - lp_set_logfile(lfile); - SAFE_FREE(lfile); - } - - SAFE_FREE(extension); - - reopen_logs(); -} - -static void lsasd_smb_conf_updated(struct messaging_context *msg, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data) -{ - struct tevent_context *ev_ctx; - - DEBUG(10, ("Got message saying smb.conf was updated. Reloading.\n")); - ev_ctx = talloc_get_type_abort(private_data, struct tevent_context); - - change_to_root_user(); - lp_load_global(get_dyn_CONFIGFILE()); - - lsasd_reopen_logs(lsasd_child_id); - if (lsasd_child_id == 0) { - pfh_daemon_config(DAEMON_NAME, - &pf_lsasd_cfg, - &default_pf_lsasd_cfg); - pfh_manage_pool(ev_ctx, msg, &pf_lsasd_cfg, lsasd_pool); - } -} - -static void lsasd_sig_term_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *private_data) -{ - exit_server_cleanly("termination signal"); -} - -static void lsasd_setup_sig_term_handler(struct tevent_context *ev_ctx) -{ - struct tevent_signal *se; - - se = tevent_add_signal(ev_ctx, - ev_ctx, - SIGTERM, 0, - lsasd_sig_term_handler, - NULL); - if (!se) { - exit_server("failed to setup SIGTERM handler"); - } -} - -static void lsasd_sig_hup_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *pvt) -{ - - change_to_root_user(); - lp_load_global(get_dyn_CONFIGFILE()); - - lsasd_reopen_logs(lsasd_child_id); - pfh_daemon_config(DAEMON_NAME, - &pf_lsasd_cfg, - &default_pf_lsasd_cfg); - - /* relay to all children */ - prefork_send_signal_to_all(lsasd_pool, SIGHUP); -} - -static void lsasd_setup_sig_hup_handler(struct tevent_context *ev_ctx) -{ - struct tevent_signal *se; - - se = tevent_add_signal(ev_ctx, - ev_ctx, - SIGHUP, 0, - lsasd_sig_hup_handler, - NULL); - if (!se) { - DEBUG(0, ("failed to setup SIGHUP handler\n")); - exit(1); - } -} - -/********************************************************** - * Children - **********************************************************/ - -static void lsasd_chld_sig_hup_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *pvt) -{ - change_to_root_user(); - lsasd_reopen_logs(lsasd_child_id); -} - -static bool lsasd_setup_chld_hup_handler(struct tevent_context *ev_ctx) -{ - struct tevent_signal *se; - - se = tevent_add_signal(ev_ctx, - ev_ctx, - SIGHUP, 0, - lsasd_chld_sig_hup_handler, - NULL); - if (!se) { - DEBUG(1, ("failed to setup SIGHUP handler")); - return false; - } - - return true; -} - -static void parent_ping(struct messaging_context *msg_ctx, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data) -{ - - /* The fact we received this message is enough to let make the event - * loop if it was idle. lsasd_children_main will cycle through - * lsasd_next_client at least once. That function will take whatever - * action is necessary */ - - DEBUG(10, ("Got message that the parent changed status.\n")); - return; -} - -static bool lsasd_child_init(struct tevent_context *ev_ctx, - int child_id, - struct pf_worker_data *pf) -{ - NTSTATUS status; - struct messaging_context *msg_ctx = global_messaging_context(); - bool ok; - - status = reinit_after_fork(msg_ctx, ev_ctx, - true, "lsasd-child"); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("reinit_after_fork() failed\n")); - smb_panic("reinit_after_fork() failed"); - } - initialize_password_db(true, ev_ctx); - - lsasd_child_id = child_id; - lsasd_reopen_logs(child_id); - - ok = lsasd_setup_chld_hup_handler(ev_ctx); - if (!ok) { - return false; - } - - messaging_register(msg_ctx, ev_ctx, - MSG_SMB_CONF_UPDATED, lsasd_smb_conf_updated); - messaging_register(msg_ctx, ev_ctx, - MSG_PREFORK_PARENT_EVENT, parent_ping); - id_cache_register_msgs(msg_ctx); - - return true; -} - -struct lsasd_children_data { - struct tevent_context *ev_ctx; - struct messaging_context *msg_ctx; - struct dcesrv_context *dce_ctx; - struct pf_worker_data *pf; - int listen_fd_size; - struct pf_listen_fd *listen_fds; -}; - -static void lsasd_next_client(void *pvt); - -static int lsasd_children_main(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct pf_worker_data *pf, - int child_id, - int listen_fd_size, - struct pf_listen_fd *listen_fds, - void *private_data) -{ - struct lsasd_children_data *data; - bool ok; - int ret = 0; - struct dcesrv_context *dce_ctx = NULL; - - dce_ctx = talloc_get_type_abort(private_data, struct dcesrv_context); - - ok = lsasd_child_init(ev_ctx, child_id, pf); - if (!ok) { - return 1; - } - - data = talloc(ev_ctx, struct lsasd_children_data); - if (!data) { - return 1; - } - data->pf = pf; - data->ev_ctx = ev_ctx; - data->msg_ctx = msg_ctx; - data->dce_ctx = dce_ctx; - data->listen_fd_size = listen_fd_size; - data->listen_fds = listen_fds; - - /* loop until it is time to exit */ - while (pf->status != PF_WORKER_EXITING) { - /* try to see if it is time to schedule the next client */ - lsasd_next_client(data); - - ret = tevent_loop_once(ev_ctx); - if (ret != 0) { - DEBUG(0, ("tevent_loop_once() exited with %d: %s\n", - ret, strerror(errno))); - pf->status = PF_WORKER_EXITING; - } - } - - return ret; -} - -static void lsasd_client_terminated(struct dcesrv_connection *conn, void *pvt) -{ - struct lsasd_children_data *data; - - data = talloc_get_type_abort(pvt, struct lsasd_children_data); - - pfh_client_terminated(data->pf); - - lsasd_next_client(pvt); -} - -struct lsasd_new_client { - struct lsasd_children_data *data; -}; - -static void lsasd_handle_client(struct tevent_req *req); - -static void lsasd_next_client(void *pvt) -{ - struct tevent_req *req; - struct lsasd_children_data *data; - struct lsasd_new_client *next; - - data = talloc_get_type_abort(pvt, struct lsasd_children_data); - - if (!pfh_child_allowed_to_accept(data->pf)) { - /* nothing to do for now we are already listening - * or we are not allowed to listen further */ - return; - } - - next = talloc_zero(data, struct lsasd_new_client); - if (!next) { - DEBUG(1, ("Out of memory!?\n")); - return; - } - next->data = data; - - req = prefork_listen_send(next, - data->ev_ctx, - data->pf, - data->listen_fd_size, - data->listen_fds); - if (!req) { - DEBUG(1, ("Failed to make listening request!?\n")); - talloc_free(next); - return; - } - tevent_req_set_callback(req, lsasd_handle_client, next); -} - -static void lsasd_handle_client(struct tevent_req *req) -{ - struct lsasd_children_data *data; - struct lsasd_new_client *client; - const DATA_BLOB ping = data_blob_null; - int rc; - int sd; - TALLOC_CTX *tmp_ctx; - struct tsocket_address *srv_addr; - struct tsocket_address *cli_addr; - void *listen_fd_data = NULL; - struct dcesrv_endpoint *ep = NULL; - enum dcerpc_transport_t transport; - dcerpc_ncacn_termination_fn term_fn = NULL; - void *term_fn_data = NULL; - - client = tevent_req_callback_data(req, struct lsasd_new_client); - data = client->data; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - DEBUG(1, ("Failed to allocate stackframe!\n")); - return; - } - - rc = prefork_listen_recv(req, - tmp_ctx, - &sd, - &listen_fd_data, - &srv_addr, - &cli_addr); - - /* this will free the request too */ - talloc_free(client); - - if (rc != 0) { - DEBUG(6, ("No client connection was available after all!\n")); - goto done; - } - - ep = talloc_get_type_abort(listen_fd_data, struct dcesrv_endpoint); - transport = dcerpc_binding_get_transport(ep->ep_description); - if (transport == NCACN_NP) { - term_fn = lsasd_client_terminated; - term_fn_data = data; - } - - /* Warn parent that our status changed */ - messaging_send(data->msg_ctx, parent_id, - MSG_PREFORK_CHILD_EVENT, &ping); - - DBG_INFO("LSASD preforked child %d got client connection on '%s'\n", - (int)(data->pf->pid), dcerpc_binding_string(tmp_ctx, - ep->ep_description)); - - dcerpc_ncacn_accept(data->ev_ctx, - data->msg_ctx, - data->dce_ctx, - ep, - &cli_addr, - &srv_addr, - sd, - term_fn, - term_fn_data); - -done: - talloc_free(tmp_ctx); -} - -/* - * MAIN - */ - -static void child_ping(struct messaging_context *msg_ctx, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data) -{ - struct tevent_context *ev_ctx; - - ev_ctx = talloc_get_type_abort(private_data, struct tevent_context); - - DEBUG(10, ("Got message that a child changed status.\n")); - pfh_manage_pool(ev_ctx, msg_ctx, &pf_lsasd_cfg, lsasd_pool); -} - -static bool lsasd_schedule_check(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct timeval current_time); - -static void lsasd_check_children(struct tevent_context *ev_ctx, - struct tevent_timer *te, - struct timeval current_time, - void *pvt); - -static void lsasd_sigchld_handler(struct tevent_context *ev_ctx, - struct prefork_pool *pfp, - void *pvt) -{ - struct messaging_context *msg_ctx; - - msg_ctx = talloc_get_type_abort(pvt, struct messaging_context); - - /* run pool management so we can fork/retire or increase - * the allowed connections per child based on load */ - pfh_manage_pool(ev_ctx, msg_ctx, &pf_lsasd_cfg, lsasd_pool); -} - -static bool lsasd_setup_children_monitor(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - bool ok; - - /* add our oun sigchld callback */ - prefork_set_sigchld_callback(lsasd_pool, lsasd_sigchld_handler, msg_ctx); - - ok = lsasd_schedule_check(ev_ctx, msg_ctx, tevent_timeval_current()); - - return ok; -} - -static bool lsasd_schedule_check(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct timeval current_time) -{ - struct tevent_timer *te; - struct timeval next_event; - - /* check situation again in 10 seconds */ - next_event = tevent_timeval_current_ofs(10, 0); - - /* TODO: check when the socket becomes readable, so that children - * are checked only when there is some activity ? */ - te = tevent_add_timer(ev_ctx, lsasd_pool, next_event, - lsasd_check_children, msg_ctx); - if (!te) { - DEBUG(2, ("Failed to set up children monitoring!\n")); - return false; - } - - return true; -} - -static void lsasd_check_children(struct tevent_context *ev_ctx, - struct tevent_timer *te, - struct timeval current_time, - void *pvt) -{ - struct messaging_context *msg_ctx; - - msg_ctx = talloc_get_type_abort(pvt, struct messaging_context); - - pfh_manage_pool(ev_ctx, msg_ctx, &pf_lsasd_cfg, lsasd_pool); - - lsasd_schedule_check(ev_ctx, msg_ctx, current_time); -} - -/* - * start it up - */ - -static NTSTATUS lsasd_create_sockets(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - TALLOC_CTX *mem_ctx, - struct pf_listen_fd **plisten_fds, - size_t *pnum_listen_fds) -{ - NTSTATUS status; - size_t i, num_fds; - struct pf_listen_fd *fds = NULL; - int rc; - struct dcesrv_endpoint *e = dce_ctx->endpoint_list; - - DBG_INFO("Initializing DCE/RPC connection endpoints\n"); - - status = dcesrv_create_endpoint_list_pf_listen_fds( - ev_ctx, msg_ctx, dce_ctx, e, mem_ctx, &num_fds, &fds); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - for (i = 0; i < num_fds; i++) { - rc = listen(fds[i].fd, pf_lsasd_cfg.max_allowed_clients); - if (rc == -1) { - char *ep_string = NULL; - e = fds[i].fd_data; - - ep_string = dcerpc_binding_string(dce_ctx, - e->ep_description); - DBG_ERR("Failed to listen on endpoint '%s': %s\n", - ep_string, strerror(errno)); - status = map_nt_error_from_unix(errno); - TALLOC_FREE(ep_string); - goto done; - } - } - - for (e = dce_ctx->endpoint_list; e; e = e->next) { - struct dcesrv_if_list *ifl = NULL; - for (ifl = e->interface_list; ifl; ifl = ifl->next) { - status = rpc_ep_register(ev_ctx, - msg_ctx, - dce_ctx, - ifl->iface); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register interface in " - "endpoint mapper: %s", - nt_errstr(status)); - goto done; - } - } - } - - *plisten_fds = fds; - *pnum_listen_fds = num_fds; - - status = NT_STATUS_OK; -done: - return status; -} - -void start_lsasd(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx) -{ - NTSTATUS status; - struct pf_listen_fd *listen_fd = NULL; - size_t listen_fd_size = 0; - pid_t pid; - int rc; - bool ok; - const struct dcesrv_endpoint_server *ep_server = NULL; - const char *ep_servers[] = { "lsarpc", "samr", "netlogon", NULL }; - - DEBUG(1, ("Forking LSA Service Daemon\n")); - - /* - * Block signals before forking child as it will have to - * set its own handlers. Child will re-enable SIGHUP as - * soon as the handlers are set up. - */ - BlockSignals(true, SIGTERM); - BlockSignals(true, SIGHUP); - - pid = fork(); - if (pid == -1) { - DEBUG(0, ("Failed to fork LSASD [%s], aborting ...\n", - strerror(errno))); - exit(1); - } - - /* parent or error */ - if (pid != 0) { - - /* Re-enable SIGHUP before returnig */ - BlockSignals(false, SIGTERM); - BlockSignals(false, SIGHUP); - - return; - } - - status = smbd_reinit_after_fork(msg_ctx, ev_ctx, true, "lsasd-master"); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("reinit_after_fork() failed\n")); - smb_panic("reinit_after_fork() failed"); - } - initialize_password_db(true, ev_ctx); - - /* save the parent process id so the children can use it later */ - parent_id = messaging_server_id(msg_ctx); - - lsasd_reopen_logs(0); - pfh_daemon_config(DAEMON_NAME, - &pf_lsasd_cfg, - &default_pf_lsasd_cfg); - - lsasd_setup_sig_term_handler(ev_ctx); - lsasd_setup_sig_hup_handler(ev_ctx); - - BlockSignals(false, SIGTERM); - BlockSignals(false, SIGHUP); - - DBG_INFO("Registering DCE/RPC endpoint servers\n"); - - ep_server = lsarpc_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'lsarpc' endpoint server\n"); - exit(1); - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register 'lsarpc' endpoint server: %s\n", - nt_errstr(status)); - exit(1); - } - - ep_server = samr_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'samr' endpoint server\n"); - exit(1); - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register 'samr' endpoint server: %s\n", - nt_errstr(status)); - exit(1); - } - - ep_server = netlogon_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'netlogon' endpoint server\n"); - exit(1); - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register 'netlogon' endpoint server: %s\n", - nt_errstr(status)); - exit(1); - } - - DBG_INFO("Reinitializing DCE/RPC server context\n"); - - status = dcesrv_reinit_context(dce_ctx); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to reinit DCE/RPC context: %s\n", - nt_errstr(status)); - exit(1); - } - - DBG_INFO("Initializing DCE/RPC registered endpoint servers\n"); - - /* Init ep servers */ - status = dcesrv_init_ep_servers(dce_ctx, ep_servers); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to init DCE/RPC endpoint server: %s\n", - nt_errstr(status)); - exit(1); - } - - status = lsasd_create_sockets(ev_ctx, - msg_ctx, - dce_ctx, - dce_ctx, - &listen_fd, - &listen_fd_size); - if (!NT_STATUS_IS_OK(status)) { - exit(1); - } - - /* start children before any more initialization is done */ - ok = prefork_create_pool(ev_ctx, /* mem_ctx */ - ev_ctx, - msg_ctx, - listen_fd_size, - listen_fd, - pf_lsasd_cfg.min_children, - pf_lsasd_cfg.max_children, - &lsasd_children_main, - dce_ctx, - &lsasd_pool); - TALLOC_FREE(listen_fd); - if (!ok) { - exit(1); - } - - messaging_register(msg_ctx, - ev_ctx, - MSG_SMB_CONF_UPDATED, - lsasd_smb_conf_updated); - messaging_register(msg_ctx, ev_ctx, - MSG_PREFORK_CHILD_EVENT, child_ping); - - ok = lsasd_setup_children_monitor(ev_ctx, msg_ctx); - if (!ok) { - DEBUG(0, ("Failed to setup children monitoring!\n")); - exit(1); - } - - DEBUG(1, ("LSASD Daemon Started (%u)\n", (unsigned int)getpid())); - - /* loop forever */ - rc = tevent_loop_wait(ev_ctx); - - /* should not be reached */ - DEBUG(0,("lsasd: tevent_loop_wait() exited with %d - %s\n", - rc, (rc == 0) ? "out of events" : strerror(errno))); - exit(1); -} diff --git a/source3/rpc_server/lsasd.h b/source3/rpc_server/lsasd.h deleted file mode 100644 index dfb5ffc5e9e..00000000000 --- a/source3/rpc_server/lsasd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * LSASD header file - * - * Copyright (c) 2018 Volker Lendecke - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef __RPC_SERVER_LSASD_H__ -#define __RPC_SERVER_LSASD_H__ - -#include "replace.h" -#include "messages.h" - -struct dcesrv_context; - -void start_lsasd(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx); - -#endif diff --git a/source3/rpc_server/mdssd.c b/source3/rpc_server/mdssd.c deleted file mode 100644 index aec5c082b0b..00000000000 --- a/source3/rpc_server/mdssd.c +++ /dev/null @@ -1,691 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * mds service daemon - * - * Copyright (c) 2014 Ralph Boehme - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include "includes.h" -#include "messages.h" -#include "ntdomain.h" - -#include "lib/id_cache.h" - -#include "../lib/tsocket/tsocket.h" -#include "lib/server_prefork.h" -#include "lib/server_prefork_util.h" -#include "librpc/rpc/dcerpc_ep.h" -#include "librpc/rpc/dcesrv_core.h" - -#include "rpc_server/rpc_server.h" -#include "rpc_server/rpc_service_setup.h" -#include "rpc_server/rpc_ep_register.h" -#include "rpc_server/rpc_sock_helper.h" -#include "rpc_server/rpc_modules.h" - -#include "rpc_server/mdssvc/srv_mdssvc_nt.h" -#include "rpc_server/mdssd.h" -#include "lib/global_contexts.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -#define DAEMON_NAME "mdssd" - -static struct server_id parent_id; -static struct prefork_pool *mdssd_pool = NULL; -static int mdssd_child_id = 0; - -static const struct pf_daemon_config default_pf_mdssd_cfg = { - .prefork_status = PFH_INIT, - .min_children = 5, - .max_children = 25, - .spawn_rate = 5, - .max_allowed_clients = 1000, - .child_min_life = 60 /* 1 minute minimum life time */ -}; -static struct pf_daemon_config pf_mdssd_cfg = { 0 }; - -static void mdssd_smb_conf_updated(struct messaging_context *msg, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data) -{ - struct tevent_context *ev_ctx; - - DEBUG(10, ("Got message saying smb.conf was updated. Reloading.\n")); - ev_ctx = talloc_get_type_abort(private_data, struct tevent_context); - - change_to_root_user(); - lp_load_global(get_dyn_CONFIGFILE()); - - reopen_logs(); - if (mdssd_child_id == 0) { - pfh_daemon_config(DAEMON_NAME, - &pf_mdssd_cfg, - &default_pf_mdssd_cfg); - pfh_manage_pool(ev_ctx, msg, &pf_mdssd_cfg, mdssd_pool); - } -} - -static void mdssd_sig_term_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *private_data) -{ - exit_server_cleanly("termination signal"); -} - -static void mdssd_setup_sig_term_handler(struct tevent_context *ev_ctx) -{ - struct tevent_signal *se; - - se = tevent_add_signal(ev_ctx, - ev_ctx, - SIGTERM, 0, - mdssd_sig_term_handler, - NULL); - if (!se) { - exit_server("failed to setup SIGTERM handler"); - } -} - -static void mdssd_sig_hup_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *pvt) -{ - - change_to_root_user(); - lp_load_global(get_dyn_CONFIGFILE()); - - reopen_logs(); - pfh_daemon_config(DAEMON_NAME, - &pf_mdssd_cfg, - &default_pf_mdssd_cfg); - - /* relay to all children */ - prefork_send_signal_to_all(mdssd_pool, SIGHUP); -} - -static void mdssd_setup_sig_hup_handler(struct tevent_context *ev_ctx) -{ - struct tevent_signal *se; - - se = tevent_add_signal(ev_ctx, - ev_ctx, - SIGHUP, 0, - mdssd_sig_hup_handler, - NULL); - if (!se) { - DEBUG(0, ("failed to setup SIGHUP handler\n")); - exit(1); - } -} - -/********************************************************** - * Children - **********************************************************/ - -static void mdssd_chld_sig_hup_handler(struct tevent_context *ev, - struct tevent_signal *se, - int signum, - int count, - void *siginfo, - void *pvt) -{ - change_to_root_user(); - reopen_logs(); -} - -static bool mdssd_setup_chld_hup_handler(struct tevent_context *ev_ctx) -{ - struct tevent_signal *se; - - se = tevent_add_signal(ev_ctx, - ev_ctx, - SIGHUP, 0, - mdssd_chld_sig_hup_handler, - NULL); - if (!se) { - DEBUG(1, ("failed to setup SIGHUP handler")); - return false; - } - - return true; -} - -static void parent_ping(struct messaging_context *msg_ctx, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data) -{ - /* - * The fact we received this message is enough to let make the - * event loop if it was idle. mdssd_children_main will cycle - * through mdssd_next_client at least once. That function will - * take whatever action is necessary - */ - DEBUG(10, ("Got message that the parent changed status.\n")); - return; -} - -static bool mdssd_child_init(struct tevent_context *ev_ctx, - int child_id, - struct pf_worker_data *pf) -{ - NTSTATUS status; - struct messaging_context *msg_ctx = global_messaging_context(); - bool ok; - - status = reinit_after_fork(msg_ctx, ev_ctx, - true, "mdssd-child"); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("reinit_after_fork() failed\n")); - smb_panic("reinit_after_fork() failed"); - } - - mdssd_child_id = child_id; - reopen_logs(); - - ok = mdssd_setup_chld_hup_handler(ev_ctx); - if (!ok) { - return false; - } - - messaging_register(msg_ctx, ev_ctx, - MSG_SMB_CONF_UPDATED, mdssd_smb_conf_updated); - messaging_register(msg_ctx, ev_ctx, - MSG_PREFORK_PARENT_EVENT, parent_ping); - - return true; -} - -struct mdssd_children_data { - struct tevent_context *ev_ctx; - struct messaging_context *msg_ctx; - struct dcesrv_context *dce_ctx; - struct pf_worker_data *pf; - int listen_fd_size; - struct pf_listen_fd *listen_fds; -}; - -static void mdssd_next_client(void *pvt); - -static int mdssd_children_main(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct pf_worker_data *pf, - int child_id, - int listen_fd_size, - struct pf_listen_fd *listen_fds, - void *private_data) -{ - struct mdssd_children_data *data; - bool ok; - int ret = 0; - struct dcesrv_context *dce_ctx = NULL; - - dce_ctx = talloc_get_type_abort(private_data, struct dcesrv_context); - - ok = mdssd_child_init(ev_ctx, child_id, pf); - if (!ok) { - return 1; - } - - data = talloc(ev_ctx, struct mdssd_children_data); - if (!data) { - return 1; - } - data->pf = pf; - data->ev_ctx = ev_ctx; - data->msg_ctx = msg_ctx; - data->dce_ctx = dce_ctx; - data->listen_fd_size = listen_fd_size; - data->listen_fds = listen_fds; - - /* loop until it is time to exit */ - while (pf->status != PF_WORKER_EXITING) { - /* try to see if it is time to schedule the next client */ - mdssd_next_client(data); - - ret = tevent_loop_once(ev_ctx); - if (ret != 0) { - DEBUG(0, ("tevent_loop_once() exited with %d: %s\n", - ret, strerror(errno))); - pf->status = PF_WORKER_EXITING; - } - } - - return ret; -} - -static void mdssd_client_terminated(struct dcesrv_connection *conn, void *pvt) -{ - struct mdssd_children_data *data; - - data = talloc_get_type_abort(pvt, struct mdssd_children_data); - - pfh_client_terminated(data->pf); - - mdssd_next_client(pvt); -} - -struct mdssd_new_client { - struct mdssd_children_data *data; -}; - -static void mdssd_handle_client(struct tevent_req *req); - -static void mdssd_next_client(void *pvt) -{ - struct tevent_req *req; - struct mdssd_children_data *data; - struct mdssd_new_client *next; - - data = talloc_get_type_abort(pvt, struct mdssd_children_data); - - if (!pfh_child_allowed_to_accept(data->pf)) { - /* nothing to do for now we are already listening - * or we are not allowed to listen further */ - return; - } - - next = talloc_zero(data, struct mdssd_new_client); - if (!next) { - DEBUG(1, ("Out of memory!?\n")); - return; - } - next->data = data; - - req = prefork_listen_send(next, - data->ev_ctx, - data->pf, - data->listen_fd_size, - data->listen_fds); - if (!req) { - DEBUG(1, ("Failed to make listening request!?\n")); - talloc_free(next); - return; - } - tevent_req_set_callback(req, mdssd_handle_client, next); -} - -static void mdssd_handle_client(struct tevent_req *req) -{ - struct mdssd_children_data *data; - struct mdssd_new_client *client; - const DATA_BLOB ping = data_blob_null; - int rc; - int sd; - TALLOC_CTX *tmp_ctx; - struct tsocket_address *srv_addr; - struct tsocket_address *cli_addr; - void *listen_fd_data = NULL; - struct dcesrv_endpoint *ep = NULL; - enum dcerpc_transport_t transport; - dcerpc_ncacn_termination_fn term_fn = NULL; - void *term_fn_data = NULL; - - client = tevent_req_callback_data(req, struct mdssd_new_client); - data = client->data; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - DEBUG(1, ("Failed to allocate stackframe!\n")); - return; - } - - rc = prefork_listen_recv(req, - tmp_ctx, - &sd, - &listen_fd_data, - &srv_addr, - &cli_addr); - - /* this will free the request too */ - talloc_free(client); - - if (rc != 0) { - DEBUG(6, ("No client connection was available after all!\n")); - goto done; - } - - ep = talloc_get_type_abort(listen_fd_data, struct dcesrv_endpoint); - transport = dcerpc_binding_get_transport(ep->ep_description); - if (transport == NCACN_NP) { - term_fn = mdssd_client_terminated; - term_fn_data = data; - } - - /* Warn parent that our status changed */ - messaging_send(data->msg_ctx, parent_id, - MSG_PREFORK_CHILD_EVENT, &ping); - - DBG_INFO("MDSSD preforked child %d got client connection on '%s'\n", - (int)(data->pf->pid), dcerpc_binding_string(tmp_ctx, - ep->ep_description)); - - dcerpc_ncacn_accept(data->ev_ctx, - data->msg_ctx, - data->dce_ctx, - ep, - &cli_addr, - &srv_addr, - sd, - term_fn, - term_fn_data); - -done: - talloc_free(tmp_ctx); -} - -/* - * MAIN - */ - -static void child_ping(struct messaging_context *msg_ctx, - void *private_data, - uint32_t msg_type, - struct server_id server_id, - DATA_BLOB *data) -{ - struct tevent_context *ev_ctx; - - ev_ctx = talloc_get_type_abort(private_data, struct tevent_context); - - DEBUG(10, ("Got message that a child changed status.\n")); - pfh_manage_pool(ev_ctx, msg_ctx, &pf_mdssd_cfg, mdssd_pool); -} - -static bool mdssd_schedule_check(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct timeval current_time); - -static void mdssd_check_children(struct tevent_context *ev_ctx, - struct tevent_timer *te, - struct timeval current_time, - void *pvt); - -static void mdssd_sigchld_handler(struct tevent_context *ev_ctx, - struct prefork_pool *pfp, - void *pvt) -{ - struct messaging_context *msg_ctx; - - msg_ctx = talloc_get_type_abort(pvt, struct messaging_context); - - /* run pool management so we can fork/retire or increase - * the allowed connections per child based on load */ - pfh_manage_pool(ev_ctx, msg_ctx, &pf_mdssd_cfg, mdssd_pool); -} - -static bool mdssd_setup_children_monitor(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - bool ok; - - /* add our oun sigchld callback */ - prefork_set_sigchld_callback(mdssd_pool, mdssd_sigchld_handler, msg_ctx); - - ok = mdssd_schedule_check(ev_ctx, msg_ctx, tevent_timeval_current()); - - return ok; -} - -static bool mdssd_schedule_check(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct timeval current_time) -{ - struct tevent_timer *te; - struct timeval next_event; - - /* check situation again in 10 seconds */ - next_event = tevent_timeval_current_ofs(10, 0); - - /* TODO: check when the socket becomes readable, so that children - * are checked only when there is some activity ? */ - te = tevent_add_timer(ev_ctx, mdssd_pool, next_event, - mdssd_check_children, msg_ctx); - if (!te) { - DEBUG(2, ("Failed to set up children monitoring!\n")); - return false; - } - - return true; -} - -static void mdssd_check_children(struct tevent_context *ev_ctx, - struct tevent_timer *te, - struct timeval current_time, - void *pvt) -{ - struct messaging_context *msg_ctx; - - msg_ctx = talloc_get_type_abort(pvt, struct messaging_context); - - pfh_manage_pool(ev_ctx, msg_ctx, &pf_mdssd_cfg, mdssd_pool); - - mdssd_schedule_check(ev_ctx, msg_ctx, current_time); -} - -/* - * start it up - */ - -static NTSTATUS mdssd_create_sockets(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - TALLOC_CTX *mem_ctx, - struct pf_listen_fd **plisten_fds, - size_t *pnum_listen_fds) -{ - NTSTATUS status; - size_t i, num_fds; - struct pf_listen_fd *fds = NULL; - int rc; - struct dcesrv_endpoint *e = dce_ctx->endpoint_list; - - DBG_INFO("Initializing DCE/RPC connection endpoints\n"); - - status = dcesrv_create_endpoint_list_pf_listen_fds( - ev_ctx, msg_ctx, dce_ctx, e, mem_ctx, &num_fds, &fds); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - for (i = 0; i < num_fds; i++) { - rc = listen(fds[i].fd, pf_mdssd_cfg.max_allowed_clients); - if (rc == -1) { - char *ep_string = NULL; - e = fds[i].fd_data; - - ep_string = dcerpc_binding_string(dce_ctx, - e->ep_description); - DBG_ERR("Failed to listen on endpoint '%s': %s\n", - ep_string, strerror(errno)); - status = map_nt_error_from_unix(errno); - TALLOC_FREE(ep_string); - goto done; - } - } - - for (e = dce_ctx->endpoint_list; e; e = e->next) { - struct dcesrv_if_list *ifl = NULL; - for (ifl = e->interface_list; ifl; ifl = ifl->next) { - status = rpc_ep_register(ev_ctx, - msg_ctx, - dce_ctx, - ifl->iface); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register interface in " - "endpoint mapper: %s", - nt_errstr(status)); - goto done; - } - } - } - - *plisten_fds = fds; - *pnum_listen_fds = num_fds; - - status = NT_STATUS_OK; -done: - return status; -} - -void start_mdssd(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx) -{ - NTSTATUS status; - struct pf_listen_fd *listen_fd = NULL; - size_t listen_fd_size = 0; - pid_t pid; - int rc; - bool ok; - - DEBUG(1, ("Forking Metadata Service Daemon\n")); - - /* - * Block signals before forking child as it will have to - * set its own handlers. Child will re-enable SIGHUP as - * soon as the handlers are set up. - */ - BlockSignals(true, SIGTERM); - BlockSignals(true, SIGHUP); - - pid = fork(); - if (pid == -1) { - DEBUG(0, ("Failed to fork mdssd [%s], aborting ...\n", - strerror(errno))); - exit(1); - } - - /* parent or error */ - if (pid != 0) { - - /* Re-enable SIGHUP before returnig */ - BlockSignals(false, SIGTERM); - BlockSignals(false, SIGHUP); - - return; - } - - status = smbd_reinit_after_fork(msg_ctx, ev_ctx, true, "mdssd-master"); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("reinit_after_fork() failed\n")); - smb_panic("reinit_after_fork() failed"); - } - - reopen_logs(); - - /* save the parent process id so the children can use it later */ - parent_id = messaging_server_id(msg_ctx); - - pfh_daemon_config(DAEMON_NAME, - &pf_mdssd_cfg, - &default_pf_mdssd_cfg); - - mdssd_setup_sig_term_handler(ev_ctx); - mdssd_setup_sig_hup_handler(ev_ctx); - - BlockSignals(false, SIGTERM); - BlockSignals(false, SIGHUP); - - /* The module setup function will register the endpoint server, - * necessary to setup the endpoints below. It is not possible to - * register it here because MDS service is built as a module. - */ - ok = setup_rpc_module(ev_ctx, msg_ctx, "mdssvc"); - if (!ok) { - DBG_ERR("Failed to setup DCE/RPC module\n"); - exit(1); - } - - DBG_INFO("Reinitializing DCE/RPC server context\n"); - - status = dcesrv_reinit_context(dce_ctx); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to reinit DCE/RPC context: %s\n", - nt_errstr(status)); - exit(1); - } - - DBG_INFO("Initializing DCE/RPC registered endpoint servers\n"); - - /* Init ep servers */ - status = dcesrv_init_ep_server(dce_ctx, "mdssvc"); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to init DCE/RPC endpoint server: %s\n", - nt_errstr(status)); - exit(1); - } - - status = mdssd_create_sockets(ev_ctx, - msg_ctx, - dce_ctx, - dce_ctx, - &listen_fd, - &listen_fd_size); - if (!NT_STATUS_IS_OK(status)) { - exit(1); - } - - /* start children before any more initialization is done */ - ok = prefork_create_pool(ev_ctx, /* mem_ctx */ - ev_ctx, - msg_ctx, - listen_fd_size, - listen_fd, - pf_mdssd_cfg.min_children, - pf_mdssd_cfg.max_children, - &mdssd_children_main, - dce_ctx, - &mdssd_pool); - TALLOC_FREE(listen_fd); - if (!ok) { - exit(1); - } - - messaging_register(msg_ctx, - ev_ctx, - MSG_SMB_CONF_UPDATED, - mdssd_smb_conf_updated); - messaging_register(msg_ctx, ev_ctx, - MSG_PREFORK_CHILD_EVENT, child_ping); - - ok = mdssd_setup_children_monitor(ev_ctx, msg_ctx); - if (!ok) { - exit(1); - } - - DEBUG(1, ("mdssd Daemon Started (%u)\n", (unsigned int)getpid())); - - /* loop forever */ - rc = tevent_loop_wait(ev_ctx); - - /* should not be reached */ - DEBUG(0,("mdssd: tevent_loop_wait() exited with %d - %s\n", - rc, (rc == 0) ? "out of events" : strerror(errno))); - exit(1); -} diff --git a/source3/rpc_server/mdssd.h b/source3/rpc_server/mdssd.h deleted file mode 100644 index 8a008b43227..00000000000 --- a/source3/rpc_server/mdssd.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * MDSSD header file - * - * Copyright (c) 2018 Volker Lendecke - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef __RPC_SERVER_MDSSD_H__ -#define __RPC_SERVER_MDSSD_H__ - -#include "replace.h" -#include "messages.h" - -struct dcesrv_context; - -void start_mdssd(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx); - -#endif diff --git a/source3/rpc_server/rpc_config.c b/source3/rpc_server/rpc_config.c index d5a03560b53..5153e9229c8 100644 --- a/source3/rpc_server/rpc_config.c +++ b/source3/rpc_server/rpc_config.c @@ -73,131 +73,3 @@ void global_dcesrv_context_free(void) { TALLOC_FREE(global_dcesrv_ctx); } - -#if 0 -/* the default is "embedded" so this table - * lists only services that are not using - * the default in order to keep enumerating it - * in rpc_service_mode() as short as possible - */ -struct rpc_service_defaults { - const char *name; - const char *def_mode; -} rpc_service_defaults[] = { - { "epmapper", "disabled" }, - /* { "mdssvc", "embedded" }, */ - /* { "spoolss", "embedded" }, */ - /* { "lsarpc", "embedded" }, */ - /* { "samr", "embedded" }, */ - /* { "netlogon", "embedded" }, */ - { "fssagentrpc", "external" }, - - { NULL, NULL } -}; - -enum rpc_service_mode_e rpc_service_mode(const char *name) -{ - const char *pipe_name = name; - const char *rpcsrv_type; - enum rpc_service_mode_e state; - const char *def; - enum server_role server_role = lp_server_role(); - int i; - - /* Handle pipes with multiple names */ - if (strcmp(pipe_name, "lsass") == 0) { - pipe_name = "lsarpc"; - } else if (strcmp(pipe_name, "plugplay") == 0) { - pipe_name = "ntsvcs"; - } - - def = lp_parm_const_string(GLOBAL_SECTION_SNUM, - "rpc_server", "default", NULL); - if (def == NULL) { - for (i = 0; rpc_service_defaults[i].name; i++) { - if (strcasecmp_m(pipe_name, rpc_service_defaults[i].name) == 0) { - def = rpc_service_defaults[i].def_mode; - break; - } - } - /* if the default is unspecified then use 'embedded' */ - if (def == NULL) { - def = "embedded"; - } - } - - /* - * Only enable the netlogon server by default if we are a - * classic/NT4 domain controller - */ - if (strcasecmp_m(name, "netlogon") == 0) { - switch (server_role) { - case ROLE_STANDALONE: - case ROLE_DOMAIN_MEMBER: - def = "disabled"; - break; - default: - break; - } - } - - rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM, - "rpc_server", pipe_name, def); - - if (strcasecmp_m(rpcsrv_type, "embedded") == 0) { - state = RPC_SERVICE_MODE_EMBEDDED; - } else if (strcasecmp_m(rpcsrv_type, "external") == 0) { - state = RPC_SERVICE_MODE_EXTERNAL; - } else { - state = RPC_SERVICE_MODE_DISABLED; - } - - return state; -} - - -/* the default is "embedded" so this table - * lists only daemons that are not using - * the default in order to keep enumerating it - * in rpc_daemon_type() as short as possible - */ -struct rpc_daemon_defaults { - const char *name; - const char *def_type; -} rpc_daemon_defaults[] = { - { "epmd", "disabled" }, - /* { "spoolssd", "embedded" }, */ - /* { "lsasd", "embedded" }, */ - { "fssd", "disabled" }, - - { NULL, NULL } -}; - -enum rpc_daemon_type_e rpc_daemon_type(const char *name) -{ - const char *rpcsrv_type; - enum rpc_daemon_type_e type; - const char *def; - int i; - - def = "embedded"; - for (i = 0; rpc_daemon_defaults[i].name; i++) { - if (strcasecmp_m(name, rpc_daemon_defaults[i].name) == 0) { - def = rpc_daemon_defaults[i].def_type; - } - } - - rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM, - "rpc_daemon", name, def); - - if (strcasecmp_m(rpcsrv_type, "embedded") == 0) { - type = RPC_DAEMON_EMBEDDED; - } else if (strcasecmp_m(rpcsrv_type, "fork") == 0) { - type = RPC_DAEMON_FORK; - } else { - type = RPC_DAEMON_DISABLED; - } - - return type; -} -#endif diff --git a/source3/rpc_server/rpc_config.h b/source3/rpc_server/rpc_config.h index aa7944e5afb..40d5855cd99 100644 --- a/source3/rpc_server/rpc_config.h +++ b/source3/rpc_server/rpc_config.h @@ -23,54 +23,6 @@ #ifndef _RPC_CONFIG_H #define _RPC_CONFIG_H -#if 0 -enum rpc_service_mode_e { - RPC_SERVICE_MODE_DISABLED = 0, - RPC_SERVICE_MODE_EMBEDDED, - RPC_SERVICE_MODE_EXTERNAL -}; - -/** - * @brief Get the mode in which service pipes are configured. - * - * @param name Name of the service - * - * @return The actual configured mode. - */ -enum rpc_service_mode_e rpc_service_mode(const char *name); - -#define rpc_epmapper_mode() rpc_service_mode("epmapper") -#define rpc_spoolss_mode() rpc_service_mode("spoolss") -#define rpc_lsarpc_mode() rpc_service_mode("lsarpc") -#define rpc_samr_mode() rpc_service_mode("samr") -#define rpc_netlogon_mode() rpc_service_mode("netlogon") -#define rpc_fssagentrpc_mode() rpc_service_mode("fssagentrpc") -#define rpc_mdssvc_mode() rpc_service_mode("mdssvc") - - - -enum rpc_daemon_type_e { - RPC_DAEMON_DISABLED = 0, - RPC_DAEMON_EMBEDDED, - RPC_DAEMON_FORK -}; - -/** - * @brief Get the mode in which a server is started. - * - * @param name Name of the rpc server - * - * @return The actual configured type. - */ -enum rpc_daemon_type_e rpc_daemon_type(const char *name); - -#define rpc_epmapper_daemon() rpc_daemon_type("epmd") -#define rpc_spoolss_daemon() rpc_daemon_type("spoolssd") -#define rpc_lsasd_daemon() rpc_daemon_type("lsasd") -#define rpc_fss_daemon() rpc_daemon_type("fssd") -#define rpc_mdssd_daemon() rpc_daemon_type("mdssd") -#endif - struct dcesrv_context; struct dcesrv_context *global_dcesrv_context(void); void global_dcesrv_context_free(void); diff --git a/source3/rpc_server/rpc_ep_register.c b/source3/rpc_server/rpc_ep_register.c deleted file mode 100644 index cf28f04d207..00000000000 --- a/source3/rpc_server/rpc_ep_register.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * RPC Endpoint Registration - * - * Copyright (c) 2011 Andreas Schneider - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include "includes.h" -#include "ntdomain.h" - -#include "../librpc/gen_ndr/ndr_epmapper_c.h" - -#include "librpc/rpc/dcerpc_ep.h" -#include "librpc/rpc/dcesrv_core.h" -#include "rpc_server/rpc_ep_register.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -static void rpc_ep_register_loop(struct tevent_req *subreq); -static NTSTATUS rpc_ep_try_register(TALLOC_CTX *mem_ctx, - struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - const struct dcesrv_interface *iface, - struct dcerpc_binding_handle **pbh); - -struct rpc_ep_register_state { - struct dcerpc_binding_handle *h; - - struct tevent_context *ev_ctx; - struct messaging_context *msg_ctx; - struct dcesrv_context *dce_ctx; - - const struct dcesrv_interface *iface; - - uint32_t wait_time; -}; - -NTSTATUS rpc_ep_register(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - const struct dcesrv_interface *iface) -{ - struct rpc_ep_register_state *state; - struct tevent_req *req; - - /* Allocate under iface to stop the loop if the interface is - * removed from server */ - state = talloc_zero(iface, struct rpc_ep_register_state); - if (state == NULL) { - return NT_STATUS_NO_MEMORY; - } - - state->wait_time = 1; - state->ev_ctx = ev_ctx; - state->msg_ctx = msg_ctx; - state->dce_ctx = dce_ctx; - state->iface = iface; - - req = tevent_wakeup_send(state, - state->ev_ctx, - timeval_current_ofs(1, 0)); - if (req == NULL) { - talloc_free(state); - return NT_STATUS_NO_MEMORY; - } - - tevent_req_set_callback(req, rpc_ep_register_loop, state); - - return NT_STATUS_OK; -} - -#define MONITOR_WAIT_TIME 30 -static void rpc_ep_monitor_loop(struct tevent_req *subreq); - -static void rpc_ep_register_loop(struct tevent_req *subreq) -{ - struct rpc_ep_register_state *state = - tevent_req_callback_data(subreq, struct rpc_ep_register_state); - NTSTATUS status; - bool ok; - - ok = tevent_wakeup_recv(subreq); - TALLOC_FREE(subreq); - if (!ok) { - talloc_free(state); - return; - } - - status = rpc_ep_try_register(state, - state->ev_ctx, - state->msg_ctx, - state->dce_ctx, - state->iface, - &state->h); - if (NT_STATUS_IS_OK(status)) { - /* endpoint registered, monitor the connnection. */ - subreq = tevent_wakeup_send(state, - state->ev_ctx, - timeval_current_ofs(MONITOR_WAIT_TIME, 0)); - if (subreq == NULL) { - talloc_free(state); - return; - } - - tevent_req_set_callback(subreq, rpc_ep_monitor_loop, state); - return; - } - - state->wait_time = state->wait_time * 2; - if (state->wait_time > 16) { - DEBUG(0, ("Failed to register endpoint '%s'!\n", - state->iface->name)); - state->wait_time = 16; - } - - subreq = tevent_wakeup_send(state, - state->ev_ctx, - timeval_current_ofs(state->wait_time, 0)); - if (subreq == NULL) { - talloc_free(state); - return; - } - - tevent_req_set_callback(subreq, rpc_ep_register_loop, state); - return; -} - -static NTSTATUS rpc_ep_try_register(TALLOC_CTX *mem_ctx, - struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - const struct dcesrv_interface *iface, - struct dcerpc_binding_handle **pbh) -{ - NTSTATUS status; - - status = dcerpc_ep_register(mem_ctx, - msg_ctx, - dce_ctx, - iface, - &iface->syntax_id.uuid, - iface->name, - pbh); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - return status; -} - -/* - * Monitor the connection to the endpoint mapper and if it goes away, try to - * register the endpoint. - */ -static void rpc_ep_monitor_loop(struct tevent_req *subreq) -{ - struct rpc_ep_register_state *state = - tevent_req_callback_data(subreq, struct rpc_ep_register_state); - struct policy_handle entry_handle; - struct dcerpc_binding *map_binding; - struct epm_twr_p_t towers[10]; - struct epm_twr_t *map_tower; - uint32_t num_towers = 0; - struct GUID object; - NTSTATUS status; - uint32_t result = EPMAPPER_STATUS_CANT_PERFORM_OP; - TALLOC_CTX *tmp_ctx; - bool ok; - - ZERO_STRUCT(object); - ZERO_STRUCT(entry_handle); - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - talloc_free(state); - return; - } - - ok = tevent_wakeup_recv(subreq); - TALLOC_FREE(subreq); - if (!ok) { - talloc_free(tmp_ctx); - talloc_free(state); - return; - } - - /* Create map tower */ - status = dcerpc_parse_binding(tmp_ctx, "ncacn_np:", &map_binding); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - talloc_free(state); - return; - } - - status = dcerpc_binding_set_abstract_syntax(map_binding, - &state->iface->syntax_id); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - talloc_free(state); - return; - } - - map_tower = talloc_zero(tmp_ctx, struct epm_twr_t); - if (map_tower == NULL) { - talloc_free(tmp_ctx); - talloc_free(state); - return; - } - - status = dcerpc_binding_build_tower(map_tower, map_binding, - &map_tower->tower); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - talloc_free(state); - return; - } - - ok = false; - status = dcerpc_epm_Map(state->h, - tmp_ctx, - &object, - map_tower, - &entry_handle, - 10, - &num_towers, - towers, - &result); - if (NT_STATUS_IS_OK(status)) { - ok = true; - } - if (result == EPMAPPER_STATUS_OK || - result == EPMAPPER_STATUS_NO_MORE_ENTRIES) { - ok = true; - } - if (num_towers == 0) { - ok = false; - } - - dcerpc_epm_LookupHandleFree(state->h, - tmp_ctx, - &entry_handle, - &result); - talloc_free(tmp_ctx); - - subreq = tevent_wakeup_send(state, - state->ev_ctx, - timeval_current_ofs(MONITOR_WAIT_TIME, 0)); - if (subreq == NULL) { - talloc_free(state); - return; - } - - if (ok) { - tevent_req_set_callback(subreq, rpc_ep_monitor_loop, state); - } else { - TALLOC_FREE(state->h); - state->wait_time = 1; - - tevent_req_set_callback(subreq, rpc_ep_register_loop, state); - } - - return; -} diff --git a/source3/rpc_server/rpc_ep_register.h b/source3/rpc_server/rpc_ep_register.h deleted file mode 100644 index cd61778edda..00000000000 --- a/source3/rpc_server/rpc_ep_register.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * RPC Endpoint Registration - * - * Copyright (c) 2011 Andreas Schneider - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef _RPC_EP_REGISTER_H -#define _RPC_EP_REGISTER_H - -struct dcesrv_context; -struct dcesrv_interface; - -/** - * @brief Register an endpoint at the endpoint mapper. - * - * This just sets up a register and monitor loop to try to regsiter the - * endpoint at the endpoint mapper. - * - * @param[in] ev_ctx The event context to setup the loop. - * - * @param[in] msg_ctx The messaging context to use for the connnection. - * - * @param[in] iface The interface table to register. - * - * @param[in] v The binding vector to register. - * - * @return NT_STATUS_OK on success or a corresponding error code. - */ -NTSTATUS rpc_ep_register(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - const struct dcesrv_interface *iface); - -#endif /* _RPC_EP_REGISTER_H */ - -/* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */ diff --git a/source3/rpc_server/rpc_modules.c b/source3/rpc_server/rpc_modules.c deleted file mode 100644 index be678eb5f81..00000000000 --- a/source3/rpc_server/rpc_modules.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * SMBD RPC modules - * - * Copyright (c) 2015 Ralph Boehme - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include "includes.h" -#include "rpc_server/rpc_modules.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -static struct rpc_module *rpc_modules; - -struct rpc_module { - struct rpc_module *prev, *next; - char *name; - struct rpc_module_fns *fns; -}; - -static struct rpc_module *find_rpc_module(const char *name) -{ - struct rpc_module *module = NULL; - - for (module = rpc_modules; module != NULL; module = module->next) { - if (strequal(module->name, name)) { - return module; - } - } - - return NULL; -} - -NTSTATUS register_rpc_module(struct rpc_module_fns *fns, - const char *name) -{ - struct rpc_module *module = find_rpc_module(name); - - if (module != NULL) { - DBG_ERR("RPC module %s already loaded!\n", name); - return NT_STATUS_OBJECT_NAME_COLLISION; - } - - module = SMB_XMALLOC_P(struct rpc_module); - module->name = smb_xstrdup(name); - module->fns = fns; - - DLIST_ADD(rpc_modules, module); - DBG_NOTICE("Successfully added RPC module '%s'\n", name); - - return NT_STATUS_OK; -} - -bool setup_rpc_module(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - const char *name) -{ - bool ok; - struct rpc_module *module = find_rpc_module(name); - - if (module == NULL) { - return false; - } - - ok = module->fns->setup(ev_ctx, msg_ctx); - if (!ok) { - DBG_ERR("calling setup for %s failed\n", name); - } - - return true; -} - -bool setup_rpc_modules(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - bool ok; - struct rpc_module *module = rpc_modules; - - for (module = rpc_modules; module; module = module->next) { - ok = module->fns->setup(ev_ctx, msg_ctx); - if (!ok) { - DBG_ERR("calling setup for %s failed\n", module->name); - } - } - - return true; -} diff --git a/source3/rpc_server/rpc_modules.h b/source3/rpc_server/rpc_modules.h deleted file mode 100644 index ccdaabb4cce..00000000000 --- a/source3/rpc_server/rpc_modules.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * SMBD RPC modules - * - * Copyright (c) 2015 Ralph Boehme - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef _RPC_MODULES_H -#define _RPC_MODULES_H - -struct rpc_module_fns { - bool (*setup)(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx); -}; - -NTSTATUS register_rpc_module(struct rpc_module_fns *fns, - const char *name); - -bool setup_rpc_modules(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx); - -bool setup_rpc_module(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - const char *name); -#endif diff --git a/source3/rpc_server/rpc_ncacn_np.c b/source3/rpc_server/rpc_ncacn_np.c index 322516deb6d..a5dc8707b19 100644 --- a/source3/rpc_server/rpc_ncacn_np.c +++ b/source3/rpc_server/rpc_ncacn_np.c @@ -78,581 +78,6 @@ fail: return NULL; } -#if 0 -NTSTATUS make_internal_rpc_pipe_socketpair( - TALLOC_CTX *mem_ctx, - struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - struct dcesrv_endpoint *endpoint, - 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 dcerpc_ncacn_conn *ncacn_conn = NULL; - struct dcesrv_connection *dcesrv_conn = NULL; - struct npa_state *npa; - NTSTATUS status; - int rc; - enum dcerpc_transport_t transport = dcerpc_binding_get_transport( - endpoint->ep_description); - const char *pipe_name = dcerpc_binding_get_string_option( - endpoint->ep_description, "endpoint"); - - 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; - - status = dcerpc_ncacn_conn_init(npa, - ev_ctx, - msg_ctx, - dce_ctx, - endpoint, - NULL, /* termination fn */ - NULL, /* termination data */ - &ncacn_conn); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - - npa->private_data = (void*)ncacn_conn; - - rc = tstream_npa_socketpair(npa->file_type, - npa, - &npa->stream, - ncacn_conn, - &ncacn_conn->tstream); - if (rc == -1) { - status = map_nt_error_from_unix(errno); - goto out; - } - - ncacn_conn->remote_client_addr = tsocket_address_copy(remote_address, - ncacn_conn); - if (ncacn_conn->remote_client_addr == NULL) { - status = NT_STATUS_NO_MEMORY; - goto out; - } - - ncacn_conn->remote_client_name = tsocket_address_inet_addr_string( - ncacn_conn->remote_client_addr, ncacn_conn); - if (ncacn_conn->remote_client_name == NULL) { - status = NT_STATUS_NO_MEMORY; - goto out; - } - - ncacn_conn->local_server_addr = tsocket_address_copy(local_address, - ncacn_conn); - if (ncacn_conn->local_server_addr == NULL) { - status = NT_STATUS_NO_MEMORY; - goto out; - } - - ncacn_conn->local_server_name = tsocket_address_inet_addr_string( - ncacn_conn->local_server_addr, ncacn_conn); - if (ncacn_conn->local_server_name == NULL) { - status = NT_STATUS_NO_MEMORY; - goto out; - } - - ncacn_conn->session_info = copy_session_info(ncacn_conn, session_info); - if (ncacn_conn->session_info == NULL) { - status = NT_STATUS_NO_MEMORY; - goto out; - } - - rc = make_base_pipes_struct(ncacn_conn, - ncacn_conn->msg_ctx, - pipe_name, - transport, - ncacn_conn->remote_client_addr, - ncacn_conn->local_server_addr, - &ncacn_conn->p); - if (rc != 0) { - status = map_nt_error_from_unix(rc); - goto out; - } - - /* - * This fills in dcesrv_conn->endpoint with the endpoint - * associated with the socket. From this point on we know - * which (group of) services we are handling, but not the - * specific interface. - */ - status = dcesrv_endpoint_connect(ncacn_conn->dce_ctx, - ncacn_conn, - ncacn_conn->endpoint, - ncacn_conn->session_info, - ncacn_conn->ev_ctx, - DCESRV_CALL_STATE_FLAG_MAY_ASYNC, - &dcesrv_conn); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to connect to endpoint: %s\n", - nt_errstr(status)); - goto out; - } - - dcesrv_conn->transport.private_data = ncacn_conn; - dcesrv_conn->transport.report_output_data = - dcesrv_sock_report_output_data; - dcesrv_conn->transport.terminate_connection = - dcesrv_transport_terminate_connection; - dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, - "dcesrv send queue"); - if (dcesrv_conn->send_queue == NULL) { - status = NT_STATUS_NO_MEMORY; - DBG_ERR("Failed to create send queue: %s\n", - nt_errstr(status)); - goto out; - } - - dcesrv_conn->stream = talloc_move(dcesrv_conn, &ncacn_conn->tstream); - dcesrv_conn->local_address = ncacn_conn->local_server_addr; - dcesrv_conn->remote_address = ncacn_conn->remote_client_addr; - - status = dcesrv_connection_loop_start(dcesrv_conn); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to start dcesrv_connection loop: %s\n", - nt_errstr(status)); - goto out; - } - - *pnpa = talloc_move(mem_ctx, &npa); - status = NT_STATUS_OK; -out: - talloc_free(tmp_ctx); - return status; -} - -static NTSTATUS make_internal_ncacn_conn(TALLOC_CTX *mem_ctx, - const struct ndr_interface_table *table, - const struct tsocket_address *remote_address, - const struct tsocket_address *local_address, - const struct auth_session_info *session_info, - struct messaging_context *msg_ctx, - struct dcerpc_ncacn_conn **_out) -{ - struct dcerpc_ncacn_conn *ncacn_conn = NULL; - const char *pipe_name = NULL; - NTSTATUS status; - int ret; - - pipe_name = dcerpc_default_transport_endpoint(mem_ctx, - NCACN_NP, - table); - - DBG_INFO("Create pipe requested %s\n", pipe_name); - - ncacn_conn = talloc_zero(mem_ctx, struct dcerpc_ncacn_conn); - if (ncacn_conn == NULL) { - return NT_STATUS_NO_MEMORY; - } - - ncacn_conn->msg_ctx = msg_ctx; - - if (remote_address != NULL) { - ncacn_conn->remote_client_addr = - tsocket_address_copy(remote_address, ncacn_conn); - if (ncacn_conn->remote_client_addr == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - } - - if (local_address != NULL) { - ncacn_conn->local_server_addr = - tsocket_address_copy(local_address, ncacn_conn); - if (ncacn_conn->local_server_addr == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - } - - ncacn_conn->session_info = copy_session_info(ncacn_conn, session_info); - if (ncacn_conn->session_info == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - - ret = make_base_pipes_struct(ncacn_conn, - msg_ctx, - pipe_name, - NCALRPC, - ncacn_conn->remote_client_addr, - ncacn_conn->local_server_addr, - &ncacn_conn->p); - if (ret) { - DBG_ERR("No memory for pipes_struct!\n"); - status = NT_STATUS_NO_MEMORY; - goto fail; - } - - DEBUG(4,("Created internal pipe %s\n", pipe_name)); - - *_out = ncacn_conn; - - return NT_STATUS_OK; - -fail: - talloc_free(ncacn_conn); - return status; -} - -static NTSTATUS find_ncalrpc_default_endpoint(struct dcesrv_context *dce_ctx, - const struct ndr_interface_table *ndr_table, - struct dcesrv_endpoint **ep) -{ - TALLOC_CTX *tmp_ctx = NULL; - struct dcerpc_binding *binding = NULL; - const char *ep_description = NULL; - NTSTATUS status; - - tmp_ctx = talloc_new(dce_ctx); - if (tmp_ctx == NULL) { - return NT_STATUS_NO_MEMORY; - } - - if (rpc_service_mode(ndr_table->name) == RPC_SERVICE_MODE_EXTERNAL) { - ep_description = talloc_asprintf(tmp_ctx, "ncalrpc:[%s]", - talloc_strdup_upper(tmp_ctx, ndr_table->name)); - if (ep_description == NULL) { - status = NT_STATUS_NO_MEMORY; - goto out; - } - - status = dcerpc_parse_binding(tmp_ctx, ep_description, &binding); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - - status = dcesrv_find_endpoint(dce_ctx, binding, ep); - if (NT_STATUS_IS_OK(status)) { - goto out; - } - } - - /* - * Some services use a rpcint binding handle in their initialization, - * before the server is fully initialized. Search the NCALRPC endpoint - * with and without endpoint - */ - status = dcerpc_parse_binding(tmp_ctx, "ncalrpc:", &binding); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - - status = dcesrv_find_endpoint(dce_ctx, binding, ep); - if (NT_STATUS_IS_OK(status)) { - goto out; - } - - if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) { - ep_description = "ncalrpc:[SMBD]"; - } else { - ep_description = "ncalrpc:[DEFAULT]"; - } - - status = dcerpc_parse_binding(tmp_ctx, ep_description, &binding); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - - status = dcesrv_find_endpoint(dce_ctx, binding, ep); - if (!NT_STATUS_IS_OK(status)) { - goto out; - } - -out: - talloc_free(tmp_ctx); - return status; -} - -static NTSTATUS make_internal_dcesrv_connection(TALLOC_CTX *mem_ctx, - const struct ndr_interface_table *ndr_table, - struct dcerpc_ncacn_conn *ncacn_conn, - struct dcesrv_connection **_out) -{ - struct dcesrv_connection *conn = NULL; - struct dcesrv_connection_context *context = NULL; - struct dcesrv_endpoint *endpoint = NULL; - NTSTATUS status; - - conn = talloc_zero(mem_ctx, struct dcesrv_connection); - if (conn == NULL) { - return NT_STATUS_NO_MEMORY; - } - conn->dce_ctx = global_dcesrv_context(); - conn->preferred_transfer = &ndr_transfer_syntax_ndr; - conn->transport.private_data = ncacn_conn; - - status = find_ncalrpc_default_endpoint(conn->dce_ctx, ndr_table, &endpoint); - if (!NT_STATUS_IS_OK(status)) { - goto fail; - } - conn->endpoint = endpoint; - - conn->default_auth_state = talloc_zero(conn, struct dcesrv_auth); - if (conn->default_auth_state == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - conn->default_auth_state->session_info = ncacn_conn->session_info; - conn->default_auth_state->auth_finished = true; - - context = talloc_zero(conn, struct dcesrv_connection_context); - if (context == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - context->conn = conn; - context->context_id = 0; - context->transfer_syntax = *(conn->preferred_transfer); - context->iface = find_interface_by_syntax_id( - conn->endpoint, &ndr_table->syntax_id); - if (context->iface == NULL) { - status = NT_STATUS_RPC_INTERFACE_NOT_FOUND; - goto fail; - } - - DLIST_ADD(conn->contexts, context); - - *_out = conn; - - return NT_STATUS_OK; -fail: - talloc_free(conn); - return status; -} - -struct rpcint_bh_state { - struct dcesrv_connection *conn; -}; - -static bool rpcint_bh_is_connected(struct dcerpc_binding_handle *h) -{ - struct rpcint_bh_state *hs = dcerpc_binding_handle_data(h, - struct rpcint_bh_state); - - if (hs->conn == NULL) { - return false; - } - - return true; -} - -static uint32_t rpcint_bh_set_timeout(struct dcerpc_binding_handle *h, - uint32_t timeout) -{ - /* TODO: implement timeouts */ - return UINT32_MAX; -} - -struct rpcint_bh_raw_call_state { - struct dcesrv_call_state *call; -}; - -static struct tevent_req *rpcint_bh_raw_call_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct dcerpc_binding_handle *h, - const struct GUID *object, - uint32_t opnum, - uint32_t in_flags, - const uint8_t *in_data, - size_t in_length) -{ - struct rpcint_bh_state *hs = - dcerpc_binding_handle_data(h, - struct rpcint_bh_state); - struct tevent_req *req; - struct rpcint_bh_raw_call_state *state; - struct dcesrv_context *dce_ctx = global_dcesrv_context(); - bool ok; - NTSTATUS status; - - req = tevent_req_create(mem_ctx, &state, - struct rpcint_bh_raw_call_state); - if (req == NULL) { - return NULL; - } - - ok = rpcint_bh_is_connected(h); - if (!ok) { - tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED); - return tevent_req_post(req, ev); - } - - state->call = talloc_zero(state, struct dcesrv_call_state); - if (tevent_req_nomem(state->call, req)) { - return tevent_req_post(req, ev); - } - - state->call->event_ctx = ev; - state->call->conn = hs->conn; - state->call->context = hs->conn->contexts; - state->call->auth_state = hs->conn->default_auth_state; - - if (hs->conn->assoc_group == NULL) { - ZERO_STRUCT(state->call->pkt); - state->call->pkt.u.bind.assoc_group_id = 0; - status = dce_ctx->callbacks->assoc_group.find( - state->call, - dce_ctx->callbacks->assoc_group.private_data); - if (tevent_req_nterror(req, status)) { - return tevent_req_post(req, ev); - } - } - - ZERO_STRUCT(state->call->pkt); - state->call->pkt.u.request.opnum = opnum; - state->call->pkt.u.request.context_id = 0; - state->call->pkt.u.request.stub_and_verifier.data = discard_const_p(uint8_t, in_data); - state->call->pkt.u.request.stub_and_verifier.length = in_length; - - /* TODO: allow async */ - status = dcesrv_call_dispatch_local(state->call); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - return tevent_req_post(req, ev); - } - - tevent_req_done(req); - return tevent_req_post(req, ev); -} - -static NTSTATUS rpcint_bh_raw_call_recv(struct tevent_req *req, - TALLOC_CTX *mem_ctx, - uint8_t **out_data, - size_t *out_length, - uint32_t *out_flags) -{ - struct rpcint_bh_raw_call_state *state = - tevent_req_data(req, - struct rpcint_bh_raw_call_state); - struct data_blob_list_item *rep = NULL; - NTSTATUS status; - - if (tevent_req_is_nterror(req, &status)) { - tevent_req_received(req); - return status; - } - - rep = state->call->replies; - DLIST_REMOVE(state->call->replies, rep); - - *out_data = talloc_steal(mem_ctx, rep->blob.data); - *out_length = rep->blob.length; - *out_flags = 0; - - talloc_free(rep); - - tevent_req_received(req); - return NT_STATUS_OK; -} - -struct rpcint_bh_disconnect_state { - uint8_t _dummy; -}; - -static struct tevent_req *rpcint_bh_disconnect_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct dcerpc_binding_handle *h) -{ - struct rpcint_bh_state *hs = dcerpc_binding_handle_data(h, - struct rpcint_bh_state); - struct tevent_req *req; - struct rpcint_bh_disconnect_state *state; - bool ok; - - req = tevent_req_create(mem_ctx, &state, - struct rpcint_bh_disconnect_state); - if (req == NULL) { - return NULL; - } - - ok = rpcint_bh_is_connected(h); - if (!ok) { - tevent_req_nterror(req, NT_STATUS_CONNECTION_DISCONNECTED); - return tevent_req_post(req, ev); - } - - /* - * TODO: do a real async disconnect ... - * - * For now the caller needs to free dcesrv_connection - */ - hs->conn = NULL; - - tevent_req_done(req); - return tevent_req_post(req, ev); -} - -static NTSTATUS rpcint_bh_disconnect_recv(struct tevent_req *req) -{ - NTSTATUS status; - - if (tevent_req_is_nterror(req, &status)) { - tevent_req_received(req); - return status; - } - - tevent_req_received(req); - return NT_STATUS_OK; -} - -static bool rpcint_bh_ref_alloc(struct dcerpc_binding_handle *h) -{ - return true; -} - -static void rpcint_bh_do_ndr_print(struct dcerpc_binding_handle *h, - int ndr_flags, - const void *_struct_ptr, - const struct ndr_interface_call *call) -{ - void *struct_ptr = discard_const(_struct_ptr); - - if (DEBUGLEVEL < 11) { - return; - } - - if (ndr_flags & NDR_IN) { - ndr_print_function_debug(call->ndr_print, - call->name, - ndr_flags, - struct_ptr); - } - if (ndr_flags & NDR_OUT) { - ndr_print_function_debug(call->ndr_print, - call->name, - ndr_flags, - struct_ptr); - } -} - -static const struct dcerpc_binding_handle_ops rpcint_bh_ops = { - .name = "rpcint", - .is_connected = rpcint_bh_is_connected, - .set_timeout = rpcint_bh_set_timeout, - .raw_call_send = rpcint_bh_raw_call_send, - .raw_call_recv = rpcint_bh_raw_call_recv, - .disconnect_send = rpcint_bh_disconnect_send, - .disconnect_recv = rpcint_bh_disconnect_recv, - - .ref_alloc = rpcint_bh_ref_alloc, - .do_ndr_print = rpcint_bh_do_ndr_print, -}; -#endif - static NTSTATUS rpcint_binding_handle_ex(TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *abstract_syntax, const struct ndr_interface_table *ndr_table, @@ -731,453 +156,6 @@ NTSTATUS rpcint_binding_handle(TALLOC_CTX *mem_ctx, msg_ctx, binding_handle); } -#if 0 -/** - * @internal - * - * @brief Create a new RPC client context which uses a local transport. - * - * This creates a local transport. It is a shortcut to directly call the server - * functions and avoid marshalling. - * NOTE: this function should be used only by rpc_pipe_open_interface() - * - * @param[in] mem_ctx The memory context to use. - * - * @param[in] ndr_table the ndr_table_ structure. - * - * @param[in] serversupplied_info The server supplied authentication function. - * - * @param[in] remote_address The client address information. - * - * @param[in] msg_ctx The messaging context to use. - * - * @param[out] presult A pointer to store the connected rpc client pipe. - * - * @return NT_STATUS_OK on success, a corresponding NT status if an - * error occurred. - */ -NTSTATUS rpc_pipe_open_internal(TALLOC_CTX *mem_ctx, - const struct ndr_interface_table *ndr_table, - const struct auth_session_info *session_info, - const struct tsocket_address *remote_address, - const struct tsocket_address *local_address, - struct messaging_context *msg_ctx, - struct rpc_pipe_client **presult) -{ - struct rpc_pipe_client *result; - NTSTATUS status; - - result = talloc_zero(mem_ctx, struct rpc_pipe_client); - if (result == NULL) { - return NT_STATUS_NO_MEMORY; - } - - result->abstract_syntax = ndr_table->syntax_id; - result->transfer_syntax = ndr_transfer_syntax_ndr; - - if (remote_address == NULL) { - struct tsocket_address *local; - int rc; - - rc = tsocket_address_inet_from_strings(mem_ctx, - "ip", - "127.0.0.1", - 0, - &local); - if (rc < 0) { - TALLOC_FREE(result); - return NT_STATUS_NO_MEMORY; - } - - remote_address = local; - } - - result->max_xmit_frag = -1; - - status = rpcint_binding_handle(result, - ndr_table, - remote_address, - local_address, - session_info, - msg_ctx, - &result->binding_handle); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(result); - return status; - } - - *presult = result; - return NT_STATUS_OK; -} - -/**************************************************************************** - * External pipes functions - ***************************************************************************/ - -NTSTATUS make_external_rpc_pipe(TALLOC_CTX *mem_ctx, - const char *pipe_name, - const struct tsocket_address *remote_client_address, - const struct tsocket_address *local_server_address, - const struct auth_session_info *session_info, - struct npa_state **pnpa) -{ - TALLOC_CTX *tmp_ctx = talloc_stackframe(); - struct auth_session_info_transport *session_info_t; - struct tevent_context *ev_ctx; - struct tevent_req *subreq; - const char *socket_np_dir; - const char *socket_dir; - struct npa_state *npa; - int sys_errno; - NTSTATUS status; - int rc = -1; - bool ok; - - npa = npa_state_init(tmp_ctx); - if (npa == NULL) { - status = NT_STATUS_NO_MEMORY; - goto out; - } - - socket_dir = lp_parm_const_string(GLOBAL_SECTION_SNUM, - "external_rpc_pipe", - "socket_dir", - lp_ncalrpc_dir()); - if (socket_dir == NULL) { - DEBUG(0, ("external_rpc_pipe: socket_dir not set\n")); - status = NT_STATUS_PIPE_NOT_AVAILABLE; - goto out; - } - - socket_np_dir = talloc_asprintf(tmp_ctx, "%s/np", socket_dir); - if (socket_np_dir == NULL) { - DEBUG(0, ("talloc_asprintf failed\n")); - status = NT_STATUS_NO_MEMORY; - goto out; - } - - session_info_t = talloc_zero(tmp_ctx, - struct auth_session_info_transport); - if (session_info_t == NULL) { - DEBUG(0, ("talloc failed\n")); - status = NT_STATUS_NO_MEMORY; - goto out; - } - - session_info_t->session_info = copy_session_info(session_info_t, - session_info); - if (session_info_t->session_info == NULL) { - DEBUG(0, ("copy_session_info failed\n")); - status = NT_STATUS_NO_MEMORY; - goto out; - } - - ev_ctx = samba_tevent_context_init(tmp_ctx); - if (ev_ctx == NULL) { - DEBUG(0, ("samba_tevent_context_init failed\n")); - status = NT_STATUS_NO_MEMORY; - goto out; - } - - become_root(); - subreq = tstream_npa_connect_send(tmp_ctx, - ev_ctx, - socket_np_dir, - pipe_name, - NCACN_NP, - remote_client_address, - NULL, /* client_name */ - local_server_address, - NULL, /* server_name */ - session_info_t); - if (subreq == NULL) { - unbecome_root(); - DEBUG(0, ("tstream_npa_connect_send to %s for pipe %s and " - "user %s\\%s failed\n", - socket_np_dir, pipe_name, session_info_t->session_info->info->domain_name, - session_info_t->session_info->info->account_name)); - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto out; - } - ok = tevent_req_poll(subreq, ev_ctx); - unbecome_root(); - if (!ok) { - DEBUG(0, ("tevent_req_poll to %s for pipe %s and user %s\\%s " - "failed for tstream_npa_connect: %s\n", - socket_np_dir, - pipe_name, - session_info_t->session_info->info->domain_name, - session_info_t->session_info->info->account_name, - strerror(errno))); - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto out; - } - - rc = tstream_npa_connect_recv(subreq, - &sys_errno, - npa, - &npa->stream, - &npa->file_type, - &npa->device_state, - &npa->allocation_size); - talloc_free(subreq); - if (rc != 0) { - int l = 1; - - if (errno == ENOENT) { - l = 2; - } - - DEBUG(l, ("tstream_npa_connect_recv to %s for pipe %s and " - "user %s\\%s failed: %s\n", - socket_np_dir, - pipe_name, - session_info_t->session_info->info->domain_name, - session_info_t->session_info->info->account_name, - strerror(sys_errno))); - status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto out; - } - - *pnpa = talloc_steal(mem_ctx, npa); - status = NT_STATUS_OK; -out: - talloc_free(tmp_ctx); - - return status; -} - -static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx, - const char *pipe_name, - const struct tsocket_address *remote_address, - const struct tsocket_address *local_address, - const struct auth_session_info *session_info) -{ - struct np_proxy_state *result; - char *socket_np_dir; - const char *socket_dir; - struct tevent_context *ev; - struct tevent_req *subreq; - struct auth_session_info_transport *session_info_t; - bool ok; - int ret; - int sys_errno; - - result = talloc(mem_ctx, struct np_proxy_state); - if (result == NULL) { - DEBUG(0, ("talloc failed\n")); - return NULL; - } - - result->read_queue = tevent_queue_create(result, "np_read"); - if (result->read_queue == NULL) { - DEBUG(0, ("tevent_queue_create failed\n")); - goto fail; - } - - result->write_queue = tevent_queue_create(result, "np_write"); - if (result->write_queue == NULL) { - DEBUG(0, ("tevent_queue_create failed\n")); - goto fail; - } - - ev = samba_tevent_context_init(talloc_tos()); - if (ev == NULL) { - DEBUG(0, ("samba_tevent_context_init failed\n")); - goto fail; - } - - socket_dir = lp_parm_const_string( - GLOBAL_SECTION_SNUM, "external_rpc_pipe", "socket_dir", - lp_ncalrpc_dir()); - if (socket_dir == NULL) { - DEBUG(0, ("external_rpc_pipe:socket_dir not set\n")); - goto fail; - } - socket_np_dir = talloc_asprintf(talloc_tos(), "%s/np", socket_dir); - if (socket_np_dir == NULL) { - DEBUG(0, ("talloc_asprintf failed\n")); - goto fail; - } - - session_info_t = talloc_zero(talloc_tos(), struct auth_session_info_transport); - if (session_info_t == NULL) { - DEBUG(0, ("talloc failed\n")); - goto fail; - } - - session_info_t->session_info = copy_session_info(session_info_t, - session_info); - if (session_info_t->session_info == NULL) { - DEBUG(0, ("copy_session_info failed\n")); - goto fail; - } - - become_root(); - subreq = tstream_npa_connect_send(talloc_tos(), ev, - socket_np_dir, - pipe_name, - NCACN_NP, - remote_address, - NULL, /* client_name */ - local_address, - NULL, /* server_name */ - session_info_t); - if (subreq == NULL) { - unbecome_root(); - DEBUG(0, ("tstream_npa_connect_send to %s for pipe %s and " - "user %s\\%s failed\n", - socket_np_dir, pipe_name, session_info_t->session_info->info->domain_name, - session_info_t->session_info->info->account_name)); - goto fail; - } - ok = tevent_req_poll(subreq, ev); - unbecome_root(); - if (!ok) { - DEBUG(0, ("tevent_req_poll to %s for pipe %s and user %s\\%s " - "failed for tstream_npa_connect: %s\n", - socket_np_dir, pipe_name, session_info_t->session_info->info->domain_name, - session_info_t->session_info->info->account_name, - strerror(errno))); - goto fail; - - } - ret = tstream_npa_connect_recv(subreq, &sys_errno, - result, - &result->npipe, - &result->file_type, - &result->device_state, - &result->allocation_size); - TALLOC_FREE(subreq); - if (ret != 0) { - int l = 1; - if (sys_errno == ENOENT) { - l = 2; - } - DEBUG(l, ("tstream_npa_connect_recv to %s for pipe %s and " - "user %s\\%s failed: %s\n", - socket_np_dir, pipe_name, session_info_t->session_info->info->domain_name, - session_info_t->session_info->info->account_name, - strerror(sys_errno))); - goto fail; - } - - return result; - - fail: - TALLOC_FREE(result); - return NULL; -} - -static NTSTATUS rpc_pipe_open_external(TALLOC_CTX *mem_ctx, - const char *pipe_name, - const struct ndr_interface_table *table, - const struct auth_session_info *session_info, - const struct tsocket_address *remote_client_address, - const struct tsocket_address *local_server_address, - struct rpc_pipe_client **_result) -{ - struct rpc_pipe_client *result = NULL; - struct np_proxy_state *proxy_state = NULL; - struct pipe_auth_data *auth; - struct tsocket_address *remote_client_addr; - struct tsocket_address *local_server_addr; - NTSTATUS status; - int ret; - - if (local_server_address == NULL) { - /* this is an internal connection, fake up ip addresses */ - ret = tsocket_address_inet_from_strings(talloc_tos(), "ip", - NULL, 0, &local_server_addr); - if (ret) { - return NT_STATUS_NO_MEMORY; - } - local_server_address = local_server_addr; - } - - if (remote_client_address == NULL) { - /* this is an internal connection, fake up ip addresses */ - ret = tsocket_address_inet_from_strings(talloc_tos(), "ip", - NULL, 0, &remote_client_addr); - if (ret) { - return NT_STATUS_NO_MEMORY; - } - remote_client_address = remote_client_addr; - } - - proxy_state = make_external_rpc_pipe_p(mem_ctx, pipe_name, - remote_client_address, - local_server_address, - session_info); - if (!proxy_state) { - DEBUG(1, ("Unable to make proxy_state for connection to %s.\n", pipe_name)); - return NT_STATUS_UNSUCCESSFUL; - } - - result = talloc_zero(mem_ctx, struct rpc_pipe_client); - if (result == NULL) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - - result->abstract_syntax = table->syntax_id; - result->transfer_syntax = ndr_transfer_syntax_ndr; - - result->desthost = get_myname(result); - result->srv_name_slash = talloc_asprintf_strupper_m( - result, "\\\\%s", result->desthost); - if ((result->desthost == NULL) || (result->srv_name_slash == NULL)) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - - result->max_xmit_frag = RPC_MAX_PDU_FRAG_LEN; - - status = rpc_transport_tstream_init(result, - &proxy_state->npipe, - &result->transport); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - result->binding_handle = rpccli_bh_create(result, NULL, table); - if (result->binding_handle == NULL) { - status = NT_STATUS_NO_MEMORY; - DEBUG(0, ("Failed to create binding handle.\n")); - goto done; - } - - result->auth = talloc_zero(result, struct pipe_auth_data); - if (!result->auth) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - result->auth->auth_type = DCERPC_AUTH_TYPE_NONE; - result->auth->auth_level = DCERPC_AUTH_LEVEL_NONE; - result->auth->auth_context_id = 0; - - status = rpccli_anon_bind_data(result, &auth); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Failed to initialize anonymous bind.\n")); - goto done; - } - - status = rpc_pipe_bind(result, auth); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Failed to bind external pipe.\n")); - goto done; - } - -done: - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(result); - } - TALLOC_FREE(proxy_state); - *_result = result; - return status; -} -#endif - /** * @brief Create a new RPC client context which uses a local dispatch function * or a remote transport, depending on rpc_server configuration for the diff --git a/source3/rpc_server/rpc_pipes.h b/source3/rpc_server/rpc_pipes.h index bb9fd80f6bb..f0fa5399f57 100644 --- a/source3/rpc_server/rpc_pipes.h +++ b/source3/rpc_server/rpc_pipes.h @@ -26,7 +26,6 @@ #include "source3/librpc/rpc/dcerpc.h" -struct dcesrv_ep_entry_list; struct tsocket_address; struct pipes_struct; struct dcesrv_context; @@ -46,8 +45,6 @@ struct pipes_struct { struct auth_session_info *session_info; struct messaging_context *msg_ctx; - struct dcesrv_ep_entry_list *ep_entries; - struct pipe_auth_data auth; /* diff --git a/source3/rpc_server/rpc_server.c b/source3/rpc_server/rpc_server.c index 809b229e65d..26facad3c97 100644 --- a/source3/rpc_server/rpc_server.c +++ b/source3/rpc_server/rpc_server.c @@ -51,157 +51,6 @@ struct dcerpc_ncacn_listen_state { void *termination_data; }; -#if 0 -static void dcesrv_ncacn_listener( - struct tevent_context *ev, - struct tevent_fd *fde, - uint16_t flags, - void *private_data); - -int dcesrv_setup_ncacn_listener( - TALLOC_CTX *mem_ctx, - struct dcesrv_context *dce_ctx, - struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_endpoint *e, - int *fd, - dcerpc_ncacn_termination_fn term_fn, - void *termination_data, - struct dcerpc_ncacn_listen_state **listen_state) -{ - struct dcerpc_ncacn_listen_state *state = NULL; - struct tevent_fd *fde = NULL; - int rc, err = ENOMEM; - - state = talloc_zero(mem_ctx, struct dcerpc_ncacn_listen_state); - if (state == NULL) { - DBG_ERR("Out of memory\n"); - return ENOMEM; - } - - state->fd = *fd; - state->ev_ctx = ev_ctx; - state->msg_ctx = msg_ctx; - state->dce_ctx = dce_ctx; - state->endpoint = e; - state->termination_fn = term_fn; - state->termination_data = termination_data; - - rc = listen(state->fd, SMBD_LISTEN_BACKLOG); - if (rc < 0) { - err = errno; - DBG_ERR("listen(%d) failed: %s\n", - state->fd, - strerror(err)); - goto fail; - } - - /* Set server socket to non-blocking for the accept. */ - rc = set_blocking(state->fd, false); - if (rc < 0) { - err = errno; - goto fail; - } - - fde = tevent_add_fd( - state->ev_ctx, - state, - state->fd, - TEVENT_FD_READ, - dcesrv_ncacn_listener, - state); - if (fde == NULL) { - err = errno; - DBG_ERR("tevent_add_fd for %d failed: %s\n", - state->fd, - strerror(err)); - goto fail; - } - tevent_fd_set_auto_close(fde); - *fd = -1; - - *listen_state = state; - - return 0; - -fail: - TALLOC_FREE(state); - return err; -} - -static void dcesrv_ncacn_listener( - struct tevent_context *ev, - struct tevent_fd *fde, - uint16_t flags, - void *private_data) -{ - struct dcerpc_ncacn_listen_state *state = talloc_get_type_abort( - private_data, struct dcerpc_ncacn_listen_state); - struct tsocket_address *cli_addr = NULL, *srv_addr = NULL; - struct samba_sockaddr addr = { - .sa_socklen = sizeof(struct samba_sockaddr), - }; - int sd = -1; - int rc; - - sd = accept(state->fd, &addr.u.sa, &addr.sa_socklen); - if (sd == -1) { - if (errno != EINTR) { - DBG_ERR("Failed to accept: %s\n", strerror(errno)); - } - return; - } - smb_set_close_on_exec(sd); - - rc = tsocket_address_bsd_from_samba_sockaddr(state, &addr, &cli_addr); - if (rc < 0) { - goto fail; - } - - rc = getsockname(sd, &addr.u.sa, &addr.sa_socklen); - if (rc < 0) { - goto fail; - } - - rc = tsocket_address_bsd_from_samba_sockaddr(state, &addr, &srv_addr); - if (rc < 0) { - goto fail; - } - - dcerpc_ncacn_accept( - state->ev_ctx, - state->msg_ctx, - state->dce_ctx, - state->endpoint, - &cli_addr, - &srv_addr, - sd, - state->termination_fn, - state->termination_data); - return; - -fail: - TALLOC_FREE(cli_addr); - TALLOC_FREE(srv_addr); - if (sd != -1) { - close(sd); - } -} - -static int dcesrv_connection_destructor(struct dcesrv_connection *conn) -{ - struct dcerpc_ncacn_conn *ncacn_conn = talloc_get_type_abort( - conn->transport.private_data, - struct dcerpc_ncacn_conn); - - if (ncacn_conn->termination_fn != NULL) { - ncacn_conn->termination_fn(conn, ncacn_conn->termination_data); - } - - return 0; -} -#endif - NTSTATUS dcerpc_ncacn_conn_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct messaging_context *msg_ctx, @@ -231,331 +80,9 @@ NTSTATUS dcerpc_ncacn_conn_init(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -#if 0 -static void dcesrv_ncacn_np_accept_done(struct tevent_req *subreq); -static void dcesrv_ncacn_accept_step2(struct dcerpc_ncacn_conn *ncacn_conn); -#endif - static void ncacn_terminate_connection(struct dcerpc_ncacn_conn *conn, const char *reason); -#if 0 -void dcerpc_ncacn_accept(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - struct dcesrv_endpoint *e, - struct tsocket_address **cli_addr, - struct tsocket_address **srv_addr, - int s, - dcerpc_ncacn_termination_fn termination_fn, - void *termination_data) -{ - enum dcerpc_transport_t transport = - dcerpc_binding_get_transport(e->ep_description); - struct dcerpc_ncacn_conn *ncacn_conn; - NTSTATUS status; - int rc; - - DBG_DEBUG("dcerpc_ncacn_accept\n"); - - status = dcerpc_ncacn_conn_init(ev_ctx, - ev_ctx, - msg_ctx, - dce_ctx, - e, - termination_fn, - termination_data, - &ncacn_conn); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to initialize dcerpc_ncacn_connection: %s\n", - nt_errstr(status)); - close(s); - return; - } - - ncacn_conn->sock = s; - - if ((cli_addr != NULL) && (*cli_addr != NULL)) { - ncacn_conn->remote_client_addr = talloc_move( - ncacn_conn, cli_addr); - - if (tsocket_address_is_inet(ncacn_conn->remote_client_addr, "ip")) { - ncacn_conn->remote_client_name = - tsocket_address_inet_addr_string(ncacn_conn->remote_client_addr, - ncacn_conn); - } else { - ncacn_conn->remote_client_name = - tsocket_address_unix_path(ncacn_conn->remote_client_addr, - ncacn_conn); - } - - if (ncacn_conn->remote_client_name == NULL) { - DBG_ERR("Out of memory obtaining remote socket address as a string!\n"); - ncacn_terminate_connection(ncacn_conn, "No memory"); - close(s); - return; - } - } - - if ((srv_addr != NULL) && (*srv_addr != NULL)) { - ncacn_conn->local_server_addr = talloc_move( - ncacn_conn, srv_addr); - - if (tsocket_address_is_inet(ncacn_conn->local_server_addr, "ip")) { - ncacn_conn->local_server_name = - tsocket_address_inet_addr_string(ncacn_conn->local_server_addr, - ncacn_conn); - } else { - ncacn_conn->local_server_name = - tsocket_address_unix_path(ncacn_conn->local_server_addr, - ncacn_conn); - } - if (ncacn_conn->local_server_name == NULL) { - DBG_ERR("No memory\n"); - ncacn_terminate_connection(ncacn_conn, "No memory"); - close(s); - return; - } - } - - rc = set_blocking(s, false); - if (rc < 0) { - DBG_WARNING("Failed to set dcerpc socket to non-blocking\n"); - ncacn_terminate_connection(ncacn_conn, strerror(errno)); - close(s); - return; - } - - /* - * As soon as we have tstream_bsd_existing_socket set up it will - * take care of closing the socket. - */ - rc = tstream_bsd_existing_socket(ncacn_conn, s, &ncacn_conn->tstream); - if (rc < 0) { - DBG_WARNING("Failed to create tstream socket for dcerpc\n"); - ncacn_terminate_connection(ncacn_conn, "No memory"); - close(s); - return; - } - - if (transport == NCACN_NP) { - struct tevent_req *subreq = NULL; - uint64_t allocation_size = 4096; - uint16_t device_state = 0xff | 0x0400 | 0x0100; - uint16_t file_type = FILE_TYPE_MESSAGE_MODE_PIPE; - - subreq = tstream_npa_accept_existing_send(ncacn_conn, - ncacn_conn->ev_ctx, - ncacn_conn->tstream, - file_type, - device_state, - allocation_size); - if (subreq == NULL) { - ncacn_terminate_connection(ncacn_conn, "No memory"); - return; - } - tevent_req_set_callback(subreq, dcesrv_ncacn_np_accept_done, - ncacn_conn); - return; - } - - dcesrv_ncacn_accept_step2(ncacn_conn); -} - -static void dcesrv_ncacn_np_accept_done(struct tevent_req *subreq) -{ - struct dcerpc_ncacn_conn *ncacn_conn = tevent_req_callback_data( - subreq, struct dcerpc_ncacn_conn); - struct auth_session_info_transport *session_info_transport = NULL; - enum dcerpc_transport_t transport; - int error; - int ret; - - ret = tstream_npa_accept_existing_recv(subreq, &error, ncacn_conn, - &ncacn_conn->tstream, - NULL, - &transport, - &ncacn_conn->remote_client_addr, - &ncacn_conn->remote_client_name, - &ncacn_conn->local_server_addr, - &ncacn_conn->local_server_name, - &session_info_transport); - ncacn_conn->session_info = talloc_move(ncacn_conn, - &session_info_transport->session_info); - - if (transport != NCACN_NP) { - ncacn_terminate_connection( - ncacn_conn, - "Only allow NCACN_NP transport on named pipes\n"); - return; - } - - if (security_token_is_system( - ncacn_conn->session_info->security_token)) { - ncacn_terminate_connection( - ncacn_conn, - "No system token via NCACN_NP allowed\n"); - return; - } - - TALLOC_FREE(subreq); - if (ret != 0) { - DBG_ERR("Failed to accept named pipe connection: %s\n", - strerror(error)); - ncacn_terminate_connection(ncacn_conn, strerror(errno)); - return; - } - - dcesrv_ncacn_accept_step2(ncacn_conn); -} - -static void dcesrv_ncacn_accept_step2(struct dcerpc_ncacn_conn *ncacn_conn) -{ - char *pipe_name = NULL; - uid_t uid; - gid_t gid; - int rc; - enum dcerpc_transport_t transport = dcerpc_binding_get_transport( - ncacn_conn->endpoint->ep_description); - const char *endpoint = dcerpc_binding_get_string_option( - ncacn_conn->endpoint->ep_description, "endpoint"); - struct dcesrv_connection *dcesrv_conn = NULL; - NTSTATUS status; - - switch (transport) { - case NCACN_IP_TCP: - pipe_name = tsocket_address_string(ncacn_conn->remote_client_addr, - ncacn_conn); - if (pipe_name == NULL) { - DBG_ERR("No memory\n"); - ncacn_terminate_connection(ncacn_conn, "No memory"); - return; - } - - break; - case NCALRPC: - rc = getpeereid(ncacn_conn->sock, &uid, &gid); - if (rc < 0) { - DEBUG(2, ("Failed to get ncalrpc connecting " - "uid - %s!\n", strerror(errno))); - } else { - if (uid == sec_initial_uid()) { - TALLOC_FREE(ncacn_conn->remote_client_addr); - - rc = tsocket_address_unix_from_path(ncacn_conn, - AS_SYSTEM_MAGIC_PATH_TOKEN, - &ncacn_conn->remote_client_addr); - if (rc < 0) { - DBG_ERR("No memory\n"); - ncacn_terminate_connection(ncacn_conn, "No memory"); - return; - } - - TALLOC_FREE(ncacn_conn->remote_client_name); - ncacn_conn->remote_client_name - = tsocket_address_unix_path(ncacn_conn->remote_client_addr, - ncacn_conn); - if (ncacn_conn->remote_client_name == NULL) { - DBG_ERR("No memory\n"); - ncacn_terminate_connection(ncacn_conn, "No memory"); - return; - } - } - } - - FALL_THROUGH; - case NCACN_NP: - pipe_name = talloc_strdup(ncacn_conn, endpoint); - if (pipe_name == NULL) { - DBG_ERR("No memory\n"); - ncacn_terminate_connection(ncacn_conn, "No memory"); - return; - } - break; - default: - DBG_ERR("unknown dcerpc transport: %u!\n", transport); - ncacn_terminate_connection(ncacn_conn, - "Unknown DCE/RPC transport"); - return; - } - - if (ncacn_conn->session_info == NULL) { - status = make_session_info_anonymous(ncacn_conn, - &ncacn_conn->session_info); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to create anonymous session info: " - "%s\n", nt_errstr(status)); - ncacn_terminate_connection(ncacn_conn, - nt_errstr(status)); - return; - } - } - - rc = make_base_pipes_struct(ncacn_conn, - ncacn_conn->msg_ctx, - pipe_name, - transport, - ncacn_conn->remote_client_addr, - ncacn_conn->local_server_addr, - &ncacn_conn->p); - if (rc != 0) { - const char *errstr = strerror(rc); - DBG_ERR("Failed to create pipe struct: %s\n", errstr); - ncacn_terminate_connection(ncacn_conn, errstr); - return; - } - - /* - * This fills in dcesrv_conn->endpoint with the endpoint - * associated with the socket. From this point on we know - * which (group of) services we are handling, but not the - * specific interface. - */ - status = dcesrv_endpoint_connect(ncacn_conn->dce_ctx, - ncacn_conn, - ncacn_conn->endpoint, - ncacn_conn->session_info, - ncacn_conn->ev_ctx, - DCESRV_CALL_STATE_FLAG_MAY_ASYNC, - &dcesrv_conn); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to connect to endpoint: %s\n", - nt_errstr(status)); - ncacn_terminate_connection(ncacn_conn, nt_errstr(status)); - return; - } - talloc_set_destructor(dcesrv_conn, dcesrv_connection_destructor); - - dcesrv_conn->transport.private_data = ncacn_conn; - dcesrv_conn->transport.report_output_data = - dcesrv_sock_report_output_data; - dcesrv_conn->transport.terminate_connection = - dcesrv_transport_terminate_connection; - dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, - "dcesrv send queue"); - if (dcesrv_conn->send_queue == NULL) { - status = NT_STATUS_NO_MEMORY; - DBG_ERR("Failed to create send queue: %s\n", - nt_errstr(status)); - ncacn_terminate_connection(ncacn_conn, nt_errstr(status)); - return; - } - - dcesrv_conn->stream = talloc_move(dcesrv_conn, &ncacn_conn->tstream); - dcesrv_conn->local_address = ncacn_conn->local_server_addr; - dcesrv_conn->remote_address = ncacn_conn->remote_client_addr; - status = dcesrv_connection_loop_start(dcesrv_conn); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to start dcesrv_connection loop: %s\n", - nt_errstr(status)); - ncacn_terminate_connection(ncacn_conn, nt_errstr(status)); - } - DBG_DEBUG("dcerpc_ncacn_accept done\n"); - - return; -} -#endif - NTSTATUS dcesrv_auth_gensec_prepare( TALLOC_CTX *mem_ctx, struct dcesrv_call_state *call, diff --git a/source3/rpc_server/rpc_service_setup.c b/source3/rpc_server/rpc_service_setup.c deleted file mode 100644 index 2d585af6f47..00000000000 --- a/source3/rpc_server/rpc_service_setup.c +++ /dev/null @@ -1,941 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * SMBD RPC service callbacks - * - * Copyright (c) 2011 Andreas Schneider - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include "includes.h" -#include "ntdomain.h" - -#include "librpc/gen_ndr/ndr_winreg_scompat.h" -#include "librpc/gen_ndr/ndr_srvsvc_scompat.h" -#include "librpc/gen_ndr/ndr_lsa_scompat.h" -#include "librpc/gen_ndr/ndr_samr_scompat.h" -#include "librpc/gen_ndr/ndr_netlogon_scompat.h" -#include "librpc/gen_ndr/ndr_dfs_scompat.h" -#include "librpc/gen_ndr/ndr_echo_scompat.h" -#include "librpc/gen_ndr/ndr_dssetup_scompat.h" -#include "librpc/gen_ndr/ndr_wkssvc_scompat.h" -#include "librpc/gen_ndr/ndr_spoolss_scompat.h" -#include "librpc/gen_ndr/ndr_svcctl_scompat.h" -#include "librpc/gen_ndr/ndr_ntsvcs_scompat.h" -#include "librpc/gen_ndr/ndr_eventlog_scompat.h" -#include "librpc/gen_ndr/ndr_initshutdown_scompat.h" - -#include "printing/nt_printing_migrate_internal.h" -#include "rpc_server/eventlog/srv_eventlog_reg.h" -#include "rpc_server/svcctl/srv_svcctl_reg.h" -#include "rpc_server/spoolss/srv_spoolss_nt.h" -#include "rpc_server/svcctl/srv_svcctl_nt.h" - -#include "lib/server_prefork.h" -#include "librpc/rpc/dcesrv_core.h" -#include "librpc/rpc/dcerpc_ep.h" -#include "rpc_server/rpc_sock_helper.h" -#include "rpc_server/rpc_service_setup.h" -#include "rpc_server/rpc_ep_register.h" -#include "rpc_server/rpc_server.h" -#include "rpc_server/rpc_config.h" -#include "rpc_server/rpc_modules.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -static_decl_rpc; - -/* Common routine for embedded RPC servers */ -NTSTATUS rpc_setup_embedded(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - const struct dcesrv_interface *iface) -{ - enum rpc_service_mode_e epm_mode = rpc_epmapper_mode(); - NTSTATUS status; - - /* Registration of ncacn_np services is problematic. The - * ev_ctx passed in here is passed down to all children of the - * smbd process, and if the end point mapper ever goes away, - * they will all attempt to re-register. But we want to test - * the code for now, so it is enabled in on environment in - * make test */ - if (epm_mode != RPC_SERVICE_MODE_DISABLED && - (lp_parm_bool(-1, "rpc_server", "register_embedded_np", false))) { - status = rpc_ep_register(ev_ctx, msg_ctx, dce_ctx, iface); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - } - - return NT_STATUS_OK; -} - -NTSTATUS dcesrv_create_endpoint_sockets(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_endpoint *e, - TALLOC_CTX *mem_ctx, - size_t *pnum_fds, - int **pfds) -{ - struct dcerpc_binding *b = e->ep_description; - char *binding = NULL; - int *fds = NULL; - size_t num_fds; - NTSTATUS status; - - binding = dcerpc_binding_string(mem_ctx, b); - if (binding == NULL) { - return NT_STATUS_NO_MEMORY; - } - DBG_DEBUG("Creating endpoint '%s'\n", binding); - TALLOC_FREE(binding); - - status = dcesrv_create_binding_sockets(b, mem_ctx, &num_fds, &fds); - - /* Build binding string again as the endpoint may have changed by - * dcesrv_create__socket functions */ - binding = dcerpc_binding_string(mem_ctx, b); - if (binding == NULL) { - return NT_STATUS_NO_MEMORY; - } - - if (!NT_STATUS_IS_OK(status)) { - struct dcesrv_if_list *iface = NULL; - DBG_ERR("Failed to create '%s' sockets for ", binding); - for (iface = e->interface_list; iface; iface = iface->next) { - DEBUGADD(DBGLVL_ERR, ("'%s' ", iface->iface->name)); - } - DEBUGADD(DBGLVL_ERR, (": %s\n", nt_errstr(status))); - return status; - } else { - struct dcesrv_if_list *iface = NULL; - DBG_INFO("Successfully listening on '%s' for ", binding); - for (iface = e->interface_list; iface; iface = iface->next) { - DEBUGADD(DBGLVL_INFO, ("'%s' ", iface->iface->name)); - } - DEBUGADD(DBGLVL_INFO, ("\n")); - } - - TALLOC_FREE(binding); - - *pnum_fds = num_fds; - *pfds = fds; - - return status; -} - -NTSTATUS dcesrv_create_endpoint_list_pf_listen_fds( - struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - struct dcesrv_endpoint *e, - TALLOC_CTX *mem_ctx, - size_t *pnum_fds, - struct pf_listen_fd **pfds) -{ - struct pf_listen_fd *fds = NULL; - size_t num_fds = 0; - NTSTATUS status; - - for (; e != NULL; e = e->next) { - int *ep_fds = NULL; - struct pf_listen_fd *tmp = NULL; - size_t i, num_ep_fds; - - status = dcesrv_create_endpoint_sockets( - ev_ctx, - msg_ctx, - e, - mem_ctx, - &num_ep_fds, - &ep_fds); - if (!NT_STATUS_IS_OK(status)) { - char *ep_string = dcerpc_binding_string( - dce_ctx, e->ep_description); - DBG_ERR("Failed to create endpoint '%s': %s\n", - ep_string, nt_errstr(status)); - TALLOC_FREE(ep_string); - goto fail; - } - - if (num_fds + num_ep_fds < num_fds) { - /* overflow */ - status = NT_STATUS_INTEGER_OVERFLOW; - goto fail; - } - - tmp = talloc_realloc( - mem_ctx, - fds, - struct pf_listen_fd, - num_fds + num_ep_fds); - if (tmp == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - fds = tmp; - - for (i=0; iep_description; - char *binding = NULL; - NTSTATUS status = NT_STATUS_NO_MEMORY; - struct dcesrv_if_list *iface = NULL; - int *fds = NULL; - size_t i, num_fds = 0; - struct dcerpc_ncacn_listen_state **listen_states = NULL; - - binding = dcerpc_binding_string(frame, b); - if (binding == NULL) { - goto fail; - } - - DBG_DEBUG("Setting up endpoint '%s'\n", binding); - TALLOC_FREE(binding); - - status = dcesrv_create_binding_sockets(b, frame, &num_fds, &fds); - - /* Build binding string again as the endpoint may have changed by - * dcesrv_create__socket functions */ - binding = dcerpc_binding_string(frame, b); - if (binding == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to setup '%s' sockets for ", binding); - for (iface = e->interface_list; iface; iface = iface->next) { - DEBUGADD(DBGLVL_ERR, ("'%s' ", iface->iface->name)); - } - DEBUGADD(DBGLVL_ERR, (": %s\n", nt_errstr(status))); - goto fail; - } - - listen_states = talloc_array( - frame, struct dcerpc_ncacn_listen_state *, num_fds); - if (listen_states == NULL) { - status = NT_STATUS_NO_MEMORY; - goto fail; - } - - for (i=0; iinterface_list; iface; iface = iface->next) { - DEBUGADD(DBGLVL_INFO, ("'%s' ", iface->iface->name)); - } - DEBUGADD(DBGLVL_INFO, ("\n")); - - TALLOC_FREE(frame); - return NT_STATUS_OK; - -fail: - for (i=0; iendpoint_list; e; e = e->next) { - enum dcerpc_transport_t transport = - dcerpc_binding_get_transport(e->ep_description); - - if (transport == NCACN_HTTP) { - /* - * We don't support ncacn_http yet - */ - continue; - } - - status = dcesrv_setup_endpoint_sockets(ev_ctx, - msg_ctx, - dce_ctx, - e, - NULL, - NULL); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* Register only NCACN_NP for embedded services */ - if (transport == NCACN_NP) { - struct dcesrv_if_list *ifl = NULL; - for (ifl = e->interface_list; ifl; ifl = ifl->next) { - status = rpc_setup_embedded(ev_ctx, - msg_ctx, - dce_ctx, - ifl->iface); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register embedded " - "interface in endpoint mapper " - ": %s", nt_errstr(status)); - return status; - } - } - } - } - - return NT_STATUS_OK; -} - -static NTSTATUS rpc_setup_winreg(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - NTSTATUS status; - enum rpc_service_mode_e service_mode; - const struct dcesrv_endpoint_server *ep_server = NULL; - - /* Register the endpoint server in DCERPC core */ - ep_server = winreg_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'winreg' endpoint server\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - service_mode = rpc_service_mode(ep_server->name); - if (service_mode != RPC_SERVICE_MODE_EMBEDDED) { - return NT_STATUS_OK; - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register '%s' endpoint server: " - "%s\n", ep_server->name, nt_errstr(status)); - return status; - } - - return NT_STATUS_OK; -} - -static NTSTATUS rpc_setup_srvsvc(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - NTSTATUS status; - enum rpc_service_mode_e service_mode; - const struct dcesrv_endpoint_server *ep_server = NULL; - - /* Register the endpoint server in DCERPC core */ - ep_server = srvsvc_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'srvsvc' endpoint server\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - service_mode = rpc_service_mode(ep_server->name); - if (service_mode != RPC_SERVICE_MODE_EMBEDDED) { - return NT_STATUS_OK; - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register '%s' endpoint server: " - "%s\n", ep_server->name, nt_errstr(status)); - return status; - } - - return NT_STATUS_OK; -} - -static NTSTATUS rpc_setup_lsarpc(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - enum rpc_daemon_type_e lsasd_type = rpc_lsasd_daemon(); - NTSTATUS status; - enum rpc_service_mode_e service_mode; - const struct dcesrv_endpoint_server *ep_server = NULL; - - /* Register the endpoint server in DCERPC core */ - ep_server = lsarpc_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'lsarpc' endpoint server\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - service_mode = rpc_service_mode(ep_server->name); - if (service_mode != RPC_SERVICE_MODE_EMBEDDED || - lsasd_type != RPC_DAEMON_EMBEDDED) { - return NT_STATUS_OK; - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register '%s' endpoint server: " - "%s\n", ep_server->name, nt_errstr(status)); - return status; - } - - return NT_STATUS_OK; -} - -static NTSTATUS rpc_setup_samr(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - enum rpc_daemon_type_e lsasd_type = rpc_lsasd_daemon(); - NTSTATUS status; - enum rpc_service_mode_e service_mode; - const struct dcesrv_endpoint_server *ep_server = NULL; - - /* Register the endpoint server in DCERPC core */ - ep_server = samr_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'samr' endpoint server\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - service_mode = rpc_service_mode(ep_server->name); - if (service_mode != RPC_SERVICE_MODE_EMBEDDED || - lsasd_type != RPC_DAEMON_EMBEDDED) { - return NT_STATUS_OK; - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register '%s' endpoint server: " - "%s\n", ep_server->name, nt_errstr(status)); - return status; - } - - return NT_STATUS_OK; -} - -static NTSTATUS rpc_setup_netlogon(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - enum rpc_daemon_type_e lsasd_type = rpc_lsasd_daemon(); - NTSTATUS status; - enum rpc_service_mode_e service_mode; - const struct dcesrv_endpoint_server *ep_server = NULL; - - /* Register the endpoint server in DCERPC core */ - ep_server = netlogon_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'netlogon' endpoint server\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - service_mode = rpc_service_mode(ep_server->name); - if (service_mode != RPC_SERVICE_MODE_EMBEDDED || - lsasd_type != RPC_DAEMON_EMBEDDED) { - return NT_STATUS_OK; - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register '%s' endpoint server: " - "%s\n", ep_server->name, nt_errstr(status)); - return status; - } - - return NT_STATUS_OK; -} - -static NTSTATUS rpc_setup_netdfs(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - NTSTATUS status; - enum rpc_service_mode_e service_mode; - const struct dcesrv_endpoint_server *ep_server = NULL; - - /* Register the endpoint server in DCERPC core */ - ep_server = netdfs_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'netdfs' endpoint server\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - service_mode = rpc_service_mode(ep_server->name); - if (service_mode != RPC_SERVICE_MODE_EMBEDDED) { - return NT_STATUS_OK; - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register '%s' endpoint server: " - "%s\n", ep_server->name, nt_errstr(status)); - return status; - } - - return NT_STATUS_OK; -} - -#ifdef DEVELOPER -static NTSTATUS rpc_setup_rpcecho(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - NTSTATUS status; - enum rpc_service_mode_e service_mode; - const struct dcesrv_endpoint_server *ep_server = NULL; - - /* Register the endpoint server in DCERPC core */ - ep_server = rpcecho_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'rpcecho' endpoint server\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - service_mode = rpc_service_mode(ep_server->name); - if (service_mode != RPC_SERVICE_MODE_EMBEDDED) { - return NT_STATUS_OK; - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register '%s' endpoint server: " - "%s\n", ep_server->name, nt_errstr(status)); - return status; - } - - return NT_STATUS_OK; -} -#endif - -static NTSTATUS rpc_setup_dssetup(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - NTSTATUS status; - enum rpc_service_mode_e service_mode; - const struct dcesrv_endpoint_server *ep_server = NULL; - - /* Register the endpoint server in DCERPC core */ - ep_server = dssetup_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'dssetup' endpoint server\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - service_mode = rpc_service_mode(ep_server->name); - if (service_mode != RPC_SERVICE_MODE_EMBEDDED) { - return NT_STATUS_OK; - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register '%s' endpoint server: " - "%s\n", ep_server->name, nt_errstr(status)); - return status; - } - - return NT_STATUS_OK; -} - -static NTSTATUS rpc_setup_wkssvc(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - NTSTATUS status; - enum rpc_service_mode_e service_mode; - const struct dcesrv_endpoint_server *ep_server = NULL; - - /* Register the endpoint server in DCERPC core */ - ep_server = wkssvc_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'wkssvc' endpoint server\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - service_mode = rpc_service_mode(ep_server->name); - if (service_mode != RPC_SERVICE_MODE_EMBEDDED) { - return NT_STATUS_OK; - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register '%s' endpoint server: " - "%s\n", ep_server->name, nt_errstr(status)); - return status; - } - - return NT_STATUS_OK; -} - -static NTSTATUS rpc_setup_spoolss(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - enum rpc_daemon_type_e spoolss_type = rpc_spoolss_daemon(); - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - enum rpc_service_mode_e service_mode; - const struct dcesrv_endpoint_server *ep_server = NULL; - - if (lp__disable_spoolss()) { - return NT_STATUS_OK; - } - - /* Register the endpoint server in DCERPC core */ - ep_server = spoolss_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'spoolss' endpoint server\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - service_mode = rpc_service_mode(ep_server->name); - if (service_mode != RPC_SERVICE_MODE_EMBEDDED || - spoolss_type != RPC_DAEMON_EMBEDDED) { - return NT_STATUS_OK; - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register '%s' endpoint server" - ": %s\n", ep_server->name, nt_errstr(status)); - return status; - } - - return NT_STATUS_OK; -} - -static NTSTATUS rpc_setup_svcctl(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - NTSTATUS status; - enum rpc_service_mode_e service_mode; - const struct dcesrv_endpoint_server *ep_server = NULL; - - /* Register the endpoint server in DCERPC core */ - ep_server = svcctl_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'svcctl' endpoint server\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - service_mode = rpc_service_mode(ep_server->name); - if (service_mode != RPC_SERVICE_MODE_EMBEDDED) { - return NT_STATUS_OK; - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register '%s' endpoint server" - ": %s\n", ep_server->name, nt_errstr(status)); - return status; - } - - return NT_STATUS_OK; -} - -static NTSTATUS rpc_setup_ntsvcs(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - NTSTATUS status; - enum rpc_service_mode_e service_mode; - const struct dcesrv_endpoint_server *ep_server = NULL; - - /* Register the endpoint server in DCERPC core */ - ep_server = ntsvcs_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'ntsvcs' endpoint server\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - service_mode = rpc_service_mode(ep_server->name); - if (service_mode != RPC_SERVICE_MODE_EMBEDDED) { - return NT_STATUS_OK; - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register '%s' endpoint server" - ": %s\n", ep_server->name, nt_errstr(status)); - return status; - } - - return NT_STATUS_OK; -} - -static NTSTATUS rpc_setup_eventlog(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - NTSTATUS status; - enum rpc_service_mode_e service_mode; - const struct dcesrv_endpoint_server *ep_server = NULL; - - /* Register the endpoint server in DCERPC core */ - ep_server = eventlog_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'eventlog' endpoint server\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - service_mode = rpc_service_mode(ep_server->name); - if (service_mode != RPC_SERVICE_MODE_EMBEDDED) { - return NT_STATUS_OK; - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register '%s' endpoint server" - ": %s\n", ep_server->name, nt_errstr(status)); - return status; - } - - return NT_STATUS_OK; -} - -static NTSTATUS rpc_setup_initshutdown(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx) -{ - NTSTATUS status; - enum rpc_service_mode_e service_mode; - const struct dcesrv_endpoint_server *ep_server = NULL; - - /* Register the endpoint server in DCERPC core */ - ep_server = initshutdown_get_ep_server(); - if (ep_server == NULL) { - DBG_ERR("Failed to get 'initshutdown' endpoint server\n"); - return NT_STATUS_UNSUCCESSFUL; - } - - service_mode = rpc_service_mode(ep_server->name); - if (service_mode != RPC_SERVICE_MODE_EMBEDDED) { - return NT_STATUS_OK; - } - - status = dcerpc_register_ep_server(ep_server); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to register '%s' endpoint " - "server: %s\n", ep_server->name, nt_errstr(status)); - return status; - } - - return NT_STATUS_OK; -} - -NTSTATUS dcesrv_init(TALLOC_CTX *mem_ctx, - struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx) -{ - TALLOC_CTX *tmp_ctx; - bool ok; - init_module_fn *mod_init_fns = NULL; - NTSTATUS status; - - tmp_ctx = talloc_stackframe(); - if (tmp_ctx == NULL) { - return NT_STATUS_NO_MEMORY; - } - - DBG_INFO("Registering DCE/RPC endpoint servers\n"); - - status = rpc_setup_winreg(ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = rpc_setup_srvsvc(ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = rpc_setup_lsarpc(ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = rpc_setup_samr(ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = rpc_setup_netlogon(ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = rpc_setup_netdfs(ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - -#ifdef DEVELOPER - status = rpc_setup_rpcecho(ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } -#endif - - status = rpc_setup_dssetup(ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = rpc_setup_wkssvc(ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = rpc_setup_spoolss(ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = rpc_setup_svcctl(ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = rpc_setup_ntsvcs(ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = rpc_setup_eventlog(ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - status = rpc_setup_initshutdown(ev_ctx, msg_ctx); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - DBG_INFO("Initializing DCE/RPC modules\n"); - - /* Initialize static subsystems */ - static_init_rpc(NULL); - - /* Initialize shared modules */ - mod_init_fns = load_samba_modules(tmp_ctx, "rpc"); - if ((mod_init_fns == NULL) && (errno != ENOENT)) { - /* - * ENOENT means the directory doesn't exist which can happen if - * all modules are static. So ENOENT is ok, everything else is - * not ok. - */ - DBG_ERR("Loading shared DCE/RPC modules failed [%s]\n", - strerror(errno)); - status = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - ok = run_init_functions(NULL, mod_init_fns); - if (!ok) { - DBG_ERR("Initializing shared DCE/RPC modules failed\n"); - status = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* The RPC module setup function has to register the endpoint server */ - ok = setup_rpc_modules(ev_ctx, msg_ctx); - if (!ok) { - DBG_ERR("Shared DCE/RPC modules setup failed\n"); - status = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - DBG_INFO("Initializing DCE/RPC registered endpoint servers\n"); - - status = dcesrv_init_registered_ep_servers(dce_ctx); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to init DCE/RPC endpoint servers: %s\n", - nt_errstr(status)); - goto done; - } - - DBG_INFO("Initializing DCE/RPC connection endpoints\n"); - - status = dcesrv_init_endpoints(ev_ctx, msg_ctx, dce_ctx); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Failed to init DCE/RPC endpoints: %s\n", - nt_errstr(status)); - goto done; - } - - status = NT_STATUS_OK; -done: - talloc_free(tmp_ctx); - return status; -} - -/* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */ diff --git a/source3/rpc_server/rpc_service_setup.h b/source3/rpc_server/rpc_service_setup.h deleted file mode 100644 index 668561794ff..00000000000 --- a/source3/rpc_server/rpc_service_setup.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * - * SMBD RPC service callbacks - * - * Copyright (c) 2011 Andreas Schneider - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef _RPC_EP_SETUP_H -#define _RPC_EP_SETUP_H - -#include "rpc_server/rpc_server.h" - -struct pf_listen_fd; - -NTSTATUS dcesrv_init(TALLOC_CTX *mem_ctx, - struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx); - -NTSTATUS dcesrv_setup_endpoint_sockets(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - struct dcesrv_endpoint *e, - dcerpc_ncacn_termination_fn term_fn, - void *term_data); - -NTSTATUS dcesrv_create_endpoint_sockets(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_endpoint *e, - TALLOC_CTX *mem_ctx, - size_t *pnum_fds, - int **pfds); -NTSTATUS dcesrv_create_endpoint_list_pf_listen_fds( - struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - struct dcesrv_endpoint *e, - TALLOC_CTX *mem_ctx, - size_t *pnum_fds, - struct pf_listen_fd **pfds); - -NTSTATUS rpc_setup_embedded(struct tevent_context *ev_ctx, - struct messaging_context *msg_ctx, - struct dcesrv_context *dce_ctx, - const struct dcesrv_interface *iface); - -#endif /* _RPC_EP_SETUP_H */ - -/* vim: set ts=8 sw=8 noet cindent ft=c.doxygen: */ diff --git a/source3/rpc_server/rpc_sock_helper.c b/source3/rpc_server/rpc_sock_helper.c index 932c9e1e22e..364b889d9b7 100644 --- a/source3/rpc_server/rpc_sock_helper.c +++ b/source3/rpc_server/rpc_sock_helper.c @@ -25,7 +25,6 @@ #include "../lib/tsocket/tsocket.h" #include "librpc/rpc/dcesrv_core.h" #include "rpc_server/rpc_sock_helper.h" -#include "lib/server_prefork.h" #include "librpc/ndr/ndr_table.h" #undef DBGC_CLASS diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c deleted file mode 100644 index 1a1a5c90946..00000000000 --- a/source3/rpc_server/srv_pipe.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * Almost completely rewritten by (C) Jeremy Allison 2005 - 2010 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -/* this module apparently provides an implementation of DCE/RPC over a - * named pipe (IPC$ connection using SMBtrans). details of DCE/RPC - * documentation are available (in on-line form) from the X-Open group. - * - * this module should provide a level of abstraction between SMB - * and DCE/RPC, while minimising the amount of mallocs, unnecessary - * data copies, and network traffic. - * - */ - -#include "includes.h" -#include "rpc_server.h" -#include "rpc_server/srv_pipe.h" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_SRV - -/** - * Is a named pipe known? - * @param[in] dce_ctx The rpc server context - * @param[in] pipename Just the filename - * @param[out] endpoint The DCERPC endpoint serving the pipe name - * @result NT error code - */ -NTSTATUS is_known_pipename(struct dcesrv_context *dce_ctx, - const char *pipename, - struct dcesrv_endpoint **ep) -{ - NTSTATUS status; - - if (strchr(pipename, '/')) { - DBG_WARNING("Refusing open on pipe %s\n", pipename); - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - - if (lp_disable_spoolss() && strequal(pipename, "spoolss")) { - DBG_DEBUG("refusing spoolss access\n"); - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - - status = dcesrv_endpoint_by_ncacn_np_name(dce_ctx, pipename, ep); - if (NT_STATUS_IS_OK(status)) { - return NT_STATUS_OK; - } - - status = smb_probe_module("rpc", pipename); - if (!NT_STATUS_IS_OK(status)) { - DBG_DEBUG("Unknown pipe '%s'\n", pipename); - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - DBG_DEBUG("'%s' loaded dynamically\n", pipename); - - /* - * Scan the list again for the interface id - */ - status = dcesrv_endpoint_by_ncacn_np_name(dce_ctx, pipename, ep); - if (NT_STATUS_IS_OK(status)) { - return NT_STATUS_OK; - } - - DBG_DEBUG("pipe %s did not register itself!\n", pipename); - - return NT_STATUS_OBJECT_NAME_NOT_FOUND; -} diff --git a/source3/rpc_server/srv_pipe.h b/source3/rpc_server/srv_pipe.h deleted file mode 100644 index e8ebc9ab5dc..00000000000 --- a/source3/rpc_server/srv_pipe.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * RPC Pipe client / server routines - * Almost completely rewritten by (C) Jeremy Allison 2005 - 2010 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#ifndef _RPC_SERVER_SRV_PIPE_H_ -#define _RPC_SERVER_SRV_PIPE_H_ - -struct dcesrv_context; -struct dcesrv_endpoint; - -/* The following definitions come from rpc_server/srv_pipe.c */ - -NTSTATUS is_known_pipename(struct dcesrv_context *dce_ctx, - const char *pipename, - struct dcesrv_endpoint **ep); - -#endif /* _RPC_SERVER_SRV_PIPE_H_ */ diff --git a/source3/wscript_build b/source3/wscript_build index 2f794e477e6..b5d12a499f3 100644 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -378,8 +378,6 @@ bld.SAMBA3_SUBSYSTEM('samba3core', lib/gencache.c lib/util_event.c lib/global_contexts.c - lib/server_prefork.c - lib/server_prefork_util.c lib/ldap_escape.c lib/system_smbd.c lib/audit.c