along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "source3/include/includes.h"
-
-/* we use the full source3/source4 prefixes as this code mixes the two
- sets of header pathsx */
-#include "source3/smbd/globals.h"
-#include "source3/smbd/proto.h"
-#include "source3/include/memcache.h"
-#include "source3/include/passdb.h"
-#include "source3/include/secrets.h"
-#include "source3/locking/proto.h"
-#include "source3/include/messages.h"
-#include "source3/include/serverid.h"
-#include "source3/printing/printer_list.h"
-#include "source3/registry/reg_init_full.h"
-#include "source3/include/printing.h"
-#include "source3/include/auth.h"
-#include "rpc_server/rpc_service_setup.h"
-#include "source4/smbd/service_stream.h"
+#include "includes.h"
+#include "talloc.h"
+#include "tevent.h"
+#include "system/filesys.h"
#include "lib/param/param.h"
-#include "source4/lib/socket/socket.h"
#include "source4/smbd/service.h"
#include "source4/smbd/process_model.h"
-#include "source4/lib/socket/netif.h"
-#include "libcli/auth/schannel.h"
#include "file_server/file_server.h"
-
+#include "dynconfig.h"
/*
- this runs through the initialisation that the samba3 file server
- normally does. It is derived from main() in source3/smbd/server.c
+ generate a smbd config file for the file server
*/
-static int s3fs_server_init(struct loadparm_context *lp_ctx)
+static const char *generate_smb_conf(struct task_server *task)
{
- uint64_t unique_id;
- NTSTATUS status;
- struct tevent_context *ev_ctx;
- struct messaging_context *msg_ctx;
-
- /* create a stackframe for the file server child */
- talloc_stackframe();
-
- smbd_init_globals();
-
- TimeInit();
-
- set_remote_machine_name("smbd", False);
-
- /* get initial effective uid and gid */
- sec_init();
-
- lp_set_cmdline("config file", lpcfg_configfile(lp_ctx));
- lp_set_cmdline("auth methods", "guest samba4");
- lp_set_cmdline("passdb backend", "samba4");
- lp_set_cmdline("rpc_server:lsarpc", "external");
- lp_set_cmdline("rpc_server:netlogon", "external");
- lp_set_cmdline("rpc_server:samr", "external");
-
- lp_set_cmdline("rpc_server:epmapper", "disabled");
- lp_set_cmdline("rpc_server:rpcecho", "disabled");
- lp_set_cmdline("rpc_server:dssetup", "disabled");
- lp_set_cmdline("rpc_server:svctl", "disabled");
- lp_set_cmdline("rpc_server:ntsvcs", "disabled");
- lp_set_cmdline("rpc_server:eventlog", "disabled");
- lp_set_cmdline("rpc_server:initshutdown", "disabled");
-
- lp_set_cmdline("rpc_server:winreg", "embedded");
- lp_set_cmdline("rpc_server:srvsvc", "embedded");
- lp_set_cmdline("rpc_server:netdfs", "embedded");
- lp_set_cmdline("rpc_server:wkssvc", "embedded");
- lp_set_cmdline("rpc_server:spoolss", "embedded");
-
- lp_set_cmdline("rpc_daemon:epmd", "disabled");
- lp_set_cmdline("rpc_daemon:lsasd", "disabled");
- lp_set_cmdline("rpc_daemon:spoolssd", "disabled");
-
- lp_set_cmdline("rpc_server:tcpip", "no");
-
- if (!lp_load_initial_only(lpcfg_configfile(lp_ctx))) {
- DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
- return -1;
- }
-
- /* Init the security context and global current_user */
- init_sec_ctx();
-
- /*
- * Initialize the event context. The event context needs to be
- * initialized before the messaging context, cause the messaging
- * context holds an event context.
- * FIXME: This should be s3_tevent_context_init()
- */
- ev_ctx = server_event_context();
- if (ev_ctx == NULL) {
- DEBUG(0, ("Failed to get server event context"));
- return -1;
- }
-
- /*
- * Init the messaging context
- * FIXME: This should only call messaging_init()
- */
- msg_ctx = server_messaging_context();
- if (msg_ctx == NULL) {
- DEBUG(0, ("Failed to get server messaging context"));
- return -1;
- }
-
- /*
- * Reloading of the printers will not work here as we don't have a
- * server info and rpc services set up. It will be called later.
- */
- if (!reload_services(NULL, -1, False)) {
- DEBUG(0, ("Failed to reload smb.conf"));
- return -1;
- }
-
- /* ...NOTE... Log files are working from this point! */
-
- generate_random_buffer((uint8_t *)&unique_id, sizeof(unique_id));
- set_my_unique_id(unique_id);
-
- status = reinit_after_fork(msg_ctx,
- ev_ctx,
- procid_self(), false);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("reinit_after_fork() failed\n"));
- return -1;
- }
-
- smbd_server_conn->msg_ctx = msg_ctx;
-
- smbd_setup_sig_term_handler();
- smbd_setup_sig_hup_handler(ev_ctx,
- msg_ctx);
-
- /* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */
-
- if (smbd_memcache() == NULL) {
- DEBUG(0, ("Failed to init smbd memcache"));
- return -1;
- }
-
- memcache_set_global(smbd_memcache());
-
- /* Initialise the password backed before the global_sam_sid
- to ensure that we fetch from ldap before we make a domain sid up */
-
- if(!initialize_password_db(false, ev_ctx)) {
- DEBUG(0, ("Failed to init passdb backends"));
- return -1;
- }
-
- if (!secrets_init()) {
- DEBUG(0, ("ERROR: smbd can not open secrets.tdb\n"));
- return -1;
- }
-
- if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
- if (!open_schannel_session_store(NULL, lp_ctx)) {
- DEBUG(0,("ERROR: Samba cannot open schannel store for secured NETLOGON operations.\n"));
- return -1;
- }
- }
-
- if(!get_global_sam_sid()) {
- DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
- return -1;
- }
-
- if (!sessionid_init()) {
- DEBUG(0, ("Failed to init sessionid database"));
- return -1;
- }
-
- if (!connections_init(True)) {
- DEBUG(0, ("Failed to init connections database"));
- return -1;
- }
-
- if (!locking_init()) {
- DEBUG(0, ("Failed to init locking database"));
- return -1;
- }
- if (!messaging_tdb_parent_init(ev_ctx)) {
- DEBUG(0, ("Failed to init messaging tdb as parent task"));
- return -1;
- }
-
- if (!notify_internal_parent_init(ev_ctx)) {
- DEBUG(0, ("Failed to init notify db as parent task"));
- return -1;
- }
-
- if (!serverid_parent_init(ev_ctx)) {
- return -1;
- }
-
- if (!W_ERROR_IS_OK(registry_init_full())) {
- DEBUG(0, ("Failed to init registry"));
- return -1;
- }
-
- /* Open the share_info.tdb here, so we don't have to open
- after the fork on every single connection. This is a small
- performance improvment and reduces the total number of system
- fds used. */
- if (!share_info_db_init()) {
- DEBUG(0,("ERROR: failed to load share info db.\n"));
- return -1;
- }
-
- status = init_system_info();
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("ERROR: failed to setup system user info: %s.\n",
- nt_errstr(status)));
- return -1;
- }
-
- if (!init_guest_info()) {
- DEBUG(0,("ERROR: failed to setup guest info.\n"));
- return -1;
- }
-
- if (!file_init(smbd_server_conn)) {
- DEBUG(0, ("ERROR: file_init failed\n"));
- return -1;
- }
-
- if (!dcesrv_ep_setup(ev_ctx, msg_ctx)) {
- DEBUG(0, ("Failed to init dcerpc endpoints"));
- return -1;
- }
-
- init_names();
-
-
- return 0;
+ int fd;
+ struct loadparm_context *lp_ctx = task->lp_ctx;
+ const char *path = smbd_tmp_path(task, lp_ctx, "fileserver.conf");
+
+ if (path == NULL) {
+ return NULL;
+ }
+
+ fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ if (fd == -1) {
+ DEBUG(0,("Failed to create %s", path));
+ return NULL;
+ }
+
+ fdprintf(fd, "# auto-generated config for fileserver\n");
+ fdprintf(fd, "auth methods = guest samba4\n");
+ fdprintf(fd, "passdb backend = samba4\n");
+ fdprintf(fd, "rpc_server:lsarpc = external\n");
+ fdprintf(fd, "rpc_server:netlogon = external\n");
+ fdprintf(fd, "rpc_server:samr = external\n");
+ fdprintf(fd, "rpc_server:rpcecho = disabled\n");
+ fdprintf(fd, "rpc_server:dssetup = disabled\n");
+ fdprintf(fd, "rpc_server:svctl = disabled\n");
+ fdprintf(fd, "rpc_server:ntsvcs = disabled\n");
+ fdprintf(fd, "rpc_server:eventlog = disabled\n");
+ fdprintf(fd, "rpc_server:initshutdown = disabled\n");
+ fdprintf(fd, "rpc_server:winreg = embedded\n");
+ fdprintf(fd, "rpc_server:srvsvc = embedded\n");
+ fdprintf(fd, "rpc_server:netdfs = embedded\n");
+ fdprintf(fd, "rpc_server:wkssvc = embedded\n");
+ fdprintf(fd, "rpc_server:spoolss = embedded\n");
+ fdprintf(fd, "rpc_daemon:lsasd = disabled\n");
+ fdprintf(fd, "rpc_daemon:spoolssd = disabled\n");
+ fdprintf(fd, "rpc_server:tcpip = no\n");
+
+ fdprintf(fd, "include = %s\n", lpcfg_configfile(lp_ctx));
+ close(fd);
+ return path;
}
/*
- initialise a server_context from a open socket and register a event handler
- for reading from that socket
-*/
-static void s3fs_smb_accept(struct stream_connection *conn)
+ called if smbd exits
+ */
+static void file_server_smbd_done(struct tevent_req *subreq)
{
- if (lpcfg_parm_bool(conn->lp_ctx, NULL, "s3fs", "gdb", false)) {
- samba_start_debugger();
- sleep(2);
- }
- DEBUG(0,(__location__ ": new s3fs smbd connection\n"));
-
- if (s3fs_server_init(conn->lp_ctx) != 0) {
- DEBUG(0,("Failed to initialise s3fs backend\n"));
- exit(1);
- }
+ int sys_errno;
+ int ret;
- smbd_server_conn->sock = socket_get_fd(conn->socket);
-
- if (!serverid_register(procid_self(),
- FLAG_MSG_GENERAL|FLAG_MSG_SMBD
- |FLAG_MSG_DBWRAP
- |FLAG_MSG_PRINT_GENERAL)) {
- exit_server_cleanly("Could not register myself in "
- "serverid.tdb");
+ ret = samba_runcmd_recv(subreq, &sys_errno);
+ if (ret != 0) {
+ DEBUG(0,("file_server smbd daemon died with exit status %d\n", sys_errno));
+ } else {
+ DEBUG(0,("file_server smbd daemon exited normally\n"));
}
-
- smbd_process(server_event_context(), smbd_server_conn);
- exit(1);
}
-static const struct stream_server_ops s3fs_smb_stream_ops = {
- .name = "s3fs",
- .accept_connection = s3fs_smb_accept,
-};
-
-/*
- setup a listening socket on all the SMB ports for a particular address
-*/
-static NTSTATUS s3fs_add_socket(struct task_server *task,
- struct tevent_context *event_context,
- struct loadparm_context *lp_ctx,
- const struct model_ops *model_ops,
- const char *address)
-{
- const char **ports = lpcfg_smb_ports(lp_ctx);
- int i;
- NTSTATUS status;
-
- for (i=0;ports[i];i++) {
- uint16_t port = atoi(ports[i]);
- if (port == 0) continue;
- status = stream_setup_socket(task, event_context, lp_ctx,
- model_ops, &s3fs_smb_stream_ops,
- "ip", address, &port,
- lpcfg_socket_options(lp_ctx),
- NULL);
- NT_STATUS_NOT_OK_RETURN(status);
- }
-
- return NT_STATUS_OK;
-}
/*
- open the s3 smb server sockets
+ startup a copy of smbd as a child daemon
*/
static void s3fs_task_init(struct task_server *task)
{
- NTSTATUS status;
- const struct model_ops *model_ops;
-
- model_ops = process_model_startup("standard");
-
- if (model_ops == NULL) {
- goto failed;
- }
+ const char *fileserver_conf;
+ struct tevent_req *req;
+ const char *smbd_path;
+ const char *smbd_cmd[2] = { NULL, NULL };
task_server_set_title(task, "task[s3fs_parent]");
- if (lpcfg_interfaces(task->lp_ctx) && lpcfg_bind_interfaces_only(task->lp_ctx)) {
- int num_interfaces;
- int i;
- struct interface *ifaces;
-
- load_interface_list(task, task->lp_ctx, &ifaces);
+ /* create a smb.conf for smbd to use */
+ fileserver_conf = generate_smb_conf(task);
- num_interfaces = iface_list_count(ifaces);
+ smbd_path = talloc_asprintf(task, "%s/smbd", dyn_SBINDIR);
+ smbd_cmd[0] = smbd_path;
- /* We have been given an interfaces line, and been
- told to only bind to those interfaces. Create a
- socket per interface and bind to only these.
- */
- for(i = 0; i < num_interfaces; i++) {
- const char *address = iface_list_n_ip(ifaces, i);
- status = s3fs_add_socket(task, task->event_ctx, task->lp_ctx, model_ops, address);
- if (!NT_STATUS_IS_OK(status)) goto failed;
- }
- } else {
- const char **wcard;
- int i;
- wcard = iface_list_wildcard(task, task->lp_ctx);
- if (wcard == NULL) {
- DEBUG(0,("No wildcard addresses available\n"));
- goto failed;
- }
- for (i=0; wcard[i]; i++) {
- status = s3fs_add_socket(task, task->event_ctx, task->lp_ctx, model_ops, wcard[i]);
- if (!NT_STATUS_IS_OK(status)) goto failed;
- }
- talloc_free(wcard);
+ /* start it as a child process */
+ req = samba_runcmd_send(task, task->event_ctx, timeval_zero(), 1, 0,
+ smbd_cmd,
+ "--configfile", fileserver_conf,
+ "--foreground", NULL);
+ if (req == NULL) {
+ DEBUG(0, ("Failed to start smbd as child daemon\n"));
+ goto failed;
}
+ tevent_req_set_callback(req, file_server_smbd_done, task);
+
+ DEBUG(1,("Started file server smbd with config %s\n", fileserver_conf));
return;
failed:
task_server_terminate(task, "Failed to startup s3fs smb task", true);