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"
46 #include "libsmb/samlogon_cache.h"
47 #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 struct messaging_context *msg = server_messaging_context();
225 struct server_id self = messaging_server_id(msg);
226 serverid_deregister(self);
227 pidfile_unlink(lp_pid_directory(), "winbindd");
233 static void winbindd_sig_term_handler(struct tevent_context *ev,
234 struct tevent_signal *se,
240 bool *is_parent = talloc_get_type_abort(private_data, bool);
242 DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
243 signum, (int)*is_parent));
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 ret = (uint8_t)winbindd_validate_cache_nobackup();
516 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
517 messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
522 static struct winbindd_dispatch_table {
523 enum winbindd_cmd cmd;
524 void (*fn)(struct winbindd_cli_state *state);
525 const char *winbindd_cmd_name;
526 } dispatch_table[] = {
528 /* Enumeration functions */
530 { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
535 { WINBINDD_INFO, winbindd_info, "INFO" },
536 { WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
537 "INTERFACE_VERSION" },
538 { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
539 { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
540 { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" },
541 { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
542 { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
543 "WINBINDD_PRIV_PIPE_DIR" },
545 /* Credential cache access */
546 { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
547 { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
551 { WINBINDD_NUM_CMDS, NULL, "NONE" }
554 struct winbindd_async_dispatch_table {
555 enum winbindd_cmd cmd;
556 const char *cmd_name;
557 struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
558 struct tevent_context *ev,
559 struct winbindd_cli_state *cli,
560 struct winbindd_request *request);
561 NTSTATUS (*recv_req)(struct tevent_req *req,
562 struct winbindd_response *presp);
565 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
566 { WINBINDD_PING, "PING",
567 wb_ping_send, wb_ping_recv },
568 { WINBINDD_LOOKUPSID, "LOOKUPSID",
569 winbindd_lookupsid_send, winbindd_lookupsid_recv },
570 { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
571 winbindd_lookupsids_send, winbindd_lookupsids_recv },
572 { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
573 winbindd_lookupname_send, winbindd_lookupname_recv },
574 { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
575 winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
576 { WINBINDD_XIDS_TO_SIDS, "XIDS_TO_SIDS",
577 winbindd_xids_to_sids_send, winbindd_xids_to_sids_recv },
578 { WINBINDD_GETPWSID, "GETPWSID",
579 winbindd_getpwsid_send, winbindd_getpwsid_recv },
580 { WINBINDD_GETPWNAM, "GETPWNAM",
581 winbindd_getpwnam_send, winbindd_getpwnam_recv },
582 { WINBINDD_GETPWUID, "GETPWUID",
583 winbindd_getpwuid_send, winbindd_getpwuid_recv },
584 { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
585 winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
586 { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
587 winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
588 { WINBINDD_GETGROUPS, "GETGROUPS",
589 winbindd_getgroups_send, winbindd_getgroups_recv },
590 { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
591 winbindd_show_sequence_send, winbindd_show_sequence_recv },
592 { WINBINDD_GETGRGID, "GETGRGID",
593 winbindd_getgrgid_send, winbindd_getgrgid_recv },
594 { WINBINDD_GETGRNAM, "GETGRNAM",
595 winbindd_getgrnam_send, winbindd_getgrnam_recv },
596 { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
597 winbindd_getusersids_send, winbindd_getusersids_recv },
598 { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
599 winbindd_lookuprids_send, winbindd_lookuprids_recv },
600 { WINBINDD_SETPWENT, "SETPWENT",
601 winbindd_setpwent_send, winbindd_setpwent_recv },
602 { WINBINDD_GETPWENT, "GETPWENT",
603 winbindd_getpwent_send, winbindd_getpwent_recv },
604 { WINBINDD_ENDPWENT, "ENDPWENT",
605 winbindd_endpwent_send, winbindd_endpwent_recv },
606 { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
607 winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
608 { WINBINDD_GETDCNAME, "GETDCNAME",
609 winbindd_getdcname_send, winbindd_getdcname_recv },
610 { WINBINDD_SETGRENT, "SETGRENT",
611 winbindd_setgrent_send, winbindd_setgrent_recv },
612 { WINBINDD_GETGRENT, "GETGRENT",
613 winbindd_getgrent_send, winbindd_getgrent_recv },
614 { WINBINDD_ENDGRENT, "ENDGRENT",
615 winbindd_endgrent_send, winbindd_endgrent_recv },
616 { WINBINDD_LIST_USERS, "LIST_USERS",
617 winbindd_list_users_send, winbindd_list_users_recv },
618 { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
619 winbindd_list_groups_send, winbindd_list_groups_recv },
620 { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
621 winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
622 { WINBINDD_PING_DC, "PING_DC",
623 winbindd_ping_dc_send, winbindd_ping_dc_recv },
624 { WINBINDD_PAM_AUTH, "PAM_AUTH",
625 winbindd_pam_auth_send, winbindd_pam_auth_recv },
626 { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
627 winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
628 { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
629 winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
630 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
631 winbindd_pam_chng_pswd_auth_crap_send,
632 winbindd_pam_chng_pswd_auth_crap_recv },
633 { WINBINDD_WINS_BYIP, "WINS_BYIP",
634 winbindd_wins_byip_send, winbindd_wins_byip_recv },
635 { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
636 winbindd_wins_byname_send, winbindd_wins_byname_recv },
638 { 0, NULL, NULL, NULL }
641 static struct winbindd_async_dispatch_table async_priv_table[] = {
642 { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
643 winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
644 { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
645 winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
646 { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
647 winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
648 { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
649 winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
651 { 0, NULL, NULL, NULL }
654 static void wb_request_done(struct tevent_req *req);
656 static void process_request(struct winbindd_cli_state *state)
658 struct winbindd_dispatch_table *table = dispatch_table;
659 struct winbindd_async_dispatch_table *atable;
661 state->mem_ctx = talloc_named(state, 0, "winbind request");
662 if (state->mem_ctx == NULL)
665 /* Remember who asked us. */
666 state->pid = state->request->pid;
668 state->cmd_name = "unknown request";
669 state->recv_fn = NULL;
670 /* client is newest */
671 winbindd_promote_client(state);
673 /* Process command */
675 for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
676 if (state->request->cmd == atable->cmd) {
681 if ((atable->send_req == NULL) && state->privileged) {
682 for (atable = async_priv_table; atable->send_req;
684 if (state->request->cmd == atable->cmd) {
690 if (atable->send_req != NULL) {
691 struct tevent_req *req;
693 state->cmd_name = atable->cmd_name;
694 state->recv_fn = atable->recv_req;
696 DEBUG(10, ("process_request: Handling async request %d:%s\n",
697 (int)state->pid, state->cmd_name));
699 req = atable->send_req(state->mem_ctx, server_event_context(),
700 state, state->request);
702 DEBUG(0, ("process_request: atable->send failed for "
703 "%s\n", atable->cmd_name));
704 request_error(state);
707 tevent_req_set_callback(req, wb_request_done, state);
711 state->response = talloc_zero(state->mem_ctx,
712 struct winbindd_response);
713 if (state->response == NULL) {
714 DEBUG(10, ("talloc failed\n"));
715 remove_client(state);
718 state->response->result = WINBINDD_PENDING;
719 state->response->length = sizeof(struct winbindd_response);
721 for (table = dispatch_table; table->fn; table++) {
722 if (state->request->cmd == table->cmd) {
723 DEBUG(10,("process_request: request fn %s\n",
724 table->winbindd_cmd_name ));
725 state->cmd_name = table->winbindd_cmd_name;
732 DEBUG(10,("process_request: unknown request fn number %d\n",
733 (int)state->request->cmd ));
734 request_error(state);
738 static void wb_request_done(struct tevent_req *req)
740 struct winbindd_cli_state *state = tevent_req_callback_data(
741 req, struct winbindd_cli_state);
744 state->response = talloc_zero(state->mem_ctx,
745 struct winbindd_response);
746 if (state->response == NULL) {
747 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
748 (int)state->pid, state->cmd_name));
749 remove_client(state);
752 state->response->result = WINBINDD_PENDING;
753 state->response->length = sizeof(struct winbindd_response);
755 status = state->recv_fn(req, state->response);
758 DEBUG(10,("wb_request_done[%d:%s]: %s\n",
759 (int)state->pid, state->cmd_name, nt_errstr(status)));
761 if (!NT_STATUS_IS_OK(status)) {
762 request_error(state);
769 * This is the main event loop of winbind requests. It goes through a
770 * state-machine of 3 read/write requests, 4 if you have extra data to send.
772 * An idle winbind client has a read request of 4 bytes outstanding,
773 * finalizing function is request_len_recv, checking the length. request_recv
774 * then processes the packet. The processing function then at some point has
775 * to call request_finished which schedules sending the response.
778 static void request_finished(struct winbindd_cli_state *state);
780 static void winbind_client_request_read(struct tevent_req *req);
781 static void winbind_client_response_written(struct tevent_req *req);
782 static void winbind_client_activity(struct tevent_req *req);
784 static void request_finished(struct winbindd_cli_state *state)
786 struct tevent_req *req;
788 /* free client socket monitoring request */
789 TALLOC_FREE(state->io_req);
791 TALLOC_FREE(state->request);
793 req = wb_resp_write_send(state, server_event_context(),
794 state->out_queue, state->sock,
797 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
798 (int)state->pid, state->cmd_name));
799 remove_client(state);
802 tevent_req_set_callback(req, winbind_client_response_written, state);
806 static void winbind_client_response_written(struct tevent_req *req)
808 struct winbindd_cli_state *state = tevent_req_callback_data(
809 req, struct winbindd_cli_state);
813 state->io_req = NULL;
815 ret = wb_resp_write_recv(req, &err);
820 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
821 (int)state->pid, state->cmd_name, strerror(err)));
822 remove_client(state);
826 DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
827 "to client\n", (int)state->pid, state->cmd_name));
829 TALLOC_FREE(state->mem_ctx);
830 state->response = NULL;
831 state->cmd_name = "no request";
832 state->recv_fn = NULL;
834 req = wb_req_read_send(state, server_event_context(), state->sock,
835 WINBINDD_MAX_EXTRA_DATA);
837 remove_client(state);
840 tevent_req_set_callback(req, winbind_client_request_read, state);
844 void request_error(struct winbindd_cli_state *state)
846 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
847 state->response->result = WINBINDD_ERROR;
848 request_finished(state);
851 void request_ok(struct winbindd_cli_state *state)
853 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
854 state->response->result = WINBINDD_OK;
855 request_finished(state);
858 /* Process a new connection by adding it to the client connection list */
860 static void new_connection(int listen_sock, bool privileged)
862 struct sockaddr_un sunaddr;
863 struct winbindd_cli_state *state;
864 struct tevent_req *req;
868 /* Accept connection */
870 len = sizeof(sunaddr);
872 sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
875 if (errno != EINTR) {
876 DEBUG(0, ("Failed to accept socket - %s\n",
882 DEBUG(6,("accepted socket %d\n", sock));
884 /* Create new connection structure */
886 if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
893 state->out_queue = tevent_queue_create(state, "winbind client reply");
894 if (state->out_queue == NULL) {
900 state->privileged = privileged;
902 req = wb_req_read_send(state, server_event_context(), state->sock,
903 WINBINDD_MAX_EXTRA_DATA);
909 tevent_req_set_callback(req, winbind_client_request_read, state);
912 /* Add to connection list */
914 winbindd_add_client(state);
917 static void winbind_client_request_read(struct tevent_req *req)
919 struct winbindd_cli_state *state = tevent_req_callback_data(
920 req, struct winbindd_cli_state);
924 state->io_req = NULL;
926 ret = wb_req_read_recv(req, state, &state->request, &err);
930 DEBUG(6, ("closing socket %d, client exited\n",
933 DEBUG(2, ("Could not read client request from fd %d: "
934 "%s\n", state->sock, strerror(err)));
938 remove_client(state);
942 req = wait_for_read_send(state, server_event_context(), state->sock,
945 DEBUG(0, ("winbind_client_request_read[%d:%s]:"
946 " wait_for_read_send failed - removing client\n",
947 (int)state->pid, state->cmd_name));
948 remove_client(state);
951 tevent_req_set_callback(req, winbind_client_activity, state);
954 process_request(state);
957 static void winbind_client_activity(struct tevent_req *req)
959 struct winbindd_cli_state *state =
960 tevent_req_callback_data(req, struct winbindd_cli_state);
964 has_data = wait_for_read_recv(req, &err);
967 DEBUG(0, ("winbind_client_activity[%d:%s]:"
968 "unexpected data from client - removing client\n",
969 (int)state->pid, state->cmd_name));
972 DEBUG(6, ("winbind_client_activity[%d:%s]: "
973 "client has closed connection - removing "
975 (int)state->pid, state->cmd_name));
977 DEBUG(2, ("winbind_client_activity[%d:%s]: "
978 "client socket error (%s) - removing "
980 (int)state->pid, state->cmd_name,
985 remove_client(state);
988 /* Remove a client connection from client connection list */
990 static void remove_client(struct winbindd_cli_state *state)
995 /* It's a dead client - hold a funeral */
1002 * We need to remove a pending wb_req_read_*
1003 * or wb_resp_write_* request before closing the
1006 * This is important as they might have used tevent_add_fd() and we
1007 * use the epoll * backend on linux. So we must remove the tevent_fd
1008 * before closing the fd.
1010 * Otherwise we might hit a race with close_conns_after_fork() (via
1011 * winbindd_reinit_after_fork()) where a file description
1012 * is still open in a child, which means it's still active in
1013 * the parents epoll queue, but the related tevent_fd is already
1014 * already gone in the parent.
1018 TALLOC_FREE(state->io_req);
1020 if (state->sock != -1) {
1021 /* tell client, we are closing ... */
1022 nwritten = write(state->sock, &c, sizeof(c));
1023 if (nwritten == -1) {
1024 DEBUG(2, ("final write to client failed: %s\n",
1034 TALLOC_FREE(state->mem_ctx);
1036 /* Remove from list and free */
1038 winbindd_remove_client(state);
1042 /* Is a client idle? */
1044 static bool client_is_idle(struct winbindd_cli_state *state) {
1045 return (state->request == NULL &&
1046 state->response == NULL &&
1047 !state->pwent_state && !state->grent_state);
1050 /* Shutdown client connection which has been idle for the longest time */
1052 static bool remove_idle_client(void)
1054 struct winbindd_cli_state *state, *remove_state = NULL;
1057 for (state = winbindd_client_list(); state; state = state->next) {
1058 if (client_is_idle(state)) {
1060 /* list is sorted by access time */
1061 remove_state = state;
1066 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1067 nidle, remove_state->sock, (unsigned int)remove_state->pid));
1068 remove_client(remove_state);
1076 * Terminate all clients whose requests have taken longer than
1077 * "winbind request timeout" seconds to process, or have been
1078 * idle for more than "winbind request timeout" seconds.
1081 static void remove_timed_out_clients(void)
1083 struct winbindd_cli_state *state, *prev = NULL;
1084 time_t curr_time = time(NULL);
1085 int timeout_val = lp_winbind_request_timeout();
1087 for (state = winbindd_client_list_tail(); state; state = prev) {
1090 prev = winbindd_client_list_prev(state);
1091 expiry_time = state->last_access + timeout_val;
1093 if (curr_time <= expiry_time) {
1094 /* list is sorted, previous clients in
1099 if (client_is_idle(state)) {
1100 DEBUG(5,("Idle client timed out, "
1101 "shutting down sock %d, pid %u\n",
1103 (unsigned int)state->pid));
1105 DEBUG(5,("Client request timed out, "
1106 "shutting down sock %d, pid %u\n",
1108 (unsigned int)state->pid));
1111 remove_client(state);
1115 static void winbindd_scrub_clients_handler(struct tevent_context *ev,
1116 struct tevent_timer *te,
1117 struct timeval current_time,
1120 remove_timed_out_clients();
1121 if (tevent_add_timer(ev, ev,
1122 timeval_current_ofs(SCRUB_CLIENTS_INTERVAL, 0),
1123 winbindd_scrub_clients_handler, NULL) == NULL) {
1124 DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
1129 struct winbindd_listen_state {
1134 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1135 struct tevent_fd *fde,
1139 struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1140 struct winbindd_listen_state);
1142 while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1143 DEBUG(5,("winbindd: Exceeding %d client "
1144 "connections, removing idle "
1145 "connection.\n", lp_winbind_max_clients()));
1146 if (!remove_idle_client()) {
1147 DEBUG(0,("winbindd: Exceeding %d "
1148 "client connections, no idle "
1149 "connection found\n",
1150 lp_winbind_max_clients()));
1154 remove_timed_out_clients();
1155 new_connection(s->fd, s->privileged);
1159 * Winbindd socket accessor functions
1162 char *get_winbind_priv_pipe_dir(void)
1164 return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1167 static void winbindd_setup_max_fds(void)
1169 int num_fds = MAX_OPEN_FUDGEFACTOR;
1172 num_fds += lp_winbind_max_clients();
1173 /* Add some more to account for 2 sockets open
1174 when the client transitions from unprivileged
1175 to privileged socket
1177 num_fds += lp_winbind_max_clients() / 10;
1179 /* Add one socket per child process
1180 (yeah there are child processes other than the
1181 domain children but only domain children can vary
1184 num_fds += lp_winbind_max_domain_connections() *
1185 (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
1187 actual_fds = set_maxfiles(num_fds);
1189 if (actual_fds < num_fds) {
1190 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1191 "requested %d open files, %d are available.\n",
1192 num_fds, actual_fds));
1196 static bool winbindd_setup_listeners(void)
1198 struct winbindd_listen_state *pub_state = NULL;
1199 struct winbindd_listen_state *priv_state = NULL;
1200 struct tevent_fd *fde;
1204 pub_state = talloc(server_event_context(),
1205 struct winbindd_listen_state);
1210 pub_state->privileged = false;
1211 pub_state->fd = create_pipe_sock(
1212 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1213 if (pub_state->fd == -1) {
1216 rc = listen(pub_state->fd, 5);
1221 fde = tevent_add_fd(server_event_context(), pub_state, pub_state->fd,
1222 TEVENT_FD_READ, winbindd_listen_fde_handler,
1225 close(pub_state->fd);
1228 tevent_fd_set_auto_close(fde);
1230 priv_state = talloc(server_event_context(),
1231 struct winbindd_listen_state);
1236 socket_path = get_winbind_priv_pipe_dir();
1237 if (socket_path == NULL) {
1241 priv_state->privileged = true;
1242 priv_state->fd = create_pipe_sock(
1243 socket_path, WINBINDD_SOCKET_NAME, 0750);
1244 TALLOC_FREE(socket_path);
1245 if (priv_state->fd == -1) {
1248 rc = listen(priv_state->fd, 5);
1253 fde = tevent_add_fd(server_event_context(), priv_state,
1254 priv_state->fd, TEVENT_FD_READ,
1255 winbindd_listen_fde_handler, priv_state);
1257 close(priv_state->fd);
1260 tevent_fd_set_auto_close(fde);
1262 winbindd_scrub_clients_handler(server_event_context(), NULL,
1263 timeval_current(), NULL);
1266 TALLOC_FREE(pub_state);
1267 TALLOC_FREE(priv_state);
1271 bool winbindd_use_idmap_cache(void)
1273 return !opt_nocache;
1276 bool winbindd_use_cache(void)
1278 return !opt_nocache;
1281 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1285 /* Setup signal handlers */
1287 if (!winbindd_setup_sig_term_handler(true))
1289 if (!winbindd_setup_stdin_handler(true, foreground))
1291 if (!winbindd_setup_sig_hup_handler(NULL))
1293 if (!winbindd_setup_sig_chld_handler())
1295 if (!winbindd_setup_sig_usr2_handler())
1298 CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
1301 * Ensure all cache and idmap caches are consistent
1302 * and initialized before we startup.
1304 if (!winbindd_cache_validate_and_initialize()) {
1308 /* get broadcast messages */
1310 if (!serverid_register(messaging_server_id(msg_ctx),
1314 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
1318 /* React on 'smbcontrol winbindd reload-config' in the same way
1319 as to SIGHUP signal */
1320 messaging_register(msg_ctx, NULL,
1321 MSG_SMB_CONF_UPDATED, msg_reload_services);
1322 messaging_register(msg_ctx, NULL,
1323 MSG_SHUTDOWN, msg_shutdown);
1325 /* Handle online/offline messages. */
1326 messaging_register(msg_ctx, NULL,
1327 MSG_WINBIND_OFFLINE, winbind_msg_offline);
1328 messaging_register(msg_ctx, NULL,
1329 MSG_WINBIND_ONLINE, winbind_msg_online);
1330 messaging_register(msg_ctx, NULL,
1331 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1333 /* Handle domain online/offline messages for domains */
1334 messaging_register(server_messaging_context(), NULL,
1335 MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1336 messaging_register(server_messaging_context(), NULL,
1337 MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1339 messaging_register(msg_ctx, NULL,
1340 MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
1342 messaging_register(msg_ctx, NULL,
1343 MSG_WINBIND_VALIDATE_CACHE,
1344 winbind_msg_validate_cache);
1346 messaging_register(msg_ctx, NULL,
1347 MSG_WINBIND_DUMP_DOMAIN_LIST,
1348 winbind_msg_dump_domain_list);
1350 messaging_register(msg_ctx, NULL,
1351 MSG_WINBIND_IP_DROPPED,
1352 winbind_msg_ip_dropped_parent);
1354 /* Register handler for MSG_DEBUG. */
1355 messaging_register(msg_ctx, NULL,
1359 netsamlogon_cache_init(); /* Non-critical */
1361 /* clear the cached list of trusted domains */
1365 if (!init_domain_list()) {
1366 DEBUG(0,("unable to initialize domain list\n"));
1371 init_locator_child();
1373 smb_nscd_flush_user_cache();
1374 smb_nscd_flush_group_cache();
1376 if (lp_allow_trusted_domains()) {
1377 if (tevent_add_timer(server_event_context(), NULL, timeval_zero(),
1378 rescan_trusted_domains, NULL) == NULL) {
1379 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1384 status = wb_irpc_register();
1386 if (!NT_STATUS_IS_OK(status)) {
1387 DEBUG(0, ("Could not register IRPC handlers\n"));
1392 struct winbindd_addrchanged_state {
1393 struct addrchange_context *ctx;
1394 struct tevent_context *ev;
1395 struct messaging_context *msg_ctx;
1398 static void winbindd_addr_changed(struct tevent_req *req);
1400 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1401 struct tevent_context *ev,
1402 struct messaging_context *msg_ctx)
1404 struct winbindd_addrchanged_state *state;
1405 struct tevent_req *req;
1408 state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1409 if (state == NULL) {
1410 DEBUG(10, ("talloc failed\n"));
1414 state->msg_ctx = msg_ctx;
1416 status = addrchange_context_create(state, &state->ctx);
1417 if (!NT_STATUS_IS_OK(status)) {
1418 DEBUG(10, ("addrchange_context_create failed: %s\n",
1419 nt_errstr(status)));
1423 req = addrchange_send(state, ev, state->ctx);
1425 DEBUG(0, ("addrchange_send failed\n"));
1429 tevent_req_set_callback(req, winbindd_addr_changed, state);
1432 static void winbindd_addr_changed(struct tevent_req *req)
1434 struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1435 req, struct winbindd_addrchanged_state);
1436 enum addrchange_type type;
1437 struct sockaddr_storage addr;
1440 status = addrchange_recv(req, &type, &addr);
1442 if (!NT_STATUS_IS_OK(status)) {
1443 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1444 nt_errstr(status)));
1448 if (type == ADDRCHANGE_DEL) {
1449 char addrstr[INET6_ADDRSTRLEN];
1452 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1454 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1457 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1459 status = messaging_send(state->msg_ctx,
1460 messaging_server_id(state->msg_ctx),
1461 MSG_WINBIND_IP_DROPPED, &blob);
1462 if (!NT_STATUS_IS_OK(status)) {
1463 DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1464 nt_errstr(status)));
1467 req = addrchange_send(state, state->ev, state->ctx);
1469 DEBUG(0, ("addrchange_send failed\n"));
1473 tevent_req_set_callback(req, winbindd_addr_changed, state);
1478 int main(int argc, const char **argv)
1480 static bool is_daemon = False;
1481 static bool Fork = True;
1482 static bool log_stdout = False;
1483 static bool no_process_group = False;
1487 OPT_NO_PROCESS_GROUP,
1490 struct poptOption long_options[] = {
1492 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1493 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1494 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1495 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1496 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1497 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1508 * Do this before any other talloc operation
1510 talloc_enable_null_tracking();
1511 frame = talloc_stackframe();
1514 * We want total control over the permissions on created files,
1515 * so set our umask to 0.
1519 setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1521 /* glibc (?) likes to print "User defined signal 1" and exit if a
1522 SIGUSR[12] is received before a handler is installed */
1524 CatchSignal(SIGUSR1, SIG_IGN);
1525 CatchSignal(SIGUSR2, SIG_IGN);
1528 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1532 /* Initialise for running in non-root mode */
1536 set_remote_machine_name("winbindd", False);
1538 /* Set environment variable so we don't recursively call ourselves.
1539 This may also be useful interactively. */
1541 if ( !winbind_off() ) {
1542 DEBUG(0,("Failed to disable recusive winbindd calls. Exiting.\n"));
1546 /* Initialise samba/rpc client stuff */
1548 pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1550 while ((opt = poptGetNextOpt(pc)) != -1) {
1552 /* Don't become a daemon */
1564 case OPT_NO_PROCESS_GROUP:
1565 no_process_group = true;
1567 case OPT_LOG_STDOUT:
1574 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1575 poptBadOption(pc, 0), poptStrerror(opt));
1576 poptPrintUsage(pc, stderr, 0);
1581 /* We call dump_core_setup one more time because the command line can
1582 * set the log file or the log-basename and this will influence where
1583 * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1584 * the default value derived from build's prefix. For EOM this value
1585 * is often not related to the path where winbindd is actually run
1588 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1589 if (is_daemon && interactive) {
1590 d_fprintf(stderr,"\nERROR: "
1591 "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1592 poptPrintUsage(pc, stderr, 0);
1596 if (log_stdout && Fork) {
1597 d_fprintf(stderr, "\nERROR: "
1598 "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1599 poptPrintUsage(pc, stderr, 0);
1603 poptFreeContext(pc);
1605 if (!override_logfile) {
1607 if (asprintf(&lfile,"%s/log.winbindd",
1608 get_dyn_LOGFILEBASE()) > 0) {
1609 lp_set_logfile(lfile);
1615 setup_logging("winbindd", DEBUG_STDOUT);
1617 setup_logging("winbindd", DEBUG_FILE);
1621 DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1622 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1624 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1625 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1628 /* After parsing the configuration file we setup the core path one more time
1629 * as the log file might have been set in the configuration and cores's
1630 * path is by default basename(lp_logfile()).
1632 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1634 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1635 && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1636 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1637 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"));
1641 if (!cluster_probe_ok()) {
1645 /* Initialise messaging system */
1647 if (server_messaging_context() == NULL) {
1651 if (!reload_services_file(NULL)) {
1652 DEBUG(0, ("error opening config file\n"));
1658 const char *idmap_backend;
1659 const char *invalid_backends[] = {
1660 "ad", "rfc2307", "rid",
1663 idmap_backend = lp_idmap_default_backend();
1664 for (i = 0; i < ARRAY_SIZE(invalid_backends); i++) {
1665 ok = strequal(idmap_backend, invalid_backends[i]);
1667 DBG_ERR("FATAL: Invalid idmap backend %s "
1668 "configured as the default backend!\n",
1675 ok = directory_create_or_exist(lp_lock_directory(), 0755);
1677 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1678 lp_lock_directory(), strerror(errno)));
1682 ok = directory_create_or_exist(lp_pid_directory(), 0755);
1684 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1685 lp_pid_directory(), strerror(errno)));
1696 if (!secrets_init()) {
1698 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1702 status = rpccli_pre_open_netlogon_creds();
1703 if (!NT_STATUS_IS_OK(status)) {
1704 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1705 nt_errstr(status)));
1709 /* Unblock all signals we are interested in as they may have been
1710 blocked by the parent process. */
1712 BlockSignals(False, SIGINT);
1713 BlockSignals(False, SIGQUIT);
1714 BlockSignals(False, SIGTERM);
1715 BlockSignals(False, SIGUSR1);
1716 BlockSignals(False, SIGUSR2);
1717 BlockSignals(False, SIGHUP);
1718 BlockSignals(False, SIGCHLD);
1721 become_daemon(Fork, no_process_group, log_stdout);
1723 pidfile_create(lp_pid_directory(), "winbindd");
1727 * If we're interactive we want to set our own process group for
1728 * signal management.
1730 if (interactive && !no_process_group)
1731 setpgid( (pid_t)0, (pid_t)0);
1736 /* Don't use winbindd_reinit_after_fork here as
1737 * we're just starting up and haven't created any
1738 * winbindd-specific resources we must free yet. JRA.
1741 status = reinit_after_fork(server_messaging_context(),
1742 server_event_context(),
1744 if (!NT_STATUS_IS_OK(status)) {
1745 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1749 * Do not initialize the parent-child-pipe before becoming
1750 * a daemon: this is used to detect a died parent in the child
1753 status = init_before_fork();
1754 if (!NT_STATUS_IS_OK(status)) {
1755 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1758 winbindd_register_handlers(server_messaging_context(), !Fork);
1760 if (!messaging_parent_dgm_cleanup_init(server_messaging_context())) {
1764 status = init_system_session_info();
1765 if (!NT_STATUS_IS_OK(status)) {
1766 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1769 rpc_lsarpc_init(NULL);
1770 rpc_samr_init(NULL);
1772 winbindd_init_addrchange(NULL, server_event_context(),
1773 server_messaging_context());
1775 /* setup listen sockets */
1777 if (!winbindd_setup_listeners()) {
1778 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1781 irpc_add_name(winbind_imessaging_context(), "winbind_server");
1786 daemon_ready("winbindd");
1789 /* Loop waiting for requests */
1791 frame = talloc_stackframe();
1793 if (tevent_loop_once(server_event_context()) == -1) {
1794 DEBUG(1, ("tevent_loop_once() failed: %s\n",