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 messaging_context *msg_ctx;
103 struct server_id myself;
104 struct loadparm_context *lp_ctx;
110 msg_ctx = server_messaging_context();
111 if (msg_ctx == NULL) {
112 smb_panic("server_messaging_context failed\n");
114 myself = messaging_server_id(msg_ctx);
116 lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
117 if (lp_ctx == NULL) {
118 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
122 * Note we MUST use the NULL context here, not the autofree context,
123 * to avoid side effects in forked children exiting.
125 msg = imessaging_init(NULL, lp_ctx, myself, winbind_event_context(),
127 talloc_unlink(NULL, lp_ctx);
130 smb_panic("Could not init winbindd's messaging context.\n");
135 /* Reload configuration */
137 static bool reload_services_file(const char *lfile)
142 char *fname = lp_next_configfile(talloc_tos());
144 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
145 set_dyn_CONFIGFILE(fname);
150 /* if this is a child, restore the logfile to the special
151 name - <domain>, idmap, etc. */
152 if (lfile && *lfile) {
153 lp_set_logfile(lfile);
157 ret = lp_load_global(get_dyn_CONFIGFILE());
161 winbindd_setup_max_fds();
167 static void winbindd_status(void)
169 struct winbindd_cli_state *tmp;
171 DEBUG(0, ("winbindd status:\n"));
173 /* Print client state information */
175 DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
177 if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
178 DEBUG(2, ("\tclient list:\n"));
179 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
180 DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
181 (unsigned long)tmp->pid, tmp->sock,
182 client_is_idle(tmp) ? "idle" : "active"));
187 /* Flush client cache */
189 static void flush_caches(void)
191 /* We need to invalidate cached user list entries on a SIGHUP
192 otherwise cached access denied errors due to restrict anonymous
193 hang around until the sequence number changes. */
195 if (!wcache_invalidate_cache()) {
196 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
197 if (!winbindd_cache_validate_and_initialize()) {
203 static void flush_caches_noinit(void)
206 * We need to invalidate cached user list entries on a SIGHUP
207 * otherwise cached access denied errors due to restrict anonymous
208 * hang around until the sequence number changes.
210 * Skip uninitialized domains when flush cache.
211 * If domain is not initialized, it means it is never
212 * used or never become online. look, wcache_invalidate_cache()
213 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
214 * for unused domains and large traffic for primay domain's DC if there
218 if (!wcache_invalidate_cache_noinit()) {
219 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
220 if (!winbindd_cache_validate_and_initialize()) {
226 /* Handle the signal by unlinking socket and exiting */
228 static void terminate(bool is_parent)
231 /* When parent goes away we should
232 * remove the socket file. Not so
233 * when children terminate.
237 if (asprintf(&path, "%s/%s",
238 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) {
246 trustdom_cache_shutdown();
248 gencache_stabilize();
252 TALLOC_CTX *mem_ctx = talloc_init("end_description");
253 char *description = talloc_describe_all(mem_ctx);
255 DEBUG(3, ("tallocs left:\n%s\n", description));
256 talloc_destroy(mem_ctx);
261 struct messaging_context *msg = winbind_messaging_context();
262 struct server_id self = messaging_server_id(msg);
263 serverid_deregister(self);
264 pidfile_unlink(lp_pid_directory(), "winbindd");
270 static void winbindd_sig_term_handler(struct tevent_context *ev,
271 struct tevent_signal *se,
277 bool *is_parent = talloc_get_type_abort(private_data, bool);
279 DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
280 signum, (int)*is_parent));
281 terminate(*is_parent);
285 handle stdin becoming readable when we are in --foreground mode
287 static void winbindd_stdin_handler(struct tevent_context *ev,
288 struct tevent_fd *fde,
293 if (read(0, &c, 1) != 1) {
294 bool *is_parent = talloc_get_type_abort(private_data, bool);
296 /* we have reached EOF on stdin, which means the
297 parent has exited. Shutdown the server */
298 DEBUG(0,("EOF on stdin (is_parent=%d)\n",
300 terminate(*is_parent);
304 bool winbindd_setup_sig_term_handler(bool parent)
306 struct tevent_signal *se;
309 is_parent = talloc(winbind_event_context(), bool);
316 se = tevent_add_signal(winbind_event_context(),
319 winbindd_sig_term_handler,
322 DEBUG(0,("failed to setup SIGTERM handler"));
323 talloc_free(is_parent);
327 se = tevent_add_signal(winbind_event_context(),
330 winbindd_sig_term_handler,
333 DEBUG(0,("failed to setup SIGINT handler"));
334 talloc_free(is_parent);
338 se = tevent_add_signal(winbind_event_context(),
341 winbindd_sig_term_handler,
344 DEBUG(0,("failed to setup SIGINT handler"));
345 talloc_free(is_parent);
352 bool winbindd_setup_stdin_handler(bool parent, bool foreground)
359 is_parent = talloc(winbind_event_context(), bool);
366 /* if we are running in the foreground then look for
367 EOF on stdin, and exit if it happens. This allows
368 us to die if the parent process dies
369 Only do this on a pipe or socket, no other device.
371 if (fstat(0, &st) != 0) {
374 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
375 tevent_add_fd(winbind_event_context(),
379 winbindd_stdin_handler,
387 static void winbindd_sig_hup_handler(struct tevent_context *ev,
388 struct tevent_signal *se,
394 const char *file = (const char *)private_data;
396 DEBUG(1,("Reloading services after SIGHUP\n"));
397 flush_caches_noinit();
398 reload_services_file(file);
401 bool winbindd_setup_sig_hup_handler(const char *lfile)
403 struct tevent_signal *se;
407 file = talloc_strdup(winbind_event_context(),
414 se = tevent_add_signal(winbind_event_context(),
415 winbind_event_context(),
417 winbindd_sig_hup_handler,
426 static void winbindd_sig_chld_handler(struct tevent_context *ev,
427 struct tevent_signal *se,
435 while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) {
436 winbind_child_died(pid);
440 static bool winbindd_setup_sig_chld_handler(void)
442 struct tevent_signal *se;
444 se = tevent_add_signal(winbind_event_context(),
445 winbind_event_context(),
447 winbindd_sig_chld_handler,
456 static void winbindd_sig_usr2_handler(struct tevent_context *ev,
457 struct tevent_signal *se,
466 static bool winbindd_setup_sig_usr2_handler(void)
468 struct tevent_signal *se;
470 se = tevent_add_signal(winbind_event_context(),
471 winbind_event_context(),
473 winbindd_sig_usr2_handler,
482 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
483 static void msg_reload_services(struct messaging_context *msg,
486 struct server_id server_id,
489 /* Flush various caches */
491 reload_services_file((const char *) private_data);
494 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
495 static void msg_shutdown(struct messaging_context *msg,
498 struct server_id server_id,
501 /* only the parent waits for this message */
502 DEBUG(0,("Got shutdown message\n"));
507 static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
510 struct server_id server_id,
517 DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
521 * call the validation code from a child:
522 * so we don't block the main winbindd and the validation
523 * code can safely use fork/waitpid...
527 if (child_pid == -1) {
528 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
533 if (child_pid != 0) {
535 DEBUG(5, ("winbind_msg_validate_cache: child created with "
536 "pid %d.\n", (int)child_pid));
542 status = winbindd_reinit_after_fork(NULL, NULL);
543 if (!NT_STATUS_IS_OK(status)) {
544 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
549 /* install default SIGCHLD handler: validation code uses fork/waitpid */
550 CatchSignal(SIGCHLD, SIG_DFL);
552 ret = (uint8_t)winbindd_validate_cache_nobackup();
553 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
554 messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
559 static struct winbindd_dispatch_table {
560 enum winbindd_cmd cmd;
561 void (*fn)(struct winbindd_cli_state *state);
562 const char *winbindd_cmd_name;
563 } dispatch_table[] = {
565 /* Enumeration functions */
567 { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
572 { WINBINDD_INFO, winbindd_info, "INFO" },
573 { WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
574 "INTERFACE_VERSION" },
575 { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
576 { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
577 { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" },
578 { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
579 { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
580 "WINBINDD_PRIV_PIPE_DIR" },
582 /* Credential cache access */
583 { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
584 { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
588 { WINBINDD_NUM_CMDS, NULL, "NONE" }
591 struct winbindd_async_dispatch_table {
592 enum winbindd_cmd cmd;
593 const char *cmd_name;
594 struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
595 struct tevent_context *ev,
596 struct winbindd_cli_state *cli,
597 struct winbindd_request *request);
598 NTSTATUS (*recv_req)(struct tevent_req *req,
599 struct winbindd_response *presp);
602 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
603 { WINBINDD_PING, "PING",
604 wb_ping_send, wb_ping_recv },
605 { WINBINDD_LOOKUPSID, "LOOKUPSID",
606 winbindd_lookupsid_send, winbindd_lookupsid_recv },
607 { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
608 winbindd_lookupsids_send, winbindd_lookupsids_recv },
609 { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
610 winbindd_lookupname_send, winbindd_lookupname_recv },
611 { WINBINDD_UID_TO_SID, "UID_TO_SID",
612 winbindd_uid_to_sid_send, winbindd_uid_to_sid_recv },
613 { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
614 winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
615 { WINBINDD_XIDS_TO_SIDS, "XIDS_TO_SIDS",
616 winbindd_xids_to_sids_send, winbindd_xids_to_sids_recv },
617 { WINBINDD_GETPWSID, "GETPWSID",
618 winbindd_getpwsid_send, winbindd_getpwsid_recv },
619 { WINBINDD_GETPWNAM, "GETPWNAM",
620 winbindd_getpwnam_send, winbindd_getpwnam_recv },
621 { WINBINDD_GETPWUID, "GETPWUID",
622 winbindd_getpwuid_send, winbindd_getpwuid_recv },
623 { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
624 winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
625 { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
626 winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
627 { WINBINDD_GETGROUPS, "GETGROUPS",
628 winbindd_getgroups_send, winbindd_getgroups_recv },
629 { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
630 winbindd_show_sequence_send, winbindd_show_sequence_recv },
631 { WINBINDD_GETGRGID, "GETGRGID",
632 winbindd_getgrgid_send, winbindd_getgrgid_recv },
633 { WINBINDD_GETGRNAM, "GETGRNAM",
634 winbindd_getgrnam_send, winbindd_getgrnam_recv },
635 { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
636 winbindd_getusersids_send, winbindd_getusersids_recv },
637 { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
638 winbindd_lookuprids_send, winbindd_lookuprids_recv },
639 { WINBINDD_SETPWENT, "SETPWENT",
640 winbindd_setpwent_send, winbindd_setpwent_recv },
641 { WINBINDD_GETPWENT, "GETPWENT",
642 winbindd_getpwent_send, winbindd_getpwent_recv },
643 { WINBINDD_ENDPWENT, "ENDPWENT",
644 winbindd_endpwent_send, winbindd_endpwent_recv },
645 { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
646 winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
647 { WINBINDD_GETDCNAME, "GETDCNAME",
648 winbindd_getdcname_send, winbindd_getdcname_recv },
649 { WINBINDD_SETGRENT, "SETGRENT",
650 winbindd_setgrent_send, winbindd_setgrent_recv },
651 { WINBINDD_GETGRENT, "GETGRENT",
652 winbindd_getgrent_send, winbindd_getgrent_recv },
653 { WINBINDD_ENDGRENT, "ENDGRENT",
654 winbindd_endgrent_send, winbindd_endgrent_recv },
655 { WINBINDD_LIST_USERS, "LIST_USERS",
656 winbindd_list_users_send, winbindd_list_users_recv },
657 { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
658 winbindd_list_groups_send, winbindd_list_groups_recv },
659 { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
660 winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
661 { WINBINDD_PING_DC, "PING_DC",
662 winbindd_ping_dc_send, winbindd_ping_dc_recv },
663 { WINBINDD_PAM_AUTH, "PAM_AUTH",
664 winbindd_pam_auth_send, winbindd_pam_auth_recv },
665 { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
666 winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
667 { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
668 winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
669 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
670 winbindd_pam_chng_pswd_auth_crap_send,
671 winbindd_pam_chng_pswd_auth_crap_recv },
672 { WINBINDD_WINS_BYIP, "WINS_BYIP",
673 winbindd_wins_byip_send, winbindd_wins_byip_recv },
674 { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
675 winbindd_wins_byname_send, winbindd_wins_byname_recv },
677 { 0, NULL, NULL, NULL }
680 static struct winbindd_async_dispatch_table async_priv_table[] = {
681 { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
682 winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
683 { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
684 winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
685 { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
686 winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
687 { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
688 winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
690 { 0, NULL, NULL, NULL }
693 static void wb_request_done(struct tevent_req *req);
695 static void process_request(struct winbindd_cli_state *state)
697 struct winbindd_dispatch_table *table = dispatch_table;
698 struct winbindd_async_dispatch_table *atable;
700 state->mem_ctx = talloc_named(state, 0, "winbind request");
701 if (state->mem_ctx == NULL)
704 /* Remember who asked us. */
705 state->pid = state->request->pid;
707 state->cmd_name = "unknown request";
708 state->recv_fn = NULL;
709 /* client is newest */
710 winbindd_promote_client(state);
712 /* Process command */
714 for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
715 if (state->request->cmd == atable->cmd) {
720 if ((atable->send_req == NULL) && state->privileged) {
721 for (atable = async_priv_table; atable->send_req;
723 if (state->request->cmd == atable->cmd) {
729 if (atable->send_req != NULL) {
730 struct tevent_req *req;
732 state->cmd_name = atable->cmd_name;
733 state->recv_fn = atable->recv_req;
735 DEBUG(10, ("process_request: Handling async request %d:%s\n",
736 (int)state->pid, state->cmd_name));
738 req = atable->send_req(state->mem_ctx, winbind_event_context(),
739 state, state->request);
741 DEBUG(0, ("process_request: atable->send failed for "
742 "%s\n", atable->cmd_name));
743 request_error(state);
746 tevent_req_set_callback(req, wb_request_done, state);
750 state->response = talloc_zero(state->mem_ctx,
751 struct winbindd_response);
752 if (state->response == NULL) {
753 DEBUG(10, ("talloc failed\n"));
754 remove_client(state);
757 state->response->result = WINBINDD_PENDING;
758 state->response->length = sizeof(struct winbindd_response);
760 for (table = dispatch_table; table->fn; table++) {
761 if (state->request->cmd == table->cmd) {
762 DEBUG(10,("process_request: request fn %s\n",
763 table->winbindd_cmd_name ));
764 state->cmd_name = table->winbindd_cmd_name;
771 DEBUG(10,("process_request: unknown request fn number %d\n",
772 (int)state->request->cmd ));
773 request_error(state);
777 static void wb_request_done(struct tevent_req *req)
779 struct winbindd_cli_state *state = tevent_req_callback_data(
780 req, struct winbindd_cli_state);
783 state->response = talloc_zero(state->mem_ctx,
784 struct winbindd_response);
785 if (state->response == NULL) {
786 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
787 (int)state->pid, state->cmd_name));
788 remove_client(state);
791 state->response->result = WINBINDD_PENDING;
792 state->response->length = sizeof(struct winbindd_response);
794 status = state->recv_fn(req, state->response);
797 DEBUG(10,("wb_request_done[%d:%s]: %s\n",
798 (int)state->pid, state->cmd_name, nt_errstr(status)));
800 if (!NT_STATUS_IS_OK(status)) {
801 request_error(state);
808 * This is the main event loop of winbind requests. It goes through a
809 * state-machine of 3 read/write requests, 4 if you have extra data to send.
811 * An idle winbind client has a read request of 4 bytes outstanding,
812 * finalizing function is request_len_recv, checking the length. request_recv
813 * then processes the packet. The processing function then at some point has
814 * to call request_finished which schedules sending the response.
817 static void request_finished(struct winbindd_cli_state *state);
819 static void winbind_client_request_read(struct tevent_req *req);
820 static void winbind_client_response_written(struct tevent_req *req);
821 static void winbind_client_activity(struct tevent_req *req);
823 static void request_finished(struct winbindd_cli_state *state)
825 struct tevent_req *req;
827 /* free client socket monitoring request */
828 TALLOC_FREE(state->io_req);
830 TALLOC_FREE(state->request);
832 req = wb_resp_write_send(state, winbind_event_context(),
833 state->out_queue, state->sock,
836 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
837 (int)state->pid, state->cmd_name));
838 remove_client(state);
841 tevent_req_set_callback(req, winbind_client_response_written, state);
845 static void winbind_client_response_written(struct tevent_req *req)
847 struct winbindd_cli_state *state = tevent_req_callback_data(
848 req, struct winbindd_cli_state);
852 state->io_req = NULL;
854 ret = wb_resp_write_recv(req, &err);
859 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
860 (int)state->pid, state->cmd_name, strerror(err)));
861 remove_client(state);
865 DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
866 "to client\n", (int)state->pid, state->cmd_name));
868 TALLOC_FREE(state->mem_ctx);
869 state->response = NULL;
870 state->cmd_name = "no request";
871 state->recv_fn = NULL;
873 req = wb_req_read_send(state, winbind_event_context(), state->sock,
874 WINBINDD_MAX_EXTRA_DATA);
876 remove_client(state);
879 tevent_req_set_callback(req, winbind_client_request_read, state);
883 void request_error(struct winbindd_cli_state *state)
885 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
886 state->response->result = WINBINDD_ERROR;
887 request_finished(state);
890 void request_ok(struct winbindd_cli_state *state)
892 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
893 state->response->result = WINBINDD_OK;
894 request_finished(state);
897 /* Process a new connection by adding it to the client connection list */
899 static void new_connection(int listen_sock, bool privileged)
901 struct sockaddr_un sunaddr;
902 struct winbindd_cli_state *state;
903 struct tevent_req *req;
907 /* Accept connection */
909 len = sizeof(sunaddr);
911 sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
914 if (errno != EINTR) {
915 DEBUG(0, ("Failed to accept socket - %s\n",
921 DEBUG(6,("accepted socket %d\n", sock));
923 /* Create new connection structure */
925 if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
932 state->out_queue = tevent_queue_create(state, "winbind client reply");
933 if (state->out_queue == NULL) {
939 state->privileged = privileged;
941 req = wb_req_read_send(state, winbind_event_context(), state->sock,
942 WINBINDD_MAX_EXTRA_DATA);
948 tevent_req_set_callback(req, winbind_client_request_read, state);
951 /* Add to connection list */
953 winbindd_add_client(state);
956 static void winbind_client_request_read(struct tevent_req *req)
958 struct winbindd_cli_state *state = tevent_req_callback_data(
959 req, struct winbindd_cli_state);
963 state->io_req = NULL;
965 ret = wb_req_read_recv(req, state, &state->request, &err);
969 DEBUG(6, ("closing socket %d, client exited\n",
972 DEBUG(2, ("Could not read client request from fd %d: "
973 "%s\n", state->sock, strerror(err)));
977 remove_client(state);
981 req = wait_for_read_send(state, winbind_event_context(), state->sock,
984 DEBUG(0, ("winbind_client_request_read[%d:%s]:"
985 " wait_for_read_send failed - removing client\n",
986 (int)state->pid, state->cmd_name));
987 remove_client(state);
990 tevent_req_set_callback(req, winbind_client_activity, state);
993 process_request(state);
996 static void winbind_client_activity(struct tevent_req *req)
998 struct winbindd_cli_state *state =
999 tevent_req_callback_data(req, struct winbindd_cli_state);
1003 has_data = wait_for_read_recv(req, &err);
1006 DEBUG(0, ("winbind_client_activity[%d:%s]:"
1007 "unexpected data from client - removing client\n",
1008 (int)state->pid, state->cmd_name));
1011 DEBUG(6, ("winbind_client_activity[%d:%s]: "
1012 "client has closed connection - removing "
1014 (int)state->pid, state->cmd_name));
1016 DEBUG(2, ("winbind_client_activity[%d:%s]: "
1017 "client socket error (%s) - removing "
1019 (int)state->pid, state->cmd_name,
1024 remove_client(state);
1027 /* Remove a client connection from client connection list */
1029 static void remove_client(struct winbindd_cli_state *state)
1034 /* It's a dead client - hold a funeral */
1036 if (state == NULL) {
1041 * We need to remove a pending wb_req_read_*
1042 * or wb_resp_write_* request before closing the
1045 * This is important as they might have used tevent_add_fd() and we
1046 * use the epoll * backend on linux. So we must remove the tevent_fd
1047 * before closing the fd.
1049 * Otherwise we might hit a race with close_conns_after_fork() (via
1050 * winbindd_reinit_after_fork()) where a file description
1051 * is still open in a child, which means it's still active in
1052 * the parents epoll queue, but the related tevent_fd is already
1053 * already gone in the parent.
1057 TALLOC_FREE(state->io_req);
1059 if (state->sock != -1) {
1060 /* tell client, we are closing ... */
1061 nwritten = write(state->sock, &c, sizeof(c));
1062 if (nwritten == -1) {
1063 DEBUG(2, ("final write to client failed: %s\n",
1073 TALLOC_FREE(state->mem_ctx);
1075 /* Remove from list and free */
1077 winbindd_remove_client(state);
1081 /* Is a client idle? */
1083 static bool client_is_idle(struct winbindd_cli_state *state) {
1084 return (state->request == NULL &&
1085 state->response == NULL &&
1086 !state->pwent_state && !state->grent_state);
1089 /* Shutdown client connection which has been idle for the longest time */
1091 static bool remove_idle_client(void)
1093 struct winbindd_cli_state *state, *remove_state = NULL;
1096 for (state = winbindd_client_list(); state; state = state->next) {
1097 if (client_is_idle(state)) {
1099 /* list is sorted by access time */
1100 remove_state = state;
1105 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1106 nidle, remove_state->sock, (unsigned int)remove_state->pid));
1107 remove_client(remove_state);
1115 * Terminate all clients whose requests have taken longer than
1116 * "winbind request timeout" seconds to process, or have been
1117 * idle for more than "winbind request timeout" seconds.
1120 static void remove_timed_out_clients(void)
1122 struct winbindd_cli_state *state, *prev = NULL;
1123 time_t curr_time = time(NULL);
1124 int timeout_val = lp_winbind_request_timeout();
1126 for (state = winbindd_client_list_tail(); state; state = prev) {
1129 prev = winbindd_client_list_prev(state);
1130 expiry_time = state->last_access + timeout_val;
1132 if (curr_time > expiry_time) {
1133 if (client_is_idle(state)) {
1134 DEBUG(5,("Idle client timed out, "
1135 "shutting down sock %d, pid %u\n",
1137 (unsigned int)state->pid));
1139 DEBUG(5,("Client request timed out, "
1140 "shutting down sock %d, pid %u\n",
1142 (unsigned int)state->pid));
1144 remove_client(state);
1146 /* list is sorted, previous clients in
1153 static void winbindd_scrub_clients_handler(struct tevent_context *ev,
1154 struct tevent_timer *te,
1155 struct timeval current_time,
1158 remove_timed_out_clients();
1159 if (tevent_add_timer(ev, ev,
1160 timeval_current_ofs(SCRUB_CLIENTS_INTERVAL, 0),
1161 winbindd_scrub_clients_handler, NULL) == NULL) {
1162 DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
1167 struct winbindd_listen_state {
1172 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1173 struct tevent_fd *fde,
1177 struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1178 struct winbindd_listen_state);
1180 while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1181 DEBUG(5,("winbindd: Exceeding %d client "
1182 "connections, removing idle "
1183 "connection.\n", lp_winbind_max_clients()));
1184 if (!remove_idle_client()) {
1185 DEBUG(0,("winbindd: Exceeding %d "
1186 "client connections, no idle "
1187 "connection found\n",
1188 lp_winbind_max_clients()));
1192 remove_timed_out_clients();
1193 new_connection(s->fd, s->privileged);
1197 * Winbindd socket accessor functions
1200 char *get_winbind_priv_pipe_dir(void)
1202 return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1205 static void winbindd_setup_max_fds(void)
1207 int num_fds = MAX_OPEN_FUDGEFACTOR;
1210 num_fds += lp_winbind_max_clients();
1211 /* Add some more to account for 2 sockets open
1212 when the client transitions from unprivileged
1213 to privileged socket
1215 num_fds += lp_winbind_max_clients() / 10;
1217 /* Add one socket per child process
1218 (yeah there are child processes other than the
1219 domain children but only domain children can vary
1222 num_fds += lp_winbind_max_domain_connections() *
1223 (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
1225 actual_fds = set_maxfiles(num_fds);
1227 if (actual_fds < num_fds) {
1228 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1229 "requested %d open files, %d are available.\n",
1230 num_fds, actual_fds));
1234 static bool winbindd_setup_listeners(void)
1236 struct winbindd_listen_state *pub_state = NULL;
1237 struct winbindd_listen_state *priv_state = NULL;
1238 struct tevent_fd *fde;
1242 pub_state = talloc(winbind_event_context(),
1243 struct winbindd_listen_state);
1248 pub_state->privileged = false;
1249 pub_state->fd = create_pipe_sock(
1250 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1251 if (pub_state->fd == -1) {
1254 rc = listen(pub_state->fd, 5);
1259 fde = tevent_add_fd(winbind_event_context(), pub_state, pub_state->fd,
1260 TEVENT_FD_READ, winbindd_listen_fde_handler,
1263 close(pub_state->fd);
1266 tevent_fd_set_auto_close(fde);
1268 priv_state = talloc(winbind_event_context(),
1269 struct winbindd_listen_state);
1274 socket_path = get_winbind_priv_pipe_dir();
1275 if (socket_path == NULL) {
1279 priv_state->privileged = true;
1280 priv_state->fd = create_pipe_sock(
1281 socket_path, WINBINDD_SOCKET_NAME, 0750);
1282 TALLOC_FREE(socket_path);
1283 if (priv_state->fd == -1) {
1286 rc = listen(priv_state->fd, 5);
1291 fde = tevent_add_fd(winbind_event_context(), priv_state,
1292 priv_state->fd, TEVENT_FD_READ,
1293 winbindd_listen_fde_handler, priv_state);
1295 close(priv_state->fd);
1298 tevent_fd_set_auto_close(fde);
1300 winbindd_scrub_clients_handler(winbind_event_context(), NULL,
1301 timeval_current(), NULL);
1304 TALLOC_FREE(pub_state);
1305 TALLOC_FREE(priv_state);
1309 bool winbindd_use_idmap_cache(void)
1311 return !opt_nocache;
1314 bool winbindd_use_cache(void)
1316 return !opt_nocache;
1319 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1323 /* Setup signal handlers */
1325 if (!winbindd_setup_sig_term_handler(true))
1327 if (!winbindd_setup_stdin_handler(true, foreground))
1329 if (!winbindd_setup_sig_hup_handler(NULL))
1331 if (!winbindd_setup_sig_chld_handler())
1333 if (!winbindd_setup_sig_usr2_handler())
1336 CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
1339 * Ensure all cache and idmap caches are consistent
1340 * and initialized before we startup.
1342 if (!winbindd_cache_validate_and_initialize()) {
1346 /* get broadcast messages */
1348 if (!serverid_register(messaging_server_id(msg_ctx),
1352 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
1356 /* React on 'smbcontrol winbindd reload-config' in the same way
1357 as to SIGHUP signal */
1358 messaging_register(msg_ctx, NULL,
1359 MSG_SMB_CONF_UPDATED, msg_reload_services);
1360 messaging_register(msg_ctx, NULL,
1361 MSG_SHUTDOWN, msg_shutdown);
1363 /* Handle online/offline messages. */
1364 messaging_register(msg_ctx, NULL,
1365 MSG_WINBIND_OFFLINE, winbind_msg_offline);
1366 messaging_register(msg_ctx, NULL,
1367 MSG_WINBIND_ONLINE, winbind_msg_online);
1368 messaging_register(msg_ctx, NULL,
1369 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1371 /* Handle domain online/offline messages for domains */
1372 messaging_register(winbind_messaging_context(), NULL,
1373 MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1374 messaging_register(winbind_messaging_context(), NULL,
1375 MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1377 messaging_register(msg_ctx, NULL,
1378 MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
1380 messaging_register(msg_ctx, NULL,
1381 MSG_WINBIND_VALIDATE_CACHE,
1382 winbind_msg_validate_cache);
1384 messaging_register(msg_ctx, NULL,
1385 MSG_WINBIND_DUMP_DOMAIN_LIST,
1386 winbind_msg_dump_domain_list);
1388 messaging_register(msg_ctx, NULL,
1389 MSG_WINBIND_IP_DROPPED,
1390 winbind_msg_ip_dropped_parent);
1392 /* Register handler for MSG_DEBUG. */
1393 messaging_register(msg_ctx, NULL,
1397 netsamlogon_cache_init(); /* Non-critical */
1399 /* clear the cached list of trusted domains */
1403 if (!init_domain_list()) {
1404 DEBUG(0,("unable to initialize domain list\n"));
1409 init_locator_child();
1411 smb_nscd_flush_user_cache();
1412 smb_nscd_flush_group_cache();
1414 if (lp_allow_trusted_domains()) {
1415 if (tevent_add_timer(winbind_event_context(), NULL, timeval_zero(),
1416 rescan_trusted_domains, NULL) == NULL) {
1417 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1422 status = wb_irpc_register();
1424 if (!NT_STATUS_IS_OK(status)) {
1425 DEBUG(0, ("Could not register IRPC handlers\n"));
1430 struct winbindd_addrchanged_state {
1431 struct addrchange_context *ctx;
1432 struct tevent_context *ev;
1433 struct messaging_context *msg_ctx;
1436 static void winbindd_addr_changed(struct tevent_req *req);
1438 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1439 struct tevent_context *ev,
1440 struct messaging_context *msg_ctx)
1442 struct winbindd_addrchanged_state *state;
1443 struct tevent_req *req;
1446 state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1447 if (state == NULL) {
1448 DEBUG(10, ("talloc failed\n"));
1452 state->msg_ctx = msg_ctx;
1454 status = addrchange_context_create(state, &state->ctx);
1455 if (!NT_STATUS_IS_OK(status)) {
1456 DEBUG(10, ("addrchange_context_create failed: %s\n",
1457 nt_errstr(status)));
1461 req = addrchange_send(state, ev, state->ctx);
1463 DEBUG(0, ("addrchange_send failed\n"));
1467 tevent_req_set_callback(req, winbindd_addr_changed, state);
1470 static void winbindd_addr_changed(struct tevent_req *req)
1472 struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1473 req, struct winbindd_addrchanged_state);
1474 enum addrchange_type type;
1475 struct sockaddr_storage addr;
1478 status = addrchange_recv(req, &type, &addr);
1480 if (!NT_STATUS_IS_OK(status)) {
1481 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1482 nt_errstr(status)));
1486 if (type == ADDRCHANGE_DEL) {
1487 char addrstr[INET6_ADDRSTRLEN];
1490 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1492 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1495 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1497 status = messaging_send(state->msg_ctx,
1498 messaging_server_id(state->msg_ctx),
1499 MSG_WINBIND_IP_DROPPED, &blob);
1500 if (!NT_STATUS_IS_OK(status)) {
1501 DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1502 nt_errstr(status)));
1505 req = addrchange_send(state, state->ev, state->ctx);
1507 DEBUG(0, ("addrchange_send failed\n"));
1511 tevent_req_set_callback(req, winbindd_addr_changed, state);
1516 int main(int argc, const char **argv)
1518 static bool is_daemon = False;
1519 static bool Fork = True;
1520 static bool log_stdout = False;
1521 static bool no_process_group = False;
1525 OPT_NO_PROCESS_GROUP,
1528 struct poptOption long_options[] = {
1530 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1531 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1532 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1533 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1534 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1535 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1546 * Do this before any other talloc operation
1548 talloc_enable_null_tracking();
1549 frame = talloc_stackframe();
1552 * We want total control over the permissions on created files,
1553 * so set our umask to 0.
1557 setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1559 /* glibc (?) likes to print "User defined signal 1" and exit if a
1560 SIGUSR[12] is received before a handler is installed */
1562 CatchSignal(SIGUSR1, SIG_IGN);
1563 CatchSignal(SIGUSR2, SIG_IGN);
1566 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1570 /* Initialise for running in non-root mode */
1574 set_remote_machine_name("winbindd", False);
1576 /* Set environment variable so we don't recursively call ourselves.
1577 This may also be useful interactively. */
1579 if ( !winbind_off() ) {
1580 DEBUG(0,("Failed to disable recusive winbindd calls. Exiting.\n"));
1584 /* Initialise samba/rpc client stuff */
1586 pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1588 while ((opt = poptGetNextOpt(pc)) != -1) {
1590 /* Don't become a daemon */
1602 case OPT_NO_PROCESS_GROUP:
1603 no_process_group = true;
1605 case OPT_LOG_STDOUT:
1612 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1613 poptBadOption(pc, 0), poptStrerror(opt));
1614 poptPrintUsage(pc, stderr, 0);
1619 /* We call dump_core_setup one more time because the command line can
1620 * set the log file or the log-basename and this will influence where
1621 * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1622 * the default value derived from build's prefix. For EOM this value
1623 * is often not related to the path where winbindd is actually run
1626 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1627 if (is_daemon && interactive) {
1628 d_fprintf(stderr,"\nERROR: "
1629 "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1630 poptPrintUsage(pc, stderr, 0);
1634 if (log_stdout && Fork) {
1635 d_fprintf(stderr, "\nERROR: "
1636 "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1637 poptPrintUsage(pc, stderr, 0);
1641 poptFreeContext(pc);
1643 if (!override_logfile) {
1645 if (asprintf(&lfile,"%s/log.winbindd",
1646 get_dyn_LOGFILEBASE()) > 0) {
1647 lp_set_logfile(lfile);
1653 setup_logging("winbindd", DEBUG_STDOUT);
1655 setup_logging("winbindd", DEBUG_FILE);
1659 DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1660 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1662 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1663 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1666 /* After parsing the configuration file we setup the core path one more time
1667 * as the log file might have been set in the configuration and cores's
1668 * path is by default basename(lp_logfile()).
1670 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1672 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1673 && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1674 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1675 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"));
1679 if (!cluster_probe_ok()) {
1683 /* Initialise messaging system */
1685 if (winbind_messaging_context() == NULL) {
1689 if (!reload_services_file(NULL)) {
1690 DEBUG(0, ("error opening config file\n"));
1694 ok = directory_create_or_exist(lp_lock_directory(), 0755);
1696 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1697 lp_lock_directory(), strerror(errno)));
1701 ok = directory_create_or_exist(lp_pid_directory(), 0755);
1703 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1704 lp_pid_directory(), strerror(errno)));
1715 if (!secrets_init()) {
1717 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1721 status = rpccli_pre_open_netlogon_creds();
1722 if (!NT_STATUS_IS_OK(status)) {
1723 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1724 nt_errstr(status)));
1728 /* Unblock all signals we are interested in as they may have been
1729 blocked by the parent process. */
1731 BlockSignals(False, SIGINT);
1732 BlockSignals(False, SIGQUIT);
1733 BlockSignals(False, SIGTERM);
1734 BlockSignals(False, SIGUSR1);
1735 BlockSignals(False, SIGUSR2);
1736 BlockSignals(False, SIGHUP);
1737 BlockSignals(False, SIGCHLD);
1740 become_daemon(Fork, no_process_group, log_stdout);
1742 pidfile_create(lp_pid_directory(), "winbindd");
1746 * If we're interactive we want to set our own process group for
1747 * signal management.
1749 if (interactive && !no_process_group)
1750 setpgid( (pid_t)0, (pid_t)0);
1755 /* Don't use winbindd_reinit_after_fork here as
1756 * we're just starting up and haven't created any
1757 * winbindd-specific resources we must free yet. JRA.
1760 status = reinit_after_fork(winbind_messaging_context(),
1761 winbind_event_context(),
1763 if (!NT_STATUS_IS_OK(status)) {
1764 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1768 * Do not initialize the parent-child-pipe before becoming
1769 * a daemon: this is used to detect a died parent in the child
1772 status = init_before_fork();
1773 if (!NT_STATUS_IS_OK(status)) {
1774 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1777 winbindd_register_handlers(winbind_messaging_context(), !Fork);
1779 if (!messaging_parent_dgm_cleanup_init(winbind_messaging_context())) {
1783 status = init_system_session_info();
1784 if (!NT_STATUS_IS_OK(status)) {
1785 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1788 rpc_lsarpc_init(NULL);
1789 rpc_samr_init(NULL);
1791 winbindd_init_addrchange(NULL, winbind_event_context(),
1792 winbind_messaging_context());
1794 /* setup listen sockets */
1796 if (!winbindd_setup_listeners()) {
1797 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1800 irpc_add_name(winbind_imessaging_context(), "winbind_server");
1805 daemon_ready("winbindd");
1808 /* Loop waiting for requests */
1810 frame = talloc_stackframe();
1812 if (tevent_loop_once(winbind_event_context()) == -1) {
1813 DEBUG(1, ("tevent_loop_once() failed: %s\n",