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"
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 #include "lib/util/tevent_req_profile.h"
51 #define DBGC_CLASS DBGC_WINBIND
53 #define SCRUB_CLIENTS_INTERVAL 5
55 static bool client_is_idle(struct winbindd_cli_state
*state
);
56 static void remove_client(struct winbindd_cli_state
*state
);
57 static void winbindd_setup_max_fds(void);
59 static bool opt_nocache
= False
;
60 static bool interactive
= False
;
62 extern bool override_logfile
;
64 struct imessaging_context
*winbind_imessaging_context(void)
66 static struct imessaging_context
*msg
= NULL
;
67 struct messaging_context
*msg_ctx
;
68 struct server_id myself
;
69 struct loadparm_context
*lp_ctx
;
75 msg_ctx
= server_messaging_context();
76 if (msg_ctx
== NULL
) {
77 smb_panic("server_messaging_context failed\n");
79 myself
= messaging_server_id(msg_ctx
);
81 lp_ctx
= loadparm_init_s3(NULL
, loadparm_s3_helpers());
83 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
87 * Note we MUST use the NULL context here, not the autofree context,
88 * to avoid side effects in forked children exiting.
90 msg
= imessaging_init(NULL
, lp_ctx
, myself
, server_event_context());
91 talloc_unlink(NULL
, lp_ctx
);
94 smb_panic("Could not init winbindd's messaging context.\n");
99 /* Reload configuration */
101 static bool reload_services_file(const char *lfile
)
106 char *fname
= lp_next_configfile(talloc_tos());
108 if (file_exist(fname
) && !strcsequal(fname
,get_dyn_CONFIGFILE())) {
109 set_dyn_CONFIGFILE(fname
);
114 /* if this is a child, restore the logfile to the special
115 name - <domain>, idmap, etc. */
116 if (lfile
&& *lfile
) {
117 lp_set_logfile(lfile
);
121 ret
= lp_load_global(get_dyn_CONFIGFILE());
125 winbindd_setup_max_fds();
131 static void winbindd_status(void)
133 struct winbindd_cli_state
*tmp
;
135 DEBUG(0, ("winbindd status:\n"));
137 /* Print client state information */
139 DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
141 if (DEBUGLEVEL
>= 2 && winbindd_num_clients()) {
142 DEBUG(2, ("\tclient list:\n"));
143 for(tmp
= winbindd_client_list(); tmp
; tmp
= tmp
->next
) {
144 DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
145 (unsigned long)tmp
->pid
, tmp
->sock
,
146 client_is_idle(tmp
) ? "idle" : "active"));
151 /* Flush client cache */
153 static void flush_caches(void)
155 /* We need to invalidate cached user list entries on a SIGHUP
156 otherwise cached access denied errors due to restrict anonymous
157 hang around until the sequence number changes. */
159 if (!wcache_invalidate_cache()) {
160 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
161 if (!winbindd_cache_validate_and_initialize()) {
167 static void flush_caches_noinit(void)
170 * We need to invalidate cached user list entries on a SIGHUP
171 * otherwise cached access denied errors due to restrict anonymous
172 * hang around until the sequence number changes.
174 * Skip uninitialized domains when flush cache.
175 * If domain is not initialized, it means it is never
176 * used or never become online. look, wcache_invalidate_cache()
177 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
178 * for unused domains and large traffic for primay domain's DC if there
182 if (!wcache_invalidate_cache_noinit()) {
183 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
184 if (!winbindd_cache_validate_and_initialize()) {
190 /* Handle the signal by unlinking socket and exiting */
192 static void terminate(bool is_parent
)
195 /* When parent goes away we should
196 * remove the socket file. Not so
197 * when children terminate.
201 if (asprintf(&path
, "%s/%s",
202 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME
) > 0) {
210 gencache_stabilize();
212 netlogon_creds_cli_close_global_db();
216 TALLOC_CTX
*mem_ctx
= talloc_init("end_description");
217 char *description
= talloc_describe_all(mem_ctx
);
219 DEBUG(3, ("tallocs left:\n%s\n", description
));
220 talloc_destroy(mem_ctx
);
225 pidfile_unlink(lp_pid_directory(), "winbindd");
231 static void winbindd_sig_term_handler(struct tevent_context
*ev
,
232 struct tevent_signal
*se
,
238 bool *p
= talloc_get_type_abort(private_data
, bool);
243 DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
245 terminate(is_parent
);
249 handle stdin becoming readable when we are in --foreground mode
251 static void winbindd_stdin_handler(struct tevent_context
*ev
,
252 struct tevent_fd
*fde
,
257 if (read(0, &c
, 1) != 1) {
258 bool *is_parent
= talloc_get_type_abort(private_data
, bool);
260 /* we have reached EOF on stdin, which means the
261 parent has exited. Shutdown the server */
262 DEBUG(0,("EOF on stdin (is_parent=%d)\n",
264 terminate(*is_parent
);
268 bool winbindd_setup_sig_term_handler(bool parent
)
270 struct tevent_signal
*se
;
273 is_parent
= talloc(server_event_context(), bool);
280 se
= tevent_add_signal(server_event_context(),
283 winbindd_sig_term_handler
,
286 DEBUG(0,("failed to setup SIGTERM handler"));
287 talloc_free(is_parent
);
291 se
= tevent_add_signal(server_event_context(),
294 winbindd_sig_term_handler
,
297 DEBUG(0,("failed to setup SIGINT handler"));
298 talloc_free(is_parent
);
302 se
= tevent_add_signal(server_event_context(),
305 winbindd_sig_term_handler
,
308 DEBUG(0,("failed to setup SIGINT handler"));
309 talloc_free(is_parent
);
316 bool winbindd_setup_stdin_handler(bool parent
, bool foreground
)
323 is_parent
= talloc(server_event_context(), bool);
330 /* if we are running in the foreground then look for
331 EOF on stdin, and exit if it happens. This allows
332 us to die if the parent process dies
333 Only do this on a pipe or socket, no other device.
335 if (fstat(0, &st
) != 0) {
338 if (S_ISFIFO(st
.st_mode
) || S_ISSOCK(st
.st_mode
)) {
339 tevent_add_fd(server_event_context(),
343 winbindd_stdin_handler
,
351 static void winbindd_sig_hup_handler(struct tevent_context
*ev
,
352 struct tevent_signal
*se
,
358 const char *file
= (const char *)private_data
;
360 DEBUG(1,("Reloading services after SIGHUP\n"));
361 flush_caches_noinit();
362 reload_services_file(file
);
365 bool winbindd_setup_sig_hup_handler(const char *lfile
)
367 struct tevent_signal
*se
;
371 file
= talloc_strdup(server_event_context(),
378 se
= tevent_add_signal(server_event_context(),
379 server_event_context(),
381 winbindd_sig_hup_handler
,
390 static void winbindd_sig_chld_handler(struct tevent_context
*ev
,
391 struct tevent_signal
*se
,
399 while ((pid
= waitpid(-1, NULL
, WNOHANG
)) > 0) {
400 winbind_child_died(pid
);
404 static bool winbindd_setup_sig_chld_handler(void)
406 struct tevent_signal
*se
;
408 se
= tevent_add_signal(server_event_context(),
409 server_event_context(),
411 winbindd_sig_chld_handler
,
420 static void winbindd_sig_usr2_handler(struct tevent_context
*ev
,
421 struct tevent_signal
*se
,
430 static bool winbindd_setup_sig_usr2_handler(void)
432 struct tevent_signal
*se
;
434 se
= tevent_add_signal(server_event_context(),
435 server_event_context(),
437 winbindd_sig_usr2_handler
,
446 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
447 static void msg_reload_services(struct messaging_context
*msg
,
450 struct server_id server_id
,
453 /* Flush various caches */
455 reload_services_file((const char *) private_data
);
458 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
459 static void msg_shutdown(struct messaging_context
*msg
,
462 struct server_id server_id
,
465 /* only the parent waits for this message */
466 DEBUG(0,("Got shutdown message\n"));
471 static void winbind_msg_validate_cache(struct messaging_context
*msg_ctx
,
474 struct server_id server_id
,
481 DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
485 * call the validation code from a child:
486 * so we don't block the main winbindd and the validation
487 * code can safely use fork/waitpid...
491 if (child_pid
== -1) {
492 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
497 if (child_pid
!= 0) {
499 DEBUG(5, ("winbind_msg_validate_cache: child created with "
500 "pid %d.\n", (int)child_pid
));
506 status
= winbindd_reinit_after_fork(NULL
, NULL
);
507 if (!NT_STATUS_IS_OK(status
)) {
508 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
513 /* install default SIGCHLD handler: validation code uses fork/waitpid */
514 CatchSignal(SIGCHLD
, SIG_DFL
);
516 setproctitle("validate cache child");
518 ret
= (uint8_t)winbindd_validate_cache_nobackup();
519 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret
));
520 messaging_send_buf(msg_ctx
, server_id
, MSG_WINBIND_VALIDATE_CACHE
, &ret
,
525 static struct winbindd_bool_dispatch_table
{
526 enum winbindd_cmd cmd
;
527 bool (*fn
)(struct winbindd_cli_state
*state
);
528 const char *cmd_name
;
529 } bool_dispatch_table
[] = {
530 { WINBINDD_INTERFACE_VERSION
,
531 winbindd_interface_version
,
532 "INTERFACE_VERSION" },
539 { WINBINDD_DOMAIN_NAME
,
540 winbindd_domain_name
,
542 { WINBINDD_NETBIOS_NAME
,
543 winbindd_netbios_name
,
548 { WINBINDD_CCACHE_NTLMAUTH
,
549 winbindd_ccache_ntlm_auth
,
551 { WINBINDD_CCACHE_SAVE
,
552 winbindd_ccache_save
,
554 { WINBINDD_PRIV_PIPE_DIR
,
555 winbindd_priv_pipe_dir
,
556 "WINBINDD_PRIV_PIPE_DIR" },
557 { WINBINDD_LIST_TRUSTDOM
,
558 winbindd_list_trusted_domains
,
562 struct winbindd_async_dispatch_table
{
563 enum winbindd_cmd cmd
;
564 const char *cmd_name
;
565 struct tevent_req
*(*send_req
)(TALLOC_CTX
*mem_ctx
,
566 struct tevent_context
*ev
,
567 struct winbindd_cli_state
*cli
,
568 struct winbindd_request
*request
);
569 NTSTATUS (*recv_req
)(struct tevent_req
*req
,
570 struct winbindd_response
*presp
);
573 static struct winbindd_async_dispatch_table async_nonpriv_table
[] = {
574 { WINBINDD_LOOKUPSID
, "LOOKUPSID",
575 winbindd_lookupsid_send
, winbindd_lookupsid_recv
},
576 { WINBINDD_LOOKUPSIDS
, "LOOKUPSIDS",
577 winbindd_lookupsids_send
, winbindd_lookupsids_recv
},
578 { WINBINDD_LOOKUPNAME
, "LOOKUPNAME",
579 winbindd_lookupname_send
, winbindd_lookupname_recv
},
580 { WINBINDD_SIDS_TO_XIDS
, "SIDS_TO_XIDS",
581 winbindd_sids_to_xids_send
, winbindd_sids_to_xids_recv
},
582 { WINBINDD_XIDS_TO_SIDS
, "XIDS_TO_SIDS",
583 winbindd_xids_to_sids_send
, winbindd_xids_to_sids_recv
},
584 { WINBINDD_GETPWSID
, "GETPWSID",
585 winbindd_getpwsid_send
, winbindd_getpwsid_recv
},
586 { WINBINDD_GETPWNAM
, "GETPWNAM",
587 winbindd_getpwnam_send
, winbindd_getpwnam_recv
},
588 { WINBINDD_GETPWUID
, "GETPWUID",
589 winbindd_getpwuid_send
, winbindd_getpwuid_recv
},
590 { WINBINDD_GETSIDALIASES
, "GETSIDALIASES",
591 winbindd_getsidaliases_send
, winbindd_getsidaliases_recv
},
592 { WINBINDD_GETUSERDOMGROUPS
, "GETUSERDOMGROUPS",
593 winbindd_getuserdomgroups_send
, winbindd_getuserdomgroups_recv
},
594 { WINBINDD_GETGROUPS
, "GETGROUPS",
595 winbindd_getgroups_send
, winbindd_getgroups_recv
},
596 { WINBINDD_SHOW_SEQUENCE
, "SHOW_SEQUENCE",
597 winbindd_show_sequence_send
, winbindd_show_sequence_recv
},
598 { WINBINDD_GETGRGID
, "GETGRGID",
599 winbindd_getgrgid_send
, winbindd_getgrgid_recv
},
600 { WINBINDD_GETGRNAM
, "GETGRNAM",
601 winbindd_getgrnam_send
, winbindd_getgrnam_recv
},
602 { WINBINDD_GETUSERSIDS
, "GETUSERSIDS",
603 winbindd_getusersids_send
, winbindd_getusersids_recv
},
604 { WINBINDD_LOOKUPRIDS
, "LOOKUPRIDS",
605 winbindd_lookuprids_send
, winbindd_lookuprids_recv
},
606 { WINBINDD_SETPWENT
, "SETPWENT",
607 winbindd_setpwent_send
, winbindd_setpwent_recv
},
608 { WINBINDD_GETPWENT
, "GETPWENT",
609 winbindd_getpwent_send
, winbindd_getpwent_recv
},
610 { WINBINDD_ENDPWENT
, "ENDPWENT",
611 winbindd_endpwent_send
, winbindd_endpwent_recv
},
612 { WINBINDD_DSGETDCNAME
, "DSGETDCNAME",
613 winbindd_dsgetdcname_send
, winbindd_dsgetdcname_recv
},
614 { WINBINDD_GETDCNAME
, "GETDCNAME",
615 winbindd_getdcname_send
, winbindd_getdcname_recv
},
616 { WINBINDD_SETGRENT
, "SETGRENT",
617 winbindd_setgrent_send
, winbindd_setgrent_recv
},
618 { WINBINDD_GETGRENT
, "GETGRENT",
619 winbindd_getgrent_send
, winbindd_getgrent_recv
},
620 { WINBINDD_ENDGRENT
, "ENDGRENT",
621 winbindd_endgrent_send
, winbindd_endgrent_recv
},
622 { WINBINDD_LIST_USERS
, "LIST_USERS",
623 winbindd_list_users_send
, winbindd_list_users_recv
},
624 { WINBINDD_LIST_GROUPS
, "LIST_GROUPS",
625 winbindd_list_groups_send
, winbindd_list_groups_recv
},
626 { WINBINDD_CHECK_MACHACC
, "CHECK_MACHACC",
627 winbindd_check_machine_acct_send
, winbindd_check_machine_acct_recv
},
628 { WINBINDD_PING_DC
, "PING_DC",
629 winbindd_ping_dc_send
, winbindd_ping_dc_recv
},
630 { WINBINDD_PAM_AUTH
, "PAM_AUTH",
631 winbindd_pam_auth_send
, winbindd_pam_auth_recv
},
632 { WINBINDD_PAM_LOGOFF
, "PAM_LOGOFF",
633 winbindd_pam_logoff_send
, winbindd_pam_logoff_recv
},
634 { WINBINDD_PAM_CHAUTHTOK
, "PAM_CHAUTHTOK",
635 winbindd_pam_chauthtok_send
, winbindd_pam_chauthtok_recv
},
636 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP
, "PAM_CHNG_PSWD_AUTH_CRAP",
637 winbindd_pam_chng_pswd_auth_crap_send
,
638 winbindd_pam_chng_pswd_auth_crap_recv
},
639 { WINBINDD_WINS_BYIP
, "WINS_BYIP",
640 winbindd_wins_byip_send
, winbindd_wins_byip_recv
},
641 { WINBINDD_WINS_BYNAME
, "WINS_BYNAME",
642 winbindd_wins_byname_send
, winbindd_wins_byname_recv
},
643 { WINBINDD_DOMAIN_INFO
, "DOMAIN_INFO",
644 winbindd_domain_info_send
, winbindd_domain_info_recv
},
646 { 0, NULL
, NULL
, NULL
}
649 static struct winbindd_async_dispatch_table async_priv_table
[] = {
650 { WINBINDD_ALLOCATE_UID
, "ALLOCATE_UID",
651 winbindd_allocate_uid_send
, winbindd_allocate_uid_recv
},
652 { WINBINDD_ALLOCATE_GID
, "ALLOCATE_GID",
653 winbindd_allocate_gid_send
, winbindd_allocate_gid_recv
},
654 { WINBINDD_CHANGE_MACHACC
, "CHANGE_MACHACC",
655 winbindd_change_machine_acct_send
, winbindd_change_machine_acct_recv
},
656 { WINBINDD_PAM_AUTH_CRAP
, "PAM_AUTH_CRAP",
657 winbindd_pam_auth_crap_send
, winbindd_pam_auth_crap_recv
},
659 { 0, NULL
, NULL
, NULL
}
662 struct process_request_state
{
663 struct winbindd_cli_state
*cli_state
;
664 struct tevent_context
*ev
;
667 static void process_request_done(struct tevent_req
*subreq
);
668 static void process_request_written(struct tevent_req
*subreq
);
670 static struct tevent_req
*process_request_send(
672 struct tevent_context
*ev
,
673 struct winbindd_cli_state
*cli_state
)
675 struct tevent_req
*req
, *subreq
;
676 struct process_request_state
*state
;
677 struct winbindd_async_dispatch_table
*atable
;
678 enum winbindd_cmd cmd
= cli_state
->request
->cmd
;
682 req
= tevent_req_create(mem_ctx
, &state
,
683 struct process_request_state
);
687 state
->cli_state
= cli_state
;
690 ok
= tevent_req_set_profile(req
);
692 return tevent_req_post(req
, ev
);
695 SMB_ASSERT(cli_state
->mem_ctx
== NULL
);
696 cli_state
->mem_ctx
= talloc_named(cli_state
, 0, "winbind request");
697 if (tevent_req_nomem(cli_state
->mem_ctx
, req
)) {
698 return tevent_req_post(req
, ev
);
701 cli_state
->response
= talloc_zero(
703 struct winbindd_response
);
704 if (tevent_req_nomem(cli_state
->response
, req
)) {
705 return tevent_req_post(req
, ev
);
707 cli_state
->response
->result
= WINBINDD_PENDING
;
708 cli_state
->response
->length
= sizeof(struct winbindd_response
);
710 /* Remember who asked us. */
711 cli_state
->pid
= cli_state
->request
->pid
;
713 cli_state
->cmd_name
= "unknown request";
714 cli_state
->recv_fn
= NULL
;
716 /* client is newest */
717 winbindd_promote_client(cli_state
);
719 for (atable
= async_nonpriv_table
; atable
->send_req
; atable
+= 1) {
720 if (cmd
== atable
->cmd
) {
725 if ((atable
->send_req
== NULL
) && cli_state
->privileged
) {
726 for (atable
= async_priv_table
; atable
->send_req
;
728 if (cmd
== atable
->cmd
) {
734 if (atable
->send_req
!= NULL
) {
735 cli_state
->cmd_name
= atable
->cmd_name
;
736 cli_state
->recv_fn
= atable
->recv_req
;
738 DEBUG(10, ("process_request: Handling async request %d:%s\n",
739 (int)cli_state
->pid
, cli_state
->cmd_name
));
741 subreq
= atable
->send_req(
746 if (tevent_req_nomem(subreq
, req
)) {
747 return tevent_req_post(req
, ev
);
749 tevent_req_set_callback(subreq
, process_request_done
, req
);
753 for (i
=0; i
<ARRAY_SIZE(bool_dispatch_table
); i
++) {
754 if (cmd
== bool_dispatch_table
[i
].cmd
) {
761 if (i
< ARRAY_SIZE(bool_dispatch_table
)) {
762 DBG_DEBUG("process_request: request fn %s\n",
763 bool_dispatch_table
[i
].cmd_name
);
764 ok
= bool_dispatch_table
[i
].fn(cli_state
);
767 cli_state
->response
->result
= ok
? WINBINDD_OK
: WINBINDD_ERROR
;
769 TALLOC_FREE(cli_state
->io_req
);
770 TALLOC_FREE(cli_state
->request
);
772 subreq
= wb_resp_write_send(
775 cli_state
->out_queue
,
777 cli_state
->response
);
778 if (tevent_req_nomem(subreq
, req
)) {
779 return tevent_req_post(req
, ev
);
781 tevent_req_set_callback(subreq
, process_request_written
, req
);
783 cli_state
->io_req
= subreq
;
788 static void process_request_done(struct tevent_req
*subreq
)
790 struct tevent_req
*req
= tevent_req_callback_data(
791 subreq
, struct tevent_req
);
792 struct process_request_state
*state
= tevent_req_data(
793 req
, struct process_request_state
);
794 struct winbindd_cli_state
*cli_state
= state
->cli_state
;
798 status
= cli_state
->recv_fn(subreq
, cli_state
->response
);
801 DBG_DEBUG("[%d:%s]: %s\n",
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("[%d:%s]: delivered response to client\n",
846 (int)cli_state
->pid
, cli_state
->cmd_name
);
848 TALLOC_FREE(cli_state
->mem_ctx
);
849 cli_state
->response
= NULL
;
850 cli_state
->cmd_name
= "no request";
851 cli_state
->recv_fn
= NULL
;
853 tevent_req_done(req
);
856 static NTSTATUS
process_request_recv(
857 struct tevent_req
*req
,
859 struct tevent_req_profile
**profile
)
863 if (tevent_req_is_nterror(req
, &status
)) {
864 tevent_req_received(req
);
868 *profile
= tevent_req_move_profile(req
, mem_ctx
);
869 tevent_req_received(req
);
874 * This is the main event loop of winbind requests. It goes through a
875 * state-machine of 3 read/write requests, 4 if you have extra data to send.
877 * An idle winbind client has a read request of 4 bytes outstanding,
878 * finalizing function is request_len_recv, checking the length. request_recv
879 * then processes the packet. The processing function then at some point has
880 * to call request_finished which schedules sending the response.
883 static void winbind_client_request_read(struct tevent_req
*req
);
884 static void winbind_client_activity(struct tevent_req
*req
);
885 static void winbind_client_processed(struct tevent_req
*req
);
887 /* Process a new connection by adding it to the client connection list */
889 static void new_connection(int listen_sock
, bool privileged
)
891 struct sockaddr_un sunaddr
;
892 struct winbindd_cli_state
*state
;
893 struct tevent_req
*req
;
897 /* Accept connection */
899 len
= sizeof(sunaddr
);
901 sock
= accept(listen_sock
, (struct sockaddr
*)(void *)&sunaddr
, &len
);
904 if (errno
!= EINTR
) {
905 DEBUG(0, ("Failed to accept socket - %s\n",
910 smb_set_close_on_exec(sock
);
912 DEBUG(6,("accepted socket %d\n", sock
));
914 /* Create new connection structure */
916 if ((state
= talloc_zero(NULL
, struct winbindd_cli_state
)) == NULL
) {
923 state
->out_queue
= tevent_queue_create(state
, "winbind client reply");
924 if (state
->out_queue
== NULL
) {
930 state
->privileged
= privileged
;
932 req
= wb_req_read_send(state
, server_event_context(), state
->sock
,
933 WINBINDD_MAX_EXTRA_DATA
);
939 tevent_req_set_callback(req
, winbind_client_request_read
, state
);
942 /* Add to connection list */
944 winbindd_add_client(state
);
947 static void winbind_client_request_read(struct tevent_req
*req
)
949 struct winbindd_cli_state
*state
= tevent_req_callback_data(
950 req
, struct winbindd_cli_state
);
954 state
->io_req
= NULL
;
956 ret
= wb_req_read_recv(req
, state
, &state
->request
, &err
);
960 DEBUG(6, ("closing socket %d, client exited\n",
963 DEBUG(2, ("Could not read client request from fd %d: "
964 "%s\n", state
->sock
, strerror(err
)));
968 remove_client(state
);
972 req
= wait_for_read_send(state
, server_event_context(), state
->sock
,
975 DEBUG(0, ("winbind_client_request_read[%d:%s]:"
976 " wait_for_read_send failed - removing client\n",
977 (int)state
->pid
, state
->cmd_name
));
978 remove_client(state
);
981 tevent_req_set_callback(req
, winbind_client_activity
, state
);
984 req
= process_request_send(state
, server_event_context(), state
);
986 DBG_ERR("process_request_send failed\n");
987 remove_client(state
);
990 tevent_req_set_callback(req
, winbind_client_processed
, state
);
993 static void winbind_client_activity(struct tevent_req
*req
)
995 struct winbindd_cli_state
*state
=
996 tevent_req_callback_data(req
, struct winbindd_cli_state
);
1000 has_data
= wait_for_read_recv(req
, &err
);
1003 DEBUG(0, ("winbind_client_activity[%d:%s]:"
1004 "unexpected data from client - removing client\n",
1005 (int)state
->pid
, state
->cmd_name
));
1008 DEBUG(6, ("winbind_client_activity[%d:%s]: "
1009 "client has closed connection - removing "
1011 (int)state
->pid
, state
->cmd_name
));
1013 DEBUG(2, ("winbind_client_activity[%d:%s]: "
1014 "client socket error (%s) - removing "
1016 (int)state
->pid
, state
->cmd_name
,
1021 remove_client(state
);
1024 static void winbind_client_processed(struct tevent_req
*req
)
1026 struct winbindd_cli_state
*cli_state
= tevent_req_callback_data(
1027 req
, struct winbindd_cli_state
);
1028 struct tevent_req_profile
*profile
= NULL
;
1029 struct timeval start
, stop
, diff
;
1033 status
= process_request_recv(req
, cli_state
, &profile
);
1035 if (!NT_STATUS_IS_OK(status
)) {
1036 DBG_DEBUG("process_request failed: %s\n", nt_errstr(status
));
1037 remove_client(cli_state
);
1041 tevent_req_profile_get_start(profile
, NULL
, &start
);
1042 tevent_req_profile_get_stop(profile
, NULL
, &stop
);
1043 diff
= tevent_timeval_until(&start
, &stop
);
1045 threshold
= lp_parm_int(-1, "winbind", "request profile threshold", 60);
1047 if (diff
.tv_sec
>= threshold
) {
1051 depth
= lp_parm_int(
1054 "request profile depth",
1057 DBG_ERR("request took %u.%.6u seconds\n",
1058 (unsigned)diff
.tv_sec
, (unsigned)diff
.tv_usec
);
1060 str
= tevent_req_profile_string(profile
, talloc_tos(), 0, depth
);
1062 /* No "\n", already contained in "str" */
1063 DEBUGADD(0, ("%s", str
));
1068 TALLOC_FREE(profile
);
1070 req
= wb_req_read_send(
1072 server_event_context(),
1074 WINBINDD_MAX_EXTRA_DATA
);
1076 remove_client(cli_state
);
1079 tevent_req_set_callback(req
, winbind_client_request_read
, cli_state
);
1080 cli_state
->io_req
= req
;
1083 /* Remove a client connection from client connection list */
1085 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) {
1116 /* tell client, we are closing ... */
1117 nwritten
= write(state
->sock
, &c
, sizeof(c
));
1118 if (nwritten
== -1) {
1119 DEBUG(2, ("final write to client failed: %s\n",
1129 TALLOC_FREE(state
->mem_ctx
);
1131 /* Remove from list and free */
1133 winbindd_remove_client(state
);
1137 /* Is a client idle? */
1139 static bool client_is_idle(struct winbindd_cli_state
*state
) {
1140 return (state
->request
== NULL
&&
1141 state
->response
== NULL
&&
1142 !state
->pwent_state
&& !state
->grent_state
);
1145 /* Shutdown client connection which has been idle for the longest time */
1147 static bool remove_idle_client(void)
1149 struct winbindd_cli_state
*state
, *remove_state
= NULL
;
1152 for (state
= winbindd_client_list(); state
; state
= state
->next
) {
1153 if (client_is_idle(state
)) {
1155 /* list is sorted by access time */
1156 remove_state
= state
;
1161 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1162 nidle
, remove_state
->sock
, (unsigned int)remove_state
->pid
));
1163 remove_client(remove_state
);
1171 * Terminate all clients whose requests have taken longer than
1172 * "winbind request timeout" seconds to process, or have been
1173 * idle for more than "winbind request timeout" seconds.
1176 static void remove_timed_out_clients(void)
1178 struct winbindd_cli_state
*state
, *prev
= NULL
;
1179 time_t curr_time
= time(NULL
);
1180 int timeout_val
= lp_winbind_request_timeout();
1182 for (state
= winbindd_client_list_tail(); state
; state
= prev
) {
1185 prev
= winbindd_client_list_prev(state
);
1186 expiry_time
= state
->last_access
+ timeout_val
;
1188 if (curr_time
<= expiry_time
) {
1189 /* list is sorted, previous clients in
1194 if (client_is_idle(state
)) {
1195 DEBUG(5,("Idle client timed out, "
1196 "shutting down sock %d, pid %u\n",
1198 (unsigned int)state
->pid
));
1200 DEBUG(5,("Client request timed out, "
1201 "shutting down sock %d, pid %u\n",
1203 (unsigned int)state
->pid
));
1206 remove_client(state
);
1210 static void winbindd_scrub_clients_handler(struct tevent_context
*ev
,
1211 struct tevent_timer
*te
,
1212 struct timeval current_time
,
1215 remove_timed_out_clients();
1216 if (tevent_add_timer(ev
, ev
,
1217 timeval_current_ofs(SCRUB_CLIENTS_INTERVAL
, 0),
1218 winbindd_scrub_clients_handler
, NULL
) == NULL
) {
1219 DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
1224 struct winbindd_listen_state
{
1229 static void winbindd_listen_fde_handler(struct tevent_context
*ev
,
1230 struct tevent_fd
*fde
,
1234 struct winbindd_listen_state
*s
= talloc_get_type_abort(private_data
,
1235 struct winbindd_listen_state
);
1237 while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1238 DEBUG(5,("winbindd: Exceeding %d client "
1239 "connections, removing idle "
1240 "connection.\n", lp_winbind_max_clients()));
1241 if (!remove_idle_client()) {
1242 DEBUG(0,("winbindd: Exceeding %d "
1243 "client connections, no idle "
1244 "connection found\n",
1245 lp_winbind_max_clients()));
1249 remove_timed_out_clients();
1250 new_connection(s
->fd
, s
->privileged
);
1254 * Winbindd socket accessor functions
1257 char *get_winbind_priv_pipe_dir(void)
1259 return state_path(WINBINDD_PRIV_SOCKET_SUBDIR
);
1262 static void winbindd_setup_max_fds(void)
1264 int num_fds
= MAX_OPEN_FUDGEFACTOR
;
1267 num_fds
+= lp_winbind_max_clients();
1268 /* Add some more to account for 2 sockets open
1269 when the client transitions from unprivileged
1270 to privileged socket
1272 num_fds
+= lp_winbind_max_clients() / 10;
1274 /* Add one socket per child process
1275 (yeah there are child processes other than the
1276 domain children but only domain children can vary
1279 num_fds
+= lp_winbind_max_domain_connections() *
1280 (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT
: 1);
1282 actual_fds
= set_maxfiles(num_fds
);
1284 if (actual_fds
< num_fds
) {
1285 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1286 "requested %d open files, %d are available.\n",
1287 num_fds
, actual_fds
));
1291 static bool winbindd_setup_listeners(void)
1293 struct winbindd_listen_state
*pub_state
= NULL
;
1294 struct winbindd_listen_state
*priv_state
= NULL
;
1295 struct tevent_fd
*fde
;
1299 pub_state
= talloc(server_event_context(),
1300 struct winbindd_listen_state
);
1305 pub_state
->privileged
= false;
1306 pub_state
->fd
= create_pipe_sock(
1307 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME
, 0755);
1308 if (pub_state
->fd
== -1) {
1311 rc
= listen(pub_state
->fd
, 5);
1316 fde
= tevent_add_fd(server_event_context(), pub_state
, pub_state
->fd
,
1317 TEVENT_FD_READ
, winbindd_listen_fde_handler
,
1320 close(pub_state
->fd
);
1323 tevent_fd_set_auto_close(fde
);
1325 priv_state
= talloc(server_event_context(),
1326 struct winbindd_listen_state
);
1331 socket_path
= get_winbind_priv_pipe_dir();
1332 if (socket_path
== NULL
) {
1336 priv_state
->privileged
= true;
1337 priv_state
->fd
= create_pipe_sock(
1338 socket_path
, WINBINDD_SOCKET_NAME
, 0750);
1339 TALLOC_FREE(socket_path
);
1340 if (priv_state
->fd
== -1) {
1343 rc
= listen(priv_state
->fd
, 5);
1348 fde
= tevent_add_fd(server_event_context(), priv_state
,
1349 priv_state
->fd
, TEVENT_FD_READ
,
1350 winbindd_listen_fde_handler
, priv_state
);
1352 close(priv_state
->fd
);
1355 tevent_fd_set_auto_close(fde
);
1357 winbindd_scrub_clients_handler(server_event_context(), NULL
,
1358 timeval_current(), NULL
);
1361 TALLOC_FREE(pub_state
);
1362 TALLOC_FREE(priv_state
);
1366 bool winbindd_use_idmap_cache(void)
1368 return !opt_nocache
;
1371 bool winbindd_use_cache(void)
1373 return !opt_nocache
;
1376 static void winbindd_register_handlers(struct messaging_context
*msg_ctx
,
1379 bool scan_trusts
= true;
1381 /* Setup signal handlers */
1383 if (!winbindd_setup_sig_term_handler(true))
1385 if (!winbindd_setup_stdin_handler(true, foreground
))
1387 if (!winbindd_setup_sig_hup_handler(NULL
))
1389 if (!winbindd_setup_sig_chld_handler())
1391 if (!winbindd_setup_sig_usr2_handler())
1394 CatchSignal(SIGPIPE
, SIG_IGN
); /* Ignore sigpipe */
1397 * Ensure all cache and idmap caches are consistent
1398 * and initialized before we startup.
1400 if (!winbindd_cache_validate_and_initialize()) {
1404 /* React on 'smbcontrol winbindd reload-config' in the same way
1405 as to SIGHUP signal */
1406 messaging_register(msg_ctx
, NULL
,
1407 MSG_SMB_CONF_UPDATED
, msg_reload_services
);
1408 messaging_register(msg_ctx
, NULL
,
1409 MSG_SHUTDOWN
, msg_shutdown
);
1411 /* Handle online/offline messages. */
1412 messaging_register(msg_ctx
, NULL
,
1413 MSG_WINBIND_OFFLINE
, winbind_msg_offline
);
1414 messaging_register(msg_ctx
, NULL
,
1415 MSG_WINBIND_ONLINE
, winbind_msg_online
);
1416 messaging_register(msg_ctx
, NULL
,
1417 MSG_WINBIND_ONLINESTATUS
, winbind_msg_onlinestatus
);
1419 /* Handle domain online/offline messages for domains */
1420 messaging_register(server_messaging_context(), NULL
,
1421 MSG_WINBIND_DOMAIN_OFFLINE
, winbind_msg_domain_offline
);
1422 messaging_register(server_messaging_context(), NULL
,
1423 MSG_WINBIND_DOMAIN_ONLINE
, winbind_msg_domain_online
);
1425 messaging_register(msg_ctx
, NULL
,
1426 MSG_WINBIND_VALIDATE_CACHE
,
1427 winbind_msg_validate_cache
);
1429 messaging_register(msg_ctx
, NULL
,
1430 MSG_WINBIND_DUMP_DOMAIN_LIST
,
1431 winbind_msg_dump_domain_list
);
1433 messaging_register(msg_ctx
, NULL
,
1434 MSG_WINBIND_IP_DROPPED
,
1435 winbind_msg_ip_dropped_parent
);
1437 /* Register handler for MSG_DEBUG. */
1438 messaging_register(msg_ctx
, NULL
,
1442 messaging_register(msg_ctx
, NULL
,
1443 MSG_WINBIND_DISCONNECT_DC
,
1444 winbind_disconnect_dc_parent
);
1446 netsamlogon_cache_init(); /* Non-critical */
1448 /* clear the cached list of trusted domains */
1452 if (!init_domain_list()) {
1453 DEBUG(0,("unable to initialize domain list\n"));
1458 init_locator_child();
1460 smb_nscd_flush_user_cache();
1461 smb_nscd_flush_group_cache();
1463 if (!lp_winbind_scan_trusted_domains()) {
1464 scan_trusts
= false;
1467 if (!lp_allow_trusted_domains()) {
1468 scan_trusts
= false;
1472 scan_trusts
= false;
1476 if (tevent_add_timer(server_event_context(), NULL
, timeval_zero(),
1477 rescan_trusted_domains
, NULL
) == NULL
) {
1478 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1483 status
= wb_irpc_register();
1485 if (!NT_STATUS_IS_OK(status
)) {
1486 DEBUG(0, ("Could not register IRPC handlers\n"));
1491 struct winbindd_addrchanged_state
{
1492 struct addrchange_context
*ctx
;
1493 struct tevent_context
*ev
;
1494 struct messaging_context
*msg_ctx
;
1497 static void winbindd_addr_changed(struct tevent_req
*req
);
1499 static void winbindd_init_addrchange(TALLOC_CTX
*mem_ctx
,
1500 struct tevent_context
*ev
,
1501 struct messaging_context
*msg_ctx
)
1503 struct winbindd_addrchanged_state
*state
;
1504 struct tevent_req
*req
;
1507 state
= talloc(mem_ctx
, struct winbindd_addrchanged_state
);
1508 if (state
== NULL
) {
1509 DEBUG(10, ("talloc failed\n"));
1513 state
->msg_ctx
= msg_ctx
;
1515 status
= addrchange_context_create(state
, &state
->ctx
);
1516 if (!NT_STATUS_IS_OK(status
)) {
1517 DEBUG(10, ("addrchange_context_create failed: %s\n",
1518 nt_errstr(status
)));
1522 req
= addrchange_send(state
, ev
, state
->ctx
);
1524 DEBUG(0, ("addrchange_send failed\n"));
1528 tevent_req_set_callback(req
, winbindd_addr_changed
, state
);
1531 static void winbindd_addr_changed(struct tevent_req
*req
)
1533 struct winbindd_addrchanged_state
*state
= tevent_req_callback_data(
1534 req
, struct winbindd_addrchanged_state
);
1535 enum addrchange_type type
;
1536 struct sockaddr_storage addr
;
1539 status
= addrchange_recv(req
, &type
, &addr
);
1541 if (!NT_STATUS_IS_OK(status
)) {
1542 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1543 nt_errstr(status
)));
1547 if (type
== ADDRCHANGE_DEL
) {
1548 char addrstr
[INET6_ADDRSTRLEN
];
1551 print_sockaddr(addrstr
, sizeof(addrstr
), &addr
);
1553 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1556 blob
= data_blob_const(addrstr
, strlen(addrstr
)+1);
1558 status
= messaging_send(state
->msg_ctx
,
1559 messaging_server_id(state
->msg_ctx
),
1560 MSG_WINBIND_IP_DROPPED
, &blob
);
1561 if (!NT_STATUS_IS_OK(status
)) {
1562 DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1563 nt_errstr(status
)));
1566 req
= addrchange_send(state
, state
->ev
, state
->ctx
);
1568 DEBUG(0, ("addrchange_send failed\n"));
1572 tevent_req_set_callback(req
, winbindd_addr_changed
, state
);
1577 int main(int argc
, const char **argv
)
1579 static bool is_daemon
= False
;
1580 static bool Fork
= True
;
1581 static bool log_stdout
= False
;
1582 static bool no_process_group
= False
;
1586 OPT_NO_PROCESS_GROUP
,
1589 struct poptOption long_options
[] = {
1591 { "stdout", 'S', POPT_ARG_NONE
, NULL
, OPT_LOG_STDOUT
, "Log to stdout" },
1592 { "foreground", 'F', POPT_ARG_NONE
, NULL
, OPT_FORK
, "Daemon in foreground mode" },
1593 { "no-process-group", 0, POPT_ARG_NONE
, NULL
, OPT_NO_PROCESS_GROUP
, "Don't create a new process group" },
1594 { "daemon", 'D', POPT_ARG_NONE
, NULL
, OPT_DAEMON
, "Become a daemon (default)" },
1595 { "interactive", 'i', POPT_ARG_NONE
, NULL
, 'i', "Interactive mode" },
1596 { "no-caching", 'n', POPT_ARG_NONE
, NULL
, 'n', "Disable caching" },
1606 setproctitle_init(argc
, discard_const(argv
), environ
);
1609 * Do this before any other talloc operation
1611 talloc_enable_null_tracking();
1612 frame
= talloc_stackframe();
1615 * We want total control over the permissions on created files,
1616 * so set our umask to 0.
1620 setup_logging("winbindd", DEBUG_DEFAULT_STDOUT
);
1622 /* glibc (?) likes to print "User defined signal 1" and exit if a
1623 SIGUSR[12] is received before a handler is installed */
1625 CatchSignal(SIGUSR1
, SIG_IGN
);
1626 CatchSignal(SIGUSR2
, SIG_IGN
);
1629 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1633 /* Initialise for running in non-root mode */
1637 set_remote_machine_name("winbindd", False
);
1639 /* Set environment variable so we don't recursively call ourselves.
1640 This may also be useful interactively. */
1642 if ( !winbind_off() ) {
1643 DEBUG(0,("Failed to disable recusive winbindd calls. Exiting.\n"));
1647 /* Initialise samba/rpc client stuff */
1649 pc
= poptGetContext("winbindd", argc
, argv
, long_options
, 0);
1651 while ((opt
= poptGetNextOpt(pc
)) != -1) {
1653 /* Don't become a daemon */
1665 case OPT_NO_PROCESS_GROUP
:
1666 no_process_group
= true;
1668 case OPT_LOG_STDOUT
:
1675 d_fprintf(stderr
, "\nInvalid option %s: %s\n\n",
1676 poptBadOption(pc
, 0), poptStrerror(opt
));
1677 poptPrintUsage(pc
, stderr
, 0);
1682 /* We call dump_core_setup one more time because the command line can
1683 * set the log file or the log-basename and this will influence where
1684 * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1685 * the default value derived from build's prefix. For EOM this value
1686 * is often not related to the path where winbindd is actually run
1689 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1690 if (is_daemon
&& interactive
) {
1691 d_fprintf(stderr
,"\nERROR: "
1692 "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1693 poptPrintUsage(pc
, stderr
, 0);
1697 if (log_stdout
&& Fork
) {
1698 d_fprintf(stderr
, "\nERROR: "
1699 "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1700 poptPrintUsage(pc
, stderr
, 0);
1704 poptFreeContext(pc
);
1706 if (!override_logfile
) {
1708 if (asprintf(&lfile
,"%s/log.winbindd",
1709 get_dyn_LOGFILEBASE()) > 0) {
1710 lp_set_logfile(lfile
);
1716 setup_logging("winbindd", DEBUG_STDOUT
);
1718 setup_logging("winbindd", DEBUG_FILE
);
1722 DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1723 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE
));
1725 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1726 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1729 /* After parsing the configuration file we setup the core path one more time
1730 * as the log file might have been set in the configuration and cores's
1731 * path is by default basename(lp_logfile()).
1733 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1735 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1736 && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1737 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1738 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"));
1742 if (!cluster_probe_ok()) {
1746 /* Initialise messaging system */
1748 if (server_messaging_context() == NULL
) {
1752 if (!reload_services_file(NULL
)) {
1753 DEBUG(0, ("error opening config file\n"));
1759 const char *idmap_backend
;
1760 const char *invalid_backends
[] = {
1761 "ad", "rfc2307", "rid",
1764 idmap_backend
= lp_idmap_default_backend();
1765 for (i
= 0; i
< ARRAY_SIZE(invalid_backends
); i
++) {
1766 ok
= strequal(idmap_backend
, invalid_backends
[i
]);
1768 DBG_ERR("FATAL: Invalid idmap backend %s "
1769 "configured as the default backend!\n",
1776 ok
= directory_create_or_exist(lp_lock_directory(), 0755);
1778 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1779 lp_lock_directory(), strerror(errno
)));
1783 ok
= directory_create_or_exist(lp_pid_directory(), 0755);
1785 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1786 lp_pid_directory(), strerror(errno
)));
1797 if (!secrets_init()) {
1799 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1803 status
= rpccli_pre_open_netlogon_creds();
1804 if (!NT_STATUS_IS_OK(status
)) {
1805 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1806 nt_errstr(status
)));
1810 /* Unblock all signals we are interested in as they may have been
1811 blocked by the parent process. */
1813 BlockSignals(False
, SIGINT
);
1814 BlockSignals(False
, SIGQUIT
);
1815 BlockSignals(False
, SIGTERM
);
1816 BlockSignals(False
, SIGUSR1
);
1817 BlockSignals(False
, SIGUSR2
);
1818 BlockSignals(False
, SIGHUP
);
1819 BlockSignals(False
, SIGCHLD
);
1822 become_daemon(Fork
, no_process_group
, log_stdout
);
1824 pidfile_create(lp_pid_directory(), "winbindd");
1828 * If we're interactive we want to set our own process group for
1829 * signal management.
1831 if (interactive
&& !no_process_group
)
1832 setpgid( (pid_t
)0, (pid_t
)0);
1837 /* Don't use winbindd_reinit_after_fork here as
1838 * we're just starting up and haven't created any
1839 * winbindd-specific resources we must free yet. JRA.
1842 status
= reinit_after_fork(server_messaging_context(),
1843 server_event_context(),
1845 if (!NT_STATUS_IS_OK(status
)) {
1846 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status
));
1849 ok
= initialize_password_db(true, server_event_context());
1851 exit_daemon("Failed to initialize passdb backend! "
1852 "Check the 'passdb backend' variable in your "
1853 "smb.conf file.", EINVAL
);
1857 * Do not initialize the parent-child-pipe before becoming
1858 * a daemon: this is used to detect a died parent in the child
1861 status
= init_before_fork();
1862 if (!NT_STATUS_IS_OK(status
)) {
1863 exit_daemon(nt_errstr(status
), map_errno_from_nt_status(status
));
1866 winbindd_register_handlers(server_messaging_context(), !Fork
);
1868 if (!messaging_parent_dgm_cleanup_init(server_messaging_context())) {
1872 status
= init_system_session_info(NULL
);
1873 if (!NT_STATUS_IS_OK(status
)) {
1874 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status
));
1877 rpc_lsarpc_init(NULL
);
1878 rpc_samr_init(NULL
);
1880 winbindd_init_addrchange(NULL
, server_event_context(),
1881 server_messaging_context());
1883 /* setup listen sockets */
1885 if (!winbindd_setup_listeners()) {
1886 exit_daemon("Winbindd failed to setup listeners", EPIPE
);
1889 irpc_add_name(winbind_imessaging_context(), "winbind_server");
1894 daemon_ready("winbindd");
1899 /* Loop waiting for requests */
1901 frame
= talloc_stackframe();
1903 if (tevent_loop_once(server_event_context()) == -1) {
1904 DEBUG(1, ("tevent_loop_once() failed: %s\n",