static bool rpc_setup_spoolss(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx) { const struct ndr_interface_table *t = &ndr_table_spoolss; struct rpc_srv_callbacks spoolss_cb; enum rpc_daemon_type_e spoolss_type = rpc_spoolss_daemon(); NTSTATUS status = NT_STATUS_UNSUCCESSFUL; enum rpc_service_mode_e service_mode = rpc_service_mode(t->name); if (lp__disable_spoolss()) { return true; } if (service_mode != RPC_SERVICE_MODE_EMBEDDED || spoolss_type != RPC_DAEMON_EMBEDDED) { return true; } spoolss_cb.init = spoolss_init_cb; spoolss_cb.shutdown = spoolss_shutdown_cb; spoolss_cb.private_data = msg_ctx; status = rpc_spoolss_init(&spoolss_cb); if (!NT_STATUS_IS_OK(status)) { return false; } return rpc_setup_embedded(ev_ctx, msg_ctx, t, NULL); }
void start_spoolssd(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx) { struct rpc_srv_callbacks spoolss_cb; pid_t pid; NTSTATUS status; int ret; DEBUG(1, ("Forking SPOOLSS Daemon\n")); pid = sys_fork(); if (pid == -1) { DEBUG(0, ("Failed to fork SPOOLSS [%s], aborting ...\n", strerror(errno))); exit(1); } if (pid) { /* parent */ return; } /* child */ close_low_fds(false); status = reinit_after_fork(msg_ctx, ev_ctx, procid_self(), true); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("reinit_after_fork() failed\n")); smb_panic("reinit_after_fork() failed"); } spoolss_reopen_logs(); spoolss_setup_sig_term_handler(ev_ctx); spoolss_setup_sig_hup_handler(ev_ctx, msg_ctx); if (!serverid_register(procid_self(), FLAG_MSG_GENERAL|FLAG_MSG_SMBD |FLAG_MSG_PRINT_GENERAL)) { exit(1); } if (!locking_init()) { exit(1); } messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE, print_queue_receive); messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED, smb_conf_updated); /* * Initialize spoolss with an init function to convert printers first. * static_init_rpc will try to initialize the spoolss server too but you * can't register it twice. */ spoolss_cb.init = spoolss_init_cb; spoolss_cb.shutdown = spoolss_shutdown_cb; spoolss_cb.private_data = msg_ctx; status = rpc_winreg_init(NULL); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to register winreg rpc inteface! (%s)\n", nt_errstr(status))); exit(1); } status = rpc_spoolss_init(&spoolss_cb); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to register spoolss rpc inteface! (%s)\n", nt_errstr(status))); exit(1); } if (!setup_named_pipe_socket(SPOOLSS_PIPE_NAME, ev_ctx)) { exit(1); } status = rpc_ep_setup_register(ev_ctx, msg_ctx, &ndr_table_spoolss, NULL, 0); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to register spoolss endpoint! (%s)\n", nt_errstr(status))); exit(1); } DEBUG(1, ("SPOOLSS Daemon Started (%d)\n", getpid())); /* loop forever */ ret = tevent_loop_wait(ev_ctx); /* should not be reached */ DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n", ret, (ret == 0) ? "out of events" : strerror(errno))); exit(1); }
static bool spoolss_child_init(struct tevent_context *ev_ctx, int child_id, struct pf_worker_data *pf) { NTSTATUS status; struct rpc_srv_callbacks spoolss_cb; struct messaging_context *msg_ctx = messaging_init(NULL, ev_ctx); bool ok; status = reinit_after_fork(msg_ctx, ev_ctx, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("reinit_after_fork() failed\n")); smb_panic("reinit_after_fork() failed"); } prctl_set_comment("spoolssd-child"); 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 (!serverid_register(messaging_server_id(msg_ctx), FLAG_MSG_GENERAL | FLAG_MSG_PRINT_GENERAL)) { 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. */ if (pcap_cache_loaded(NULL)) { load_printers(ev_ctx, msg_ctx); } /* try to reinit rpc queues */ spoolss_cb.init = spoolss_init_cb; spoolss_cb.shutdown = spoolss_shutdown_cb; spoolss_cb.private_data = msg_ctx; status = rpc_winreg_init(NULL); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to register winreg rpc inteface! (%s)\n", nt_errstr(status))); return false; } status = rpc_spoolss_init(&spoolss_cb); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to register spoolss rpc inteface! (%s)\n", nt_errstr(status))); return false; } return true; }