Copyright (C) Andrew Tridgell 2002
Copyright (C) Jelmer Vernooij 2003
Copyright (C) Volker Lendecke 2004
+ Copyright (C) James Peach 2007
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 2 of the License, or
+ 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,
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, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#define DBGC_CLASS DBGC_WINBIND
BOOL opt_nocache = False;
-static BOOL interactive = False;
extern BOOL override_logfile;
static struct event_context *ctx;
if (!ctx && !(ctx = event_context_init(NULL))) {
- smb_panic("Could not init winbind event context\n");
+ smb_panic("Could not init winbind event context");
+ }
+ return ctx;
+}
+
+struct messaging_context *winbind_messaging_context(void)
+{
+ static struct messaging_context *ctx;
+
+ if (!ctx && !(ctx = messaging_init(NULL, server_id_self(),
+ winbind_event_context()))) {
+ smb_panic("Could not init winbind messaging context");
}
return ctx;
}
static void terminate(void)
{
- pstring path;
+ winbindd_release_sockets();
idmap_close();
- /* Remove socket file */
- pstr_sprintf(path, "%s/%s",
- WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME);
- unlink(path);
+ trustdom_cache_shutdown();
#if 0
if (interactive) {
}
/* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
-static void msg_reload_services(int msg_type, struct process_id src,
- void *buf, size_t len, void *private_data)
+static void msg_reload_services(struct messaging_context *msg,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
{
/* Flush various caches */
flush_caches();
}
/* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
-static void msg_shutdown(int msg_type, struct process_id src,
- void *buf, size_t len, void *private_data)
+static void msg_shutdown(struct messaging_context *msg,
+ void *private_data,
+ uint32_t msg_type,
+ struct server_id server_id,
+ DATA_BLOB *data)
{
do_sigterm = True;
}
{ WINBINDD_SID_TO_GID, winbindd_sid_to_gid, "SID_TO_GID" },
{ WINBINDD_UID_TO_SID, winbindd_uid_to_sid, "UID_TO_SID" },
{ WINBINDD_GID_TO_SID, winbindd_gid_to_sid, "GID_TO_SID" },
+#if 0 /* DISABLED until we fix the interface in Samba 3.0.26 --jerry */
{ WINBINDD_SIDS_TO_XIDS, winbindd_sids_to_unixids, "SIDS_TO_XIDS" },
+#endif /* end DISABLED */
{ WINBINDD_ALLOCATE_UID, winbindd_allocate_uid, "ALLOCATE_UID" },
{ WINBINDD_ALLOCATE_GID, winbindd_allocate_gid, "ALLOCATE_GID" },
{ WINBINDD_SET_MAPPING, winbindd_set_mapping, "SET_MAPPING" },
if (state->mem_ctx == NULL)
return;
+ /* Remember who asked us. */
+ state->pid = state->request.pid;
+
/* Process command */
for (table = dispatch_table; table->fn; table++) {
simultaneous connections while remaining impervious to many denial of
service attacks. */
-static void process_loop(void)
+static int process_loop(int listen_sock, int listen_priv_sock)
{
struct winbindd_cli_state *state;
struct fd_event *ev;
fd_set r_fds, w_fds;
- int maxfd, listen_sock, listen_priv_sock, selret;
+ int maxfd, selret;
struct timeval timeout, ev_timeout;
/* We'll be doing this a lot */
/* Handle messages */
- message_dispatch();
+ message_dispatch(winbind_messaging_context());
run_events(winbind_event_context(), 0, NULL, NULL);
/* Initialise fd lists for select() */
- listen_sock = open_winbindd_socket();
- listen_priv_sock = open_winbindd_priv_socket();
-
- if (listen_sock == -1 || listen_priv_sock == -1) {
- perror("open_winbind_socket");
- exit(1);
- }
-
maxfd = MAX(listen_sock, listen_priv_sock);
FD_ZERO(&r_fds);
DEBUG(3, ("got SIGHUP\n"));
- msg_reload_services(MSG_SMB_CONF_UPDATED, pid_to_procid(0), NULL, 0, NULL);
+ flush_caches();
+ reload_services_file();
+
do_sighup = False;
}
winbind_child_died(pid);
}
}
+
+
+ return winbindd_num_clients();
+}
+
+static void winbindd_process_loop(enum smb_server_mode server_mode)
+{
+ int idle_timeout_sec;
+ struct timeval starttime;
+ int listen_public, listen_priv;
+
+ errno = 0;
+ if (!winbindd_init_sockets(&listen_public, &listen_priv,
+ &idle_timeout_sec)) {
+ terminate();
+ }
+
+ starttime = timeval_current();
+
+ if (listen_public == -1 || listen_priv == -1) {
+ DEBUG(0, ("failed to open winbindd pipes: %s\n",
+ errno ? strerror(errno) : "unknown error"));
+ terminate();
+ }
+
+ for (;;) {
+ int clients = process_loop(listen_public, listen_priv);
+
+ /* Don't bother figuring out the idle time if we won't be
+ * timing out anyway.
+ */
+ if (idle_timeout_sec < 0) {
+ continue;
+ }
+
+ if (clients == 0 && server_mode == SERVER_MODE_FOREGROUND) {
+ struct timeval now;
+
+ now = timeval_current();
+ if (timeval_elapsed2(&starttime, &now) >
+ (double)idle_timeout_sec) {
+ DEBUG(0, ("idle for %d secs, exitting\n",
+ idle_timeout_sec));
+ terminate();
+ }
+ } else {
+ starttime = timeval_current();
+ }
+ }
}
/* Main function */
int main(int argc, char **argv, char **envp)
{
pstring logfile;
- static BOOL Fork = True;
- static BOOL log_stdout = False;
- static BOOL no_process_group = False;
+ BOOL log_stdout = False;
+ BOOL no_process_group = False;
+
+ enum smb_server_mode server_mode = SERVER_MODE_DAEMON;
+
struct poptOption long_options[] = {
POPT_AUTOHELP
{ "stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
- { "foreground", 'F', POPT_ARG_VAL, &Fork, False, "Daemon in foreground mode" },
+ { "foreground", 'F', POPT_ARG_VAL, &server_mode, SERVER_MODE_FOREGROUND, "Daemon in foreground mode" },
{ "no-process-group", 0, POPT_ARG_VAL, &no_process_group, True, "Don't create a new process group" },
- { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
+ { "interactive", 'i', POPT_ARG_VAL, &server_mode, SERVER_MODE_INTERACTIVE, "Interactive mode" },
{ "no-caching", 'n', POPT_ARG_VAL, &opt_nocache, True, "Disable caching" },
POPT_COMMON_SAMBA
POPT_TABLEEND
pc = poptGetContext("winbindd", argc, (const char **)argv, long_options,
POPT_CONTEXT_KEEP_FIRST);
- while ((opt = poptGetNextOpt(pc)) != -1) {
- switch (opt) {
- /* Don't become a daemon */
- case 'i':
- interactive = True;
- log_stdout = True;
- Fork = False;
- break;
+ while ((opt = poptGetNextOpt(pc)) != -1) {}
+
+ if (server_mode == SERVER_MODE_INTERACTIVE) {
+ log_stdout = True;
+ if (DEBUGLEVEL >= 9) {
+ talloc_enable_leak_report();
}
}
-
- if (log_stdout && Fork) {
- printf("Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n");
+ if (log_stdout && server_mode == SERVER_MODE_DAEMON) {
+ printf("Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n");
poptPrintUsage(pc, stderr, 0);
exit(1);
}
/* Winbind daemon initialisation */
- if ( ! NT_STATUS_IS_OK(idmap_init()) ) {
- DEBUG(1, ("Could not init idmap! - Sid/[UG]id mapping will not be available\n"));
+ if ( ! NT_STATUS_IS_OK(idmap_init_cache()) ) {
+ DEBUG(1, ("Could not init idmap cache!\n"));
}
-#ifdef WITH_ADS
- nss_init( lp_winbind_nss_info() );
-#endif
-
/* Unblock all signals we are interested in as they may have been
blocked by the parent process. */
CatchSignal(SIGUSR2, sigusr2_handler); /* Debugging sigs */
CatchSignal(SIGHUP, sighup_handler);
- if (!interactive)
- become_daemon(Fork, no_process_group);
+ if (server_mode == SERVER_MODE_DAEMON) {
+ DEBUG( 3, ( "Becoming a daemon.\n" ) );
+ become_daemon(True, no_process_group);
+ } else if (server_mode == SERVER_MODE_FOREGROUND) {
+ become_daemon(False, no_process_group);
+ }
pidfile_create("winbindd");
* If we're interactive we want to set our own process group for
* signal management.
*/
- if (interactive && !no_process_group)
+ if (server_mode == SERVER_MODE_INTERACTIVE && !no_process_group) {
setpgid( (pid_t)0, (pid_t)0);
+ }
#endif
TimeInit();
/* Initialise messaging system */
- if (!message_init()) {
+ if (winbind_messaging_context() == NULL) {
DEBUG(0, ("unable to initialize messaging system\n"));
exit(1);
}
+ /* Initialize cache (ensure version is correct). */
+ if (!initialize_winbindd_cache()) {
+ exit(1);
+ }
+
/* React on 'smbcontrol winbindd reload-config' in the same way
as to SIGHUP signal */
- message_register(MSG_SMB_CONF_UPDATED, msg_reload_services, NULL);
- message_register(MSG_SHUTDOWN, msg_shutdown, NULL);
+ messaging_register(winbind_messaging_context(), NULL,
+ MSG_SMB_CONF_UPDATED, msg_reload_services);
+ messaging_register(winbind_messaging_context(), NULL,
+ MSG_SHUTDOWN, msg_shutdown);
/* Handle online/offline messages. */
- message_register(MSG_WINBIND_OFFLINE, winbind_msg_offline, NULL);
- message_register(MSG_WINBIND_ONLINE, winbind_msg_online, NULL);
- message_register(MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus,
- NULL);
+ messaging_register(winbind_messaging_context(), NULL,
+ MSG_WINBIND_OFFLINE, winbind_msg_offline);
+ messaging_register(winbind_messaging_context(), NULL,
+ MSG_WINBIND_ONLINE, winbind_msg_online);
+ messaging_register(winbind_messaging_context(), NULL,
+ MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
+
+ messaging_register(winbind_messaging_context(), NULL,
+ MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
poptFreeContext(pc);
netsamlogon_cache_init(); /* Non-critical */
+ /* clear the cached list of trusted domains */
+
+ wcache_tdc_clear();
+
if (!init_domain_list()) {
DEBUG(0,("unable to initalize domain list\n"));
exit(1);
smb_nscd_flush_group_cache();
/* Loop waiting for requests */
-
- while (1)
- process_loop();
-
- trustdom_cache_shutdown();
+ winbindd_process_loop(server_mode);
return 0;
}