2 Unix SMB/CIFS implementation.
4 Winbind daemon for ntdom nss module
6 Copyright (C) by Tim Potter 2000-2002
7 Copyright (C) Andrew Tridgell 2002
8 Copyright (C) Jelmer Vernooij 2003
9 Copyright (C) Volker Lendecke 2004
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include "../../nsswitch/libwbclient/wbc_async.h"
28 #include "librpc/gen_ndr/messaging.h"
32 #define DBGC_CLASS DBGC_WINBIND
36 /* Reload configuration */
38 bool winbindd_reload_services_file(const char *lfile)
43 const char *fname = lp_configfile();
45 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
46 set_dyn_CONFIGFILE(fname);
50 /* if this is a child, restore the logfile to the special
51 name - <domain>, idmap, etc. */
52 if (lfile && *lfile) {
53 lp_set_logfile(lfile);
57 ret = lp_load(get_dyn_CONFIGFILE(),False,False,True,True);
65 static void winbindd_status(void)
67 struct winbindd_cli_state *tmp;
69 DEBUG(0, ("winbindd status:\n"));
71 /* Print client state information */
73 DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
75 if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
76 DEBUG(2, ("\tclient list:\n"));
77 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
78 DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
79 (unsigned long)tmp->pid, tmp->sock,
80 client_is_idle(tmp) ? "idle" : "active"));
85 /* Flush client cache */
87 static void flush_caches(void)
89 /* We need to invalidate cached user list entries on a SIGHUP
90 otherwise cached access denied errors due to restrict anonymous
91 hang around until the sequence number changes. */
93 if (!wcache_invalidate_cache()) {
94 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
95 if (!winbindd_cache_validate_and_initialize()) {
101 static void flush_caches_noinit(void)
104 * We need to invalidate cached user list entries on a SIGHUP
105 * otherwise cached access denied errors due to restrict anonymous
106 * hang around until the sequence number changes.
108 * Skip uninitialized domains when flush cache.
109 * If domain is not initialized, it means it is never
110 * used or never become online. look, wcache_invalidate_cache()
111 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
112 * for unused domains and large traffic for primay domain's DC if there
116 if (!wcache_invalidate_cache_noinit()) {
117 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
118 if (!winbindd_cache_validate_and_initialize()) {
124 /* Handle the signal by unlinking socket and exiting */
126 static void terminate(bool is_parent)
129 /* When parent goes away we should
130 * remove the socket file. Not so
131 * when children terminate.
135 if (asprintf(&path, "%s/%s",
136 get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME) > 0) {
144 trustdom_cache_shutdown();
146 gencache_stabilize();
150 TALLOC_CTX *mem_ctx = talloc_init("end_description");
151 char *description = talloc_describe_all(mem_ctx);
153 DEBUG(3, ("tallocs left:\n%s\n", description));
154 talloc_destroy(mem_ctx);
159 serverid_deregister(procid_self());
166 static void winbindd_sig_term_handler(struct tevent_context *ev,
167 struct tevent_signal *se,
173 bool *is_parent = talloc_get_type_abort(private_data, bool);
175 DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
176 signum, (int)*is_parent));
177 terminate(*is_parent);
180 bool winbindd_setup_sig_term_handler(bool parent)
182 struct tevent_signal *se;
185 is_parent = talloc(winbind_event_context(), bool);
192 se = tevent_add_signal(winbind_event_context(),
195 winbindd_sig_term_handler,
198 DEBUG(0,("failed to setup SIGTERM handler"));
199 talloc_free(is_parent);
203 se = tevent_add_signal(winbind_event_context(),
206 winbindd_sig_term_handler,
209 DEBUG(0,("failed to setup SIGINT handler"));
210 talloc_free(is_parent);
214 se = tevent_add_signal(winbind_event_context(),
217 winbindd_sig_term_handler,
220 DEBUG(0,("failed to setup SIGINT handler"));
221 talloc_free(is_parent);
228 static void winbindd_sig_hup_handler(struct tevent_context *ev,
229 struct tevent_signal *se,
235 const char *file = (const char *)private_data;
237 DEBUG(1,("Reloading services after SIGHUP\n"));
238 flush_caches_noinit();
239 winbindd_reload_services_file(file);
242 bool winbindd_setup_sig_hup_handler(const char *lfile)
244 struct tevent_signal *se;
248 file = talloc_strdup(winbind_event_context(),
255 se = tevent_add_signal(winbind_event_context(),
256 winbind_event_context(),
258 winbindd_sig_hup_handler,
267 static void winbindd_sig_chld_handler(struct tevent_context *ev,
268 struct tevent_signal *se,
276 while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) {
277 winbind_child_died(pid);
281 static bool winbindd_setup_sig_chld_handler(void)
283 struct tevent_signal *se;
285 se = tevent_add_signal(winbind_event_context(),
286 winbind_event_context(),
288 winbindd_sig_chld_handler,
297 static void winbindd_sig_usr2_handler(struct tevent_context *ev,
298 struct tevent_signal *se,
307 static bool winbindd_setup_sig_usr2_handler(void)
309 struct tevent_signal *se;
311 se = tevent_add_signal(winbind_event_context(),
312 winbind_event_context(),
314 winbindd_sig_usr2_handler,
323 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
324 static void msg_reload_services(struct messaging_context *msg,
327 struct server_id server_id,
330 /* Flush various caches */
332 winbindd_reload_services_file((const char *) private_data);
335 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
336 static void msg_shutdown(struct messaging_context *msg,
339 struct server_id server_id,
342 /* only the parent waits for this message */
343 DEBUG(0,("Got shutdown message\n"));
348 static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
351 struct server_id server_id,
357 DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
361 * call the validation code from a child:
362 * so we don't block the main winbindd and the validation
363 * code can safely use fork/waitpid...
365 child_pid = sys_fork();
367 if (child_pid == -1) {
368 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
373 if (child_pid != 0) {
375 DEBUG(5, ("winbind_msg_validate_cache: child created with "
376 "pid %d.\n", (int)child_pid));
382 if (!winbindd_reinit_after_fork(NULL)) {
386 /* install default SIGCHLD handler: validation code uses fork/waitpid */
387 CatchSignal(SIGCHLD, SIG_DFL);
389 ret = (uint8)winbindd_validate_cache_nobackup();
390 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
391 messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
396 void winbindd_register_handlers(void)
398 struct tevent_timer *te;
399 /* Setup signal handlers */
401 if (!winbindd_setup_sig_term_handler(true))
403 if (!winbindd_setup_sig_hup_handler(NULL))
405 if (!winbindd_setup_sig_chld_handler())
407 if (!winbindd_setup_sig_usr2_handler())
410 CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
413 * Ensure all cache and idmap caches are consistent
414 * and initialized before we startup.
416 if (!winbindd_cache_validate_and_initialize()) {
420 /* get broadcast messages */
422 if (!serverid_register(procid_self(),
423 FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP)) {
424 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
428 /* React on 'smbcontrol winbindd reload-config' in the same way
429 as to SIGHUP signal */
430 messaging_register(winbind_messaging_context(), NULL,
431 MSG_SMB_CONF_UPDATED, msg_reload_services);
432 messaging_register(winbind_messaging_context(), NULL,
433 MSG_SHUTDOWN, msg_shutdown);
435 /* Handle online/offline messages. */
436 messaging_register(winbind_messaging_context(), NULL,
437 MSG_WINBIND_OFFLINE, winbind_msg_offline);
438 messaging_register(winbind_messaging_context(), NULL,
439 MSG_WINBIND_ONLINE, winbind_msg_online);
440 messaging_register(winbind_messaging_context(), NULL,
441 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
443 messaging_register(winbind_messaging_context(), NULL,
444 MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
446 messaging_register(winbind_messaging_context(), NULL,
447 MSG_WINBIND_VALIDATE_CACHE,
448 winbind_msg_validate_cache);
450 messaging_register(winbind_messaging_context(), NULL,
451 MSG_WINBIND_DUMP_DOMAIN_LIST,
452 winbind_msg_dump_domain_list);
454 /* Register handler for MSG_DEBUG. */
455 messaging_register(winbind_messaging_context(), NULL,
459 netsamlogon_cache_init(); /* Non-critical */
461 /* clear the cached list of trusted domains */
465 if (!init_domain_list()) {
466 DEBUG(0,("unable to initialize domain list\n"));
471 init_locator_child();
473 smb_nscd_flush_user_cache();
474 smb_nscd_flush_group_cache();
476 te = tevent_add_timer(winbind_event_context(), NULL, timeval_zero(),
477 rescan_trusted_domains, NULL);
479 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));