s4-dsdb: Add documentation link for Tombstone Reanimation
[Samba.git] / source3 / winbindd / winbindd.c
blob4978c97aaa89b00314c3b72b56084c69c9231b3b
1 /*
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/>.
25 #include "includes.h"
26 #include "popt_common.h"
27 #include "winbindd.h"
28 #include "nsswitch/winbind_client.h"
29 #include "nsswitch/wb_reqtrans.h"
30 #include "ntdomain.h"
31 #include "../librpc/gen_ndr/srv_lsa.h"
32 #include "../librpc/gen_ndr/srv_samr.h"
33 #include "secrets.h"
34 #include "rpc_client/cli_netlogon.h"
35 #include "idmap.h"
36 #include "lib/addrchange.h"
37 #include "serverid.h"
38 #include "auth.h"
39 #include "messages.h"
40 #include "../lib/util/pidfile.h"
41 #include "util_cluster.h"
42 #include "source4/lib/messaging/irpc.h"
43 #include "source4/lib/messaging/messaging.h"
44 #include "lib/param/param.h"
46 #undef DBGC_CLASS
47 #define DBGC_CLASS DBGC_WINBIND
49 static bool client_is_idle(struct winbindd_cli_state *state);
50 static void remove_client(struct winbindd_cli_state *state);
52 static bool opt_nocache = False;
53 static bool interactive = False;
55 extern bool override_logfile;
57 struct tevent_context *winbind_event_context(void)
59 static struct tevent_context *ev = NULL;
61 if (ev != NULL) {
62 return ev;
66 * Note we MUST use the NULL context here, not the autofree context,
67 * to avoid side effects in forked children exiting.
69 ev = samba_tevent_context_init(NULL);
70 if (ev == NULL) {
71 smb_panic("Could not init winbindd's messaging context.\n");
73 return ev;
76 struct messaging_context *winbind_messaging_context(void)
78 static struct messaging_context *msg = NULL;
80 if (msg != NULL) {
81 return msg;
85 * Note we MUST use the NULL context here, not the autofree context,
86 * to avoid side effects in forked children exiting.
88 msg = messaging_init(NULL, winbind_event_context());
89 if (msg == NULL) {
90 smb_panic("Could not init winbindd's messaging context.\n");
92 return msg;
95 struct imessaging_context *winbind_imessaging_context(void)
97 static struct imessaging_context *msg = NULL;
98 struct loadparm_context *lp_ctx;
100 if (msg != NULL) {
101 return msg;
104 lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
105 if (lp_ctx == NULL) {
106 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
110 * Note we MUST use the NULL context here, not the autofree context,
111 * to avoid side effects in forked children exiting.
113 msg = imessaging_init(NULL, lp_ctx, procid_self(), winbind_event_context(), false);
114 talloc_unlink(NULL, lp_ctx);
116 if (msg == NULL) {
117 smb_panic("Could not init winbindd's messaging context.\n");
119 return msg;
122 /* Reload configuration */
124 static bool reload_services_file(const char *lfile)
126 bool ret;
128 if (lp_loaded()) {
129 char *fname = lp_next_configfile(talloc_tos());
131 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
132 set_dyn_CONFIGFILE(fname);
134 TALLOC_FREE(fname);
137 /* if this is a child, restore the logfile to the special
138 name - <domain>, idmap, etc. */
139 if (lfile && *lfile) {
140 lp_set_logfile(lfile);
143 reopen_logs();
144 ret = lp_load_global(get_dyn_CONFIGFILE());
146 reopen_logs();
147 load_interfaces();
149 return(ret);
153 static void winbindd_status(void)
155 struct winbindd_cli_state *tmp;
157 DEBUG(0, ("winbindd status:\n"));
159 /* Print client state information */
161 DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
163 if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
164 DEBUG(2, ("\tclient list:\n"));
165 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
166 DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
167 (unsigned long)tmp->pid, tmp->sock,
168 client_is_idle(tmp) ? "idle" : "active"));
173 /* Flush client cache */
175 static void flush_caches(void)
177 /* We need to invalidate cached user list entries on a SIGHUP
178 otherwise cached access denied errors due to restrict anonymous
179 hang around until the sequence number changes. */
181 if (!wcache_invalidate_cache()) {
182 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
183 if (!winbindd_cache_validate_and_initialize()) {
184 exit(1);
189 static void flush_caches_noinit(void)
192 * We need to invalidate cached user list entries on a SIGHUP
193 * otherwise cached access denied errors due to restrict anonymous
194 * hang around until the sequence number changes.
195 * NB
196 * Skip uninitialized domains when flush cache.
197 * If domain is not initialized, it means it is never
198 * used or never become online. look, wcache_invalidate_cache()
199 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
200 * for unused domains and large traffic for primay domain's DC if there
201 * are many domains..
204 if (!wcache_invalidate_cache_noinit()) {
205 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
206 if (!winbindd_cache_validate_and_initialize()) {
207 exit(1);
212 /* Handle the signal by unlinking socket and exiting */
214 static void terminate(bool is_parent)
216 if (is_parent) {
217 /* When parent goes away we should
218 * remove the socket file. Not so
219 * when children terminate.
221 char *path = NULL;
223 if (asprintf(&path, "%s/%s",
224 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) {
225 unlink(path);
226 SAFE_FREE(path);
230 idmap_close();
232 trustdom_cache_shutdown();
234 gencache_stabilize();
236 #if 0
237 if (interactive) {
238 TALLOC_CTX *mem_ctx = talloc_init("end_description");
239 char *description = talloc_describe_all(mem_ctx);
241 DEBUG(3, ("tallocs left:\n%s\n", description));
242 talloc_destroy(mem_ctx);
244 #endif
246 if (is_parent) {
247 struct messaging_context *msg = winbind_messaging_context();
248 struct server_id self = messaging_server_id(msg);
249 serverid_deregister(self);
250 pidfile_unlink(lp_pid_directory(), "winbindd");
253 exit(0);
256 static void winbindd_sig_term_handler(struct tevent_context *ev,
257 struct tevent_signal *se,
258 int signum,
259 int count,
260 void *siginfo,
261 void *private_data)
263 bool *is_parent = talloc_get_type_abort(private_data, bool);
265 DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
266 signum, (int)*is_parent));
267 terminate(*is_parent);
271 handle stdin becoming readable when we are in --foreground mode
273 static void winbindd_stdin_handler(struct tevent_context *ev,
274 struct tevent_fd *fde,
275 uint16_t flags,
276 void *private_data)
278 char c;
279 if (read(0, &c, 1) != 1) {
280 bool *is_parent = talloc_get_type_abort(private_data, bool);
282 /* we have reached EOF on stdin, which means the
283 parent has exited. Shutdown the server */
284 DEBUG(0,("EOF on stdin (is_parent=%d)\n",
285 (int)*is_parent));
286 terminate(*is_parent);
290 bool winbindd_setup_sig_term_handler(bool parent)
292 struct tevent_signal *se;
293 bool *is_parent;
295 is_parent = talloc(winbind_event_context(), bool);
296 if (!is_parent) {
297 return false;
300 *is_parent = parent;
302 se = tevent_add_signal(winbind_event_context(),
303 is_parent,
304 SIGTERM, 0,
305 winbindd_sig_term_handler,
306 is_parent);
307 if (!se) {
308 DEBUG(0,("failed to setup SIGTERM handler"));
309 talloc_free(is_parent);
310 return false;
313 se = tevent_add_signal(winbind_event_context(),
314 is_parent,
315 SIGINT, 0,
316 winbindd_sig_term_handler,
317 is_parent);
318 if (!se) {
319 DEBUG(0,("failed to setup SIGINT handler"));
320 talloc_free(is_parent);
321 return false;
324 se = tevent_add_signal(winbind_event_context(),
325 is_parent,
326 SIGQUIT, 0,
327 winbindd_sig_term_handler,
328 is_parent);
329 if (!se) {
330 DEBUG(0,("failed to setup SIGINT handler"));
331 talloc_free(is_parent);
332 return false;
335 return true;
338 bool winbindd_setup_stdin_handler(bool parent, bool foreground)
340 bool *is_parent;
342 if (foreground) {
343 struct stat st;
345 is_parent = talloc(winbind_event_context(), bool);
346 if (!is_parent) {
347 return false;
350 *is_parent = parent;
352 /* if we are running in the foreground then look for
353 EOF on stdin, and exit if it happens. This allows
354 us to die if the parent process dies
355 Only do this on a pipe or socket, no other device.
357 if (fstat(0, &st) != 0) {
358 return false;
360 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
361 tevent_add_fd(winbind_event_context(),
362 is_parent,
364 TEVENT_FD_READ,
365 winbindd_stdin_handler,
366 is_parent);
370 return true;
373 static void winbindd_sig_hup_handler(struct tevent_context *ev,
374 struct tevent_signal *se,
375 int signum,
376 int count,
377 void *siginfo,
378 void *private_data)
380 const char *file = (const char *)private_data;
382 DEBUG(1,("Reloading services after SIGHUP\n"));
383 flush_caches_noinit();
384 reload_services_file(file);
387 bool winbindd_setup_sig_hup_handler(const char *lfile)
389 struct tevent_signal *se;
390 char *file = NULL;
392 if (lfile) {
393 file = talloc_strdup(winbind_event_context(),
394 lfile);
395 if (!file) {
396 return false;
400 se = tevent_add_signal(winbind_event_context(),
401 winbind_event_context(),
402 SIGHUP, 0,
403 winbindd_sig_hup_handler,
404 file);
405 if (!se) {
406 return false;
409 return true;
412 static void winbindd_sig_chld_handler(struct tevent_context *ev,
413 struct tevent_signal *se,
414 int signum,
415 int count,
416 void *siginfo,
417 void *private_data)
419 pid_t pid;
421 while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) {
422 winbind_child_died(pid);
426 static bool winbindd_setup_sig_chld_handler(void)
428 struct tevent_signal *se;
430 se = tevent_add_signal(winbind_event_context(),
431 winbind_event_context(),
432 SIGCHLD, 0,
433 winbindd_sig_chld_handler,
434 NULL);
435 if (!se) {
436 return false;
439 return true;
442 static void winbindd_sig_usr2_handler(struct tevent_context *ev,
443 struct tevent_signal *se,
444 int signum,
445 int count,
446 void *siginfo,
447 void *private_data)
449 winbindd_status();
452 static bool winbindd_setup_sig_usr2_handler(void)
454 struct tevent_signal *se;
456 se = tevent_add_signal(winbind_event_context(),
457 winbind_event_context(),
458 SIGUSR2, 0,
459 winbindd_sig_usr2_handler,
460 NULL);
461 if (!se) {
462 return false;
465 return true;
468 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
469 static void msg_reload_services(struct messaging_context *msg,
470 void *private_data,
471 uint32_t msg_type,
472 struct server_id server_id,
473 DATA_BLOB *data)
475 /* Flush various caches */
476 flush_caches();
477 reload_services_file((const char *) private_data);
480 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
481 static void msg_shutdown(struct messaging_context *msg,
482 void *private_data,
483 uint32_t msg_type,
484 struct server_id server_id,
485 DATA_BLOB *data)
487 /* only the parent waits for this message */
488 DEBUG(0,("Got shutdown message\n"));
489 terminate(true);
493 static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
494 void *private_data,
495 uint32_t msg_type,
496 struct server_id server_id,
497 DATA_BLOB *data)
499 uint8 ret;
500 pid_t child_pid;
501 NTSTATUS status;
503 DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
504 "message.\n"));
507 * call the validation code from a child:
508 * so we don't block the main winbindd and the validation
509 * code can safely use fork/waitpid...
511 child_pid = fork();
513 if (child_pid == -1) {
514 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
515 strerror(errno)));
516 return;
519 if (child_pid != 0) {
520 /* parent */
521 DEBUG(5, ("winbind_msg_validate_cache: child created with "
522 "pid %d.\n", (int)child_pid));
523 return;
526 /* child */
528 status = winbindd_reinit_after_fork(NULL, NULL);
529 if (!NT_STATUS_IS_OK(status)) {
530 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
531 nt_errstr(status)));
532 _exit(0);
535 /* install default SIGCHLD handler: validation code uses fork/waitpid */
536 CatchSignal(SIGCHLD, SIG_DFL);
538 ret = (uint8)winbindd_validate_cache_nobackup();
539 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
540 messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
541 (size_t)1);
542 _exit(0);
545 static struct winbindd_dispatch_table {
546 enum winbindd_cmd cmd;
547 void (*fn)(struct winbindd_cli_state *state);
548 const char *winbindd_cmd_name;
549 } dispatch_table[] = {
551 /* Enumeration functions */
553 { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
554 "LIST_TRUSTDOM" },
556 /* Miscellaneous */
558 { WINBINDD_INFO, winbindd_info, "INFO" },
559 { WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
560 "INTERFACE_VERSION" },
561 { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
562 { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
563 { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" },
564 { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
565 { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
566 "WINBINDD_PRIV_PIPE_DIR" },
568 /* Credential cache access */
569 { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
570 { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
572 /* End of list */
574 { WINBINDD_NUM_CMDS, NULL, "NONE" }
577 struct winbindd_async_dispatch_table {
578 enum winbindd_cmd cmd;
579 const char *cmd_name;
580 struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
581 struct tevent_context *ev,
582 struct winbindd_cli_state *cli,
583 struct winbindd_request *request);
584 NTSTATUS (*recv_req)(struct tevent_req *req,
585 struct winbindd_response *presp);
588 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
589 { WINBINDD_PING, "PING",
590 wb_ping_send, wb_ping_recv },
591 { WINBINDD_LOOKUPSID, "LOOKUPSID",
592 winbindd_lookupsid_send, winbindd_lookupsid_recv },
593 { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
594 winbindd_lookupsids_send, winbindd_lookupsids_recv },
595 { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
596 winbindd_lookupname_send, winbindd_lookupname_recv },
597 { WINBINDD_SID_TO_UID, "SID_TO_UID",
598 winbindd_sid_to_uid_send, winbindd_sid_to_uid_recv },
599 { WINBINDD_SID_TO_GID, "SID_TO_GID",
600 winbindd_sid_to_gid_send, winbindd_sid_to_gid_recv },
601 { WINBINDD_UID_TO_SID, "UID_TO_SID",
602 winbindd_uid_to_sid_send, winbindd_uid_to_sid_recv },
603 { WINBINDD_GID_TO_SID, "GID_TO_SID",
604 winbindd_gid_to_sid_send, winbindd_gid_to_sid_recv },
605 { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
606 winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
607 { WINBINDD_GETPWSID, "GETPWSID",
608 winbindd_getpwsid_send, winbindd_getpwsid_recv },
609 { WINBINDD_GETPWNAM, "GETPWNAM",
610 winbindd_getpwnam_send, winbindd_getpwnam_recv },
611 { WINBINDD_GETPWUID, "GETPWUID",
612 winbindd_getpwuid_send, winbindd_getpwuid_recv },
613 { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
614 winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
615 { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
616 winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
617 { WINBINDD_GETGROUPS, "GETGROUPS",
618 winbindd_getgroups_send, winbindd_getgroups_recv },
619 { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
620 winbindd_show_sequence_send, winbindd_show_sequence_recv },
621 { WINBINDD_GETGRGID, "GETGRGID",
622 winbindd_getgrgid_send, winbindd_getgrgid_recv },
623 { WINBINDD_GETGRNAM, "GETGRNAM",
624 winbindd_getgrnam_send, winbindd_getgrnam_recv },
625 { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
626 winbindd_getusersids_send, winbindd_getusersids_recv },
627 { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
628 winbindd_lookuprids_send, winbindd_lookuprids_recv },
629 { WINBINDD_SETPWENT, "SETPWENT",
630 winbindd_setpwent_send, winbindd_setpwent_recv },
631 { WINBINDD_GETPWENT, "GETPWENT",
632 winbindd_getpwent_send, winbindd_getpwent_recv },
633 { WINBINDD_ENDPWENT, "ENDPWENT",
634 winbindd_endpwent_send, winbindd_endpwent_recv },
635 { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
636 winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
637 { WINBINDD_GETDCNAME, "GETDCNAME",
638 winbindd_getdcname_send, winbindd_getdcname_recv },
639 { WINBINDD_SETGRENT, "SETGRENT",
640 winbindd_setgrent_send, winbindd_setgrent_recv },
641 { WINBINDD_GETGRENT, "GETGRENT",
642 winbindd_getgrent_send, winbindd_getgrent_recv },
643 { WINBINDD_ENDGRENT, "ENDGRENT",
644 winbindd_endgrent_send, winbindd_endgrent_recv },
645 { WINBINDD_LIST_USERS, "LIST_USERS",
646 winbindd_list_users_send, winbindd_list_users_recv },
647 { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
648 winbindd_list_groups_send, winbindd_list_groups_recv },
649 { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
650 winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
651 { WINBINDD_PING_DC, "PING_DC",
652 winbindd_ping_dc_send, winbindd_ping_dc_recv },
653 { WINBINDD_PAM_AUTH, "PAM_AUTH",
654 winbindd_pam_auth_send, winbindd_pam_auth_recv },
655 { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
656 winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
657 { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
658 winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
659 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
660 winbindd_pam_chng_pswd_auth_crap_send,
661 winbindd_pam_chng_pswd_auth_crap_recv },
662 { WINBINDD_WINS_BYIP, "WINS_BYIP",
663 winbindd_wins_byip_send, winbindd_wins_byip_recv },
664 { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
665 winbindd_wins_byname_send, winbindd_wins_byname_recv },
667 { 0, NULL, NULL, NULL }
670 static struct winbindd_async_dispatch_table async_priv_table[] = {
671 { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
672 winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
673 { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
674 winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
675 { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
676 winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
677 { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
678 winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
680 { 0, NULL, NULL, NULL }
683 static void wb_request_done(struct tevent_req *req);
685 static void process_request(struct winbindd_cli_state *state)
687 struct winbindd_dispatch_table *table = dispatch_table;
688 struct winbindd_async_dispatch_table *atable;
690 state->mem_ctx = talloc_named(state, 0, "winbind request");
691 if (state->mem_ctx == NULL)
692 return;
694 /* Remember who asked us. */
695 state->pid = state->request->pid;
697 state->cmd_name = "unknown request";
698 state->recv_fn = NULL;
699 state->last_access = time(NULL);
701 /* Process command */
703 for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
704 if (state->request->cmd == atable->cmd) {
705 break;
709 if ((atable->send_req == NULL) && state->privileged) {
710 for (atable = async_priv_table; atable->send_req;
711 atable += 1) {
712 if (state->request->cmd == atable->cmd) {
713 break;
718 if (atable->send_req != NULL) {
719 struct tevent_req *req;
721 state->cmd_name = atable->cmd_name;
722 state->recv_fn = atable->recv_req;
724 DEBUG(10, ("process_request: Handling async request %d:%s\n",
725 (int)state->pid, state->cmd_name));
727 req = atable->send_req(state->mem_ctx, winbind_event_context(),
728 state, state->request);
729 if (req == NULL) {
730 DEBUG(0, ("process_request: atable->send failed for "
731 "%s\n", atable->cmd_name));
732 request_error(state);
733 return;
735 tevent_req_set_callback(req, wb_request_done, state);
736 return;
739 state->response = talloc_zero(state->mem_ctx,
740 struct winbindd_response);
741 if (state->response == NULL) {
742 DEBUG(10, ("talloc failed\n"));
743 remove_client(state);
744 return;
746 state->response->result = WINBINDD_PENDING;
747 state->response->length = sizeof(struct winbindd_response);
749 for (table = dispatch_table; table->fn; table++) {
750 if (state->request->cmd == table->cmd) {
751 DEBUG(10,("process_request: request fn %s\n",
752 table->winbindd_cmd_name ));
753 state->cmd_name = table->winbindd_cmd_name;
754 table->fn(state);
755 break;
759 if (!table->fn) {
760 DEBUG(10,("process_request: unknown request fn number %d\n",
761 (int)state->request->cmd ));
762 request_error(state);
766 static void wb_request_done(struct tevent_req *req)
768 struct winbindd_cli_state *state = tevent_req_callback_data(
769 req, struct winbindd_cli_state);
770 NTSTATUS status;
772 state->response = talloc_zero(state->mem_ctx,
773 struct winbindd_response);
774 if (state->response == NULL) {
775 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
776 (int)state->pid, state->cmd_name));
777 remove_client(state);
778 return;
780 state->response->result = WINBINDD_PENDING;
781 state->response->length = sizeof(struct winbindd_response);
783 status = state->recv_fn(req, state->response);
784 TALLOC_FREE(req);
786 DEBUG(10,("wb_request_done[%d:%s]: %s\n",
787 (int)state->pid, state->cmd_name, nt_errstr(status)));
789 if (!NT_STATUS_IS_OK(status)) {
790 request_error(state);
791 return;
793 request_ok(state);
797 * This is the main event loop of winbind requests. It goes through a
798 * state-machine of 3 read/write requests, 4 if you have extra data to send.
800 * An idle winbind client has a read request of 4 bytes outstanding,
801 * finalizing function is request_len_recv, checking the length. request_recv
802 * then processes the packet. The processing function then at some point has
803 * to call request_finished which schedules sending the response.
806 static void request_finished(struct winbindd_cli_state *state);
808 static void winbind_client_request_read(struct tevent_req *req);
809 static void winbind_client_response_written(struct tevent_req *req);
811 static void request_finished(struct winbindd_cli_state *state)
813 struct tevent_req *req;
815 TALLOC_FREE(state->request);
817 req = wb_resp_write_send(state, winbind_event_context(),
818 state->out_queue, state->sock,
819 state->response);
820 if (req == NULL) {
821 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
822 (int)state->pid, state->cmd_name));
823 remove_client(state);
824 return;
826 tevent_req_set_callback(req, winbind_client_response_written, state);
829 static void winbind_client_response_written(struct tevent_req *req)
831 struct winbindd_cli_state *state = tevent_req_callback_data(
832 req, struct winbindd_cli_state);
833 ssize_t ret;
834 int err;
836 ret = wb_resp_write_recv(req, &err);
837 TALLOC_FREE(req);
838 if (ret == -1) {
839 close(state->sock);
840 state->sock = -1;
841 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
842 (int)state->pid, state->cmd_name, strerror(err)));
843 remove_client(state);
844 return;
847 DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
848 "to client\n", (int)state->pid, state->cmd_name));
850 TALLOC_FREE(state->mem_ctx);
851 state->response = NULL;
852 state->cmd_name = "no request";
853 state->recv_fn = NULL;
855 req = wb_req_read_send(state, winbind_event_context(), state->sock,
856 WINBINDD_MAX_EXTRA_DATA);
857 if (req == NULL) {
858 remove_client(state);
859 return;
861 tevent_req_set_callback(req, winbind_client_request_read, state);
864 void request_error(struct winbindd_cli_state *state)
866 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
867 state->response->result = WINBINDD_ERROR;
868 request_finished(state);
871 void request_ok(struct winbindd_cli_state *state)
873 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
874 state->response->result = WINBINDD_OK;
875 request_finished(state);
878 /* Process a new connection by adding it to the client connection list */
880 static void new_connection(int listen_sock, bool privileged)
882 struct sockaddr_un sunaddr;
883 struct winbindd_cli_state *state;
884 struct tevent_req *req;
885 socklen_t len;
886 int sock;
888 /* Accept connection */
890 len = sizeof(sunaddr);
892 sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
894 if (sock == -1) {
895 if (errno != EINTR) {
896 DEBUG(0, ("Failed to accept socket - %s\n",
897 strerror(errno)));
899 return;
902 DEBUG(6,("accepted socket %d\n", sock));
904 /* Create new connection structure */
906 if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
907 close(sock);
908 return;
911 state->sock = sock;
913 state->out_queue = tevent_queue_create(state, "winbind client reply");
914 if (state->out_queue == NULL) {
915 close(sock);
916 TALLOC_FREE(state);
917 return;
920 state->last_access = time(NULL);
922 state->privileged = privileged;
924 req = wb_req_read_send(state, winbind_event_context(), state->sock,
925 WINBINDD_MAX_EXTRA_DATA);
926 if (req == NULL) {
927 TALLOC_FREE(state);
928 close(sock);
929 return;
931 tevent_req_set_callback(req, winbind_client_request_read, state);
933 /* Add to connection list */
935 winbindd_add_client(state);
938 static void winbind_client_request_read(struct tevent_req *req)
940 struct winbindd_cli_state *state = tevent_req_callback_data(
941 req, struct winbindd_cli_state);
942 ssize_t ret;
943 int err;
945 ret = wb_req_read_recv(req, state, &state->request, &err);
946 TALLOC_FREE(req);
947 if (ret == -1) {
948 if (err == EPIPE) {
949 DEBUG(6, ("closing socket %d, client exited\n",
950 state->sock));
951 } else {
952 DEBUG(2, ("Could not read client request from fd %d: "
953 "%s\n", state->sock, strerror(err)));
955 close(state->sock);
956 state->sock = -1;
957 remove_client(state);
958 return;
960 process_request(state);
963 /* Remove a client connection from client connection list */
965 static void remove_client(struct winbindd_cli_state *state)
967 char c = 0;
968 int nwritten;
970 /* It's a dead client - hold a funeral */
972 if (state == NULL) {
973 return;
976 if (state->sock != -1) {
977 /* tell client, we are closing ... */
978 nwritten = write(state->sock, &c, sizeof(c));
979 if (nwritten == -1) {
980 DEBUG(2, ("final write to client failed: %s\n",
981 strerror(errno)));
984 /* Close socket */
986 close(state->sock);
987 state->sock = -1;
990 TALLOC_FREE(state->mem_ctx);
992 /* Remove from list and free */
994 winbindd_remove_client(state);
995 TALLOC_FREE(state);
998 /* Is a client idle? */
1000 static bool client_is_idle(struct winbindd_cli_state *state) {
1001 return (state->request == NULL &&
1002 state->response == NULL &&
1003 !state->pwent_state && !state->grent_state);
1006 /* Shutdown client connection which has been idle for the longest time */
1008 static bool remove_idle_client(void)
1010 struct winbindd_cli_state *state, *remove_state = NULL;
1011 time_t last_access = 0;
1012 int nidle = 0;
1014 for (state = winbindd_client_list(); state; state = state->next) {
1015 if (client_is_idle(state)) {
1016 nidle++;
1017 if (!last_access || state->last_access < last_access) {
1018 last_access = state->last_access;
1019 remove_state = state;
1024 if (remove_state) {
1025 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1026 nidle, remove_state->sock, (unsigned int)remove_state->pid));
1027 remove_client(remove_state);
1028 return True;
1031 return False;
1035 * Terminate all clients whose requests have taken longer than
1036 * "winbind request timeout" seconds to process, or have been
1037 * idle for more than "winbind request timeout" seconds.
1040 static void remove_timed_out_clients(void)
1042 struct winbindd_cli_state *state, *next = NULL;
1043 time_t curr_time = time(NULL);
1044 int timeout_val = lp_winbind_request_timeout();
1046 for (state = winbindd_client_list(); state; state = next) {
1047 time_t expiry_time;
1049 next = state->next;
1050 expiry_time = state->last_access + timeout_val;
1052 if (curr_time > expiry_time) {
1053 if (client_is_idle(state)) {
1054 DEBUG(5,("Idle client timed out, "
1055 "shutting down sock %d, pid %u\n",
1056 state->sock,
1057 (unsigned int)state->pid));
1058 } else {
1059 DEBUG(5,("Client request timed out, "
1060 "shutting down sock %d, pid %u\n",
1061 state->sock,
1062 (unsigned int)state->pid));
1064 remove_client(state);
1069 struct winbindd_listen_state {
1070 bool privileged;
1071 int fd;
1074 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1075 struct tevent_fd *fde,
1076 uint16_t flags,
1077 void *private_data)
1079 struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1080 struct winbindd_listen_state);
1082 while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1083 DEBUG(5,("winbindd: Exceeding %d client "
1084 "connections, removing idle "
1085 "connection.\n", lp_winbind_max_clients()));
1086 if (!remove_idle_client()) {
1087 DEBUG(0,("winbindd: Exceeding %d "
1088 "client connections, no idle "
1089 "connection found\n",
1090 lp_winbind_max_clients()));
1091 break;
1094 remove_timed_out_clients();
1095 new_connection(s->fd, s->privileged);
1099 * Winbindd socket accessor functions
1102 char *get_winbind_priv_pipe_dir(void)
1104 return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1107 static bool winbindd_setup_listeners(void)
1109 struct winbindd_listen_state *pub_state = NULL;
1110 struct winbindd_listen_state *priv_state = NULL;
1111 struct tevent_fd *fde;
1112 int rc;
1113 char *socket_path;
1115 pub_state = talloc(winbind_event_context(),
1116 struct winbindd_listen_state);
1117 if (!pub_state) {
1118 goto failed;
1121 pub_state->privileged = false;
1122 pub_state->fd = create_pipe_sock(
1123 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1124 if (pub_state->fd == -1) {
1125 goto failed;
1127 rc = listen(pub_state->fd, 5);
1128 if (rc < 0) {
1129 goto failed;
1132 fde = tevent_add_fd(winbind_event_context(), pub_state, pub_state->fd,
1133 TEVENT_FD_READ, winbindd_listen_fde_handler,
1134 pub_state);
1135 if (fde == NULL) {
1136 close(pub_state->fd);
1137 goto failed;
1139 tevent_fd_set_auto_close(fde);
1141 priv_state = talloc(winbind_event_context(),
1142 struct winbindd_listen_state);
1143 if (!priv_state) {
1144 goto failed;
1147 socket_path = get_winbind_priv_pipe_dir();
1148 if (socket_path == NULL) {
1149 goto failed;
1152 priv_state->privileged = true;
1153 priv_state->fd = create_pipe_sock(
1154 socket_path, WINBINDD_SOCKET_NAME, 0750);
1155 TALLOC_FREE(socket_path);
1156 if (priv_state->fd == -1) {
1157 goto failed;
1159 rc = listen(priv_state->fd, 5);
1160 if (rc < 0) {
1161 goto failed;
1164 fde = tevent_add_fd(winbind_event_context(), priv_state,
1165 priv_state->fd, TEVENT_FD_READ,
1166 winbindd_listen_fde_handler, priv_state);
1167 if (fde == NULL) {
1168 close(priv_state->fd);
1169 goto failed;
1171 tevent_fd_set_auto_close(fde);
1173 return true;
1174 failed:
1175 TALLOC_FREE(pub_state);
1176 TALLOC_FREE(priv_state);
1177 return false;
1180 bool winbindd_use_idmap_cache(void)
1182 return !opt_nocache;
1185 bool winbindd_use_cache(void)
1187 return !opt_nocache;
1190 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1191 bool foreground)
1193 NTSTATUS status;
1194 /* Setup signal handlers */
1196 if (!winbindd_setup_sig_term_handler(true))
1197 exit(1);
1198 if (!winbindd_setup_stdin_handler(true, foreground))
1199 exit(1);
1200 if (!winbindd_setup_sig_hup_handler(NULL))
1201 exit(1);
1202 if (!winbindd_setup_sig_chld_handler())
1203 exit(1);
1204 if (!winbindd_setup_sig_usr2_handler())
1205 exit(1);
1207 CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
1210 * Ensure all cache and idmap caches are consistent
1211 * and initialized before we startup.
1213 if (!winbindd_cache_validate_and_initialize()) {
1214 exit(1);
1217 /* get broadcast messages */
1219 if (!serverid_register(messaging_server_id(msg_ctx),
1220 FLAG_MSG_GENERAL |
1221 FLAG_MSG_WINBIND |
1222 FLAG_MSG_DBWRAP)) {
1223 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
1224 exit(1);
1227 /* React on 'smbcontrol winbindd reload-config' in the same way
1228 as to SIGHUP signal */
1229 messaging_register(msg_ctx, NULL,
1230 MSG_SMB_CONF_UPDATED, msg_reload_services);
1231 messaging_register(msg_ctx, NULL,
1232 MSG_SHUTDOWN, msg_shutdown);
1234 /* Handle online/offline messages. */
1235 messaging_register(msg_ctx, NULL,
1236 MSG_WINBIND_OFFLINE, winbind_msg_offline);
1237 messaging_register(msg_ctx, NULL,
1238 MSG_WINBIND_ONLINE, winbind_msg_online);
1239 messaging_register(msg_ctx, NULL,
1240 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1242 /* Handle domain online/offline messages for domains */
1243 messaging_register(winbind_messaging_context(), NULL,
1244 MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1245 messaging_register(winbind_messaging_context(), NULL,
1246 MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1248 messaging_register(msg_ctx, NULL,
1249 MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
1251 messaging_register(msg_ctx, NULL,
1252 MSG_WINBIND_VALIDATE_CACHE,
1253 winbind_msg_validate_cache);
1255 messaging_register(msg_ctx, NULL,
1256 MSG_WINBIND_DUMP_DOMAIN_LIST,
1257 winbind_msg_dump_domain_list);
1259 messaging_register(msg_ctx, NULL,
1260 MSG_WINBIND_IP_DROPPED,
1261 winbind_msg_ip_dropped_parent);
1263 /* Register handler for MSG_DEBUG. */
1264 messaging_register(msg_ctx, NULL,
1265 MSG_DEBUG,
1266 winbind_msg_debug);
1268 netsamlogon_cache_init(); /* Non-critical */
1270 /* clear the cached list of trusted domains */
1272 wcache_tdc_clear();
1274 if (!init_domain_list()) {
1275 DEBUG(0,("unable to initialize domain list\n"));
1276 exit(1);
1279 init_idmap_child();
1280 init_locator_child();
1282 smb_nscd_flush_user_cache();
1283 smb_nscd_flush_group_cache();
1285 if (lp_allow_trusted_domains()) {
1286 if (tevent_add_timer(winbind_event_context(), NULL, timeval_zero(),
1287 rescan_trusted_domains, NULL) == NULL) {
1288 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1289 exit(1);
1293 status = wb_irpc_register();
1295 if (!NT_STATUS_IS_OK(status)) {
1296 DEBUG(0, ("Could not register IRPC handlers\n"));
1297 exit(1);
1301 struct winbindd_addrchanged_state {
1302 struct addrchange_context *ctx;
1303 struct tevent_context *ev;
1304 struct messaging_context *msg_ctx;
1307 static void winbindd_addr_changed(struct tevent_req *req);
1309 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1310 struct tevent_context *ev,
1311 struct messaging_context *msg_ctx)
1313 struct winbindd_addrchanged_state *state;
1314 struct tevent_req *req;
1315 NTSTATUS status;
1317 state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1318 if (state == NULL) {
1319 DEBUG(10, ("talloc failed\n"));
1320 return;
1322 state->ev = ev;
1323 state->msg_ctx = msg_ctx;
1325 status = addrchange_context_create(state, &state->ctx);
1326 if (!NT_STATUS_IS_OK(status)) {
1327 DEBUG(10, ("addrchange_context_create failed: %s\n",
1328 nt_errstr(status)));
1329 TALLOC_FREE(state);
1330 return;
1332 req = addrchange_send(state, ev, state->ctx);
1333 if (req == NULL) {
1334 DEBUG(0, ("addrchange_send failed\n"));
1335 TALLOC_FREE(state);
1336 return;
1338 tevent_req_set_callback(req, winbindd_addr_changed, state);
1341 static void winbindd_addr_changed(struct tevent_req *req)
1343 struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1344 req, struct winbindd_addrchanged_state);
1345 enum addrchange_type type;
1346 struct sockaddr_storage addr;
1347 NTSTATUS status;
1349 status = addrchange_recv(req, &type, &addr);
1350 TALLOC_FREE(req);
1351 if (!NT_STATUS_IS_OK(status)) {
1352 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1353 nt_errstr(status)));
1354 TALLOC_FREE(state);
1355 return;
1357 if (type == ADDRCHANGE_DEL) {
1358 char addrstr[INET6_ADDRSTRLEN];
1359 DATA_BLOB blob;
1361 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1363 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1364 addrstr));
1366 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1368 status = messaging_send(state->msg_ctx,
1369 messaging_server_id(state->msg_ctx),
1370 MSG_WINBIND_IP_DROPPED, &blob);
1371 if (!NT_STATUS_IS_OK(status)) {
1372 DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1373 nt_errstr(status)));
1376 req = addrchange_send(state, state->ev, state->ctx);
1377 if (req == NULL) {
1378 DEBUG(0, ("addrchange_send failed\n"));
1379 TALLOC_FREE(state);
1380 return;
1382 tevent_req_set_callback(req, winbindd_addr_changed, state);
1385 /* Main function */
1387 int main(int argc, const char **argv)
1389 static bool is_daemon = False;
1390 static bool Fork = True;
1391 static bool log_stdout = False;
1392 static bool no_process_group = False;
1393 enum {
1394 OPT_DAEMON = 1000,
1395 OPT_FORK,
1396 OPT_NO_PROCESS_GROUP,
1397 OPT_LOG_STDOUT
1399 struct poptOption long_options[] = {
1400 POPT_AUTOHELP
1401 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1402 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1403 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1404 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1405 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1406 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1407 POPT_COMMON_SAMBA
1408 POPT_TABLEEND
1410 poptContext pc;
1411 int opt;
1412 TALLOC_CTX *frame;
1413 NTSTATUS status;
1414 bool ok;
1417 * Do this before any other talloc operation
1419 talloc_enable_null_tracking();
1420 frame = talloc_stackframe();
1423 * We want total control over the permissions on created files,
1424 * so set our umask to 0.
1426 umask(0);
1428 setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1430 /* glibc (?) likes to print "User defined signal 1" and exit if a
1431 SIGUSR[12] is received before a handler is installed */
1433 CatchSignal(SIGUSR1, SIG_IGN);
1434 CatchSignal(SIGUSR2, SIG_IGN);
1436 fault_setup();
1437 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1439 load_case_tables();
1441 /* Initialise for running in non-root mode */
1443 sec_init();
1445 set_remote_machine_name("winbindd", False);
1447 /* Set environment variable so we don't recursively call ourselves.
1448 This may also be useful interactively. */
1450 if ( !winbind_off() ) {
1451 DEBUG(0,("Failed to disable recusive winbindd calls. Exiting.\n"));
1452 exit(1);
1455 /* Initialise samba/rpc client stuff */
1457 pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1459 while ((opt = poptGetNextOpt(pc)) != -1) {
1460 switch (opt) {
1461 /* Don't become a daemon */
1462 case OPT_DAEMON:
1463 is_daemon = True;
1464 break;
1465 case 'i':
1466 interactive = True;
1467 log_stdout = True;
1468 Fork = False;
1469 break;
1470 case OPT_FORK:
1471 Fork = false;
1472 break;
1473 case OPT_NO_PROCESS_GROUP:
1474 no_process_group = true;
1475 break;
1476 case OPT_LOG_STDOUT:
1477 log_stdout = true;
1478 break;
1479 case 'n':
1480 opt_nocache = true;
1481 break;
1482 default:
1483 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1484 poptBadOption(pc, 0), poptStrerror(opt));
1485 poptPrintUsage(pc, stderr, 0);
1486 exit(1);
1490 /* We call dump_core_setup one more time because the command line can
1491 * set the log file or the log-basename and this will influence where
1492 * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1493 * the default value derived from build's prefix. For EOM this value
1494 * is often not related to the path where winbindd is actually run
1495 * in production.
1497 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1498 if (is_daemon && interactive) {
1499 d_fprintf(stderr,"\nERROR: "
1500 "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1501 poptPrintUsage(pc, stderr, 0);
1502 exit(1);
1505 if (log_stdout && Fork) {
1506 d_fprintf(stderr, "\nERROR: "
1507 "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1508 poptPrintUsage(pc, stderr, 0);
1509 exit(1);
1512 poptFreeContext(pc);
1514 if (!override_logfile) {
1515 char *lfile = NULL;
1516 if (asprintf(&lfile,"%s/log.winbindd",
1517 get_dyn_LOGFILEBASE()) > 0) {
1518 lp_set_logfile(lfile);
1519 SAFE_FREE(lfile);
1523 if (log_stdout) {
1524 setup_logging("winbindd", DEBUG_STDOUT);
1525 } else {
1526 setup_logging("winbindd", DEBUG_FILE);
1528 reopen_logs();
1530 DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1531 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1533 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1534 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1535 exit(1);
1537 /* After parsing the configuration file we setup the core path one more time
1538 * as the log file might have been set in the configuration and cores's
1539 * path is by default basename(lp_logfile()).
1541 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1543 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1544 && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1545 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1546 DEBUGADD(0, ("You should start 'samba' instead, and it will control starting the internal AD DC winbindd implementation, which is not the same as this one\n"));
1547 exit(1);
1550 if (!cluster_probe_ok()) {
1551 exit(1);
1554 /* Initialise messaging system */
1556 if (winbind_messaging_context() == NULL) {
1557 exit(1);
1560 if (!reload_services_file(NULL)) {
1561 DEBUG(0, ("error opening config file\n"));
1562 exit(1);
1565 ok = directory_create_or_exist(lp_lock_directory(), 0755);
1566 if (!ok) {
1567 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1568 lp_lock_directory(), strerror(errno)));
1569 exit(1);
1572 ok = directory_create_or_exist(lp_pid_directory(), 0755);
1573 if (!ok) {
1574 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1575 lp_pid_directory(), strerror(errno)));
1576 exit(1);
1579 /* Setup names. */
1581 if (!init_names())
1582 exit(1);
1584 load_interfaces();
1586 if (!secrets_init()) {
1588 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1589 return False;
1592 status = rpccli_pre_open_netlogon_creds();
1593 if (!NT_STATUS_IS_OK(status)) {
1594 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1595 nt_errstr(status)));
1596 exit(1);
1599 /* Unblock all signals we are interested in as they may have been
1600 blocked by the parent process. */
1602 BlockSignals(False, SIGINT);
1603 BlockSignals(False, SIGQUIT);
1604 BlockSignals(False, SIGTERM);
1605 BlockSignals(False, SIGUSR1);
1606 BlockSignals(False, SIGUSR2);
1607 BlockSignals(False, SIGHUP);
1608 BlockSignals(False, SIGCHLD);
1610 if (!interactive)
1611 become_daemon(Fork, no_process_group, log_stdout);
1613 pidfile_create(lp_pid_directory(), "winbindd");
1615 #if HAVE_SETPGID
1617 * If we're interactive we want to set our own process group for
1618 * signal management.
1620 if (interactive && !no_process_group)
1621 setpgid( (pid_t)0, (pid_t)0);
1622 #endif
1624 TimeInit();
1626 /* Don't use winbindd_reinit_after_fork here as
1627 * we're just starting up and haven't created any
1628 * winbindd-specific resources we must free yet. JRA.
1631 status = reinit_after_fork(winbind_messaging_context(),
1632 winbind_event_context(),
1633 false);
1634 if (!NT_STATUS_IS_OK(status)) {
1635 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1639 * Do not initialize the parent-child-pipe before becoming
1640 * a daemon: this is used to detect a died parent in the child
1641 * process.
1643 status = init_before_fork();
1644 if (!NT_STATUS_IS_OK(status)) {
1645 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1648 winbindd_register_handlers(winbind_messaging_context(), !Fork);
1650 if (!messaging_parent_dgm_cleanup_init(winbind_messaging_context())) {
1651 exit(1);
1654 status = init_system_session_info();
1655 if (!NT_STATUS_IS_OK(status)) {
1656 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1659 rpc_lsarpc_init(NULL);
1660 rpc_samr_init(NULL);
1662 winbindd_init_addrchange(NULL, winbind_event_context(),
1663 winbind_messaging_context());
1665 /* setup listen sockets */
1667 if (!winbindd_setup_listeners()) {
1668 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1671 irpc_add_name(winbind_imessaging_context(), "winbind_server");
1673 TALLOC_FREE(frame);
1675 if (!interactive) {
1676 daemon_ready("winbindd");
1679 /* Loop waiting for requests */
1680 while (1) {
1681 frame = talloc_stackframe();
1683 if (tevent_loop_once(winbind_event_context()) == -1) {
1684 DEBUG(1, ("tevent_loop_once() failed: %s\n",
1685 strerror(errno)));
1686 return 1;
1689 TALLOC_FREE(frame);
1692 return 0;