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 "popt_common.h"
28 #include "nsswitch/winbind_client.h"
29 #include "nsswitch/wb_reqtrans.h"
31 #include "../librpc/gen_ndr/srv_lsa.h"
32 #include "../librpc/gen_ndr/srv_samr.h"
34 #include "rpc_client/cli_netlogon.h"
36 #include "lib/addrchange.h"
40 #include "../lib/util/pidfile.h"
41 #include "util_cluster.h"
42 #include "source4/lib/messaging/irpc.h"
43 #include "source4/lib/messaging/messaging.h"
44 #include "lib/param/param.h"
45 #include "lib/async_req/async_sock.h"
48 #define DBGC_CLASS DBGC_WINBIND
50 #define SCRUB_CLIENTS_INTERVAL 5
52 static bool client_is_idle(struct winbindd_cli_state
*state
);
53 static void remove_client(struct winbindd_cli_state
*state
);
54 static void winbindd_setup_max_fds(void);
56 static bool opt_nocache
= False
;
57 static bool interactive
= False
;
59 extern bool override_logfile
;
61 struct tevent_context
*winbind_event_context(void)
63 static struct tevent_context
*ev
= NULL
;
70 * Note we MUST use the NULL context here, not the autofree context,
71 * to avoid side effects in forked children exiting.
73 ev
= samba_tevent_context_init(NULL
);
75 smb_panic("Could not init winbindd's messaging context.\n");
80 struct messaging_context
*winbind_messaging_context(void)
82 static struct messaging_context
*msg
= NULL
;
89 * Note we MUST use the NULL context here, not the autofree context,
90 * to avoid side effects in forked children exiting.
92 msg
= messaging_init(NULL
, winbind_event_context());
94 smb_panic("Could not init winbindd's messaging context.\n");
99 struct imessaging_context
*winbind_imessaging_context(void)
101 static struct imessaging_context
*msg
= NULL
;
102 struct loadparm_context
*lp_ctx
;
108 lp_ctx
= loadparm_init_s3(NULL
, loadparm_s3_helpers());
109 if (lp_ctx
== NULL
) {
110 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
114 * Note we MUST use the NULL context here, not the autofree context,
115 * to avoid side effects in forked children exiting.
117 msg
= imessaging_init(NULL
, lp_ctx
, procid_self(), winbind_event_context(), false);
118 talloc_unlink(NULL
, lp_ctx
);
121 smb_panic("Could not init winbindd's messaging context.\n");
126 /* Reload configuration */
128 static bool reload_services_file(const char *lfile
)
133 char *fname
= lp_next_configfile(talloc_tos());
135 if (file_exist(fname
) && !strcsequal(fname
,get_dyn_CONFIGFILE())) {
136 set_dyn_CONFIGFILE(fname
);
141 /* if this is a child, restore the logfile to the special
142 name - <domain>, idmap, etc. */
143 if (lfile
&& *lfile
) {
144 lp_set_logfile(lfile
);
148 ret
= lp_load_global(get_dyn_CONFIGFILE());
152 winbindd_setup_max_fds();
158 static void winbindd_status(void)
160 struct winbindd_cli_state
*tmp
;
162 DEBUG(0, ("winbindd status:\n"));
164 /* Print client state information */
166 DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
168 if (DEBUGLEVEL
>= 2 && winbindd_num_clients()) {
169 DEBUG(2, ("\tclient list:\n"));
170 for(tmp
= winbindd_client_list(); tmp
; tmp
= tmp
->next
) {
171 DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
172 (unsigned long)tmp
->pid
, tmp
->sock
,
173 client_is_idle(tmp
) ? "idle" : "active"));
178 /* Flush client cache */
180 static void flush_caches(void)
182 /* We need to invalidate cached user list entries on a SIGHUP
183 otherwise cached access denied errors due to restrict anonymous
184 hang around until the sequence number changes. */
186 if (!wcache_invalidate_cache()) {
187 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
188 if (!winbindd_cache_validate_and_initialize()) {
194 static void flush_caches_noinit(void)
197 * We need to invalidate cached user list entries on a SIGHUP
198 * otherwise cached access denied errors due to restrict anonymous
199 * hang around until the sequence number changes.
201 * Skip uninitialized domains when flush cache.
202 * If domain is not initialized, it means it is never
203 * used or never become online. look, wcache_invalidate_cache()
204 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
205 * for unused domains and large traffic for primay domain's DC if there
209 if (!wcache_invalidate_cache_noinit()) {
210 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
211 if (!winbindd_cache_validate_and_initialize()) {
217 /* Handle the signal by unlinking socket and exiting */
219 static void terminate(bool is_parent
)
222 /* When parent goes away we should
223 * remove the socket file. Not so
224 * when children terminate.
228 if (asprintf(&path
, "%s/%s",
229 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME
) > 0) {
237 trustdom_cache_shutdown();
239 gencache_stabilize();
243 TALLOC_CTX
*mem_ctx
= talloc_init("end_description");
244 char *description
= talloc_describe_all(mem_ctx
);
246 DEBUG(3, ("tallocs left:\n%s\n", description
));
247 talloc_destroy(mem_ctx
);
252 struct messaging_context
*msg
= winbind_messaging_context();
253 struct server_id self
= messaging_server_id(msg
);
254 serverid_deregister(self
);
255 pidfile_unlink(lp_pid_directory(), "winbindd");
261 static void winbindd_sig_term_handler(struct tevent_context
*ev
,
262 struct tevent_signal
*se
,
268 bool *is_parent
= talloc_get_type_abort(private_data
, bool);
270 DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
271 signum
, (int)*is_parent
));
272 terminate(*is_parent
);
276 handle stdin becoming readable when we are in --foreground mode
278 static void winbindd_stdin_handler(struct tevent_context
*ev
,
279 struct tevent_fd
*fde
,
284 if (read(0, &c
, 1) != 1) {
285 bool *is_parent
= talloc_get_type_abort(private_data
, bool);
287 /* we have reached EOF on stdin, which means the
288 parent has exited. Shutdown the server */
289 DEBUG(0,("EOF on stdin (is_parent=%d)\n",
291 terminate(*is_parent
);
295 bool winbindd_setup_sig_term_handler(bool parent
)
297 struct tevent_signal
*se
;
300 is_parent
= talloc(winbind_event_context(), bool);
307 se
= tevent_add_signal(winbind_event_context(),
310 winbindd_sig_term_handler
,
313 DEBUG(0,("failed to setup SIGTERM handler"));
314 talloc_free(is_parent
);
318 se
= tevent_add_signal(winbind_event_context(),
321 winbindd_sig_term_handler
,
324 DEBUG(0,("failed to setup SIGINT handler"));
325 talloc_free(is_parent
);
329 se
= tevent_add_signal(winbind_event_context(),
332 winbindd_sig_term_handler
,
335 DEBUG(0,("failed to setup SIGINT handler"));
336 talloc_free(is_parent
);
343 bool winbindd_setup_stdin_handler(bool parent
, bool foreground
)
350 is_parent
= talloc(winbind_event_context(), bool);
357 /* if we are running in the foreground then look for
358 EOF on stdin, and exit if it happens. This allows
359 us to die if the parent process dies
360 Only do this on a pipe or socket, no other device.
362 if (fstat(0, &st
) != 0) {
365 if (S_ISFIFO(st
.st_mode
) || S_ISSOCK(st
.st_mode
)) {
366 tevent_add_fd(winbind_event_context(),
370 winbindd_stdin_handler
,
378 static void winbindd_sig_hup_handler(struct tevent_context
*ev
,
379 struct tevent_signal
*se
,
385 const char *file
= (const char *)private_data
;
387 DEBUG(1,("Reloading services after SIGHUP\n"));
388 flush_caches_noinit();
389 reload_services_file(file
);
392 bool winbindd_setup_sig_hup_handler(const char *lfile
)
394 struct tevent_signal
*se
;
398 file
= talloc_strdup(winbind_event_context(),
405 se
= tevent_add_signal(winbind_event_context(),
406 winbind_event_context(),
408 winbindd_sig_hup_handler
,
417 static void winbindd_sig_chld_handler(struct tevent_context
*ev
,
418 struct tevent_signal
*se
,
426 while ((pid
= sys_waitpid(-1, NULL
, WNOHANG
)) > 0) {
427 winbind_child_died(pid
);
431 static bool winbindd_setup_sig_chld_handler(void)
433 struct tevent_signal
*se
;
435 se
= tevent_add_signal(winbind_event_context(),
436 winbind_event_context(),
438 winbindd_sig_chld_handler
,
447 static void winbindd_sig_usr2_handler(struct tevent_context
*ev
,
448 struct tevent_signal
*se
,
457 static bool winbindd_setup_sig_usr2_handler(void)
459 struct tevent_signal
*se
;
461 se
= tevent_add_signal(winbind_event_context(),
462 winbind_event_context(),
464 winbindd_sig_usr2_handler
,
473 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
474 static void msg_reload_services(struct messaging_context
*msg
,
477 struct server_id server_id
,
480 /* Flush various caches */
482 reload_services_file((const char *) private_data
);
485 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
486 static void msg_shutdown(struct messaging_context
*msg
,
489 struct server_id server_id
,
492 /* only the parent waits for this message */
493 DEBUG(0,("Got shutdown message\n"));
498 static void winbind_msg_validate_cache(struct messaging_context
*msg_ctx
,
501 struct server_id server_id
,
508 DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
512 * call the validation code from a child:
513 * so we don't block the main winbindd and the validation
514 * code can safely use fork/waitpid...
518 if (child_pid
== -1) {
519 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
524 if (child_pid
!= 0) {
526 DEBUG(5, ("winbind_msg_validate_cache: child created with "
527 "pid %d.\n", (int)child_pid
));
533 status
= winbindd_reinit_after_fork(NULL
, NULL
);
534 if (!NT_STATUS_IS_OK(status
)) {
535 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
540 /* install default SIGCHLD handler: validation code uses fork/waitpid */
541 CatchSignal(SIGCHLD
, SIG_DFL
);
543 ret
= (uint8_t)winbindd_validate_cache_nobackup();
544 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret
));
545 messaging_send_buf(msg_ctx
, server_id
, MSG_WINBIND_VALIDATE_CACHE
, &ret
,
550 static struct winbindd_dispatch_table
{
551 enum winbindd_cmd cmd
;
552 void (*fn
)(struct winbindd_cli_state
*state
);
553 const char *winbindd_cmd_name
;
554 } dispatch_table
[] = {
556 /* Enumeration functions */
558 { WINBINDD_LIST_TRUSTDOM
, winbindd_list_trusted_domains
,
563 { WINBINDD_INFO
, winbindd_info
, "INFO" },
564 { WINBINDD_INTERFACE_VERSION
, winbindd_interface_version
,
565 "INTERFACE_VERSION" },
566 { WINBINDD_DOMAIN_NAME
, winbindd_domain_name
, "DOMAIN_NAME" },
567 { WINBINDD_DOMAIN_INFO
, winbindd_domain_info
, "DOMAIN_INFO" },
568 { WINBINDD_DC_INFO
, winbindd_dc_info
, "DC_INFO" },
569 { WINBINDD_NETBIOS_NAME
, winbindd_netbios_name
, "NETBIOS_NAME" },
570 { WINBINDD_PRIV_PIPE_DIR
, winbindd_priv_pipe_dir
,
571 "WINBINDD_PRIV_PIPE_DIR" },
573 /* Credential cache access */
574 { WINBINDD_CCACHE_NTLMAUTH
, winbindd_ccache_ntlm_auth
, "NTLMAUTH" },
575 { WINBINDD_CCACHE_SAVE
, winbindd_ccache_save
, "CCACHE_SAVE" },
579 { WINBINDD_NUM_CMDS
, NULL
, "NONE" }
582 struct winbindd_async_dispatch_table
{
583 enum winbindd_cmd cmd
;
584 const char *cmd_name
;
585 struct tevent_req
*(*send_req
)(TALLOC_CTX
*mem_ctx
,
586 struct tevent_context
*ev
,
587 struct winbindd_cli_state
*cli
,
588 struct winbindd_request
*request
);
589 NTSTATUS (*recv_req
)(struct tevent_req
*req
,
590 struct winbindd_response
*presp
);
593 static struct winbindd_async_dispatch_table async_nonpriv_table
[] = {
594 { WINBINDD_PING
, "PING",
595 wb_ping_send
, wb_ping_recv
},
596 { WINBINDD_LOOKUPSID
, "LOOKUPSID",
597 winbindd_lookupsid_send
, winbindd_lookupsid_recv
},
598 { WINBINDD_LOOKUPSIDS
, "LOOKUPSIDS",
599 winbindd_lookupsids_send
, winbindd_lookupsids_recv
},
600 { WINBINDD_LOOKUPNAME
, "LOOKUPNAME",
601 winbindd_lookupname_send
, winbindd_lookupname_recv
},
602 { WINBINDD_SID_TO_UID
, "SID_TO_UID",
603 winbindd_sid_to_uid_send
, winbindd_sid_to_uid_recv
},
604 { WINBINDD_SID_TO_GID
, "SID_TO_GID",
605 winbindd_sid_to_gid_send
, winbindd_sid_to_gid_recv
},
606 { WINBINDD_UID_TO_SID
, "UID_TO_SID",
607 winbindd_uid_to_sid_send
, winbindd_uid_to_sid_recv
},
608 { WINBINDD_GID_TO_SID
, "GID_TO_SID",
609 winbindd_gid_to_sid_send
, winbindd_gid_to_sid_recv
},
610 { WINBINDD_SIDS_TO_XIDS
, "SIDS_TO_XIDS",
611 winbindd_sids_to_xids_send
, winbindd_sids_to_xids_recv
},
612 { WINBINDD_GETPWSID
, "GETPWSID",
613 winbindd_getpwsid_send
, winbindd_getpwsid_recv
},
614 { WINBINDD_GETPWNAM
, "GETPWNAM",
615 winbindd_getpwnam_send
, winbindd_getpwnam_recv
},
616 { WINBINDD_GETPWUID
, "GETPWUID",
617 winbindd_getpwuid_send
, winbindd_getpwuid_recv
},
618 { WINBINDD_GETSIDALIASES
, "GETSIDALIASES",
619 winbindd_getsidaliases_send
, winbindd_getsidaliases_recv
},
620 { WINBINDD_GETUSERDOMGROUPS
, "GETUSERDOMGROUPS",
621 winbindd_getuserdomgroups_send
, winbindd_getuserdomgroups_recv
},
622 { WINBINDD_GETGROUPS
, "GETGROUPS",
623 winbindd_getgroups_send
, winbindd_getgroups_recv
},
624 { WINBINDD_SHOW_SEQUENCE
, "SHOW_SEQUENCE",
625 winbindd_show_sequence_send
, winbindd_show_sequence_recv
},
626 { WINBINDD_GETGRGID
, "GETGRGID",
627 winbindd_getgrgid_send
, winbindd_getgrgid_recv
},
628 { WINBINDD_GETGRNAM
, "GETGRNAM",
629 winbindd_getgrnam_send
, winbindd_getgrnam_recv
},
630 { WINBINDD_GETUSERSIDS
, "GETUSERSIDS",
631 winbindd_getusersids_send
, winbindd_getusersids_recv
},
632 { WINBINDD_LOOKUPRIDS
, "LOOKUPRIDS",
633 winbindd_lookuprids_send
, winbindd_lookuprids_recv
},
634 { WINBINDD_SETPWENT
, "SETPWENT",
635 winbindd_setpwent_send
, winbindd_setpwent_recv
},
636 { WINBINDD_GETPWENT
, "GETPWENT",
637 winbindd_getpwent_send
, winbindd_getpwent_recv
},
638 { WINBINDD_ENDPWENT
, "ENDPWENT",
639 winbindd_endpwent_send
, winbindd_endpwent_recv
},
640 { WINBINDD_DSGETDCNAME
, "DSGETDCNAME",
641 winbindd_dsgetdcname_send
, winbindd_dsgetdcname_recv
},
642 { WINBINDD_GETDCNAME
, "GETDCNAME",
643 winbindd_getdcname_send
, winbindd_getdcname_recv
},
644 { WINBINDD_SETGRENT
, "SETGRENT",
645 winbindd_setgrent_send
, winbindd_setgrent_recv
},
646 { WINBINDD_GETGRENT
, "GETGRENT",
647 winbindd_getgrent_send
, winbindd_getgrent_recv
},
648 { WINBINDD_ENDGRENT
, "ENDGRENT",
649 winbindd_endgrent_send
, winbindd_endgrent_recv
},
650 { WINBINDD_LIST_USERS
, "LIST_USERS",
651 winbindd_list_users_send
, winbindd_list_users_recv
},
652 { WINBINDD_LIST_GROUPS
, "LIST_GROUPS",
653 winbindd_list_groups_send
, winbindd_list_groups_recv
},
654 { WINBINDD_CHECK_MACHACC
, "CHECK_MACHACC",
655 winbindd_check_machine_acct_send
, winbindd_check_machine_acct_recv
},
656 { WINBINDD_PING_DC
, "PING_DC",
657 winbindd_ping_dc_send
, winbindd_ping_dc_recv
},
658 { WINBINDD_PAM_AUTH
, "PAM_AUTH",
659 winbindd_pam_auth_send
, winbindd_pam_auth_recv
},
660 { WINBINDD_PAM_LOGOFF
, "PAM_LOGOFF",
661 winbindd_pam_logoff_send
, winbindd_pam_logoff_recv
},
662 { WINBINDD_PAM_CHAUTHTOK
, "PAM_CHAUTHTOK",
663 winbindd_pam_chauthtok_send
, winbindd_pam_chauthtok_recv
},
664 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP
, "PAM_CHNG_PSWD_AUTH_CRAP",
665 winbindd_pam_chng_pswd_auth_crap_send
,
666 winbindd_pam_chng_pswd_auth_crap_recv
},
667 { WINBINDD_WINS_BYIP
, "WINS_BYIP",
668 winbindd_wins_byip_send
, winbindd_wins_byip_recv
},
669 { WINBINDD_WINS_BYNAME
, "WINS_BYNAME",
670 winbindd_wins_byname_send
, winbindd_wins_byname_recv
},
672 { 0, NULL
, NULL
, NULL
}
675 static struct winbindd_async_dispatch_table async_priv_table
[] = {
676 { WINBINDD_ALLOCATE_UID
, "ALLOCATE_UID",
677 winbindd_allocate_uid_send
, winbindd_allocate_uid_recv
},
678 { WINBINDD_ALLOCATE_GID
, "ALLOCATE_GID",
679 winbindd_allocate_gid_send
, winbindd_allocate_gid_recv
},
680 { WINBINDD_CHANGE_MACHACC
, "CHANGE_MACHACC",
681 winbindd_change_machine_acct_send
, winbindd_change_machine_acct_recv
},
682 { WINBINDD_PAM_AUTH_CRAP
, "PAM_AUTH_CRAP",
683 winbindd_pam_auth_crap_send
, winbindd_pam_auth_crap_recv
},
685 { 0, NULL
, NULL
, NULL
}
688 static void wb_request_done(struct tevent_req
*req
);
690 static void process_request(struct winbindd_cli_state
*state
)
692 struct winbindd_dispatch_table
*table
= dispatch_table
;
693 struct winbindd_async_dispatch_table
*atable
;
695 state
->mem_ctx
= talloc_named(state
, 0, "winbind request");
696 if (state
->mem_ctx
== NULL
)
699 /* Remember who asked us. */
700 state
->pid
= state
->request
->pid
;
702 state
->cmd_name
= "unknown request";
703 state
->recv_fn
= NULL
;
704 /* client is newest */
705 winbindd_promote_client(state
);
707 /* Process command */
709 for (atable
= async_nonpriv_table
; atable
->send_req
; atable
+= 1) {
710 if (state
->request
->cmd
== atable
->cmd
) {
715 if ((atable
->send_req
== NULL
) && state
->privileged
) {
716 for (atable
= async_priv_table
; atable
->send_req
;
718 if (state
->request
->cmd
== atable
->cmd
) {
724 if (atable
->send_req
!= NULL
) {
725 struct tevent_req
*req
;
727 state
->cmd_name
= atable
->cmd_name
;
728 state
->recv_fn
= atable
->recv_req
;
730 DEBUG(10, ("process_request: Handling async request %d:%s\n",
731 (int)state
->pid
, state
->cmd_name
));
733 req
= atable
->send_req(state
->mem_ctx
, winbind_event_context(),
734 state
, state
->request
);
736 DEBUG(0, ("process_request: atable->send failed for "
737 "%s\n", atable
->cmd_name
));
738 request_error(state
);
741 tevent_req_set_callback(req
, wb_request_done
, state
);
745 state
->response
= talloc_zero(state
->mem_ctx
,
746 struct winbindd_response
);
747 if (state
->response
== NULL
) {
748 DEBUG(10, ("talloc failed\n"));
749 remove_client(state
);
752 state
->response
->result
= WINBINDD_PENDING
;
753 state
->response
->length
= sizeof(struct winbindd_response
);
755 for (table
= dispatch_table
; table
->fn
; table
++) {
756 if (state
->request
->cmd
== table
->cmd
) {
757 DEBUG(10,("process_request: request fn %s\n",
758 table
->winbindd_cmd_name
));
759 state
->cmd_name
= table
->winbindd_cmd_name
;
766 DEBUG(10,("process_request: unknown request fn number %d\n",
767 (int)state
->request
->cmd
));
768 request_error(state
);
772 static void wb_request_done(struct tevent_req
*req
)
774 struct winbindd_cli_state
*state
= tevent_req_callback_data(
775 req
, struct winbindd_cli_state
);
778 state
->response
= talloc_zero(state
->mem_ctx
,
779 struct winbindd_response
);
780 if (state
->response
== NULL
) {
781 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
782 (int)state
->pid
, state
->cmd_name
));
783 remove_client(state
);
786 state
->response
->result
= WINBINDD_PENDING
;
787 state
->response
->length
= sizeof(struct winbindd_response
);
789 status
= state
->recv_fn(req
, state
->response
);
792 DEBUG(10,("wb_request_done[%d:%s]: %s\n",
793 (int)state
->pid
, state
->cmd_name
, nt_errstr(status
)));
795 if (!NT_STATUS_IS_OK(status
)) {
796 request_error(state
);
803 * This is the main event loop of winbind requests. It goes through a
804 * state-machine of 3 read/write requests, 4 if you have extra data to send.
806 * An idle winbind client has a read request of 4 bytes outstanding,
807 * finalizing function is request_len_recv, checking the length. request_recv
808 * then processes the packet. The processing function then at some point has
809 * to call request_finished which schedules sending the response.
812 static void request_finished(struct winbindd_cli_state
*state
);
814 static void winbind_client_request_read(struct tevent_req
*req
);
815 static void winbind_client_response_written(struct tevent_req
*req
);
816 static void winbind_client_activity(struct tevent_req
*req
);
818 static void request_finished(struct winbindd_cli_state
*state
)
820 struct tevent_req
*req
;
822 /* free client socket monitoring request */
823 TALLOC_FREE(state
->io_req
);
825 TALLOC_FREE(state
->request
);
827 req
= wb_resp_write_send(state
, winbind_event_context(),
828 state
->out_queue
, state
->sock
,
831 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
832 (int)state
->pid
, state
->cmd_name
));
833 remove_client(state
);
836 tevent_req_set_callback(req
, winbind_client_response_written
, state
);
840 static void winbind_client_response_written(struct tevent_req
*req
)
842 struct winbindd_cli_state
*state
= tevent_req_callback_data(
843 req
, struct winbindd_cli_state
);
847 state
->io_req
= NULL
;
849 ret
= wb_resp_write_recv(req
, &err
);
854 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
855 (int)state
->pid
, state
->cmd_name
, strerror(err
)));
856 remove_client(state
);
860 DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
861 "to client\n", (int)state
->pid
, state
->cmd_name
));
863 TALLOC_FREE(state
->mem_ctx
);
864 state
->response
= NULL
;
865 state
->cmd_name
= "no request";
866 state
->recv_fn
= NULL
;
868 req
= wb_req_read_send(state
, winbind_event_context(), state
->sock
,
869 WINBINDD_MAX_EXTRA_DATA
);
871 remove_client(state
);
874 tevent_req_set_callback(req
, winbind_client_request_read
, state
);
878 void request_error(struct winbindd_cli_state
*state
)
880 SMB_ASSERT(state
->response
->result
== WINBINDD_PENDING
);
881 state
->response
->result
= WINBINDD_ERROR
;
882 request_finished(state
);
885 void request_ok(struct winbindd_cli_state
*state
)
887 SMB_ASSERT(state
->response
->result
== WINBINDD_PENDING
);
888 state
->response
->result
= WINBINDD_OK
;
889 request_finished(state
);
892 /* Process a new connection by adding it to the client connection list */
894 static void new_connection(int listen_sock
, bool privileged
)
896 struct sockaddr_un sunaddr
;
897 struct winbindd_cli_state
*state
;
898 struct tevent_req
*req
;
902 /* Accept connection */
904 len
= sizeof(sunaddr
);
906 sock
= accept(listen_sock
, (struct sockaddr
*)(void *)&sunaddr
, &len
);
909 if (errno
!= EINTR
) {
910 DEBUG(0, ("Failed to accept socket - %s\n",
916 DEBUG(6,("accepted socket %d\n", sock
));
918 /* Create new connection structure */
920 if ((state
= talloc_zero(NULL
, struct winbindd_cli_state
)) == NULL
) {
927 state
->out_queue
= tevent_queue_create(state
, "winbind client reply");
928 if (state
->out_queue
== NULL
) {
934 state
->privileged
= privileged
;
936 req
= wb_req_read_send(state
, winbind_event_context(), state
->sock
,
937 WINBINDD_MAX_EXTRA_DATA
);
943 tevent_req_set_callback(req
, winbind_client_request_read
, state
);
946 /* Add to connection list */
948 winbindd_add_client(state
);
951 static void winbind_client_request_read(struct tevent_req
*req
)
953 struct winbindd_cli_state
*state
= tevent_req_callback_data(
954 req
, struct winbindd_cli_state
);
958 state
->io_req
= NULL
;
960 ret
= wb_req_read_recv(req
, state
, &state
->request
, &err
);
964 DEBUG(6, ("closing socket %d, client exited\n",
967 DEBUG(2, ("Could not read client request from fd %d: "
968 "%s\n", state
->sock
, strerror(err
)));
972 remove_client(state
);
976 req
= wait_for_read_send(state
, winbind_event_context(), state
->sock
,
979 DEBUG(0, ("winbind_client_request_read[%d:%s]:"
980 " wait_for_read_send failed - removing client\n",
981 (int)state
->pid
, state
->cmd_name
));
982 remove_client(state
);
985 tevent_req_set_callback(req
, winbind_client_activity
, state
);
988 process_request(state
);
991 static void winbind_client_activity(struct tevent_req
*req
)
993 struct winbindd_cli_state
*state
=
994 tevent_req_callback_data(req
, struct winbindd_cli_state
);
998 has_data
= wait_for_read_recv(req
, &err
);
1001 DEBUG(0, ("winbind_client_activity[%d:%s]:"
1002 "unexpected data from client - removing client\n",
1003 (int)state
->pid
, state
->cmd_name
));
1006 DEBUG(6, ("winbind_client_activity[%d:%s]: "
1007 "client has closed connection - removing "
1009 (int)state
->pid
, state
->cmd_name
));
1011 DEBUG(2, ("winbind_client_activity[%d:%s]: "
1012 "client socket error (%s) - removing "
1014 (int)state
->pid
, state
->cmd_name
,
1019 remove_client(state
);
1022 /* Remove a client connection from client connection list */
1024 static void remove_client(struct winbindd_cli_state
*state
)
1029 /* It's a dead client - hold a funeral */
1031 if (state
== NULL
) {
1036 * We need to remove a pending wb_req_read_*
1037 * or wb_resp_write_* request before closing the
1040 * This is important as they might have used tevent_add_fd() and we
1041 * use the epoll * backend on linux. So we must remove the tevent_fd
1042 * before closing the fd.
1044 * Otherwise we might hit a race with close_conns_after_fork() (via
1045 * winbindd_reinit_after_fork()) where a file description
1046 * is still open in a child, which means it's still active in
1047 * the parents epoll queue, but the related tevent_fd is already
1048 * already gone in the parent.
1052 TALLOC_FREE(state
->io_req
);
1054 if (state
->sock
!= -1) {
1055 /* tell client, we are closing ... */
1056 nwritten
= write(state
->sock
, &c
, sizeof(c
));
1057 if (nwritten
== -1) {
1058 DEBUG(2, ("final write to client failed: %s\n",
1068 TALLOC_FREE(state
->mem_ctx
);
1070 /* Remove from list and free */
1072 winbindd_remove_client(state
);
1076 /* Is a client idle? */
1078 static bool client_is_idle(struct winbindd_cli_state
*state
) {
1079 return (state
->request
== NULL
&&
1080 state
->response
== NULL
&&
1081 !state
->pwent_state
&& !state
->grent_state
);
1084 /* Shutdown client connection which has been idle for the longest time */
1086 static bool remove_idle_client(void)
1088 struct winbindd_cli_state
*state
, *remove_state
= NULL
;
1091 for (state
= winbindd_client_list(); state
; state
= state
->next
) {
1092 if (client_is_idle(state
)) {
1094 /* list is sorted by access time */
1095 remove_state
= state
;
1100 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1101 nidle
, remove_state
->sock
, (unsigned int)remove_state
->pid
));
1102 remove_client(remove_state
);
1110 * Terminate all clients whose requests have taken longer than
1111 * "winbind request timeout" seconds to process, or have been
1112 * idle for more than "winbind request timeout" seconds.
1115 static void remove_timed_out_clients(void)
1117 struct winbindd_cli_state
*state
, *prev
= NULL
;
1118 time_t curr_time
= time(NULL
);
1119 int timeout_val
= lp_winbind_request_timeout();
1121 for (state
= winbindd_client_list_tail(); state
; state
= prev
) {
1124 prev
= winbindd_client_list_prev(state
);
1125 expiry_time
= state
->last_access
+ timeout_val
;
1127 if (curr_time
> expiry_time
) {
1128 if (client_is_idle(state
)) {
1129 DEBUG(5,("Idle client timed out, "
1130 "shutting down sock %d, pid %u\n",
1132 (unsigned int)state
->pid
));
1134 DEBUG(5,("Client request timed out, "
1135 "shutting down sock %d, pid %u\n",
1137 (unsigned int)state
->pid
));
1139 remove_client(state
);
1141 /* list is sorted, previous clients in
1148 static void winbindd_scrub_clients_handler(struct tevent_context
*ev
,
1149 struct tevent_timer
*te
,
1150 struct timeval current_time
,
1153 remove_timed_out_clients();
1154 if (tevent_add_timer(ev
, ev
,
1155 timeval_current_ofs(SCRUB_CLIENTS_INTERVAL
, 0),
1156 winbindd_scrub_clients_handler
, NULL
) == NULL
) {
1157 DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
1162 struct winbindd_listen_state
{
1167 static void winbindd_listen_fde_handler(struct tevent_context
*ev
,
1168 struct tevent_fd
*fde
,
1172 struct winbindd_listen_state
*s
= talloc_get_type_abort(private_data
,
1173 struct winbindd_listen_state
);
1175 while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1176 DEBUG(5,("winbindd: Exceeding %d client "
1177 "connections, removing idle "
1178 "connection.\n", lp_winbind_max_clients()));
1179 if (!remove_idle_client()) {
1180 DEBUG(0,("winbindd: Exceeding %d "
1181 "client connections, no idle "
1182 "connection found\n",
1183 lp_winbind_max_clients()));
1187 remove_timed_out_clients();
1188 new_connection(s
->fd
, s
->privileged
);
1192 * Winbindd socket accessor functions
1195 char *get_winbind_priv_pipe_dir(void)
1197 return state_path(WINBINDD_PRIV_SOCKET_SUBDIR
);
1200 static void winbindd_setup_max_fds(void)
1202 int num_fds
= MAX_OPEN_FUDGEFACTOR
;
1205 num_fds
+= lp_winbind_max_clients();
1206 /* Add some more to account for 2 sockets open
1207 when the client transitions from unprivileged
1208 to privileged socket
1210 num_fds
+= lp_winbind_max_clients() / 10;
1212 /* Add one socket per child process
1213 (yeah there are child processes other than the
1214 domain children but only domain children can vary
1217 num_fds
+= lp_winbind_max_domain_connections() *
1218 (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT
: 1);
1220 actual_fds
= set_maxfiles(num_fds
);
1222 if (actual_fds
< num_fds
) {
1223 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1224 "requested %d open files, %d are available.\n",
1225 num_fds
, actual_fds
));
1229 static bool winbindd_setup_listeners(void)
1231 struct winbindd_listen_state
*pub_state
= NULL
;
1232 struct winbindd_listen_state
*priv_state
= NULL
;
1233 struct tevent_fd
*fde
;
1237 pub_state
= talloc(winbind_event_context(),
1238 struct winbindd_listen_state
);
1243 pub_state
->privileged
= false;
1244 pub_state
->fd
= create_pipe_sock(
1245 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME
, 0755);
1246 if (pub_state
->fd
== -1) {
1249 rc
= listen(pub_state
->fd
, 5);
1254 fde
= tevent_add_fd(winbind_event_context(), pub_state
, pub_state
->fd
,
1255 TEVENT_FD_READ
, winbindd_listen_fde_handler
,
1258 close(pub_state
->fd
);
1261 tevent_fd_set_auto_close(fde
);
1263 priv_state
= talloc(winbind_event_context(),
1264 struct winbindd_listen_state
);
1269 socket_path
= get_winbind_priv_pipe_dir();
1270 if (socket_path
== NULL
) {
1274 priv_state
->privileged
= true;
1275 priv_state
->fd
= create_pipe_sock(
1276 socket_path
, WINBINDD_SOCKET_NAME
, 0750);
1277 TALLOC_FREE(socket_path
);
1278 if (priv_state
->fd
== -1) {
1281 rc
= listen(priv_state
->fd
, 5);
1286 fde
= tevent_add_fd(winbind_event_context(), priv_state
,
1287 priv_state
->fd
, TEVENT_FD_READ
,
1288 winbindd_listen_fde_handler
, priv_state
);
1290 close(priv_state
->fd
);
1293 tevent_fd_set_auto_close(fde
);
1295 winbindd_scrub_clients_handler(winbind_event_context(), NULL
,
1296 timeval_current(), NULL
);
1299 TALLOC_FREE(pub_state
);
1300 TALLOC_FREE(priv_state
);
1304 bool winbindd_use_idmap_cache(void)
1306 return !opt_nocache
;
1309 bool winbindd_use_cache(void)
1311 return !opt_nocache
;
1314 static void winbindd_register_handlers(struct messaging_context
*msg_ctx
,
1318 /* Setup signal handlers */
1320 if (!winbindd_setup_sig_term_handler(true))
1322 if (!winbindd_setup_stdin_handler(true, foreground
))
1324 if (!winbindd_setup_sig_hup_handler(NULL
))
1326 if (!winbindd_setup_sig_chld_handler())
1328 if (!winbindd_setup_sig_usr2_handler())
1331 CatchSignal(SIGPIPE
, SIG_IGN
); /* Ignore sigpipe */
1334 * Ensure all cache and idmap caches are consistent
1335 * and initialized before we startup.
1337 if (!winbindd_cache_validate_and_initialize()) {
1341 /* get broadcast messages */
1343 if (!serverid_register(messaging_server_id(msg_ctx
),
1347 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
1351 /* React on 'smbcontrol winbindd reload-config' in the same way
1352 as to SIGHUP signal */
1353 messaging_register(msg_ctx
, NULL
,
1354 MSG_SMB_CONF_UPDATED
, msg_reload_services
);
1355 messaging_register(msg_ctx
, NULL
,
1356 MSG_SHUTDOWN
, msg_shutdown
);
1358 /* Handle online/offline messages. */
1359 messaging_register(msg_ctx
, NULL
,
1360 MSG_WINBIND_OFFLINE
, winbind_msg_offline
);
1361 messaging_register(msg_ctx
, NULL
,
1362 MSG_WINBIND_ONLINE
, winbind_msg_online
);
1363 messaging_register(msg_ctx
, NULL
,
1364 MSG_WINBIND_ONLINESTATUS
, winbind_msg_onlinestatus
);
1366 /* Handle domain online/offline messages for domains */
1367 messaging_register(winbind_messaging_context(), NULL
,
1368 MSG_WINBIND_DOMAIN_OFFLINE
, winbind_msg_domain_offline
);
1369 messaging_register(winbind_messaging_context(), NULL
,
1370 MSG_WINBIND_DOMAIN_ONLINE
, winbind_msg_domain_online
);
1372 messaging_register(msg_ctx
, NULL
,
1373 MSG_DUMP_EVENT_LIST
, winbind_msg_dump_event_list
);
1375 messaging_register(msg_ctx
, NULL
,
1376 MSG_WINBIND_VALIDATE_CACHE
,
1377 winbind_msg_validate_cache
);
1379 messaging_register(msg_ctx
, NULL
,
1380 MSG_WINBIND_DUMP_DOMAIN_LIST
,
1381 winbind_msg_dump_domain_list
);
1383 messaging_register(msg_ctx
, NULL
,
1384 MSG_WINBIND_IP_DROPPED
,
1385 winbind_msg_ip_dropped_parent
);
1387 /* Register handler for MSG_DEBUG. */
1388 messaging_register(msg_ctx
, NULL
,
1392 netsamlogon_cache_init(); /* Non-critical */
1394 /* clear the cached list of trusted domains */
1398 if (!init_domain_list()) {
1399 DEBUG(0,("unable to initialize domain list\n"));
1404 init_locator_child();
1406 smb_nscd_flush_user_cache();
1407 smb_nscd_flush_group_cache();
1409 if (lp_allow_trusted_domains()) {
1410 if (tevent_add_timer(winbind_event_context(), NULL
, timeval_zero(),
1411 rescan_trusted_domains
, NULL
) == NULL
) {
1412 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1417 status
= wb_irpc_register();
1419 if (!NT_STATUS_IS_OK(status
)) {
1420 DEBUG(0, ("Could not register IRPC handlers\n"));
1425 struct winbindd_addrchanged_state
{
1426 struct addrchange_context
*ctx
;
1427 struct tevent_context
*ev
;
1428 struct messaging_context
*msg_ctx
;
1431 static void winbindd_addr_changed(struct tevent_req
*req
);
1433 static void winbindd_init_addrchange(TALLOC_CTX
*mem_ctx
,
1434 struct tevent_context
*ev
,
1435 struct messaging_context
*msg_ctx
)
1437 struct winbindd_addrchanged_state
*state
;
1438 struct tevent_req
*req
;
1441 state
= talloc(mem_ctx
, struct winbindd_addrchanged_state
);
1442 if (state
== NULL
) {
1443 DEBUG(10, ("talloc failed\n"));
1447 state
->msg_ctx
= msg_ctx
;
1449 status
= addrchange_context_create(state
, &state
->ctx
);
1450 if (!NT_STATUS_IS_OK(status
)) {
1451 DEBUG(10, ("addrchange_context_create failed: %s\n",
1452 nt_errstr(status
)));
1456 req
= addrchange_send(state
, ev
, state
->ctx
);
1458 DEBUG(0, ("addrchange_send failed\n"));
1462 tevent_req_set_callback(req
, winbindd_addr_changed
, state
);
1465 static void winbindd_addr_changed(struct tevent_req
*req
)
1467 struct winbindd_addrchanged_state
*state
= tevent_req_callback_data(
1468 req
, struct winbindd_addrchanged_state
);
1469 enum addrchange_type type
;
1470 struct sockaddr_storage addr
;
1473 status
= addrchange_recv(req
, &type
, &addr
);
1475 if (!NT_STATUS_IS_OK(status
)) {
1476 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1477 nt_errstr(status
)));
1481 if (type
== ADDRCHANGE_DEL
) {
1482 char addrstr
[INET6_ADDRSTRLEN
];
1485 print_sockaddr(addrstr
, sizeof(addrstr
), &addr
);
1487 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1490 blob
= data_blob_const(addrstr
, strlen(addrstr
)+1);
1492 status
= messaging_send(state
->msg_ctx
,
1493 messaging_server_id(state
->msg_ctx
),
1494 MSG_WINBIND_IP_DROPPED
, &blob
);
1495 if (!NT_STATUS_IS_OK(status
)) {
1496 DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1497 nt_errstr(status
)));
1500 req
= addrchange_send(state
, state
->ev
, state
->ctx
);
1502 DEBUG(0, ("addrchange_send failed\n"));
1506 tevent_req_set_callback(req
, winbindd_addr_changed
, state
);
1511 int main(int argc
, const char **argv
)
1513 static bool is_daemon
= False
;
1514 static bool Fork
= True
;
1515 static bool log_stdout
= False
;
1516 static bool no_process_group
= False
;
1520 OPT_NO_PROCESS_GROUP
,
1523 struct poptOption long_options
[] = {
1525 { "stdout", 'S', POPT_ARG_NONE
, NULL
, OPT_LOG_STDOUT
, "Log to stdout" },
1526 { "foreground", 'F', POPT_ARG_NONE
, NULL
, OPT_FORK
, "Daemon in foreground mode" },
1527 { "no-process-group", 0, POPT_ARG_NONE
, NULL
, OPT_NO_PROCESS_GROUP
, "Don't create a new process group" },
1528 { "daemon", 'D', POPT_ARG_NONE
, NULL
, OPT_DAEMON
, "Become a daemon (default)" },
1529 { "interactive", 'i', POPT_ARG_NONE
, NULL
, 'i', "Interactive mode" },
1530 { "no-caching", 'n', POPT_ARG_NONE
, NULL
, 'n', "Disable caching" },
1541 * Do this before any other talloc operation
1543 talloc_enable_null_tracking();
1544 frame
= talloc_stackframe();
1547 * We want total control over the permissions on created files,
1548 * so set our umask to 0.
1552 setup_logging("winbindd", DEBUG_DEFAULT_STDOUT
);
1554 /* glibc (?) likes to print "User defined signal 1" and exit if a
1555 SIGUSR[12] is received before a handler is installed */
1557 CatchSignal(SIGUSR1
, SIG_IGN
);
1558 CatchSignal(SIGUSR2
, SIG_IGN
);
1561 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1565 /* Initialise for running in non-root mode */
1569 set_remote_machine_name("winbindd", False
);
1571 /* Set environment variable so we don't recursively call ourselves.
1572 This may also be useful interactively. */
1574 if ( !winbind_off() ) {
1575 DEBUG(0,("Failed to disable recusive winbindd calls. Exiting.\n"));
1579 /* Initialise samba/rpc client stuff */
1581 pc
= poptGetContext("winbindd", argc
, argv
, long_options
, 0);
1583 while ((opt
= poptGetNextOpt(pc
)) != -1) {
1585 /* Don't become a daemon */
1597 case OPT_NO_PROCESS_GROUP
:
1598 no_process_group
= true;
1600 case OPT_LOG_STDOUT
:
1607 d_fprintf(stderr
, "\nInvalid option %s: %s\n\n",
1608 poptBadOption(pc
, 0), poptStrerror(opt
));
1609 poptPrintUsage(pc
, stderr
, 0);
1614 /* We call dump_core_setup one more time because the command line can
1615 * set the log file or the log-basename and this will influence where
1616 * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1617 * the default value derived from build's prefix. For EOM this value
1618 * is often not related to the path where winbindd is actually run
1621 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1622 if (is_daemon
&& interactive
) {
1623 d_fprintf(stderr
,"\nERROR: "
1624 "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1625 poptPrintUsage(pc
, stderr
, 0);
1629 if (log_stdout
&& Fork
) {
1630 d_fprintf(stderr
, "\nERROR: "
1631 "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1632 poptPrintUsage(pc
, stderr
, 0);
1636 poptFreeContext(pc
);
1638 if (!override_logfile
) {
1640 if (asprintf(&lfile
,"%s/log.winbindd",
1641 get_dyn_LOGFILEBASE()) > 0) {
1642 lp_set_logfile(lfile
);
1648 setup_logging("winbindd", DEBUG_STDOUT
);
1650 setup_logging("winbindd", DEBUG_FILE
);
1654 DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1655 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE
));
1657 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1658 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1661 /* After parsing the configuration file we setup the core path one more time
1662 * as the log file might have been set in the configuration and cores's
1663 * path is by default basename(lp_logfile()).
1665 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1667 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1668 && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1669 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1670 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"));
1674 if (!cluster_probe_ok()) {
1678 /* Initialise messaging system */
1680 if (winbind_messaging_context() == NULL
) {
1684 if (!reload_services_file(NULL
)) {
1685 DEBUG(0, ("error opening config file\n"));
1689 ok
= directory_create_or_exist(lp_lock_directory(), 0755);
1691 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1692 lp_lock_directory(), strerror(errno
)));
1696 ok
= directory_create_or_exist(lp_pid_directory(), 0755);
1698 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1699 lp_pid_directory(), strerror(errno
)));
1710 if (!secrets_init()) {
1712 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1716 status
= rpccli_pre_open_netlogon_creds();
1717 if (!NT_STATUS_IS_OK(status
)) {
1718 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1719 nt_errstr(status
)));
1723 /* Unblock all signals we are interested in as they may have been
1724 blocked by the parent process. */
1726 BlockSignals(False
, SIGINT
);
1727 BlockSignals(False
, SIGQUIT
);
1728 BlockSignals(False
, SIGTERM
);
1729 BlockSignals(False
, SIGUSR1
);
1730 BlockSignals(False
, SIGUSR2
);
1731 BlockSignals(False
, SIGHUP
);
1732 BlockSignals(False
, SIGCHLD
);
1735 become_daemon(Fork
, no_process_group
, log_stdout
);
1737 pidfile_create(lp_pid_directory(), "winbindd");
1741 * If we're interactive we want to set our own process group for
1742 * signal management.
1744 if (interactive
&& !no_process_group
)
1745 setpgid( (pid_t
)0, (pid_t
)0);
1750 /* Don't use winbindd_reinit_after_fork here as
1751 * we're just starting up and haven't created any
1752 * winbindd-specific resources we must free yet. JRA.
1755 status
= reinit_after_fork(winbind_messaging_context(),
1756 winbind_event_context(),
1758 if (!NT_STATUS_IS_OK(status
)) {
1759 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status
));
1763 * Do not initialize the parent-child-pipe before becoming
1764 * a daemon: this is used to detect a died parent in the child
1767 status
= init_before_fork();
1768 if (!NT_STATUS_IS_OK(status
)) {
1769 exit_daemon(nt_errstr(status
), map_errno_from_nt_status(status
));
1772 winbindd_register_handlers(winbind_messaging_context(), !Fork
);
1774 if (!messaging_parent_dgm_cleanup_init(winbind_messaging_context())) {
1778 status
= init_system_session_info();
1779 if (!NT_STATUS_IS_OK(status
)) {
1780 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status
));
1783 rpc_lsarpc_init(NULL
);
1784 rpc_samr_init(NULL
);
1786 winbindd_init_addrchange(NULL
, winbind_event_context(),
1787 winbind_messaging_context());
1789 /* setup listen sockets */
1791 if (!winbindd_setup_listeners()) {
1792 exit_daemon("Winbindd failed to setup listeners", EPIPE
);
1795 irpc_add_name(winbind_imessaging_context(), "winbind_server");
1800 daemon_ready("winbindd");
1803 /* Loop waiting for requests */
1805 frame
= talloc_stackframe();
1807 if (tevent_loop_once(winbind_event_context()) == -1) {
1808 DEBUG(1, ("tevent_loop_once() failed: %s\n",