winbindd: Remove "DUMP_EVENT_LIST" message
[Samba.git] / source3 / winbindd / winbindd.c
blob81b86df2ffa466c926aeb14ae04006dabb89423c
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 "auth.h"
38 #include "messages.h"
39 #include "../lib/util/pidfile.h"
40 #include "util_cluster.h"
41 #include "source4/lib/messaging/irpc.h"
42 #include "source4/lib/messaging/messaging.h"
43 #include "lib/param/param.h"
44 #include "lib/async_req/async_sock.h"
45 #include "libsmb/samlogon_cache.h"
46 #include "libcli/auth/netlogon_creds_cli.h"
48 #undef DBGC_CLASS
49 #define DBGC_CLASS DBGC_WINBIND
51 #define SCRUB_CLIENTS_INTERVAL 5
53 static bool client_is_idle(struct winbindd_cli_state *state);
54 static void remove_client(struct winbindd_cli_state *state);
55 static void winbindd_setup_max_fds(void);
57 static bool opt_nocache = False;
58 static bool interactive = False;
60 extern bool override_logfile;
62 struct imessaging_context *winbind_imessaging_context(void)
64 static struct imessaging_context *msg = NULL;
65 struct messaging_context *msg_ctx;
66 struct server_id myself;
67 struct loadparm_context *lp_ctx;
69 if (msg != NULL) {
70 return msg;
73 msg_ctx = server_messaging_context();
74 if (msg_ctx == NULL) {
75 smb_panic("server_messaging_context failed\n");
77 myself = messaging_server_id(msg_ctx);
79 lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
80 if (lp_ctx == NULL) {
81 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
85 * Note we MUST use the NULL context here, not the autofree context,
86 * to avoid side effects in forked children exiting.
88 msg = imessaging_init(NULL, lp_ctx, myself, server_event_context());
89 talloc_unlink(NULL, lp_ctx);
91 if (msg == NULL) {
92 smb_panic("Could not init winbindd's messaging context.\n");
94 return msg;
97 /* Reload configuration */
99 static bool reload_services_file(const char *lfile)
101 bool ret;
103 if (lp_loaded()) {
104 char *fname = lp_next_configfile(talloc_tos());
106 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
107 set_dyn_CONFIGFILE(fname);
109 TALLOC_FREE(fname);
112 /* if this is a child, restore the logfile to the special
113 name - <domain>, idmap, etc. */
114 if (lfile && *lfile) {
115 lp_set_logfile(lfile);
118 reopen_logs();
119 ret = lp_load_global(get_dyn_CONFIGFILE());
121 reopen_logs();
122 load_interfaces();
123 winbindd_setup_max_fds();
125 return(ret);
129 static void winbindd_status(void)
131 struct winbindd_cli_state *tmp;
133 DEBUG(0, ("winbindd status:\n"));
135 /* Print client state information */
137 DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
139 if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
140 DEBUG(2, ("\tclient list:\n"));
141 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
142 DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
143 (unsigned long)tmp->pid, tmp->sock,
144 client_is_idle(tmp) ? "idle" : "active"));
149 /* Flush client cache */
151 static void flush_caches(void)
153 /* We need to invalidate cached user list entries on a SIGHUP
154 otherwise cached access denied errors due to restrict anonymous
155 hang around until the sequence number changes. */
157 if (!wcache_invalidate_cache()) {
158 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
159 if (!winbindd_cache_validate_and_initialize()) {
160 exit(1);
165 static void flush_caches_noinit(void)
168 * We need to invalidate cached user list entries on a SIGHUP
169 * otherwise cached access denied errors due to restrict anonymous
170 * hang around until the sequence number changes.
171 * NB
172 * Skip uninitialized domains when flush cache.
173 * If domain is not initialized, it means it is never
174 * used or never become online. look, wcache_invalidate_cache()
175 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
176 * for unused domains and large traffic for primay domain's DC if there
177 * are many domains..
180 if (!wcache_invalidate_cache_noinit()) {
181 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
182 if (!winbindd_cache_validate_and_initialize()) {
183 exit(1);
188 /* Handle the signal by unlinking socket and exiting */
190 static void terminate(bool is_parent)
192 if (is_parent) {
193 /* When parent goes away we should
194 * remove the socket file. Not so
195 * when children terminate.
197 char *path = NULL;
199 if (asprintf(&path, "%s/%s",
200 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) {
201 unlink(path);
202 SAFE_FREE(path);
206 idmap_close();
208 gencache_stabilize();
210 netlogon_creds_cli_close_global_db();
212 #if 0
213 if (interactive) {
214 TALLOC_CTX *mem_ctx = talloc_init("end_description");
215 char *description = talloc_describe_all(mem_ctx);
217 DEBUG(3, ("tallocs left:\n%s\n", description));
218 talloc_destroy(mem_ctx);
220 #endif
222 if (is_parent) {
223 pidfile_unlink(lp_pid_directory(), "winbindd");
226 exit(0);
229 static void winbindd_sig_term_handler(struct tevent_context *ev,
230 struct tevent_signal *se,
231 int signum,
232 int count,
233 void *siginfo,
234 void *private_data)
236 bool *p = talloc_get_type_abort(private_data, bool);
237 bool is_parent = *p;
239 TALLOC_FREE(p);
241 DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
242 signum, is_parent));
243 terminate(is_parent);
247 handle stdin becoming readable when we are in --foreground mode
249 static void winbindd_stdin_handler(struct tevent_context *ev,
250 struct tevent_fd *fde,
251 uint16_t flags,
252 void *private_data)
254 char c;
255 if (read(0, &c, 1) != 1) {
256 bool *is_parent = talloc_get_type_abort(private_data, bool);
258 /* we have reached EOF on stdin, which means the
259 parent has exited. Shutdown the server */
260 DEBUG(0,("EOF on stdin (is_parent=%d)\n",
261 (int)*is_parent));
262 terminate(*is_parent);
266 bool winbindd_setup_sig_term_handler(bool parent)
268 struct tevent_signal *se;
269 bool *is_parent;
271 is_parent = talloc(server_event_context(), bool);
272 if (!is_parent) {
273 return false;
276 *is_parent = parent;
278 se = tevent_add_signal(server_event_context(),
279 is_parent,
280 SIGTERM, 0,
281 winbindd_sig_term_handler,
282 is_parent);
283 if (!se) {
284 DEBUG(0,("failed to setup SIGTERM handler"));
285 talloc_free(is_parent);
286 return false;
289 se = tevent_add_signal(server_event_context(),
290 is_parent,
291 SIGINT, 0,
292 winbindd_sig_term_handler,
293 is_parent);
294 if (!se) {
295 DEBUG(0,("failed to setup SIGINT handler"));
296 talloc_free(is_parent);
297 return false;
300 se = tevent_add_signal(server_event_context(),
301 is_parent,
302 SIGQUIT, 0,
303 winbindd_sig_term_handler,
304 is_parent);
305 if (!se) {
306 DEBUG(0,("failed to setup SIGINT handler"));
307 talloc_free(is_parent);
308 return false;
311 return true;
314 bool winbindd_setup_stdin_handler(bool parent, bool foreground)
316 bool *is_parent;
318 if (foreground) {
319 struct stat st;
321 is_parent = talloc(server_event_context(), bool);
322 if (!is_parent) {
323 return false;
326 *is_parent = parent;
328 /* if we are running in the foreground then look for
329 EOF on stdin, and exit if it happens. This allows
330 us to die if the parent process dies
331 Only do this on a pipe or socket, no other device.
333 if (fstat(0, &st) != 0) {
334 return false;
336 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
337 tevent_add_fd(server_event_context(),
338 is_parent,
340 TEVENT_FD_READ,
341 winbindd_stdin_handler,
342 is_parent);
346 return true;
349 static void winbindd_sig_hup_handler(struct tevent_context *ev,
350 struct tevent_signal *se,
351 int signum,
352 int count,
353 void *siginfo,
354 void *private_data)
356 const char *file = (const char *)private_data;
358 DEBUG(1,("Reloading services after SIGHUP\n"));
359 flush_caches_noinit();
360 reload_services_file(file);
363 bool winbindd_setup_sig_hup_handler(const char *lfile)
365 struct tevent_signal *se;
366 char *file = NULL;
368 if (lfile) {
369 file = talloc_strdup(server_event_context(),
370 lfile);
371 if (!file) {
372 return false;
376 se = tevent_add_signal(server_event_context(),
377 server_event_context(),
378 SIGHUP, 0,
379 winbindd_sig_hup_handler,
380 file);
381 if (!se) {
382 return false;
385 return true;
388 static void winbindd_sig_chld_handler(struct tevent_context *ev,
389 struct tevent_signal *se,
390 int signum,
391 int count,
392 void *siginfo,
393 void *private_data)
395 pid_t pid;
397 while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
398 winbind_child_died(pid);
402 static bool winbindd_setup_sig_chld_handler(void)
404 struct tevent_signal *se;
406 se = tevent_add_signal(server_event_context(),
407 server_event_context(),
408 SIGCHLD, 0,
409 winbindd_sig_chld_handler,
410 NULL);
411 if (!se) {
412 return false;
415 return true;
418 static void winbindd_sig_usr2_handler(struct tevent_context *ev,
419 struct tevent_signal *se,
420 int signum,
421 int count,
422 void *siginfo,
423 void *private_data)
425 winbindd_status();
428 static bool winbindd_setup_sig_usr2_handler(void)
430 struct tevent_signal *se;
432 se = tevent_add_signal(server_event_context(),
433 server_event_context(),
434 SIGUSR2, 0,
435 winbindd_sig_usr2_handler,
436 NULL);
437 if (!se) {
438 return false;
441 return true;
444 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
445 static void msg_reload_services(struct messaging_context *msg,
446 void *private_data,
447 uint32_t msg_type,
448 struct server_id server_id,
449 DATA_BLOB *data)
451 /* Flush various caches */
452 flush_caches();
453 reload_services_file((const char *) private_data);
456 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
457 static void msg_shutdown(struct messaging_context *msg,
458 void *private_data,
459 uint32_t msg_type,
460 struct server_id server_id,
461 DATA_BLOB *data)
463 /* only the parent waits for this message */
464 DEBUG(0,("Got shutdown message\n"));
465 terminate(true);
469 static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
470 void *private_data,
471 uint32_t msg_type,
472 struct server_id server_id,
473 DATA_BLOB *data)
475 uint8_t ret;
476 pid_t child_pid;
477 NTSTATUS status;
479 DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
480 "message.\n"));
483 * call the validation code from a child:
484 * so we don't block the main winbindd and the validation
485 * code can safely use fork/waitpid...
487 child_pid = fork();
489 if (child_pid == -1) {
490 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
491 strerror(errno)));
492 return;
495 if (child_pid != 0) {
496 /* parent */
497 DEBUG(5, ("winbind_msg_validate_cache: child created with "
498 "pid %d.\n", (int)child_pid));
499 return;
502 /* child */
504 status = winbindd_reinit_after_fork(NULL, NULL);
505 if (!NT_STATUS_IS_OK(status)) {
506 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
507 nt_errstr(status)));
508 _exit(0);
511 /* install default SIGCHLD handler: validation code uses fork/waitpid */
512 CatchSignal(SIGCHLD, SIG_DFL);
514 setproctitle("validate cache child");
516 ret = (uint8_t)winbindd_validate_cache_nobackup();
517 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
518 messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
519 (size_t)1);
520 _exit(0);
523 static struct winbindd_dispatch_table {
524 enum winbindd_cmd cmd;
525 void (*fn)(struct winbindd_cli_state *state);
526 const char *winbindd_cmd_name;
527 } dispatch_table[] = {
529 /* Enumeration functions */
531 { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
532 "LIST_TRUSTDOM" },
534 /* Miscellaneous */
536 { WINBINDD_INFO, winbindd_info, "INFO" },
537 { WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
538 "INTERFACE_VERSION" },
539 { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
540 { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
541 { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" },
542 { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
543 { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
544 "WINBINDD_PRIV_PIPE_DIR" },
546 /* Credential cache access */
547 { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
548 { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
550 /* End of list */
552 { WINBINDD_NUM_CMDS, NULL, "NONE" }
555 struct winbindd_async_dispatch_table {
556 enum winbindd_cmd cmd;
557 const char *cmd_name;
558 struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
559 struct tevent_context *ev,
560 struct winbindd_cli_state *cli,
561 struct winbindd_request *request);
562 NTSTATUS (*recv_req)(struct tevent_req *req,
563 struct winbindd_response *presp);
566 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
567 { WINBINDD_PING, "PING",
568 wb_ping_send, wb_ping_recv },
569 { WINBINDD_LOOKUPSID, "LOOKUPSID",
570 winbindd_lookupsid_send, winbindd_lookupsid_recv },
571 { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
572 winbindd_lookupsids_send, winbindd_lookupsids_recv },
573 { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
574 winbindd_lookupname_send, winbindd_lookupname_recv },
575 { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
576 winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
577 { WINBINDD_XIDS_TO_SIDS, "XIDS_TO_SIDS",
578 winbindd_xids_to_sids_send, winbindd_xids_to_sids_recv },
579 { WINBINDD_GETPWSID, "GETPWSID",
580 winbindd_getpwsid_send, winbindd_getpwsid_recv },
581 { WINBINDD_GETPWNAM, "GETPWNAM",
582 winbindd_getpwnam_send, winbindd_getpwnam_recv },
583 { WINBINDD_GETPWUID, "GETPWUID",
584 winbindd_getpwuid_send, winbindd_getpwuid_recv },
585 { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
586 winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
587 { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
588 winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
589 { WINBINDD_GETGROUPS, "GETGROUPS",
590 winbindd_getgroups_send, winbindd_getgroups_recv },
591 { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
592 winbindd_show_sequence_send, winbindd_show_sequence_recv },
593 { WINBINDD_GETGRGID, "GETGRGID",
594 winbindd_getgrgid_send, winbindd_getgrgid_recv },
595 { WINBINDD_GETGRNAM, "GETGRNAM",
596 winbindd_getgrnam_send, winbindd_getgrnam_recv },
597 { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
598 winbindd_getusersids_send, winbindd_getusersids_recv },
599 { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
600 winbindd_lookuprids_send, winbindd_lookuprids_recv },
601 { WINBINDD_SETPWENT, "SETPWENT",
602 winbindd_setpwent_send, winbindd_setpwent_recv },
603 { WINBINDD_GETPWENT, "GETPWENT",
604 winbindd_getpwent_send, winbindd_getpwent_recv },
605 { WINBINDD_ENDPWENT, "ENDPWENT",
606 winbindd_endpwent_send, winbindd_endpwent_recv },
607 { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
608 winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
609 { WINBINDD_GETDCNAME, "GETDCNAME",
610 winbindd_getdcname_send, winbindd_getdcname_recv },
611 { WINBINDD_SETGRENT, "SETGRENT",
612 winbindd_setgrent_send, winbindd_setgrent_recv },
613 { WINBINDD_GETGRENT, "GETGRENT",
614 winbindd_getgrent_send, winbindd_getgrent_recv },
615 { WINBINDD_ENDGRENT, "ENDGRENT",
616 winbindd_endgrent_send, winbindd_endgrent_recv },
617 { WINBINDD_LIST_USERS, "LIST_USERS",
618 winbindd_list_users_send, winbindd_list_users_recv },
619 { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
620 winbindd_list_groups_send, winbindd_list_groups_recv },
621 { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
622 winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
623 { WINBINDD_PING_DC, "PING_DC",
624 winbindd_ping_dc_send, winbindd_ping_dc_recv },
625 { WINBINDD_PAM_AUTH, "PAM_AUTH",
626 winbindd_pam_auth_send, winbindd_pam_auth_recv },
627 { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
628 winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
629 { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
630 winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
631 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
632 winbindd_pam_chng_pswd_auth_crap_send,
633 winbindd_pam_chng_pswd_auth_crap_recv },
634 { WINBINDD_WINS_BYIP, "WINS_BYIP",
635 winbindd_wins_byip_send, winbindd_wins_byip_recv },
636 { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
637 winbindd_wins_byname_send, winbindd_wins_byname_recv },
639 { 0, NULL, NULL, NULL }
642 static struct winbindd_async_dispatch_table async_priv_table[] = {
643 { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
644 winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
645 { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
646 winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
647 { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
648 winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
649 { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
650 winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
652 { 0, NULL, NULL, NULL }
655 static void wb_request_done(struct tevent_req *req);
657 static void process_request(struct winbindd_cli_state *state)
659 struct winbindd_dispatch_table *table = dispatch_table;
660 struct winbindd_async_dispatch_table *atable;
662 state->mem_ctx = talloc_named(state, 0, "winbind request");
663 if (state->mem_ctx == NULL)
664 return;
666 /* Remember who asked us. */
667 state->pid = state->request->pid;
669 state->cmd_name = "unknown request";
670 state->recv_fn = NULL;
671 /* client is newest */
672 winbindd_promote_client(state);
674 /* Process command */
676 for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
677 if (state->request->cmd == atable->cmd) {
678 break;
682 if ((atable->send_req == NULL) && state->privileged) {
683 for (atable = async_priv_table; atable->send_req;
684 atable += 1) {
685 if (state->request->cmd == atable->cmd) {
686 break;
691 if (atable->send_req != NULL) {
692 struct tevent_req *req;
694 state->cmd_name = atable->cmd_name;
695 state->recv_fn = atable->recv_req;
697 DEBUG(10, ("process_request: Handling async request %d:%s\n",
698 (int)state->pid, state->cmd_name));
700 req = atable->send_req(state->mem_ctx, server_event_context(),
701 state, state->request);
702 if (req == NULL) {
703 DEBUG(0, ("process_request: atable->send failed for "
704 "%s\n", atable->cmd_name));
705 request_error(state);
706 return;
708 tevent_req_set_callback(req, wb_request_done, state);
709 return;
712 state->response = talloc_zero(state->mem_ctx,
713 struct winbindd_response);
714 if (state->response == NULL) {
715 DEBUG(10, ("talloc failed\n"));
716 remove_client(state);
717 return;
719 state->response->result = WINBINDD_PENDING;
720 state->response->length = sizeof(struct winbindd_response);
722 for (table = dispatch_table; table->fn; table++) {
723 if (state->request->cmd == table->cmd) {
724 DEBUG(10,("process_request: request fn %s\n",
725 table->winbindd_cmd_name ));
726 state->cmd_name = table->winbindd_cmd_name;
727 table->fn(state);
728 break;
732 if (!table->fn) {
733 DEBUG(10,("process_request: unknown request fn number %d\n",
734 (int)state->request->cmd ));
735 request_error(state);
739 static void wb_request_done(struct tevent_req *req)
741 struct winbindd_cli_state *state = tevent_req_callback_data(
742 req, struct winbindd_cli_state);
743 NTSTATUS status;
745 state->response = talloc_zero(state->mem_ctx,
746 struct winbindd_response);
747 if (state->response == NULL) {
748 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
749 (int)state->pid, state->cmd_name));
750 remove_client(state);
751 return;
753 state->response->result = WINBINDD_PENDING;
754 state->response->length = sizeof(struct winbindd_response);
756 status = state->recv_fn(req, state->response);
757 TALLOC_FREE(req);
759 DEBUG(10,("wb_request_done[%d:%s]: %s\n",
760 (int)state->pid, state->cmd_name, nt_errstr(status)));
762 if (!NT_STATUS_IS_OK(status)) {
763 request_error(state);
764 return;
766 request_ok(state);
770 * This is the main event loop of winbind requests. It goes through a
771 * state-machine of 3 read/write requests, 4 if you have extra data to send.
773 * An idle winbind client has a read request of 4 bytes outstanding,
774 * finalizing function is request_len_recv, checking the length. request_recv
775 * then processes the packet. The processing function then at some point has
776 * to call request_finished which schedules sending the response.
779 static void request_finished(struct winbindd_cli_state *state);
781 static void winbind_client_request_read(struct tevent_req *req);
782 static void winbind_client_response_written(struct tevent_req *req);
783 static void winbind_client_activity(struct tevent_req *req);
785 static void request_finished(struct winbindd_cli_state *state)
787 struct tevent_req *req;
789 /* free client socket monitoring request */
790 TALLOC_FREE(state->io_req);
792 TALLOC_FREE(state->request);
794 req = wb_resp_write_send(state, server_event_context(),
795 state->out_queue, state->sock,
796 state->response);
797 if (req == NULL) {
798 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
799 (int)state->pid, state->cmd_name));
800 remove_client(state);
801 return;
803 tevent_req_set_callback(req, winbind_client_response_written, state);
804 state->io_req = req;
807 static void winbind_client_response_written(struct tevent_req *req)
809 struct winbindd_cli_state *state = tevent_req_callback_data(
810 req, struct winbindd_cli_state);
811 ssize_t ret;
812 int err;
814 state->io_req = NULL;
816 ret = wb_resp_write_recv(req, &err);
817 TALLOC_FREE(req);
818 if (ret == -1) {
819 close(state->sock);
820 state->sock = -1;
821 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
822 (int)state->pid, state->cmd_name, strerror(err)));
823 remove_client(state);
824 return;
827 DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
828 "to client\n", (int)state->pid, state->cmd_name));
830 TALLOC_FREE(state->mem_ctx);
831 state->response = NULL;
832 state->cmd_name = "no request";
833 state->recv_fn = NULL;
835 req = wb_req_read_send(state, server_event_context(), state->sock,
836 WINBINDD_MAX_EXTRA_DATA);
837 if (req == NULL) {
838 remove_client(state);
839 return;
841 tevent_req_set_callback(req, winbind_client_request_read, state);
842 state->io_req = req;
845 void request_error(struct winbindd_cli_state *state)
847 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
848 state->response->result = WINBINDD_ERROR;
849 request_finished(state);
852 void request_ok(struct winbindd_cli_state *state)
854 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
855 state->response->result = WINBINDD_OK;
856 request_finished(state);
859 /* Process a new connection by adding it to the client connection list */
861 static void new_connection(int listen_sock, bool privileged)
863 struct sockaddr_un sunaddr;
864 struct winbindd_cli_state *state;
865 struct tevent_req *req;
866 socklen_t len;
867 int sock;
869 /* Accept connection */
871 len = sizeof(sunaddr);
873 sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
875 if (sock == -1) {
876 if (errno != EINTR) {
877 DEBUG(0, ("Failed to accept socket - %s\n",
878 strerror(errno)));
880 return;
882 smb_set_close_on_exec(sock);
884 DEBUG(6,("accepted socket %d\n", sock));
886 /* Create new connection structure */
888 if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
889 close(sock);
890 return;
893 state->sock = sock;
895 state->out_queue = tevent_queue_create(state, "winbind client reply");
896 if (state->out_queue == NULL) {
897 close(sock);
898 TALLOC_FREE(state);
899 return;
902 state->privileged = privileged;
904 req = wb_req_read_send(state, server_event_context(), state->sock,
905 WINBINDD_MAX_EXTRA_DATA);
906 if (req == NULL) {
907 TALLOC_FREE(state);
908 close(sock);
909 return;
911 tevent_req_set_callback(req, winbind_client_request_read, state);
912 state->io_req = req;
914 /* Add to connection list */
916 winbindd_add_client(state);
919 static void winbind_client_request_read(struct tevent_req *req)
921 struct winbindd_cli_state *state = tevent_req_callback_data(
922 req, struct winbindd_cli_state);
923 ssize_t ret;
924 int err;
926 state->io_req = NULL;
928 ret = wb_req_read_recv(req, state, &state->request, &err);
929 TALLOC_FREE(req);
930 if (ret == -1) {
931 if (err == EPIPE) {
932 DEBUG(6, ("closing socket %d, client exited\n",
933 state->sock));
934 } else {
935 DEBUG(2, ("Could not read client request from fd %d: "
936 "%s\n", state->sock, strerror(err)));
938 close(state->sock);
939 state->sock = -1;
940 remove_client(state);
941 return;
944 req = wait_for_read_send(state, server_event_context(), state->sock,
945 true);
946 if (req == NULL) {
947 DEBUG(0, ("winbind_client_request_read[%d:%s]:"
948 " wait_for_read_send failed - removing client\n",
949 (int)state->pid, state->cmd_name));
950 remove_client(state);
951 return;
953 tevent_req_set_callback(req, winbind_client_activity, state);
954 state->io_req = req;
956 process_request(state);
959 static void winbind_client_activity(struct tevent_req *req)
961 struct winbindd_cli_state *state =
962 tevent_req_callback_data(req, struct winbindd_cli_state);
963 int err;
964 bool has_data;
966 has_data = wait_for_read_recv(req, &err);
968 if (has_data) {
969 DEBUG(0, ("winbind_client_activity[%d:%s]:"
970 "unexpected data from client - removing client\n",
971 (int)state->pid, state->cmd_name));
972 } else {
973 if (err == EPIPE) {
974 DEBUG(6, ("winbind_client_activity[%d:%s]: "
975 "client has closed connection - removing "
976 "client\n",
977 (int)state->pid, state->cmd_name));
978 } else {
979 DEBUG(2, ("winbind_client_activity[%d:%s]: "
980 "client socket error (%s) - removing "
981 "client\n",
982 (int)state->pid, state->cmd_name,
983 strerror(err)));
987 remove_client(state);
990 /* Remove a client connection from client connection list */
992 static void remove_client(struct winbindd_cli_state *state)
994 char c = 0;
995 int nwritten;
997 /* It's a dead client - hold a funeral */
999 if (state == NULL) {
1000 return;
1004 * We need to remove a pending wb_req_read_*
1005 * or wb_resp_write_* request before closing the
1006 * socket.
1008 * This is important as they might have used tevent_add_fd() and we
1009 * use the epoll * backend on linux. So we must remove the tevent_fd
1010 * before closing the fd.
1012 * Otherwise we might hit a race with close_conns_after_fork() (via
1013 * winbindd_reinit_after_fork()) where a file description
1014 * is still open in a child, which means it's still active in
1015 * the parents epoll queue, but the related tevent_fd is already
1016 * already gone in the parent.
1018 * See bug #11141.
1020 TALLOC_FREE(state->io_req);
1022 if (state->sock != -1) {
1023 /* tell client, we are closing ... */
1024 nwritten = write(state->sock, &c, sizeof(c));
1025 if (nwritten == -1) {
1026 DEBUG(2, ("final write to client failed: %s\n",
1027 strerror(errno)));
1030 /* Close socket */
1032 close(state->sock);
1033 state->sock = -1;
1036 TALLOC_FREE(state->mem_ctx);
1038 /* Remove from list and free */
1040 winbindd_remove_client(state);
1041 TALLOC_FREE(state);
1044 /* Is a client idle? */
1046 static bool client_is_idle(struct winbindd_cli_state *state) {
1047 return (state->request == NULL &&
1048 state->response == NULL &&
1049 !state->pwent_state && !state->grent_state);
1052 /* Shutdown client connection which has been idle for the longest time */
1054 static bool remove_idle_client(void)
1056 struct winbindd_cli_state *state, *remove_state = NULL;
1057 int nidle = 0;
1059 for (state = winbindd_client_list(); state; state = state->next) {
1060 if (client_is_idle(state)) {
1061 nidle++;
1062 /* list is sorted by access time */
1063 remove_state = state;
1067 if (remove_state) {
1068 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1069 nidle, remove_state->sock, (unsigned int)remove_state->pid));
1070 remove_client(remove_state);
1071 return True;
1074 return False;
1078 * Terminate all clients whose requests have taken longer than
1079 * "winbind request timeout" seconds to process, or have been
1080 * idle for more than "winbind request timeout" seconds.
1083 static void remove_timed_out_clients(void)
1085 struct winbindd_cli_state *state, *prev = NULL;
1086 time_t curr_time = time(NULL);
1087 int timeout_val = lp_winbind_request_timeout();
1089 for (state = winbindd_client_list_tail(); state; state = prev) {
1090 time_t expiry_time;
1092 prev = winbindd_client_list_prev(state);
1093 expiry_time = state->last_access + timeout_val;
1095 if (curr_time <= expiry_time) {
1096 /* list is sorted, previous clients in
1097 list are newer */
1098 break;
1101 if (client_is_idle(state)) {
1102 DEBUG(5,("Idle client timed out, "
1103 "shutting down sock %d, pid %u\n",
1104 state->sock,
1105 (unsigned int)state->pid));
1106 } else {
1107 DEBUG(5,("Client request timed out, "
1108 "shutting down sock %d, pid %u\n",
1109 state->sock,
1110 (unsigned int)state->pid));
1113 remove_client(state);
1117 static void winbindd_scrub_clients_handler(struct tevent_context *ev,
1118 struct tevent_timer *te,
1119 struct timeval current_time,
1120 void *private_data)
1122 remove_timed_out_clients();
1123 if (tevent_add_timer(ev, ev,
1124 timeval_current_ofs(SCRUB_CLIENTS_INTERVAL, 0),
1125 winbindd_scrub_clients_handler, NULL) == NULL) {
1126 DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
1127 exit(1);
1131 struct winbindd_listen_state {
1132 bool privileged;
1133 int fd;
1136 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1137 struct tevent_fd *fde,
1138 uint16_t flags,
1139 void *private_data)
1141 struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1142 struct winbindd_listen_state);
1144 while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1145 DEBUG(5,("winbindd: Exceeding %d client "
1146 "connections, removing idle "
1147 "connection.\n", lp_winbind_max_clients()));
1148 if (!remove_idle_client()) {
1149 DEBUG(0,("winbindd: Exceeding %d "
1150 "client connections, no idle "
1151 "connection found\n",
1152 lp_winbind_max_clients()));
1153 break;
1156 remove_timed_out_clients();
1157 new_connection(s->fd, s->privileged);
1161 * Winbindd socket accessor functions
1164 char *get_winbind_priv_pipe_dir(void)
1166 return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1169 static void winbindd_setup_max_fds(void)
1171 int num_fds = MAX_OPEN_FUDGEFACTOR;
1172 int actual_fds;
1174 num_fds += lp_winbind_max_clients();
1175 /* Add some more to account for 2 sockets open
1176 when the client transitions from unprivileged
1177 to privileged socket
1179 num_fds += lp_winbind_max_clients() / 10;
1181 /* Add one socket per child process
1182 (yeah there are child processes other than the
1183 domain children but only domain children can vary
1184 with configuration
1186 num_fds += lp_winbind_max_domain_connections() *
1187 (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
1189 actual_fds = set_maxfiles(num_fds);
1191 if (actual_fds < num_fds) {
1192 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1193 "requested %d open files, %d are available.\n",
1194 num_fds, actual_fds));
1198 static bool winbindd_setup_listeners(void)
1200 struct winbindd_listen_state *pub_state = NULL;
1201 struct winbindd_listen_state *priv_state = NULL;
1202 struct tevent_fd *fde;
1203 int rc;
1204 char *socket_path;
1206 pub_state = talloc(server_event_context(),
1207 struct winbindd_listen_state);
1208 if (!pub_state) {
1209 goto failed;
1212 pub_state->privileged = false;
1213 pub_state->fd = create_pipe_sock(
1214 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1215 if (pub_state->fd == -1) {
1216 goto failed;
1218 rc = listen(pub_state->fd, 5);
1219 if (rc < 0) {
1220 goto failed;
1223 fde = tevent_add_fd(server_event_context(), pub_state, pub_state->fd,
1224 TEVENT_FD_READ, winbindd_listen_fde_handler,
1225 pub_state);
1226 if (fde == NULL) {
1227 close(pub_state->fd);
1228 goto failed;
1230 tevent_fd_set_auto_close(fde);
1232 priv_state = talloc(server_event_context(),
1233 struct winbindd_listen_state);
1234 if (!priv_state) {
1235 goto failed;
1238 socket_path = get_winbind_priv_pipe_dir();
1239 if (socket_path == NULL) {
1240 goto failed;
1243 priv_state->privileged = true;
1244 priv_state->fd = create_pipe_sock(
1245 socket_path, WINBINDD_SOCKET_NAME, 0750);
1246 TALLOC_FREE(socket_path);
1247 if (priv_state->fd == -1) {
1248 goto failed;
1250 rc = listen(priv_state->fd, 5);
1251 if (rc < 0) {
1252 goto failed;
1255 fde = tevent_add_fd(server_event_context(), priv_state,
1256 priv_state->fd, TEVENT_FD_READ,
1257 winbindd_listen_fde_handler, priv_state);
1258 if (fde == NULL) {
1259 close(priv_state->fd);
1260 goto failed;
1262 tevent_fd_set_auto_close(fde);
1264 winbindd_scrub_clients_handler(server_event_context(), NULL,
1265 timeval_current(), NULL);
1266 return true;
1267 failed:
1268 TALLOC_FREE(pub_state);
1269 TALLOC_FREE(priv_state);
1270 return false;
1273 bool winbindd_use_idmap_cache(void)
1275 return !opt_nocache;
1278 bool winbindd_use_cache(void)
1280 return !opt_nocache;
1283 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1284 bool foreground)
1286 bool scan_trusts = true;
1287 NTSTATUS status;
1288 /* Setup signal handlers */
1290 if (!winbindd_setup_sig_term_handler(true))
1291 exit(1);
1292 if (!winbindd_setup_stdin_handler(true, foreground))
1293 exit(1);
1294 if (!winbindd_setup_sig_hup_handler(NULL))
1295 exit(1);
1296 if (!winbindd_setup_sig_chld_handler())
1297 exit(1);
1298 if (!winbindd_setup_sig_usr2_handler())
1299 exit(1);
1301 CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
1304 * Ensure all cache and idmap caches are consistent
1305 * and initialized before we startup.
1307 if (!winbindd_cache_validate_and_initialize()) {
1308 exit(1);
1311 /* React on 'smbcontrol winbindd reload-config' in the same way
1312 as to SIGHUP signal */
1313 messaging_register(msg_ctx, NULL,
1314 MSG_SMB_CONF_UPDATED, msg_reload_services);
1315 messaging_register(msg_ctx, NULL,
1316 MSG_SHUTDOWN, msg_shutdown);
1318 /* Handle online/offline messages. */
1319 messaging_register(msg_ctx, NULL,
1320 MSG_WINBIND_OFFLINE, winbind_msg_offline);
1321 messaging_register(msg_ctx, NULL,
1322 MSG_WINBIND_ONLINE, winbind_msg_online);
1323 messaging_register(msg_ctx, NULL,
1324 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1326 /* Handle domain online/offline messages for domains */
1327 messaging_register(server_messaging_context(), NULL,
1328 MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1329 messaging_register(server_messaging_context(), NULL,
1330 MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1332 messaging_register(msg_ctx, NULL,
1333 MSG_WINBIND_VALIDATE_CACHE,
1334 winbind_msg_validate_cache);
1336 messaging_register(msg_ctx, NULL,
1337 MSG_WINBIND_DUMP_DOMAIN_LIST,
1338 winbind_msg_dump_domain_list);
1340 messaging_register(msg_ctx, NULL,
1341 MSG_WINBIND_IP_DROPPED,
1342 winbind_msg_ip_dropped_parent);
1344 /* Register handler for MSG_DEBUG. */
1345 messaging_register(msg_ctx, NULL,
1346 MSG_DEBUG,
1347 winbind_msg_debug);
1349 netsamlogon_cache_init(); /* Non-critical */
1351 /* clear the cached list of trusted domains */
1353 wcache_tdc_clear();
1355 if (!init_domain_list()) {
1356 DEBUG(0,("unable to initialize domain list\n"));
1357 exit(1);
1360 init_idmap_child();
1361 init_locator_child();
1363 smb_nscd_flush_user_cache();
1364 smb_nscd_flush_group_cache();
1366 if (!lp_winbind_scan_trusted_domains()) {
1367 scan_trusts = false;
1370 if (!lp_allow_trusted_domains()) {
1371 scan_trusts = false;
1374 if (IS_DC) {
1375 scan_trusts = false;
1378 if (scan_trusts) {
1379 if (tevent_add_timer(server_event_context(), NULL, timeval_zero(),
1380 rescan_trusted_domains, NULL) == NULL) {
1381 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1382 exit(1);
1386 status = wb_irpc_register();
1388 if (!NT_STATUS_IS_OK(status)) {
1389 DEBUG(0, ("Could not register IRPC handlers\n"));
1390 exit(1);
1394 struct winbindd_addrchanged_state {
1395 struct addrchange_context *ctx;
1396 struct tevent_context *ev;
1397 struct messaging_context *msg_ctx;
1400 static void winbindd_addr_changed(struct tevent_req *req);
1402 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1403 struct tevent_context *ev,
1404 struct messaging_context *msg_ctx)
1406 struct winbindd_addrchanged_state *state;
1407 struct tevent_req *req;
1408 NTSTATUS status;
1410 state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1411 if (state == NULL) {
1412 DEBUG(10, ("talloc failed\n"));
1413 return;
1415 state->ev = ev;
1416 state->msg_ctx = msg_ctx;
1418 status = addrchange_context_create(state, &state->ctx);
1419 if (!NT_STATUS_IS_OK(status)) {
1420 DEBUG(10, ("addrchange_context_create failed: %s\n",
1421 nt_errstr(status)));
1422 TALLOC_FREE(state);
1423 return;
1425 req = addrchange_send(state, ev, state->ctx);
1426 if (req == NULL) {
1427 DEBUG(0, ("addrchange_send failed\n"));
1428 TALLOC_FREE(state);
1429 return;
1431 tevent_req_set_callback(req, winbindd_addr_changed, state);
1434 static void winbindd_addr_changed(struct tevent_req *req)
1436 struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1437 req, struct winbindd_addrchanged_state);
1438 enum addrchange_type type;
1439 struct sockaddr_storage addr;
1440 NTSTATUS status;
1442 status = addrchange_recv(req, &type, &addr);
1443 TALLOC_FREE(req);
1444 if (!NT_STATUS_IS_OK(status)) {
1445 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1446 nt_errstr(status)));
1447 TALLOC_FREE(state);
1448 return;
1450 if (type == ADDRCHANGE_DEL) {
1451 char addrstr[INET6_ADDRSTRLEN];
1452 DATA_BLOB blob;
1454 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1456 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1457 addrstr));
1459 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1461 status = messaging_send(state->msg_ctx,
1462 messaging_server_id(state->msg_ctx),
1463 MSG_WINBIND_IP_DROPPED, &blob);
1464 if (!NT_STATUS_IS_OK(status)) {
1465 DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1466 nt_errstr(status)));
1469 req = addrchange_send(state, state->ev, state->ctx);
1470 if (req == NULL) {
1471 DEBUG(0, ("addrchange_send failed\n"));
1472 TALLOC_FREE(state);
1473 return;
1475 tevent_req_set_callback(req, winbindd_addr_changed, state);
1478 /* Main function */
1480 int main(int argc, const char **argv)
1482 static bool is_daemon = False;
1483 static bool Fork = True;
1484 static bool log_stdout = False;
1485 static bool no_process_group = False;
1486 enum {
1487 OPT_DAEMON = 1000,
1488 OPT_FORK,
1489 OPT_NO_PROCESS_GROUP,
1490 OPT_LOG_STDOUT
1492 struct poptOption long_options[] = {
1493 POPT_AUTOHELP
1494 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1495 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1496 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1497 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1498 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1499 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1500 POPT_COMMON_SAMBA
1501 POPT_TABLEEND
1503 poptContext pc;
1504 int opt;
1505 TALLOC_CTX *frame;
1506 NTSTATUS status;
1507 bool ok;
1509 setproctitle_init(argc, discard_const(argv), environ);
1512 * Do this before any other talloc operation
1514 talloc_enable_null_tracking();
1515 frame = talloc_stackframe();
1518 * We want total control over the permissions on created files,
1519 * so set our umask to 0.
1521 umask(0);
1523 setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1525 /* glibc (?) likes to print "User defined signal 1" and exit if a
1526 SIGUSR[12] is received before a handler is installed */
1528 CatchSignal(SIGUSR1, SIG_IGN);
1529 CatchSignal(SIGUSR2, SIG_IGN);
1531 fault_setup();
1532 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1534 smb_init_locale();
1536 /* Initialise for running in non-root mode */
1538 sec_init();
1540 set_remote_machine_name("winbindd", False);
1542 /* Set environment variable so we don't recursively call ourselves.
1543 This may also be useful interactively. */
1545 if ( !winbind_off() ) {
1546 DEBUG(0,("Failed to disable recusive winbindd calls. Exiting.\n"));
1547 exit(1);
1550 /* Initialise samba/rpc client stuff */
1552 pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1554 while ((opt = poptGetNextOpt(pc)) != -1) {
1555 switch (opt) {
1556 /* Don't become a daemon */
1557 case OPT_DAEMON:
1558 is_daemon = True;
1559 break;
1560 case 'i':
1561 interactive = True;
1562 log_stdout = True;
1563 Fork = False;
1564 break;
1565 case OPT_FORK:
1566 Fork = false;
1567 break;
1568 case OPT_NO_PROCESS_GROUP:
1569 no_process_group = true;
1570 break;
1571 case OPT_LOG_STDOUT:
1572 log_stdout = true;
1573 break;
1574 case 'n':
1575 opt_nocache = true;
1576 break;
1577 default:
1578 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1579 poptBadOption(pc, 0), poptStrerror(opt));
1580 poptPrintUsage(pc, stderr, 0);
1581 exit(1);
1585 /* We call dump_core_setup one more time because the command line can
1586 * set the log file or the log-basename and this will influence where
1587 * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1588 * the default value derived from build's prefix. For EOM this value
1589 * is often not related to the path where winbindd is actually run
1590 * in production.
1592 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1593 if (is_daemon && interactive) {
1594 d_fprintf(stderr,"\nERROR: "
1595 "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1596 poptPrintUsage(pc, stderr, 0);
1597 exit(1);
1600 if (log_stdout && Fork) {
1601 d_fprintf(stderr, "\nERROR: "
1602 "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1603 poptPrintUsage(pc, stderr, 0);
1604 exit(1);
1607 poptFreeContext(pc);
1609 if (!override_logfile) {
1610 char *lfile = NULL;
1611 if (asprintf(&lfile,"%s/log.winbindd",
1612 get_dyn_LOGFILEBASE()) > 0) {
1613 lp_set_logfile(lfile);
1614 SAFE_FREE(lfile);
1618 if (log_stdout) {
1619 setup_logging("winbindd", DEBUG_STDOUT);
1620 } else {
1621 setup_logging("winbindd", DEBUG_FILE);
1623 reopen_logs();
1625 DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1626 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1628 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1629 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1630 exit(1);
1632 /* After parsing the configuration file we setup the core path one more time
1633 * as the log file might have been set in the configuration and cores's
1634 * path is by default basename(lp_logfile()).
1636 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1638 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1639 && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1640 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1641 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"));
1642 exit(1);
1645 if (!cluster_probe_ok()) {
1646 exit(1);
1649 /* Initialise messaging system */
1651 if (server_messaging_context() == NULL) {
1652 exit(1);
1655 if (!reload_services_file(NULL)) {
1656 DEBUG(0, ("error opening config file\n"));
1657 exit(1);
1661 size_t i;
1662 const char *idmap_backend;
1663 const char *invalid_backends[] = {
1664 "ad", "rfc2307", "rid",
1667 idmap_backend = lp_idmap_default_backend();
1668 for (i = 0; i < ARRAY_SIZE(invalid_backends); i++) {
1669 ok = strequal(idmap_backend, invalid_backends[i]);
1670 if (ok) {
1671 DBG_ERR("FATAL: Invalid idmap backend %s "
1672 "configured as the default backend!\n",
1673 idmap_backend);
1674 exit(1);
1679 ok = directory_create_or_exist(lp_lock_directory(), 0755);
1680 if (!ok) {
1681 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1682 lp_lock_directory(), strerror(errno)));
1683 exit(1);
1686 ok = directory_create_or_exist(lp_pid_directory(), 0755);
1687 if (!ok) {
1688 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1689 lp_pid_directory(), strerror(errno)));
1690 exit(1);
1693 /* Setup names. */
1695 if (!init_names())
1696 exit(1);
1698 load_interfaces();
1700 if (!secrets_init()) {
1702 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1703 return False;
1706 status = rpccli_pre_open_netlogon_creds();
1707 if (!NT_STATUS_IS_OK(status)) {
1708 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1709 nt_errstr(status)));
1710 exit(1);
1713 /* Unblock all signals we are interested in as they may have been
1714 blocked by the parent process. */
1716 BlockSignals(False, SIGINT);
1717 BlockSignals(False, SIGQUIT);
1718 BlockSignals(False, SIGTERM);
1719 BlockSignals(False, SIGUSR1);
1720 BlockSignals(False, SIGUSR2);
1721 BlockSignals(False, SIGHUP);
1722 BlockSignals(False, SIGCHLD);
1724 if (!interactive)
1725 become_daemon(Fork, no_process_group, log_stdout);
1727 pidfile_create(lp_pid_directory(), "winbindd");
1729 #if HAVE_SETPGID
1731 * If we're interactive we want to set our own process group for
1732 * signal management.
1734 if (interactive && !no_process_group)
1735 setpgid( (pid_t)0, (pid_t)0);
1736 #endif
1738 TimeInit();
1740 /* Don't use winbindd_reinit_after_fork here as
1741 * we're just starting up and haven't created any
1742 * winbindd-specific resources we must free yet. JRA.
1745 status = reinit_after_fork(server_messaging_context(),
1746 server_event_context(),
1747 false, NULL);
1748 if (!NT_STATUS_IS_OK(status)) {
1749 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1753 * Do not initialize the parent-child-pipe before becoming
1754 * a daemon: this is used to detect a died parent in the child
1755 * process.
1757 status = init_before_fork();
1758 if (!NT_STATUS_IS_OK(status)) {
1759 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1762 winbindd_register_handlers(server_messaging_context(), !Fork);
1764 if (!messaging_parent_dgm_cleanup_init(server_messaging_context())) {
1765 exit(1);
1768 status = init_system_session_info(NULL);
1769 if (!NT_STATUS_IS_OK(status)) {
1770 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1773 rpc_lsarpc_init(NULL);
1774 rpc_samr_init(NULL);
1776 winbindd_init_addrchange(NULL, server_event_context(),
1777 server_messaging_context());
1779 /* setup listen sockets */
1781 if (!winbindd_setup_listeners()) {
1782 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1785 irpc_add_name(winbind_imessaging_context(), "winbind_server");
1787 TALLOC_FREE(frame);
1789 if (!interactive) {
1790 daemon_ready("winbindd");
1793 gpupdate_init();
1795 /* Loop waiting for requests */
1796 while (1) {
1797 frame = talloc_stackframe();
1799 if (tevent_loop_once(server_event_context()) == -1) {
1800 DEBUG(1, ("tevent_loop_once() failed: %s\n",
1801 strerror(errno)));
1802 return 1;
1805 TALLOC_FREE(frame);
1808 return 0;