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/>.
26 #include "lib/cmdline/cmdline.h"
28 #include "nsswitch/winbind_client.h"
29 #include "nsswitch/wb_reqtrans.h"
31 #include "librpc/rpc/dcesrv_core.h"
32 #include "librpc/gen_ndr/ndr_lsa_scompat.h"
33 #include "librpc/gen_ndr/ndr_samr_scompat.h"
34 #include "librpc/gen_ndr/ndr_winbind_scompat.h"
36 #include "rpc_client/cli_netlogon.h"
38 #include "lib/addrchange.h"
41 #include "../lib/util/pidfile.h"
42 #include "util_cluster.h"
43 #include "source4/lib/messaging/irpc.h"
44 #include "source4/lib/messaging/messaging.h"
45 #include "lib/param/param.h"
46 #include "lib/async_req/async_sock.h"
47 #include "libsmb/samlogon_cache.h"
48 #include "libcli/auth/netlogon_creds_cli.h"
50 #include "lib/util/tevent_req_profile.h"
51 #include "lib/gencache.h"
52 #include "rpc_server/rpc_config.h"
53 #include "lib/global_contexts.h"
56 #define DBGC_CLASS DBGC_WINBIND
58 #define SCRUB_CLIENTS_INTERVAL 5
60 static bool client_is_idle(struct winbindd_cli_state *state);
61 static void remove_client(struct winbindd_cli_state *state);
62 static void winbindd_setup_max_fds(void);
64 static bool opt_nocache = False;
65 static bool interactive = False;
67 struct imessaging_context *winbind_imessaging_context(void)
69 static struct imessaging_context *msg = NULL;
70 struct messaging_context *msg_ctx;
71 struct server_id myself;
72 struct loadparm_context *lp_ctx;
78 msg_ctx = global_messaging_context();
79 if (msg_ctx == NULL) {
80 smb_panic("global_messaging_context failed\n");
82 myself = messaging_server_id(msg_ctx);
84 lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
86 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
90 * Note we MUST use the NULL context here, not the autofree context,
91 * to avoid side effects in forked children exiting.
93 msg = imessaging_init(NULL, lp_ctx, myself, global_event_context());
94 talloc_unlink(NULL, lp_ctx);
97 smb_panic("Could not init winbindd's messaging context.\n");
102 /* Reload configuration */
104 bool winbindd_reload_services_file(const char *lfile)
106 const struct loadparm_substitution *lp_sub =
107 loadparm_s3_global_substitution();
111 char *fname = lp_next_configfile(talloc_tos(), lp_sub);
113 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
114 set_dyn_CONFIGFILE(fname);
120 ret = lp_load_global(get_dyn_CONFIGFILE());
122 /* if this is a child, restore the logfile to the special
123 name - <domain>, idmap, etc. */
124 if (lfile && *lfile) {
125 lp_set_logfile(lfile);
130 winbindd_setup_max_fds();
136 static void winbindd_status(void)
138 struct winbindd_cli_state *tmp;
140 DEBUG(0, ("winbindd status:\n"));
142 /* Print client state information */
144 DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
146 if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
147 DEBUG(2, ("\tclient list:\n"));
148 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
149 DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
150 (unsigned long)tmp->pid, tmp->sock,
151 client_is_idle(tmp) ? "idle" : "active"));
156 /* Flush client cache */
158 void winbindd_flush_caches(void)
160 /* We need to invalidate cached user list entries on a SIGHUP
161 otherwise cached access denied errors due to restrict anonymous
162 hang around until the sequence number changes. */
164 if (!wcache_invalidate_cache()) {
165 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
166 if (!winbindd_cache_validate_and_initialize()) {
172 static void flush_caches_noinit(void)
175 * We need to invalidate cached user list entries on a SIGHUP
176 * otherwise cached access denied errors due to restrict anonymous
177 * hang around until the sequence number changes.
179 * Skip uninitialized domains when flush cache.
180 * If domain is not initialized, it means it is never
181 * used or never become online. look, wcache_invalidate_cache()
182 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
183 * for unused domains and large traffic for primay domain's DC if there
187 if (!wcache_invalidate_cache_noinit()) {
188 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
189 if (!winbindd_cache_validate_and_initialize()) {
195 /* Handle the signal by unlinking socket and exiting */
197 static void terminate(bool is_parent)
200 /* When parent goes away we should
201 * remove the socket file. Not so
202 * when children terminate.
206 if (asprintf(&path, "%s/%s",
207 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) {
215 netlogon_creds_cli_close_global_db();
219 TALLOC_CTX *mem_ctx = talloc_init("end_description");
220 char *description = talloc_describe_all(mem_ctx);
222 DEBUG(3, ("tallocs left:\n%s\n", description));
223 talloc_destroy(mem_ctx);
228 pidfile_unlink(lp_pid_directory(), "winbindd");
234 static void winbindd_sig_term_handler(struct tevent_context *ev,
235 struct tevent_signal *se,
241 bool *p = talloc_get_type_abort(private_data, bool);
246 DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
248 terminate(is_parent);
252 handle stdin becoming readable when we are in --foreground mode
254 static void winbindd_stdin_handler(struct tevent_context *ev,
255 struct tevent_fd *fde,
260 if (read(0, &c, 1) != 1) {
261 bool *is_parent = talloc_get_type_abort(private_data, bool);
263 /* we have reached EOF on stdin, which means the
264 parent has exited. Shutdown the server */
265 DEBUG(0,("EOF on stdin (is_parent=%d)\n",
267 terminate(*is_parent);
271 bool winbindd_setup_sig_term_handler(bool parent)
273 struct tevent_signal *se;
276 is_parent = talloc(global_event_context(), bool);
283 se = tevent_add_signal(global_event_context(),
286 winbindd_sig_term_handler,
289 DEBUG(0,("failed to setup SIGTERM handler"));
290 talloc_free(is_parent);
294 se = tevent_add_signal(global_event_context(),
297 winbindd_sig_term_handler,
300 DEBUG(0,("failed to setup SIGINT handler"));
301 talloc_free(is_parent);
305 se = tevent_add_signal(global_event_context(),
308 winbindd_sig_term_handler,
311 DEBUG(0,("failed to setup SIGINT handler"));
312 talloc_free(is_parent);
319 bool winbindd_setup_stdin_handler(bool parent, bool foreground)
326 is_parent = talloc(global_event_context(), bool);
333 /* if we are running in the foreground then look for
334 EOF on stdin, and exit if it happens. This allows
335 us to die if the parent process dies
336 Only do this on a pipe or socket, no other device.
338 if (fstat(0, &st) != 0) {
341 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
342 tevent_add_fd(global_event_context(),
346 winbindd_stdin_handler,
354 static void winbindd_sig_hup_handler(struct tevent_context *ev,
355 struct tevent_signal *se,
361 const char *file = (const char *)private_data;
363 DEBUG(1,("Reloading services after SIGHUP\n"));
364 flush_caches_noinit();
365 winbindd_reload_services_file(file);
368 bool winbindd_setup_sig_hup_handler(const char *lfile)
370 struct tevent_signal *se;
374 file = talloc_strdup(global_event_context(),
381 se = tevent_add_signal(global_event_context(),
382 global_event_context(),
384 winbindd_sig_hup_handler,
393 static void winbindd_sig_chld_handler(struct tevent_context *ev,
394 struct tevent_signal *se,
402 while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
403 winbind_child_died(pid);
407 static bool winbindd_setup_sig_chld_handler(void)
409 struct tevent_signal *se;
411 se = tevent_add_signal(global_event_context(),
412 global_event_context(),
414 winbindd_sig_chld_handler,
423 static void winbindd_sig_usr2_handler(struct tevent_context *ev,
424 struct tevent_signal *se,
433 static bool winbindd_setup_sig_usr2_handler(void)
435 struct tevent_signal *se;
437 se = tevent_add_signal(global_event_context(),
438 global_event_context(),
440 winbindd_sig_usr2_handler,
449 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
450 static void msg_shutdown(struct messaging_context *msg,
453 struct server_id server_id,
456 /* only the parent waits for this message */
457 DEBUG(0,("Got shutdown message\n"));
462 static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
465 struct server_id server_id,
472 DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
476 * call the validation code from a child:
477 * so we don't block the main winbindd and the validation
478 * code can safely use fork/waitpid...
482 if (child_pid == -1) {
483 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
488 if (child_pid != 0) {
490 DEBUG(5, ("winbind_msg_validate_cache: child created with "
491 "pid %d.\n", (int)child_pid));
497 status = winbindd_reinit_after_fork(NULL, NULL);
498 if (!NT_STATUS_IS_OK(status)) {
499 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
504 /* install default SIGCHLD handler: validation code uses fork/waitpid */
505 CatchSignal(SIGCHLD, SIG_DFL);
507 setproctitle("validate cache child");
509 ret = (uint8_t)winbindd_validate_cache_nobackup();
510 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
511 messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
516 static struct winbindd_bool_dispatch_table {
517 enum winbindd_cmd cmd;
518 bool (*fn)(struct winbindd_cli_state *state);
519 const char *cmd_name;
520 } bool_dispatch_table[] = {
521 { WINBINDD_INTERFACE_VERSION,
522 winbindd_interface_version,
523 "INTERFACE_VERSION" },
530 { WINBINDD_DOMAIN_NAME,
531 winbindd_domain_name,
533 { WINBINDD_NETBIOS_NAME,
534 winbindd_netbios_name,
539 { WINBINDD_CCACHE_NTLMAUTH,
540 winbindd_ccache_ntlm_auth,
542 { WINBINDD_CCACHE_SAVE,
543 winbindd_ccache_save,
545 { WINBINDD_PRIV_PIPE_DIR,
546 winbindd_priv_pipe_dir,
547 "WINBINDD_PRIV_PIPE_DIR" },
548 { WINBINDD_LIST_TRUSTDOM,
549 winbindd_list_trusted_domains,
553 struct winbindd_async_dispatch_table {
554 enum winbindd_cmd cmd;
555 const char *cmd_name;
556 struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
557 struct tevent_context *ev,
558 struct winbindd_cli_state *cli,
559 struct winbindd_request *request);
560 NTSTATUS (*recv_req)(struct tevent_req *req,
561 struct winbindd_response *presp);
564 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
565 { WINBINDD_LOOKUPSID, "LOOKUPSID",
566 winbindd_lookupsid_send, winbindd_lookupsid_recv },
567 { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
568 winbindd_lookupsids_send, winbindd_lookupsids_recv },
569 { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
570 winbindd_lookupname_send, winbindd_lookupname_recv },
571 { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
572 winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
573 { WINBINDD_XIDS_TO_SIDS, "XIDS_TO_SIDS",
574 winbindd_xids_to_sids_send, winbindd_xids_to_sids_recv },
575 { WINBINDD_GETPWSID, "GETPWSID",
576 winbindd_getpwsid_send, winbindd_getpwsid_recv },
577 { WINBINDD_GETPWNAM, "GETPWNAM",
578 winbindd_getpwnam_send, winbindd_getpwnam_recv },
579 { WINBINDD_GETPWUID, "GETPWUID",
580 winbindd_getpwuid_send, winbindd_getpwuid_recv },
581 { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
582 winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
583 { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
584 winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
585 { WINBINDD_GETGROUPS, "GETGROUPS",
586 winbindd_getgroups_send, winbindd_getgroups_recv },
587 { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
588 winbindd_show_sequence_send, winbindd_show_sequence_recv },
589 { WINBINDD_GETGRGID, "GETGRGID",
590 winbindd_getgrgid_send, winbindd_getgrgid_recv },
591 { WINBINDD_GETGRNAM, "GETGRNAM",
592 winbindd_getgrnam_send, winbindd_getgrnam_recv },
593 { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
594 winbindd_getusersids_send, winbindd_getusersids_recv },
595 { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
596 winbindd_lookuprids_send, winbindd_lookuprids_recv },
597 { WINBINDD_SETPWENT, "SETPWENT",
598 winbindd_setpwent_send, winbindd_setpwent_recv },
599 { WINBINDD_GETPWENT, "GETPWENT",
600 winbindd_getpwent_send, winbindd_getpwent_recv },
601 { WINBINDD_ENDPWENT, "ENDPWENT",
602 winbindd_endpwent_send, winbindd_endpwent_recv },
603 { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
604 winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
605 { WINBINDD_GETDCNAME, "GETDCNAME",
606 winbindd_getdcname_send, winbindd_getdcname_recv },
607 { WINBINDD_SETGRENT, "SETGRENT",
608 winbindd_setgrent_send, winbindd_setgrent_recv },
609 { WINBINDD_GETGRENT, "GETGRENT",
610 winbindd_getgrent_send, winbindd_getgrent_recv },
611 { WINBINDD_ENDGRENT, "ENDGRENT",
612 winbindd_endgrent_send, winbindd_endgrent_recv },
613 { WINBINDD_LIST_USERS, "LIST_USERS",
614 winbindd_list_users_send, winbindd_list_users_recv },
615 { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
616 winbindd_list_groups_send, winbindd_list_groups_recv },
617 { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
618 winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
619 { WINBINDD_PING_DC, "PING_DC",
620 winbindd_ping_dc_send, winbindd_ping_dc_recv },
621 { WINBINDD_PAM_AUTH, "PAM_AUTH",
622 winbindd_pam_auth_send, winbindd_pam_auth_recv },
623 { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
624 winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
625 { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
626 winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
627 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
628 winbindd_pam_chng_pswd_auth_crap_send,
629 winbindd_pam_chng_pswd_auth_crap_recv },
630 { WINBINDD_WINS_BYIP, "WINS_BYIP",
631 winbindd_wins_byip_send, winbindd_wins_byip_recv },
632 { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
633 winbindd_wins_byname_send, winbindd_wins_byname_recv },
634 { WINBINDD_DOMAIN_INFO, "DOMAIN_INFO",
635 winbindd_domain_info_send, winbindd_domain_info_recv },
637 { 0, NULL, NULL, NULL }
640 static struct winbindd_async_dispatch_table async_priv_table[] = {
641 { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
642 winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
643 { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
644 winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
645 { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
646 winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
647 { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
648 winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
650 { 0, NULL, NULL, NULL }
653 struct process_request_state {
654 struct winbindd_cli_state *cli_state;
655 struct tevent_context *ev;
658 static void process_request_done(struct tevent_req *subreq);
659 static void process_request_written(struct tevent_req *subreq);
661 static struct tevent_req *process_request_send(
663 struct tevent_context *ev,
664 struct winbindd_cli_state *cli_state)
666 struct tevent_req *req, *subreq;
667 struct process_request_state *state;
668 struct winbindd_async_dispatch_table *atable;
669 enum winbindd_cmd cmd = cli_state->request->cmd;
673 req = tevent_req_create(mem_ctx, &state,
674 struct process_request_state);
678 state->cli_state = cli_state;
681 ok = tevent_req_set_profile(req);
683 return tevent_req_post(req, ev);
686 SMB_ASSERT(cli_state->mem_ctx == NULL);
687 cli_state->mem_ctx = talloc_named(cli_state, 0, "winbind request");
688 if (tevent_req_nomem(cli_state->mem_ctx, req)) {
689 return tevent_req_post(req, ev);
692 cli_state->response = talloc_zero(
694 struct winbindd_response);
695 if (tevent_req_nomem(cli_state->response, req)) {
696 return tevent_req_post(req, ev);
698 cli_state->response->result = WINBINDD_PENDING;
699 cli_state->response->length = sizeof(struct winbindd_response);
701 /* Remember who asked us. */
702 cli_state->pid = cli_state->request->pid;
703 memcpy(cli_state->client_name,
704 cli_state->request->client_name,
705 sizeof(cli_state->client_name));
707 cli_state->cmd_name = "unknown request";
708 cli_state->recv_fn = NULL;
710 /* client is newest */
711 winbindd_promote_client(cli_state);
713 for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
714 if (cmd == atable->cmd) {
719 if ((atable->send_req == NULL) && cli_state->privileged) {
720 for (atable = async_priv_table; atable->send_req;
722 if (cmd == atable->cmd) {
728 if (atable->send_req != NULL) {
729 cli_state->cmd_name = atable->cmd_name;
730 cli_state->recv_fn = atable->recv_req;
732 DBG_DEBUG("process_request: "
733 "Handling async request %s(%d):%s\n",
734 cli_state->client_name,
736 cli_state->cmd_name);
738 subreq = atable->send_req(
743 if (tevent_req_nomem(subreq, req)) {
744 return tevent_req_post(req, ev);
746 tevent_req_set_callback(subreq, process_request_done, req);
750 for (i=0; i<ARRAY_SIZE(bool_dispatch_table); i++) {
751 if (cmd == bool_dispatch_table[i].cmd) {
758 if (i < ARRAY_SIZE(bool_dispatch_table)) {
759 cli_state->cmd_name = bool_dispatch_table[i].cmd_name;
761 DBG_DEBUG("process_request: request fn %s\n",
762 bool_dispatch_table[i].cmd_name);
763 ok = bool_dispatch_table[i].fn(cli_state);
766 cli_state->response->result = ok ? WINBINDD_OK : WINBINDD_ERROR;
768 TALLOC_FREE(cli_state->io_req);
769 TALLOC_FREE(cli_state->request);
771 subreq = wb_resp_write_send(
774 cli_state->out_queue,
776 cli_state->response);
777 if (tevent_req_nomem(subreq, req)) {
778 return tevent_req_post(req, ev);
780 tevent_req_set_callback(subreq, process_request_written, req);
782 cli_state->io_req = subreq;
787 static void process_request_done(struct tevent_req *subreq)
789 struct tevent_req *req = tevent_req_callback_data(
790 subreq, struct tevent_req);
791 struct process_request_state *state = tevent_req_data(
792 req, struct process_request_state);
793 struct winbindd_cli_state *cli_state = state->cli_state;
797 status = cli_state->recv_fn(subreq, cli_state->response);
800 DBG_DEBUG("[%s(%d):%s]: %s\n",
801 cli_state->client_name,
806 ok = NT_STATUS_IS_OK(status);
807 cli_state->response->result = ok ? WINBINDD_OK : WINBINDD_ERROR;
809 TALLOC_FREE(cli_state->io_req);
810 TALLOC_FREE(cli_state->request);
812 subreq = wb_resp_write_send(
815 cli_state->out_queue,
817 cli_state->response);
818 if (tevent_req_nomem(subreq, req)) {
821 tevent_req_set_callback(subreq, process_request_written, req);
823 cli_state->io_req = subreq;
826 static void process_request_written(struct tevent_req *subreq)
828 struct tevent_req *req = tevent_req_callback_data(
829 subreq, struct tevent_req);
830 struct process_request_state *state = tevent_req_data(
831 req, struct process_request_state);
832 struct winbindd_cli_state *cli_state = state->cli_state;
836 cli_state->io_req = NULL;
838 ret = wb_resp_write_recv(subreq, &err);
841 tevent_req_nterror(req, map_nt_error_from_unix(err));
845 DBG_DEBUG("[%s(%d):%s]: delivered response to client\n",
846 cli_state->client_name,
848 cli_state->cmd_name);
850 TALLOC_FREE(cli_state->mem_ctx);
851 cli_state->response = NULL;
852 cli_state->cmd_name = "no request";
853 cli_state->recv_fn = NULL;
855 tevent_req_done(req);
858 static NTSTATUS process_request_recv(
859 struct tevent_req *req,
861 struct tevent_req_profile **profile)
865 if (tevent_req_is_nterror(req, &status)) {
866 tevent_req_received(req);
870 *profile = tevent_req_move_profile(req, mem_ctx);
871 tevent_req_received(req);
876 * This is the main event loop of winbind requests. It goes through a
877 * state-machine of 3 read/write requests, 4 if you have extra data to send.
879 * An idle winbind client has a read request of 4 bytes outstanding,
880 * finalizing function is request_len_recv, checking the length. request_recv
881 * then processes the packet. The processing function then at some point has
882 * to call request_finished which schedules sending the response.
885 static void winbind_client_request_read(struct tevent_req *req);
886 static void winbind_client_activity(struct tevent_req *req);
887 static void winbind_client_processed(struct tevent_req *req);
889 /* Process a new connection by adding it to the client connection list */
891 static void new_connection(int listen_sock, bool privileged)
893 struct sockaddr_un sunaddr;
894 struct winbindd_cli_state *state;
895 struct tevent_req *req;
899 /* Accept connection */
901 len = sizeof(sunaddr);
903 sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
906 if (errno != EINTR) {
907 DEBUG(0, ("Failed to accept socket - %s\n",
912 smb_set_close_on_exec(sock);
914 DEBUG(6,("accepted socket %d\n", sock));
916 /* Create new connection structure */
918 if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
925 state->out_queue = tevent_queue_create(state, "winbind client reply");
926 if (state->out_queue == NULL) {
932 state->privileged = privileged;
934 req = wb_req_read_send(state, global_event_context(), state->sock,
935 WINBINDD_MAX_EXTRA_DATA);
941 tevent_req_set_callback(req, winbind_client_request_read, state);
944 /* Add to connection list */
946 winbindd_add_client(state);
949 static void winbind_client_request_read(struct tevent_req *req)
951 struct winbindd_cli_state *state = tevent_req_callback_data(
952 req, struct winbindd_cli_state);
956 state->io_req = NULL;
958 ret = wb_req_read_recv(req, state, &state->request, &err);
962 DEBUG(6, ("closing socket %d, client exited\n",
965 DEBUG(2, ("Could not read client request from fd %d: "
966 "%s\n", state->sock, strerror(err)));
970 remove_client(state);
974 req = wait_for_read_send(state, global_event_context(), state->sock,
977 DEBUG(0, ("winbind_client_request_read[%d:%s]:"
978 " wait_for_read_send failed - removing client\n",
979 (int)state->pid, state->cmd_name));
980 remove_client(state);
983 tevent_req_set_callback(req, winbind_client_activity, state);
986 req = process_request_send(state, global_event_context(), state);
988 DBG_ERR("process_request_send failed\n");
989 remove_client(state);
992 tevent_req_set_callback(req, winbind_client_processed, state);
995 static void winbind_client_activity(struct tevent_req *req)
997 struct winbindd_cli_state *state =
998 tevent_req_callback_data(req, struct winbindd_cli_state);
1002 has_data = wait_for_read_recv(req, &err);
1005 DEBUG(0, ("winbind_client_activity[%d:%s]:"
1006 "unexpected data from client - removing client\n",
1007 (int)state->pid, state->cmd_name));
1010 DEBUG(6, ("winbind_client_activity[%d:%s]: "
1011 "client has closed connection - removing "
1013 (int)state->pid, state->cmd_name));
1015 DEBUG(2, ("winbind_client_activity[%d:%s]: "
1016 "client socket error (%s) - removing "
1018 (int)state->pid, state->cmd_name,
1023 remove_client(state);
1026 static void winbind_client_processed(struct tevent_req *req)
1028 struct winbindd_cli_state *cli_state = tevent_req_callback_data(
1029 req, struct winbindd_cli_state);
1030 struct tevent_req_profile *profile = NULL;
1031 struct timeval start, stop, diff;
1035 status = process_request_recv(req, cli_state, &profile);
1037 if (!NT_STATUS_IS_OK(status)) {
1038 DBG_DEBUG("process_request failed: %s\n", nt_errstr(status));
1039 remove_client(cli_state);
1043 tevent_req_profile_get_start(profile, NULL, &start);
1044 tevent_req_profile_get_stop(profile, NULL, &stop);
1045 diff = tevent_timeval_until(&start, &stop);
1047 threshold = lp_parm_int(-1, "winbind", "request profile threshold", 60);
1049 if (diff.tv_sec >= threshold) {
1053 depth = lp_parm_int(
1056 "request profile depth",
1059 DBG_ERR("request took %u.%.6u seconds\n",
1060 (unsigned)diff.tv_sec, (unsigned)diff.tv_usec);
1062 str = tevent_req_profile_string(
1063 talloc_tos(), profile, 0, depth);
1065 /* No "\n", already contained in "str" */
1066 DEBUGADD(0, ("%s", str));
1071 TALLOC_FREE(profile);
1073 req = wb_req_read_send(
1075 global_event_context(),
1077 WINBINDD_MAX_EXTRA_DATA);
1079 remove_client(cli_state);
1082 tevent_req_set_callback(req, winbind_client_request_read, cli_state);
1083 cli_state->io_req = req;
1086 /* Remove a client connection from client connection list */
1088 static void remove_client(struct winbindd_cli_state *state)
1090 /* It's a dead client - hold a funeral */
1092 if (state == NULL) {
1097 * We need to remove a pending wb_req_read_*
1098 * or wb_resp_write_* request before closing the
1101 * This is important as they might have used tevent_add_fd() and we
1102 * use the epoll * backend on linux. So we must remove the tevent_fd
1103 * before closing the fd.
1105 * Otherwise we might hit a race with close_conns_after_fork() (via
1106 * winbindd_reinit_after_fork()) where a file descriptor
1107 * is still open in a child, which means it's still active in
1108 * the parents epoll queue, but the related tevent_fd is already
1109 * already gone in the parent.
1113 TALLOC_FREE(state->io_req);
1115 if (state->sock != -1) {
1119 /* tell client, we are closing ... */
1120 nwritten = write(state->sock, &c, sizeof(c));
1121 if (nwritten == -1) {
1122 DEBUG(2, ("final write to client failed: %s\n",
1132 TALLOC_FREE(state->mem_ctx);
1134 /* Remove from list and free */
1136 winbindd_remove_client(state);
1140 /* Is a client idle? */
1142 static bool client_is_idle(struct winbindd_cli_state *state) {
1143 return (state->request == NULL &&
1144 state->response == NULL &&
1145 !state->pwent_state && !state->grent_state);
1148 /* Shutdown client connection which has been idle for the longest time */
1150 static bool remove_idle_client(void)
1152 struct winbindd_cli_state *state, *remove_state = NULL;
1155 for (state = winbindd_client_list(); state; state = state->next) {
1156 if (client_is_idle(state)) {
1158 /* list is sorted by access time */
1159 remove_state = state;
1164 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1165 nidle, remove_state->sock, (unsigned int)remove_state->pid));
1166 remove_client(remove_state);
1174 * Terminate all clients whose requests have taken longer than
1175 * "winbind request timeout" seconds to process, or have been
1176 * idle for more than "winbind request timeout" seconds.
1179 static void remove_timed_out_clients(void)
1181 struct winbindd_cli_state *state, *prev = NULL;
1182 time_t curr_time = time(NULL);
1183 int timeout_val = lp_winbind_request_timeout();
1185 for (state = winbindd_client_list_tail(); state; state = prev) {
1188 prev = winbindd_client_list_prev(state);
1189 expiry_time = state->last_access + timeout_val;
1191 if (curr_time <= expiry_time) {
1192 /* list is sorted, previous clients in
1197 if (client_is_idle(state)) {
1198 DEBUG(5,("Idle client timed out, "
1199 "shutting down sock %d, pid %u\n",
1201 (unsigned int)state->pid));
1203 DEBUG(5,("Client request timed out, "
1204 "shutting down sock %d, pid %u\n",
1206 (unsigned int)state->pid));
1209 remove_client(state);
1213 static void winbindd_scrub_clients_handler(struct tevent_context *ev,
1214 struct tevent_timer *te,
1215 struct timeval current_time,
1218 remove_timed_out_clients();
1219 if (tevent_add_timer(ev, ev,
1220 timeval_current_ofs(SCRUB_CLIENTS_INTERVAL, 0),
1221 winbindd_scrub_clients_handler, NULL) == NULL) {
1222 DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
1227 struct winbindd_listen_state {
1232 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1233 struct tevent_fd *fde,
1237 struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1238 struct winbindd_listen_state);
1240 while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1241 DEBUG(5,("winbindd: Exceeding %d client "
1242 "connections, removing idle "
1243 "connection.\n", lp_winbind_max_clients()));
1244 if (!remove_idle_client()) {
1245 DEBUG(0,("winbindd: Exceeding %d "
1246 "client connections, no idle "
1247 "connection found\n",
1248 lp_winbind_max_clients()));
1252 remove_timed_out_clients();
1253 new_connection(s->fd, s->privileged);
1257 * Winbindd socket accessor functions
1260 char *get_winbind_priv_pipe_dir(void)
1262 return state_path(talloc_tos(), WINBINDD_PRIV_SOCKET_SUBDIR);
1265 static void winbindd_setup_max_fds(void)
1267 int num_fds = MAX_OPEN_FUDGEFACTOR;
1270 num_fds += lp_winbind_max_clients();
1271 /* Add some more to account for 2 sockets open
1272 when the client transitions from unprivileged
1273 to privileged socket
1275 num_fds += lp_winbind_max_clients() / 10;
1277 /* Add one socket per child process
1278 (yeah there are child processes other than the
1279 domain children but only domain children can vary
1282 num_fds += lp_winbind_max_domain_connections() *
1283 (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
1285 actual_fds = set_maxfiles(num_fds);
1287 if (actual_fds < num_fds) {
1288 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1289 "requested %d open files, %d are available.\n",
1290 num_fds, actual_fds));
1294 static bool winbindd_setup_listeners(void)
1296 struct winbindd_listen_state *pub_state = NULL;
1297 struct winbindd_listen_state *priv_state = NULL;
1298 struct tevent_fd *fde;
1302 pub_state = talloc(global_event_context(),
1303 struct winbindd_listen_state);
1308 pub_state->privileged = false;
1309 pub_state->fd = create_pipe_sock(
1310 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1311 if (pub_state->fd == -1) {
1314 rc = listen(pub_state->fd, 5);
1319 fde = tevent_add_fd(global_event_context(), pub_state, pub_state->fd,
1320 TEVENT_FD_READ, winbindd_listen_fde_handler,
1323 close(pub_state->fd);
1326 tevent_fd_set_auto_close(fde);
1328 priv_state = talloc(global_event_context(),
1329 struct winbindd_listen_state);
1334 socket_path = get_winbind_priv_pipe_dir();
1335 if (socket_path == NULL) {
1339 priv_state->privileged = true;
1340 priv_state->fd = create_pipe_sock(
1341 socket_path, WINBINDD_SOCKET_NAME, 0750);
1342 TALLOC_FREE(socket_path);
1343 if (priv_state->fd == -1) {
1346 rc = listen(priv_state->fd, 5);
1351 fde = tevent_add_fd(global_event_context(), priv_state,
1352 priv_state->fd, TEVENT_FD_READ,
1353 winbindd_listen_fde_handler, priv_state);
1355 close(priv_state->fd);
1358 tevent_fd_set_auto_close(fde);
1360 winbindd_scrub_clients_handler(global_event_context(), NULL,
1361 timeval_current(), NULL);
1364 TALLOC_FREE(pub_state);
1365 TALLOC_FREE(priv_state);
1369 bool winbindd_use_idmap_cache(void)
1371 return !opt_nocache;
1374 bool winbindd_use_cache(void)
1376 return !opt_nocache;
1379 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1382 bool scan_trusts = true;
1384 struct tevent_timer *te = NULL;
1386 /* Setup signal handlers */
1388 if (!winbindd_setup_sig_term_handler(true))
1390 if (!winbindd_setup_stdin_handler(true, foreground))
1392 if (!winbindd_setup_sig_hup_handler(NULL))
1394 if (!winbindd_setup_sig_chld_handler())
1396 if (!winbindd_setup_sig_usr2_handler())
1399 CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
1402 * Ensure all cache and idmap caches are consistent
1403 * and initialized before we startup.
1405 if (!winbindd_cache_validate_and_initialize()) {
1409 /* React on 'smbcontrol winbindd reload-config' in the same way
1410 as to SIGHUP signal */
1411 messaging_register(msg_ctx, NULL,
1412 MSG_SMB_CONF_UPDATED,
1413 winbindd_msg_reload_services_parent);
1414 messaging_register(msg_ctx, NULL,
1415 MSG_SHUTDOWN, msg_shutdown);
1417 /* Handle online/offline messages. */
1418 messaging_register(msg_ctx, NULL,
1419 MSG_WINBIND_OFFLINE, winbind_msg_offline);
1420 messaging_register(msg_ctx, NULL,
1421 MSG_WINBIND_ONLINE, winbind_msg_online);
1422 messaging_register(msg_ctx, NULL,
1423 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1425 /* Handle domain online/offline messages for domains */
1426 messaging_register(global_messaging_context(), NULL,
1427 MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1428 messaging_register(global_messaging_context(), NULL,
1429 MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1431 messaging_register(msg_ctx, NULL,
1432 MSG_WINBIND_VALIDATE_CACHE,
1433 winbind_msg_validate_cache);
1435 messaging_register(msg_ctx, NULL,
1436 MSG_WINBIND_DUMP_DOMAIN_LIST,
1437 winbind_msg_dump_domain_list);
1439 messaging_register(msg_ctx, NULL,
1440 MSG_WINBIND_IP_DROPPED,
1441 winbind_msg_ip_dropped_parent);
1443 /* Register handler for MSG_DEBUG. */
1444 messaging_register(msg_ctx, NULL,
1448 messaging_register(msg_ctx, NULL,
1449 MSG_WINBIND_DISCONNECT_DC,
1450 winbind_disconnect_dc_parent);
1452 netsamlogon_cache_init(); /* Non-critical */
1454 /* clear the cached list of trusted domains */
1458 if (!init_domain_list()) {
1459 DEBUG(0,("unable to initialize domain list\n"));
1464 init_locator_child();
1466 smb_nscd_flush_user_cache();
1467 smb_nscd_flush_group_cache();
1469 if (!lp_winbind_scan_trusted_domains()) {
1470 scan_trusts = false;
1473 if (!lp_allow_trusted_domains()) {
1474 scan_trusts = false;
1478 scan_trusts = false;
1482 if (tevent_add_timer(global_event_context(), NULL, timeval_zero(),
1483 rescan_trusted_domains, NULL) == NULL) {
1484 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1489 te = tevent_add_timer(global_event_context(),
1492 winbindd_ping_offline_domains,
1495 DBG_ERR("Failed to schedule winbindd_ping_offline_domains()\n");
1499 status = wb_irpc_register();
1501 if (!NT_STATUS_IS_OK(status)) {
1502 DEBUG(0, ("Could not register IRPC handlers\n"));
1507 struct winbindd_addrchanged_state {
1508 struct addrchange_context *ctx;
1509 struct tevent_context *ev;
1510 struct messaging_context *msg_ctx;
1513 static void winbindd_addr_changed(struct tevent_req *req);
1515 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1516 struct tevent_context *ev,
1517 struct messaging_context *msg_ctx)
1519 struct winbindd_addrchanged_state *state;
1520 struct tevent_req *req;
1523 state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1524 if (state == NULL) {
1525 DEBUG(10, ("talloc failed\n"));
1529 state->msg_ctx = msg_ctx;
1531 status = addrchange_context_create(state, &state->ctx);
1532 if (!NT_STATUS_IS_OK(status)) {
1533 DEBUG(10, ("addrchange_context_create failed: %s\n",
1534 nt_errstr(status)));
1538 req = addrchange_send(state, ev, state->ctx);
1540 DEBUG(0, ("addrchange_send failed\n"));
1544 tevent_req_set_callback(req, winbindd_addr_changed, state);
1547 static void winbindd_addr_changed(struct tevent_req *req)
1549 struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1550 req, struct winbindd_addrchanged_state);
1551 enum addrchange_type type;
1552 struct sockaddr_storage addr;
1555 status = addrchange_recv(req, &type, &addr);
1557 if (!NT_STATUS_IS_OK(status)) {
1558 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1559 nt_errstr(status)));
1563 if (type == ADDRCHANGE_DEL) {
1564 char addrstr[INET6_ADDRSTRLEN];
1567 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1569 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1572 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1574 status = messaging_send(state->msg_ctx,
1575 messaging_server_id(state->msg_ctx),
1576 MSG_WINBIND_IP_DROPPED, &blob);
1577 if (!NT_STATUS_IS_OK(status)) {
1578 DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1579 nt_errstr(status)));
1582 req = addrchange_send(state, state->ev, state->ctx);
1584 DEBUG(0, ("addrchange_send failed\n"));
1588 tevent_req_set_callback(req, winbindd_addr_changed, state);
1593 int main(int argc, const char **argv)
1595 static bool log_stdout = False;
1596 struct samba_cmdline_daemon_cfg *cmdline_daemon_cfg = NULL;
1597 struct poptOption long_options[] = {
1600 .longName = "no-caching",
1602 .argInfo = POPT_ARG_NONE,
1605 .descrip = "Disable caching",
1612 const struct loadparm_substitution *lp_sub =
1613 loadparm_s3_global_substitution();
1619 const struct dcesrv_endpoint_server *ep_server = NULL;
1620 struct dcesrv_context *dce_ctx = NULL;
1621 size_t winbindd_socket_dir_len = 0;
1622 char *winbindd_priv_socket_dir = NULL;
1623 size_t winbindd_priv_socket_dir_len = 0;
1625 setproctitle_init(argc, discard_const(argv), environ);
1628 * Do this before any other talloc operation
1630 talloc_enable_null_tracking();
1631 frame = talloc_stackframe();
1634 * We want total control over the permissions on created files,
1635 * so set our umask to 0.
1641 /* glibc (?) likes to print "User defined signal 1" and exit if a
1642 SIGUSR[12] is received before a handler is installed */
1644 CatchSignal(SIGUSR1, SIG_IGN);
1645 CatchSignal(SIGUSR2, SIG_IGN);
1647 ok = samba_cmdline_init(frame,
1648 SAMBA_CMDLINE_CONFIG_SERVER,
1649 true /* require_smbconf */);
1651 DBG_ERR("Failed to setup cmdline parser\n");
1656 cmdline_daemon_cfg = samba_cmdline_get_daemon_cfg();
1658 pc = samba_popt_get_context(getprogname(), argc, argv, long_options, 0);
1660 DBG_ERR("Failed to setup popt parser!\n");
1665 while ((opt = poptGetNextOpt(pc)) != -1) {
1671 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1672 poptBadOption(pc, 0), poptStrerror(opt));
1673 poptPrintUsage(pc, stderr, 0);
1678 /* Set environment variable so we don't recursively call ourselves.
1679 This may also be useful interactively. */
1680 if ( !winbind_off() ) {
1681 DEBUG(0,("Failed to disable recusive winbindd calls. Exiting.\n"));
1685 /* Initialise for running in non-root mode */
1688 set_remote_machine_name("winbindd", False);
1690 dump_core_setup("winbindd", lp_logfile(talloc_tos(), lp_sub));
1691 if (cmdline_daemon_cfg->daemon && cmdline_daemon_cfg->interactive) {
1692 d_fprintf(stderr,"\nERROR: "
1693 "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1694 poptPrintUsage(pc, stderr, 0);
1698 log_stdout = (debug_get_log_type() == DEBUG_STDOUT);
1699 if (cmdline_daemon_cfg->interactive) {
1701 * libcmdline POPT_DAEMON callback sets "fork" to false if "-i"
1702 * for interactive is passed on the commandline. Set it back to
1703 * true. TODO: check if this is correct, smbd and nmbd don't do
1706 cmdline_daemon_cfg->fork = true;
1710 if (log_stdout && cmdline_daemon_cfg->fork) {
1711 d_fprintf(stderr, "\nERROR: "
1712 "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1713 poptPrintUsage(pc, stderr, 0);
1717 poptFreeContext(pc);
1719 if (is_default_dyn_LOGFILEBASE()) {
1721 if (asprintf(&lfile,"%s/log.winbindd",
1722 get_dyn_LOGFILEBASE()) > 0) {
1723 lp_set_logfile(lfile);
1730 DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1731 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1733 /* After parsing the configuration file we setup the core path one more time
1734 * as the log file might have been set in the configuration and cores's
1735 * path is by default basename(lp_logfile()).
1737 dump_core_setup("winbindd", lp_logfile(talloc_tos(), lp_sub));
1739 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
1740 if (!lp_parm_bool(-1, "server role check", "inhibit", false)) {
1741 DBG_ERR("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n");
1742 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"));
1745 /* Main 'samba' daemon will notify */
1746 daemon_sd_notifications(false);
1749 if (lp_security() == SEC_ADS) {
1750 const char *realm = lp_realm();
1751 const char *workgroup = lp_workgroup();
1753 if (workgroup == NULL || strlen(workgroup) == 0) {
1754 DBG_ERR("For 'secuirity = ADS' mode, the 'workgroup' "
1755 "parameter is required to be set!\n");
1759 if (realm == NULL || strlen(realm) == 0) {
1760 DBG_ERR("For 'secuirity = ADS' mode, the 'realm' "
1761 "parameter is required to be set!\n");
1766 winbindd_socket_dir_len = strlen(lp_winbindd_socket_directory());
1767 if (winbindd_socket_dir_len > 0) {
1768 size_t winbindd_socket_len =
1769 winbindd_socket_dir_len + 1 +
1770 strlen(WINBINDD_SOCKET_NAME);
1771 struct sockaddr_un un = {
1772 .sun_family = AF_UNIX,
1774 size_t sun_path_len = sizeof(un.sun_path);
1776 if (winbindd_socket_len >= sun_path_len) {
1777 DBG_ERR("The winbind socket path [%s/%s] is too long "
1779 lp_winbindd_socket_directory(),
1780 WINBINDD_SOCKET_NAME,
1781 winbindd_socket_len,
1786 DBG_ERR("'winbindd_socket_directory' parameter is empty\n");
1790 winbindd_priv_socket_dir = get_winbind_priv_pipe_dir();
1791 winbindd_priv_socket_dir_len = strlen(winbindd_priv_socket_dir);
1792 if (winbindd_priv_socket_dir_len > 0) {
1793 size_t winbindd_priv_socket_len =
1794 winbindd_priv_socket_dir_len + 1 +
1795 strlen(WINBINDD_SOCKET_NAME);
1796 struct sockaddr_un un = {
1797 .sun_family = AF_UNIX,
1799 size_t sun_path_len = sizeof(un.sun_path);
1801 if (winbindd_priv_socket_len >= sun_path_len) {
1802 DBG_ERR("The winbind priviliged socket path [%s/%s] is too long "
1804 winbindd_priv_socket_dir,
1805 WINBINDD_SOCKET_NAME,
1806 winbindd_priv_socket_len,
1811 DBG_ERR("'winbindd_priv_socket_directory' parameter is empty\n");
1814 TALLOC_FREE(winbindd_priv_socket_dir);
1816 if (!cluster_probe_ok()) {
1820 /* Initialise messaging system */
1822 if (global_messaging_context() == NULL) {
1826 if (!winbindd_reload_services_file(NULL)) {
1827 DEBUG(0, ("error opening config file\n"));
1833 const char *idmap_backend;
1834 const char *invalid_backends[] = {
1835 "ad", "rfc2307", "rid",
1838 idmap_backend = lp_idmap_default_backend();
1839 for (i = 0; i < ARRAY_SIZE(invalid_backends); i++) {
1840 ok = strequal(idmap_backend, invalid_backends[i]);
1842 DBG_ERR("FATAL: Invalid idmap backend %s "
1843 "configured as the default backend!\n",
1850 ok = directory_create_or_exist(lp_lock_directory(), 0755);
1852 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1853 lp_lock_directory(), strerror(errno)));
1857 ok = directory_create_or_exist(lp_pid_directory(), 0755);
1859 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1860 lp_pid_directory(), strerror(errno)));
1866 if (!secrets_init()) {
1868 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1872 status = rpccli_pre_open_netlogon_creds();
1873 if (!NT_STATUS_IS_OK(status)) {
1874 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1875 nt_errstr(status)));
1879 /* Unblock all signals we are interested in as they may have been
1880 blocked by the parent process. */
1882 BlockSignals(False, SIGINT);
1883 BlockSignals(False, SIGQUIT);
1884 BlockSignals(False, SIGTERM);
1885 BlockSignals(False, SIGUSR1);
1886 BlockSignals(False, SIGUSR2);
1887 BlockSignals(False, SIGHUP);
1888 BlockSignals(False, SIGCHLD);
1891 become_daemon(cmdline_daemon_cfg->fork,
1892 cmdline_daemon_cfg->no_process_group,
1895 daemon_status("winbindd", "Starting process ...");
1898 pidfile_create(lp_pid_directory(), "winbindd");
1902 * If we're interactive we want to set our own process group for
1903 * signal management.
1905 if (cmdline_daemon_cfg->interactive &&
1906 !cmdline_daemon_cfg->no_process_group)
1908 setpgid( (pid_t)0, (pid_t)0);
1914 /* Don't use winbindd_reinit_after_fork here as
1915 * we're just starting up and haven't created any
1916 * winbindd-specific resources we must free yet. JRA.
1919 status = reinit_after_fork(global_messaging_context(),
1920 global_event_context(),
1922 if (!NT_STATUS_IS_OK(status)) {
1923 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1926 ok = initialize_password_db(true, global_event_context());
1928 exit_daemon("Failed to initialize passdb backend! "
1929 "Check the 'passdb backend' variable in your "
1930 "smb.conf file.", EINVAL);
1934 * Do not initialize the parent-child-pipe before becoming
1935 * a daemon: this is used to detect a died parent in the child
1938 status = init_before_fork();
1939 if (!NT_STATUS_IS_OK(status)) {
1940 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1943 winbindd_register_handlers(global_messaging_context(),
1944 !cmdline_daemon_cfg->fork);
1946 if (!messaging_parent_dgm_cleanup_init(global_messaging_context())) {
1950 status = init_system_session_info(NULL);
1951 if (!NT_STATUS_IS_OK(status)) {
1952 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1955 DBG_INFO("Registering DCE/RPC endpoint servers\n");
1957 /* Register the endpoint server to dispatch calls locally through
1958 * the legacy api_struct */
1959 ep_server = lsarpc_get_ep_server();
1960 if (ep_server == NULL) {
1961 DBG_ERR("Failed to get 'lsarpc' endpoint server\n");
1964 status = dcerpc_register_ep_server(ep_server);
1965 if (!NT_STATUS_IS_OK(status)) {
1966 DBG_ERR("Failed to register 'lsarpc' endpoint "
1967 "server: %s\n", nt_errstr(status));
1971 /* Register the endpoint server to dispatch calls locally through
1972 * the legacy api_struct */
1973 ep_server = samr_get_ep_server();
1974 if (ep_server == NULL) {
1975 DBG_ERR("Failed to get 'samr' endpoint server\n");
1978 status = dcerpc_register_ep_server(ep_server);
1979 if (!NT_STATUS_IS_OK(status)) {
1980 DBG_ERR("Failed to register 'samr' endpoint "
1981 "server: %s\n", nt_errstr(status));
1985 ep_server = winbind_get_ep_server();
1986 if (ep_server == NULL) {
1987 DBG_ERR("Failed to get 'winbind' endpoint server\n");
1990 status = dcerpc_register_ep_server(ep_server);
1991 if (!NT_STATUS_IS_OK(status)) {
1992 DBG_ERR("Failed to register 'winbind' endpoint "
1993 "server: %s\n", nt_errstr(status));
1997 dce_ctx = global_dcesrv_context();
1999 DBG_INFO("Initializing DCE/RPC registered endpoint servers\n");
2001 /* Init all registered ep servers */
2002 status = dcesrv_init_registered_ep_servers(dce_ctx);
2003 if (!NT_STATUS_IS_OK(status)) {
2004 DBG_ERR("Failed to init DCE/RPC endpoint servers: %s\n",
2009 winbindd_init_addrchange(NULL, global_event_context(),
2010 global_messaging_context());
2012 /* setup listen sockets */
2014 if (!winbindd_setup_listeners()) {
2015 exit_daemon("Winbindd failed to setup listeners", EPIPE);
2018 irpc_add_name(winbind_imessaging_context(), "winbind_server");
2023 daemon_ready("winbindd");
2028 /* Loop waiting for requests */
2030 frame = talloc_stackframe();
2032 if (tevent_loop_once(global_event_context()) == -1) {
2033 DEBUG(1, ("tevent_loop_once() failed: %s\n",