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"
50 #define DBGC_CLASS DBGC_WINBIND
52 #define SCRUB_CLIENTS_INTERVAL 5
54 static bool client_is_idle(struct winbindd_cli_state *state);
55 static void remove_client(struct winbindd_cli_state *state);
56 static void winbindd_setup_max_fds(void);
58 static bool opt_nocache = False;
59 static bool interactive = False;
61 extern bool override_logfile;
63 struct imessaging_context *winbind_imessaging_context(void)
65 static struct imessaging_context *msg = NULL;
66 struct messaging_context *msg_ctx;
67 struct server_id myself;
68 struct loadparm_context *lp_ctx;
74 msg_ctx = server_messaging_context();
75 if (msg_ctx == NULL) {
76 smb_panic("server_messaging_context failed\n");
78 myself = messaging_server_id(msg_ctx);
80 lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
82 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
86 * Note we MUST use the NULL context here, not the autofree context,
87 * to avoid side effects in forked children exiting.
89 msg = imessaging_init(NULL, lp_ctx, myself, server_event_context());
90 talloc_unlink(NULL, lp_ctx);
93 smb_panic("Could not init winbindd's messaging context.\n");
98 /* Reload configuration */
100 static bool reload_services_file(const char *lfile)
105 char *fname = lp_next_configfile(talloc_tos());
107 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
108 set_dyn_CONFIGFILE(fname);
113 /* if this is a child, restore the logfile to the special
114 name - <domain>, idmap, etc. */
115 if (lfile && *lfile) {
116 lp_set_logfile(lfile);
120 ret = lp_load_global(get_dyn_CONFIGFILE());
124 winbindd_setup_max_fds();
130 static void winbindd_status(void)
132 struct winbindd_cli_state *tmp;
134 DEBUG(0, ("winbindd status:\n"));
136 /* Print client state information */
138 DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
140 if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
141 DEBUG(2, ("\tclient list:\n"));
142 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
143 DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
144 (unsigned long)tmp->pid, tmp->sock,
145 client_is_idle(tmp) ? "idle" : "active"));
150 /* Flush client cache */
152 static void flush_caches(void)
154 /* We need to invalidate cached user list entries on a SIGHUP
155 otherwise cached access denied errors due to restrict anonymous
156 hang around until the sequence number changes. */
158 if (!wcache_invalidate_cache()) {
159 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
160 if (!winbindd_cache_validate_and_initialize()) {
166 static void flush_caches_noinit(void)
169 * We need to invalidate cached user list entries on a SIGHUP
170 * otherwise cached access denied errors due to restrict anonymous
171 * hang around until the sequence number changes.
173 * Skip uninitialized domains when flush cache.
174 * If domain is not initialized, it means it is never
175 * used or never become online. look, wcache_invalidate_cache()
176 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
177 * for unused domains and large traffic for primay domain's DC if there
181 if (!wcache_invalidate_cache_noinit()) {
182 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
183 if (!winbindd_cache_validate_and_initialize()) {
189 /* Handle the signal by unlinking socket and exiting */
191 static void terminate(bool is_parent)
194 /* When parent goes away we should
195 * remove the socket file. Not so
196 * when children terminate.
200 if (asprintf(&path, "%s/%s",
201 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) {
209 gencache_stabilize();
211 netlogon_creds_cli_close_global_db();
215 TALLOC_CTX *mem_ctx = talloc_init("end_description");
216 char *description = talloc_describe_all(mem_ctx);
218 DEBUG(3, ("tallocs left:\n%s\n", description));
219 talloc_destroy(mem_ctx);
224 pidfile_unlink(lp_pid_directory(), "winbindd");
230 static void winbindd_sig_term_handler(struct tevent_context *ev,
231 struct tevent_signal *se,
237 bool *p = talloc_get_type_abort(private_data, bool);
242 DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
244 terminate(is_parent);
248 handle stdin becoming readable when we are in --foreground mode
250 static void winbindd_stdin_handler(struct tevent_context *ev,
251 struct tevent_fd *fde,
256 if (read(0, &c, 1) != 1) {
257 bool *is_parent = talloc_get_type_abort(private_data, bool);
259 /* we have reached EOF on stdin, which means the
260 parent has exited. Shutdown the server */
261 DEBUG(0,("EOF on stdin (is_parent=%d)\n",
263 terminate(*is_parent);
267 bool winbindd_setup_sig_term_handler(bool parent)
269 struct tevent_signal *se;
272 is_parent = talloc(server_event_context(), bool);
279 se = tevent_add_signal(server_event_context(),
282 winbindd_sig_term_handler,
285 DEBUG(0,("failed to setup SIGTERM handler"));
286 talloc_free(is_parent);
290 se = tevent_add_signal(server_event_context(),
293 winbindd_sig_term_handler,
296 DEBUG(0,("failed to setup SIGINT handler"));
297 talloc_free(is_parent);
301 se = tevent_add_signal(server_event_context(),
304 winbindd_sig_term_handler,
307 DEBUG(0,("failed to setup SIGINT handler"));
308 talloc_free(is_parent);
315 bool winbindd_setup_stdin_handler(bool parent, bool foreground)
322 is_parent = talloc(server_event_context(), bool);
329 /* if we are running in the foreground then look for
330 EOF on stdin, and exit if it happens. This allows
331 us to die if the parent process dies
332 Only do this on a pipe or socket, no other device.
334 if (fstat(0, &st) != 0) {
337 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
338 tevent_add_fd(server_event_context(),
342 winbindd_stdin_handler,
350 static void winbindd_sig_hup_handler(struct tevent_context *ev,
351 struct tevent_signal *se,
357 const char *file = (const char *)private_data;
359 DEBUG(1,("Reloading services after SIGHUP\n"));
360 flush_caches_noinit();
361 reload_services_file(file);
364 bool winbindd_setup_sig_hup_handler(const char *lfile)
366 struct tevent_signal *se;
370 file = talloc_strdup(server_event_context(),
377 se = tevent_add_signal(server_event_context(),
378 server_event_context(),
380 winbindd_sig_hup_handler,
389 static void winbindd_sig_chld_handler(struct tevent_context *ev,
390 struct tevent_signal *se,
398 while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
399 winbind_child_died(pid);
403 static bool winbindd_setup_sig_chld_handler(void)
405 struct tevent_signal *se;
407 se = tevent_add_signal(server_event_context(),
408 server_event_context(),
410 winbindd_sig_chld_handler,
419 static void winbindd_sig_usr2_handler(struct tevent_context *ev,
420 struct tevent_signal *se,
429 static bool winbindd_setup_sig_usr2_handler(void)
431 struct tevent_signal *se;
433 se = tevent_add_signal(server_event_context(),
434 server_event_context(),
436 winbindd_sig_usr2_handler,
445 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
446 static void msg_reload_services(struct messaging_context *msg,
449 struct server_id server_id,
452 /* Flush various caches */
454 reload_services_file((const char *) private_data);
457 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
458 static void msg_shutdown(struct messaging_context *msg,
461 struct server_id server_id,
464 /* only the parent waits for this message */
465 DEBUG(0,("Got shutdown message\n"));
470 static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
473 struct server_id server_id,
480 DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
484 * call the validation code from a child:
485 * so we don't block the main winbindd and the validation
486 * code can safely use fork/waitpid...
490 if (child_pid == -1) {
491 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
496 if (child_pid != 0) {
498 DEBUG(5, ("winbind_msg_validate_cache: child created with "
499 "pid %d.\n", (int)child_pid));
505 status = winbindd_reinit_after_fork(NULL, NULL);
506 if (!NT_STATUS_IS_OK(status)) {
507 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
512 /* install default SIGCHLD handler: validation code uses fork/waitpid */
513 CatchSignal(SIGCHLD, SIG_DFL);
515 setproctitle("validate cache child");
517 ret = (uint8_t)winbindd_validate_cache_nobackup();
518 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
519 messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
524 static struct winbindd_dispatch_table {
525 enum winbindd_cmd cmd;
526 void (*fn)(struct winbindd_cli_state *state);
527 const char *winbindd_cmd_name;
528 } dispatch_table[] = {
530 /* Enumeration functions */
532 { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
537 { WINBINDD_INFO, winbindd_info, "INFO" },
538 { WINBINDD_PING, winbindd_ping, "PING" },
539 { WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
540 "INTERFACE_VERSION" },
541 { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
542 { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
543 { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" },
544 { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
545 { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
546 "WINBINDD_PRIV_PIPE_DIR" },
548 /* Credential cache access */
549 { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
550 { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
554 { WINBINDD_NUM_CMDS, NULL, "NONE" }
557 struct winbindd_async_dispatch_table {
558 enum winbindd_cmd cmd;
559 const char *cmd_name;
560 struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
561 struct tevent_context *ev,
562 struct winbindd_cli_state *cli,
563 struct winbindd_request *request);
564 NTSTATUS (*recv_req)(struct tevent_req *req,
565 struct winbindd_response *presp);
568 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
569 { WINBINDD_LOOKUPSID, "LOOKUPSID",
570 winbindd_lookupsid_send, winbindd_lookupsid_recv },
571 { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
572 winbindd_lookupsids_send, winbindd_lookupsids_recv },
573 { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
574 winbindd_lookupname_send, winbindd_lookupname_recv },
575 { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
576 winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
577 { WINBINDD_XIDS_TO_SIDS, "XIDS_TO_SIDS",
578 winbindd_xids_to_sids_send, winbindd_xids_to_sids_recv },
579 { WINBINDD_GETPWSID, "GETPWSID",
580 winbindd_getpwsid_send, winbindd_getpwsid_recv },
581 { WINBINDD_GETPWNAM, "GETPWNAM",
582 winbindd_getpwnam_send, winbindd_getpwnam_recv },
583 { WINBINDD_GETPWUID, "GETPWUID",
584 winbindd_getpwuid_send, winbindd_getpwuid_recv },
585 { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
586 winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
587 { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
588 winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
589 { WINBINDD_GETGROUPS, "GETGROUPS",
590 winbindd_getgroups_send, winbindd_getgroups_recv },
591 { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
592 winbindd_show_sequence_send, winbindd_show_sequence_recv },
593 { WINBINDD_GETGRGID, "GETGRGID",
594 winbindd_getgrgid_send, winbindd_getgrgid_recv },
595 { WINBINDD_GETGRNAM, "GETGRNAM",
596 winbindd_getgrnam_send, winbindd_getgrnam_recv },
597 { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
598 winbindd_getusersids_send, winbindd_getusersids_recv },
599 { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
600 winbindd_lookuprids_send, winbindd_lookuprids_recv },
601 { WINBINDD_SETPWENT, "SETPWENT",
602 winbindd_setpwent_send, winbindd_setpwent_recv },
603 { WINBINDD_GETPWENT, "GETPWENT",
604 winbindd_getpwent_send, winbindd_getpwent_recv },
605 { WINBINDD_ENDPWENT, "ENDPWENT",
606 winbindd_endpwent_send, winbindd_endpwent_recv },
607 { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
608 winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
609 { WINBINDD_GETDCNAME, "GETDCNAME",
610 winbindd_getdcname_send, winbindd_getdcname_recv },
611 { WINBINDD_SETGRENT, "SETGRENT",
612 winbindd_setgrent_send, winbindd_setgrent_recv },
613 { WINBINDD_GETGRENT, "GETGRENT",
614 winbindd_getgrent_send, winbindd_getgrent_recv },
615 { WINBINDD_ENDGRENT, "ENDGRENT",
616 winbindd_endgrent_send, winbindd_endgrent_recv },
617 { WINBINDD_LIST_USERS, "LIST_USERS",
618 winbindd_list_users_send, winbindd_list_users_recv },
619 { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
620 winbindd_list_groups_send, winbindd_list_groups_recv },
621 { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
622 winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
623 { WINBINDD_PING_DC, "PING_DC",
624 winbindd_ping_dc_send, winbindd_ping_dc_recv },
625 { WINBINDD_PAM_AUTH, "PAM_AUTH",
626 winbindd_pam_auth_send, winbindd_pam_auth_recv },
627 { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
628 winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
629 { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
630 winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
631 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
632 winbindd_pam_chng_pswd_auth_crap_send,
633 winbindd_pam_chng_pswd_auth_crap_recv },
634 { WINBINDD_WINS_BYIP, "WINS_BYIP",
635 winbindd_wins_byip_send, winbindd_wins_byip_recv },
636 { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
637 winbindd_wins_byname_send, winbindd_wins_byname_recv },
639 { 0, NULL, NULL, NULL }
642 static struct winbindd_async_dispatch_table async_priv_table[] = {
643 { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
644 winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
645 { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
646 winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
647 { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
648 winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
649 { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
650 winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
652 { 0, NULL, NULL, NULL }
655 static void wb_request_done(struct tevent_req *req);
657 static void process_request(struct winbindd_cli_state *state)
659 struct winbindd_dispatch_table *table = dispatch_table;
660 struct winbindd_async_dispatch_table *atable;
662 state->mem_ctx = talloc_named(state, 0, "winbind request");
663 if (state->mem_ctx == NULL)
666 /* Remember who asked us. */
667 state->pid = state->request->pid;
669 state->cmd_name = "unknown request";
670 state->recv_fn = NULL;
671 /* client is newest */
672 winbindd_promote_client(state);
674 /* Process command */
676 for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
677 if (state->request->cmd == atable->cmd) {
682 if ((atable->send_req == NULL) && state->privileged) {
683 for (atable = async_priv_table; atable->send_req;
685 if (state->request->cmd == atable->cmd) {
691 if (atable->send_req != NULL) {
692 struct tevent_req *req;
694 state->cmd_name = atable->cmd_name;
695 state->recv_fn = atable->recv_req;
697 DEBUG(10, ("process_request: Handling async request %d:%s\n",
698 (int)state->pid, state->cmd_name));
700 req = atable->send_req(state->mem_ctx, server_event_context(),
701 state, state->request);
703 DEBUG(0, ("process_request: atable->send failed for "
704 "%s\n", atable->cmd_name));
705 request_error(state);
708 tevent_req_set_callback(req, wb_request_done, state);
712 state->response = talloc_zero(state->mem_ctx,
713 struct winbindd_response);
714 if (state->response == NULL) {
715 DEBUG(10, ("talloc failed\n"));
716 remove_client(state);
719 state->response->result = WINBINDD_PENDING;
720 state->response->length = sizeof(struct winbindd_response);
722 for (table = dispatch_table; table->fn; table++) {
723 if (state->request->cmd == table->cmd) {
724 DEBUG(10,("process_request: request fn %s\n",
725 table->winbindd_cmd_name ));
726 state->cmd_name = table->winbindd_cmd_name;
733 DEBUG(10,("process_request: unknown request fn number %d\n",
734 (int)state->request->cmd ));
735 request_error(state);
739 static void wb_request_done(struct tevent_req *req)
741 struct winbindd_cli_state *state = tevent_req_callback_data(
742 req, struct winbindd_cli_state);
745 state->response = talloc_zero(state->mem_ctx,
746 struct winbindd_response);
747 if (state->response == NULL) {
748 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
749 (int)state->pid, state->cmd_name));
750 remove_client(state);
753 state->response->result = WINBINDD_PENDING;
754 state->response->length = sizeof(struct winbindd_response);
756 status = state->recv_fn(req, state->response);
759 DEBUG(10,("wb_request_done[%d:%s]: %s\n",
760 (int)state->pid, state->cmd_name, nt_errstr(status)));
762 if (!NT_STATUS_IS_OK(status)) {
763 request_error(state);
770 * This is the main event loop of winbind requests. It goes through a
771 * state-machine of 3 read/write requests, 4 if you have extra data to send.
773 * An idle winbind client has a read request of 4 bytes outstanding,
774 * finalizing function is request_len_recv, checking the length. request_recv
775 * then processes the packet. The processing function then at some point has
776 * to call request_finished which schedules sending the response.
779 static void request_finished(struct winbindd_cli_state *state);
781 static void winbind_client_request_read(struct tevent_req *req);
782 static void winbind_client_response_written(struct tevent_req *req);
783 static void winbind_client_activity(struct tevent_req *req);
785 static void request_finished(struct winbindd_cli_state *state)
787 struct tevent_req *req;
789 /* free client socket monitoring request */
790 TALLOC_FREE(state->io_req);
792 TALLOC_FREE(state->request);
794 req = wb_resp_write_send(state, server_event_context(),
795 state->out_queue, state->sock,
798 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
799 (int)state->pid, state->cmd_name));
800 remove_client(state);
803 tevent_req_set_callback(req, winbind_client_response_written, state);
807 static void winbind_client_response_written(struct tevent_req *req)
809 struct winbindd_cli_state *state = tevent_req_callback_data(
810 req, struct winbindd_cli_state);
814 state->io_req = NULL;
816 ret = wb_resp_write_recv(req, &err);
821 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
822 (int)state->pid, state->cmd_name, strerror(err)));
823 remove_client(state);
827 DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
828 "to client\n", (int)state->pid, state->cmd_name));
830 TALLOC_FREE(state->mem_ctx);
831 state->response = NULL;
832 state->cmd_name = "no request";
833 state->recv_fn = NULL;
835 req = wb_req_read_send(state, server_event_context(), state->sock,
836 WINBINDD_MAX_EXTRA_DATA);
838 remove_client(state);
841 tevent_req_set_callback(req, winbind_client_request_read, state);
845 void request_error(struct winbindd_cli_state *state)
847 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
848 state->response->result = WINBINDD_ERROR;
849 request_finished(state);
852 void request_ok(struct winbindd_cli_state *state)
854 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
855 state->response->result = WINBINDD_OK;
856 request_finished(state);
859 /* Process a new connection by adding it to the client connection list */
861 static void new_connection(int listen_sock, bool privileged)
863 struct sockaddr_un sunaddr;
864 struct winbindd_cli_state *state;
865 struct tevent_req *req;
869 /* Accept connection */
871 len = sizeof(sunaddr);
873 sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
876 if (errno != EINTR) {
877 DEBUG(0, ("Failed to accept socket - %s\n",
882 smb_set_close_on_exec(sock);
884 DEBUG(6,("accepted socket %d\n", sock));
886 /* Create new connection structure */
888 if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
895 state->out_queue = tevent_queue_create(state, "winbind client reply");
896 if (state->out_queue == NULL) {
902 state->privileged = privileged;
904 req = wb_req_read_send(state, server_event_context(), state->sock,
905 WINBINDD_MAX_EXTRA_DATA);
911 tevent_req_set_callback(req, winbind_client_request_read, state);
914 /* Add to connection list */
916 winbindd_add_client(state);
919 static void winbind_client_request_read(struct tevent_req *req)
921 struct winbindd_cli_state *state = tevent_req_callback_data(
922 req, struct winbindd_cli_state);
926 state->io_req = NULL;
928 ret = wb_req_read_recv(req, state, &state->request, &err);
932 DEBUG(6, ("closing socket %d, client exited\n",
935 DEBUG(2, ("Could not read client request from fd %d: "
936 "%s\n", state->sock, strerror(err)));
940 remove_client(state);
944 req = wait_for_read_send(state, server_event_context(), state->sock,
947 DEBUG(0, ("winbind_client_request_read[%d:%s]:"
948 " wait_for_read_send failed - removing client\n",
949 (int)state->pid, state->cmd_name));
950 remove_client(state);
953 tevent_req_set_callback(req, winbind_client_activity, state);
956 process_request(state);
959 static void winbind_client_activity(struct tevent_req *req)
961 struct winbindd_cli_state *state =
962 tevent_req_callback_data(req, struct winbindd_cli_state);
966 has_data = wait_for_read_recv(req, &err);
969 DEBUG(0, ("winbind_client_activity[%d:%s]:"
970 "unexpected data from client - removing client\n",
971 (int)state->pid, state->cmd_name));
974 DEBUG(6, ("winbind_client_activity[%d:%s]: "
975 "client has closed connection - removing "
977 (int)state->pid, state->cmd_name));
979 DEBUG(2, ("winbind_client_activity[%d:%s]: "
980 "client socket error (%s) - removing "
982 (int)state->pid, state->cmd_name,
987 remove_client(state);
990 /* Remove a client connection from client connection list */
992 static void remove_client(struct winbindd_cli_state *state)
997 /* It's a dead client - hold a funeral */
1004 * We need to remove a pending wb_req_read_*
1005 * or wb_resp_write_* request before closing the
1008 * This is important as they might have used tevent_add_fd() and we
1009 * use the epoll * backend on linux. So we must remove the tevent_fd
1010 * before closing the fd.
1012 * Otherwise we might hit a race with close_conns_after_fork() (via
1013 * winbindd_reinit_after_fork()) where a file description
1014 * is still open in a child, which means it's still active in
1015 * the parents epoll queue, but the related tevent_fd is already
1016 * already gone in the parent.
1020 TALLOC_FREE(state->io_req);
1022 if (state->sock != -1) {
1023 /* tell client, we are closing ... */
1024 nwritten = write(state->sock, &c, sizeof(c));
1025 if (nwritten == -1) {
1026 DEBUG(2, ("final write to client failed: %s\n",
1036 TALLOC_FREE(state->mem_ctx);
1038 /* Remove from list and free */
1040 winbindd_remove_client(state);
1044 /* Is a client idle? */
1046 static bool client_is_idle(struct winbindd_cli_state *state) {
1047 return (state->request == NULL &&
1048 state->response == NULL &&
1049 !state->pwent_state && !state->grent_state);
1052 /* Shutdown client connection which has been idle for the longest time */
1054 static bool remove_idle_client(void)
1056 struct winbindd_cli_state *state, *remove_state = NULL;
1059 for (state = winbindd_client_list(); state; state = state->next) {
1060 if (client_is_idle(state)) {
1062 /* list is sorted by access time */
1063 remove_state = state;
1068 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1069 nidle, remove_state->sock, (unsigned int)remove_state->pid));
1070 remove_client(remove_state);
1078 * Terminate all clients whose requests have taken longer than
1079 * "winbind request timeout" seconds to process, or have been
1080 * idle for more than "winbind request timeout" seconds.
1083 static void remove_timed_out_clients(void)
1085 struct winbindd_cli_state *state, *prev = NULL;
1086 time_t curr_time = time(NULL);
1087 int timeout_val = lp_winbind_request_timeout();
1089 for (state = winbindd_client_list_tail(); state; state = prev) {
1092 prev = winbindd_client_list_prev(state);
1093 expiry_time = state->last_access + timeout_val;
1095 if (curr_time <= expiry_time) {
1096 /* list is sorted, previous clients in
1101 if (client_is_idle(state)) {
1102 DEBUG(5,("Idle client timed out, "
1103 "shutting down sock %d, pid %u\n",
1105 (unsigned int)state->pid));
1107 DEBUG(5,("Client request timed out, "
1108 "shutting down sock %d, pid %u\n",
1110 (unsigned int)state->pid));
1113 remove_client(state);
1117 static void winbindd_scrub_clients_handler(struct tevent_context *ev,
1118 struct tevent_timer *te,
1119 struct timeval current_time,
1122 remove_timed_out_clients();
1123 if (tevent_add_timer(ev, ev,
1124 timeval_current_ofs(SCRUB_CLIENTS_INTERVAL, 0),
1125 winbindd_scrub_clients_handler, NULL) == NULL) {
1126 DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
1131 struct winbindd_listen_state {
1136 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1137 struct tevent_fd *fde,
1141 struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1142 struct winbindd_listen_state);
1144 while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1145 DEBUG(5,("winbindd: Exceeding %d client "
1146 "connections, removing idle "
1147 "connection.\n", lp_winbind_max_clients()));
1148 if (!remove_idle_client()) {
1149 DEBUG(0,("winbindd: Exceeding %d "
1150 "client connections, no idle "
1151 "connection found\n",
1152 lp_winbind_max_clients()));
1156 remove_timed_out_clients();
1157 new_connection(s->fd, s->privileged);
1161 * Winbindd socket accessor functions
1164 char *get_winbind_priv_pipe_dir(void)
1166 return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1169 static void winbindd_setup_max_fds(void)
1171 int num_fds = MAX_OPEN_FUDGEFACTOR;
1174 num_fds += lp_winbind_max_clients();
1175 /* Add some more to account for 2 sockets open
1176 when the client transitions from unprivileged
1177 to privileged socket
1179 num_fds += lp_winbind_max_clients() / 10;
1181 /* Add one socket per child process
1182 (yeah there are child processes other than the
1183 domain children but only domain children can vary
1186 num_fds += lp_winbind_max_domain_connections() *
1187 (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
1189 actual_fds = set_maxfiles(num_fds);
1191 if (actual_fds < num_fds) {
1192 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1193 "requested %d open files, %d are available.\n",
1194 num_fds, actual_fds));
1198 static bool winbindd_setup_listeners(void)
1200 struct winbindd_listen_state *pub_state = NULL;
1201 struct winbindd_listen_state *priv_state = NULL;
1202 struct tevent_fd *fde;
1206 pub_state = talloc(server_event_context(),
1207 struct winbindd_listen_state);
1212 pub_state->privileged = false;
1213 pub_state->fd = create_pipe_sock(
1214 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1215 if (pub_state->fd == -1) {
1218 rc = listen(pub_state->fd, 5);
1223 fde = tevent_add_fd(server_event_context(), pub_state, pub_state->fd,
1224 TEVENT_FD_READ, winbindd_listen_fde_handler,
1227 close(pub_state->fd);
1230 tevent_fd_set_auto_close(fde);
1232 priv_state = talloc(server_event_context(),
1233 struct winbindd_listen_state);
1238 socket_path = get_winbind_priv_pipe_dir();
1239 if (socket_path == NULL) {
1243 priv_state->privileged = true;
1244 priv_state->fd = create_pipe_sock(
1245 socket_path, WINBINDD_SOCKET_NAME, 0750);
1246 TALLOC_FREE(socket_path);
1247 if (priv_state->fd == -1) {
1250 rc = listen(priv_state->fd, 5);
1255 fde = tevent_add_fd(server_event_context(), priv_state,
1256 priv_state->fd, TEVENT_FD_READ,
1257 winbindd_listen_fde_handler, priv_state);
1259 close(priv_state->fd);
1262 tevent_fd_set_auto_close(fde);
1264 winbindd_scrub_clients_handler(server_event_context(), NULL,
1265 timeval_current(), NULL);
1268 TALLOC_FREE(pub_state);
1269 TALLOC_FREE(priv_state);
1273 bool winbindd_use_idmap_cache(void)
1275 return !opt_nocache;
1278 bool winbindd_use_cache(void)
1280 return !opt_nocache;
1283 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1286 bool scan_trusts = true;
1288 /* Setup signal handlers */
1290 if (!winbindd_setup_sig_term_handler(true))
1292 if (!winbindd_setup_stdin_handler(true, foreground))
1294 if (!winbindd_setup_sig_hup_handler(NULL))
1296 if (!winbindd_setup_sig_chld_handler())
1298 if (!winbindd_setup_sig_usr2_handler())
1301 CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
1304 * Ensure all cache and idmap caches are consistent
1305 * and initialized before we startup.
1307 if (!winbindd_cache_validate_and_initialize()) {
1311 /* React on 'smbcontrol winbindd reload-config' in the same way
1312 as to SIGHUP signal */
1313 messaging_register(msg_ctx, NULL,
1314 MSG_SMB_CONF_UPDATED, msg_reload_services);
1315 messaging_register(msg_ctx, NULL,
1316 MSG_SHUTDOWN, msg_shutdown);
1318 /* Handle online/offline messages. */
1319 messaging_register(msg_ctx, NULL,
1320 MSG_WINBIND_OFFLINE, winbind_msg_offline);
1321 messaging_register(msg_ctx, NULL,
1322 MSG_WINBIND_ONLINE, winbind_msg_online);
1323 messaging_register(msg_ctx, NULL,
1324 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1326 /* Handle domain online/offline messages for domains */
1327 messaging_register(server_messaging_context(), NULL,
1328 MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1329 messaging_register(server_messaging_context(), NULL,
1330 MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1332 messaging_register(msg_ctx, NULL,
1333 MSG_WINBIND_VALIDATE_CACHE,
1334 winbind_msg_validate_cache);
1336 messaging_register(msg_ctx, NULL,
1337 MSG_WINBIND_DUMP_DOMAIN_LIST,
1338 winbind_msg_dump_domain_list);
1340 messaging_register(msg_ctx, NULL,
1341 MSG_WINBIND_IP_DROPPED,
1342 winbind_msg_ip_dropped_parent);
1344 /* Register handler for MSG_DEBUG. */
1345 messaging_register(msg_ctx, NULL,
1349 messaging_register(msg_ctx, NULL,
1350 MSG_WINBIND_DISCONNECT_DC,
1351 winbind_disconnect_dc_parent);
1353 netsamlogon_cache_init(); /* Non-critical */
1355 /* clear the cached list of trusted domains */
1359 if (!init_domain_list()) {
1360 DEBUG(0,("unable to initialize domain list\n"));
1365 init_locator_child();
1367 smb_nscd_flush_user_cache();
1368 smb_nscd_flush_group_cache();
1370 if (!lp_winbind_scan_trusted_domains()) {
1371 scan_trusts = false;
1374 if (!lp_allow_trusted_domains()) {
1375 scan_trusts = false;
1379 scan_trusts = false;
1383 if (tevent_add_timer(server_event_context(), NULL, timeval_zero(),
1384 rescan_trusted_domains, NULL) == NULL) {
1385 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1390 status = wb_irpc_register();
1392 if (!NT_STATUS_IS_OK(status)) {
1393 DEBUG(0, ("Could not register IRPC handlers\n"));
1398 struct winbindd_addrchanged_state {
1399 struct addrchange_context *ctx;
1400 struct tevent_context *ev;
1401 struct messaging_context *msg_ctx;
1404 static void winbindd_addr_changed(struct tevent_req *req);
1406 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1407 struct tevent_context *ev,
1408 struct messaging_context *msg_ctx)
1410 struct winbindd_addrchanged_state *state;
1411 struct tevent_req *req;
1414 state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1415 if (state == NULL) {
1416 DEBUG(10, ("talloc failed\n"));
1420 state->msg_ctx = msg_ctx;
1422 status = addrchange_context_create(state, &state->ctx);
1423 if (!NT_STATUS_IS_OK(status)) {
1424 DEBUG(10, ("addrchange_context_create failed: %s\n",
1425 nt_errstr(status)));
1429 req = addrchange_send(state, ev, state->ctx);
1431 DEBUG(0, ("addrchange_send failed\n"));
1435 tevent_req_set_callback(req, winbindd_addr_changed, state);
1438 static void winbindd_addr_changed(struct tevent_req *req)
1440 struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1441 req, struct winbindd_addrchanged_state);
1442 enum addrchange_type type;
1443 struct sockaddr_storage addr;
1446 status = addrchange_recv(req, &type, &addr);
1448 if (!NT_STATUS_IS_OK(status)) {
1449 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1450 nt_errstr(status)));
1454 if (type == ADDRCHANGE_DEL) {
1455 char addrstr[INET6_ADDRSTRLEN];
1458 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1460 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1463 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1465 status = messaging_send(state->msg_ctx,
1466 messaging_server_id(state->msg_ctx),
1467 MSG_WINBIND_IP_DROPPED, &blob);
1468 if (!NT_STATUS_IS_OK(status)) {
1469 DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1470 nt_errstr(status)));
1473 req = addrchange_send(state, state->ev, state->ctx);
1475 DEBUG(0, ("addrchange_send failed\n"));
1479 tevent_req_set_callback(req, winbindd_addr_changed, state);
1484 int main(int argc, const char **argv)
1486 static bool is_daemon = False;
1487 static bool Fork = True;
1488 static bool log_stdout = False;
1489 static bool no_process_group = False;
1493 OPT_NO_PROCESS_GROUP,
1496 struct poptOption long_options[] = {
1498 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1499 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1500 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1501 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1502 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1503 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1513 setproctitle_init(argc, discard_const(argv), environ);
1516 * Do this before any other talloc operation
1518 talloc_enable_null_tracking();
1519 frame = talloc_stackframe();
1522 * We want total control over the permissions on created files,
1523 * so set our umask to 0.
1527 setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1529 /* glibc (?) likes to print "User defined signal 1" and exit if a
1530 SIGUSR[12] is received before a handler is installed */
1532 CatchSignal(SIGUSR1, SIG_IGN);
1533 CatchSignal(SIGUSR2, SIG_IGN);
1536 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1540 /* Initialise for running in non-root mode */
1544 set_remote_machine_name("winbindd", False);
1546 /* Set environment variable so we don't recursively call ourselves.
1547 This may also be useful interactively. */
1549 if ( !winbind_off() ) {
1550 DEBUG(0,("Failed to disable recusive winbindd calls. Exiting.\n"));
1554 /* Initialise samba/rpc client stuff */
1556 pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1558 while ((opt = poptGetNextOpt(pc)) != -1) {
1560 /* Don't become a daemon */
1572 case OPT_NO_PROCESS_GROUP:
1573 no_process_group = true;
1575 case OPT_LOG_STDOUT:
1582 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1583 poptBadOption(pc, 0), poptStrerror(opt));
1584 poptPrintUsage(pc, stderr, 0);
1589 /* We call dump_core_setup one more time because the command line can
1590 * set the log file or the log-basename and this will influence where
1591 * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1592 * the default value derived from build's prefix. For EOM this value
1593 * is often not related to the path where winbindd is actually run
1596 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1597 if (is_daemon && interactive) {
1598 d_fprintf(stderr,"\nERROR: "
1599 "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1600 poptPrintUsage(pc, stderr, 0);
1604 if (log_stdout && Fork) {
1605 d_fprintf(stderr, "\nERROR: "
1606 "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1607 poptPrintUsage(pc, stderr, 0);
1611 poptFreeContext(pc);
1613 if (!override_logfile) {
1615 if (asprintf(&lfile,"%s/log.winbindd",
1616 get_dyn_LOGFILEBASE()) > 0) {
1617 lp_set_logfile(lfile);
1623 setup_logging("winbindd", DEBUG_STDOUT);
1625 setup_logging("winbindd", DEBUG_FILE);
1629 DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1630 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1632 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1633 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1636 /* After parsing the configuration file we setup the core path one more time
1637 * as the log file might have been set in the configuration and cores's
1638 * path is by default basename(lp_logfile()).
1640 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1642 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1643 && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1644 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1645 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"));
1649 if (!cluster_probe_ok()) {
1653 /* Initialise messaging system */
1655 if (server_messaging_context() == NULL) {
1659 if (!reload_services_file(NULL)) {
1660 DEBUG(0, ("error opening config file\n"));
1666 const char *idmap_backend;
1667 const char *invalid_backends[] = {
1668 "ad", "rfc2307", "rid",
1671 idmap_backend = lp_idmap_default_backend();
1672 for (i = 0; i < ARRAY_SIZE(invalid_backends); i++) {
1673 ok = strequal(idmap_backend, invalid_backends[i]);
1675 DBG_ERR("FATAL: Invalid idmap backend %s "
1676 "configured as the default backend!\n",
1683 ok = directory_create_or_exist(lp_lock_directory(), 0755);
1685 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1686 lp_lock_directory(), strerror(errno)));
1690 ok = directory_create_or_exist(lp_pid_directory(), 0755);
1692 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1693 lp_pid_directory(), strerror(errno)));
1704 if (!secrets_init()) {
1706 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1710 status = rpccli_pre_open_netlogon_creds();
1711 if (!NT_STATUS_IS_OK(status)) {
1712 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1713 nt_errstr(status)));
1717 /* Unblock all signals we are interested in as they may have been
1718 blocked by the parent process. */
1720 BlockSignals(False, SIGINT);
1721 BlockSignals(False, SIGQUIT);
1722 BlockSignals(False, SIGTERM);
1723 BlockSignals(False, SIGUSR1);
1724 BlockSignals(False, SIGUSR2);
1725 BlockSignals(False, SIGHUP);
1726 BlockSignals(False, SIGCHLD);
1729 become_daemon(Fork, no_process_group, log_stdout);
1731 pidfile_create(lp_pid_directory(), "winbindd");
1735 * If we're interactive we want to set our own process group for
1736 * signal management.
1738 if (interactive && !no_process_group)
1739 setpgid( (pid_t)0, (pid_t)0);
1744 /* Don't use winbindd_reinit_after_fork here as
1745 * we're just starting up and haven't created any
1746 * winbindd-specific resources we must free yet. JRA.
1749 status = reinit_after_fork(server_messaging_context(),
1750 server_event_context(),
1752 if (!NT_STATUS_IS_OK(status)) {
1753 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1755 initialize_password_db(true, server_event_context());
1758 * Do not initialize the parent-child-pipe before becoming
1759 * a daemon: this is used to detect a died parent in the child
1762 status = init_before_fork();
1763 if (!NT_STATUS_IS_OK(status)) {
1764 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1767 winbindd_register_handlers(server_messaging_context(), !Fork);
1769 if (!messaging_parent_dgm_cleanup_init(server_messaging_context())) {
1773 status = init_system_session_info(NULL);
1774 if (!NT_STATUS_IS_OK(status)) {
1775 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1778 rpc_lsarpc_init(NULL);
1779 rpc_samr_init(NULL);
1781 winbindd_init_addrchange(NULL, server_event_context(),
1782 server_messaging_context());
1784 /* setup listen sockets */
1786 if (!winbindd_setup_listeners()) {
1787 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1790 irpc_add_name(winbind_imessaging_context(), "winbind_server");
1795 daemon_ready("winbindd");
1800 /* Loop waiting for requests */
1802 frame = talloc_stackframe();
1804 if (tevent_loop_once(server_event_context()) == -1) {
1805 DEBUG(1, ("tevent_loop_once() failed: %s\n",