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 static bool client_is_idle(struct winbindd_cli_state *state);
51 static void remove_client(struct winbindd_cli_state *state);
52 static void winbindd_setup_max_fds(void);
54 static bool opt_nocache = False;
55 static bool interactive = False;
57 extern bool override_logfile;
59 struct tevent_context *winbind_event_context(void)
61 static struct tevent_context *ev = NULL;
68 * Note we MUST use the NULL context here, not the autofree context,
69 * to avoid side effects in forked children exiting.
71 ev = samba_tevent_context_init(NULL);
73 smb_panic("Could not init winbindd's messaging context.\n");
78 struct messaging_context *winbind_messaging_context(void)
80 static struct messaging_context *msg = NULL;
87 * Note we MUST use the NULL context here, not the autofree context,
88 * to avoid side effects in forked children exiting.
90 msg = messaging_init(NULL, winbind_event_context());
92 smb_panic("Could not init winbindd's messaging context.\n");
97 struct imessaging_context *winbind_imessaging_context(void)
99 static struct imessaging_context *msg = NULL;
100 struct loadparm_context *lp_ctx;
106 lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
107 if (lp_ctx == NULL) {
108 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
112 * Note we MUST use the NULL context here, not the autofree context,
113 * to avoid side effects in forked children exiting.
115 msg = imessaging_init(NULL, lp_ctx, procid_self(), winbind_event_context(), false);
116 talloc_unlink(NULL, lp_ctx);
119 smb_panic("Could not init winbindd's messaging context.\n");
124 /* Reload configuration */
126 static bool reload_services_file(const char *lfile)
131 char *fname = lp_next_configfile(talloc_tos());
133 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
134 set_dyn_CONFIGFILE(fname);
139 /* if this is a child, restore the logfile to the special
140 name - <domain>, idmap, etc. */
141 if (lfile && *lfile) {
142 lp_set_logfile(lfile);
146 ret = lp_load_global(get_dyn_CONFIGFILE());
150 winbindd_setup_max_fds();
156 static void winbindd_status(void)
158 struct winbindd_cli_state *tmp;
160 DEBUG(0, ("winbindd status:\n"));
162 /* Print client state information */
164 DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
166 if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
167 DEBUG(2, ("\tclient list:\n"));
168 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
169 DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
170 (unsigned long)tmp->pid, tmp->sock,
171 client_is_idle(tmp) ? "idle" : "active"));
176 /* Flush client cache */
178 static void flush_caches(void)
180 /* We need to invalidate cached user list entries on a SIGHUP
181 otherwise cached access denied errors due to restrict anonymous
182 hang around until the sequence number changes. */
184 if (!wcache_invalidate_cache()) {
185 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
186 if (!winbindd_cache_validate_and_initialize()) {
192 static void flush_caches_noinit(void)
195 * We need to invalidate cached user list entries on a SIGHUP
196 * otherwise cached access denied errors due to restrict anonymous
197 * hang around until the sequence number changes.
199 * Skip uninitialized domains when flush cache.
200 * If domain is not initialized, it means it is never
201 * used or never become online. look, wcache_invalidate_cache()
202 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
203 * for unused domains and large traffic for primay domain's DC if there
207 if (!wcache_invalidate_cache_noinit()) {
208 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
209 if (!winbindd_cache_validate_and_initialize()) {
215 /* Handle the signal by unlinking socket and exiting */
217 static void terminate(bool is_parent)
220 /* When parent goes away we should
221 * remove the socket file. Not so
222 * when children terminate.
226 if (asprintf(&path, "%s/%s",
227 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) {
235 trustdom_cache_shutdown();
237 gencache_stabilize();
241 TALLOC_CTX *mem_ctx = talloc_init("end_description");
242 char *description = talloc_describe_all(mem_ctx);
244 DEBUG(3, ("tallocs left:\n%s\n", description));
245 talloc_destroy(mem_ctx);
250 struct messaging_context *msg = winbind_messaging_context();
251 struct server_id self = messaging_server_id(msg);
252 serverid_deregister(self);
253 pidfile_unlink(lp_pid_directory(), "winbindd");
259 static void winbindd_sig_term_handler(struct tevent_context *ev,
260 struct tevent_signal *se,
266 bool *is_parent = talloc_get_type_abort(private_data, bool);
268 DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
269 signum, (int)*is_parent));
270 terminate(*is_parent);
274 handle stdin becoming readable when we are in --foreground mode
276 static void winbindd_stdin_handler(struct tevent_context *ev,
277 struct tevent_fd *fde,
282 if (read(0, &c, 1) != 1) {
283 bool *is_parent = talloc_get_type_abort(private_data, bool);
285 /* we have reached EOF on stdin, which means the
286 parent has exited. Shutdown the server */
287 DEBUG(0,("EOF on stdin (is_parent=%d)\n",
289 terminate(*is_parent);
293 bool winbindd_setup_sig_term_handler(bool parent)
295 struct tevent_signal *se;
298 is_parent = talloc(winbind_event_context(), bool);
305 se = tevent_add_signal(winbind_event_context(),
308 winbindd_sig_term_handler,
311 DEBUG(0,("failed to setup SIGTERM handler"));
312 talloc_free(is_parent);
316 se = tevent_add_signal(winbind_event_context(),
319 winbindd_sig_term_handler,
322 DEBUG(0,("failed to setup SIGINT 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);
341 bool winbindd_setup_stdin_handler(bool parent, bool foreground)
348 is_parent = talloc(winbind_event_context(), bool);
355 /* if we are running in the foreground then look for
356 EOF on stdin, and exit if it happens. This allows
357 us to die if the parent process dies
358 Only do this on a pipe or socket, no other device.
360 if (fstat(0, &st) != 0) {
363 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
364 tevent_add_fd(winbind_event_context(),
368 winbindd_stdin_handler,
376 static void winbindd_sig_hup_handler(struct tevent_context *ev,
377 struct tevent_signal *se,
383 const char *file = (const char *)private_data;
385 DEBUG(1,("Reloading services after SIGHUP\n"));
386 flush_caches_noinit();
387 reload_services_file(file);
390 bool winbindd_setup_sig_hup_handler(const char *lfile)
392 struct tevent_signal *se;
396 file = talloc_strdup(winbind_event_context(),
403 se = tevent_add_signal(winbind_event_context(),
404 winbind_event_context(),
406 winbindd_sig_hup_handler,
415 static void winbindd_sig_chld_handler(struct tevent_context *ev,
416 struct tevent_signal *se,
424 while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) {
425 winbind_child_died(pid);
429 static bool winbindd_setup_sig_chld_handler(void)
431 struct tevent_signal *se;
433 se = tevent_add_signal(winbind_event_context(),
434 winbind_event_context(),
436 winbindd_sig_chld_handler,
445 static void winbindd_sig_usr2_handler(struct tevent_context *ev,
446 struct tevent_signal *se,
455 static bool winbindd_setup_sig_usr2_handler(void)
457 struct tevent_signal *se;
459 se = tevent_add_signal(winbind_event_context(),
460 winbind_event_context(),
462 winbindd_sig_usr2_handler,
471 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
472 static void msg_reload_services(struct messaging_context *msg,
475 struct server_id server_id,
478 /* Flush various caches */
480 reload_services_file((const char *) private_data);
483 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
484 static void msg_shutdown(struct messaging_context *msg,
487 struct server_id server_id,
490 /* only the parent waits for this message */
491 DEBUG(0,("Got shutdown message\n"));
496 static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
499 struct server_id server_id,
506 DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
510 * call the validation code from a child:
511 * so we don't block the main winbindd and the validation
512 * code can safely use fork/waitpid...
516 if (child_pid == -1) {
517 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
522 if (child_pid != 0) {
524 DEBUG(5, ("winbind_msg_validate_cache: child created with "
525 "pid %d.\n", (int)child_pid));
531 status = winbindd_reinit_after_fork(NULL, NULL);
532 if (!NT_STATUS_IS_OK(status)) {
533 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
538 /* install default SIGCHLD handler: validation code uses fork/waitpid */
539 CatchSignal(SIGCHLD, SIG_DFL);
541 ret = (uint8_t)winbindd_validate_cache_nobackup();
542 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
543 messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
548 static struct winbindd_dispatch_table {
549 enum winbindd_cmd cmd;
550 void (*fn)(struct winbindd_cli_state *state);
551 const char *winbindd_cmd_name;
552 } dispatch_table[] = {
554 /* Enumeration functions */
556 { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
561 { WINBINDD_INFO, winbindd_info, "INFO" },
562 { WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
563 "INTERFACE_VERSION" },
564 { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
565 { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
566 { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" },
567 { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
568 { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
569 "WINBINDD_PRIV_PIPE_DIR" },
571 /* Credential cache access */
572 { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
573 { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
577 { WINBINDD_NUM_CMDS, NULL, "NONE" }
580 struct winbindd_async_dispatch_table {
581 enum winbindd_cmd cmd;
582 const char *cmd_name;
583 struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
584 struct tevent_context *ev,
585 struct winbindd_cli_state *cli,
586 struct winbindd_request *request);
587 NTSTATUS (*recv_req)(struct tevent_req *req,
588 struct winbindd_response *presp);
591 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
592 { WINBINDD_PING, "PING",
593 wb_ping_send, wb_ping_recv },
594 { WINBINDD_LOOKUPSID, "LOOKUPSID",
595 winbindd_lookupsid_send, winbindd_lookupsid_recv },
596 { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
597 winbindd_lookupsids_send, winbindd_lookupsids_recv },
598 { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
599 winbindd_lookupname_send, winbindd_lookupname_recv },
600 { WINBINDD_SID_TO_UID, "SID_TO_UID",
601 winbindd_sid_to_uid_send, winbindd_sid_to_uid_recv },
602 { WINBINDD_SID_TO_GID, "SID_TO_GID",
603 winbindd_sid_to_gid_send, winbindd_sid_to_gid_recv },
604 { WINBINDD_UID_TO_SID, "UID_TO_SID",
605 winbindd_uid_to_sid_send, winbindd_uid_to_sid_recv },
606 { WINBINDD_GID_TO_SID, "GID_TO_SID",
607 winbindd_gid_to_sid_send, winbindd_gid_to_sid_recv },
608 { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
609 winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
610 { WINBINDD_GETPWSID, "GETPWSID",
611 winbindd_getpwsid_send, winbindd_getpwsid_recv },
612 { WINBINDD_GETPWNAM, "GETPWNAM",
613 winbindd_getpwnam_send, winbindd_getpwnam_recv },
614 { WINBINDD_GETPWUID, "GETPWUID",
615 winbindd_getpwuid_send, winbindd_getpwuid_recv },
616 { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
617 winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
618 { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
619 winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
620 { WINBINDD_GETGROUPS, "GETGROUPS",
621 winbindd_getgroups_send, winbindd_getgroups_recv },
622 { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
623 winbindd_show_sequence_send, winbindd_show_sequence_recv },
624 { WINBINDD_GETGRGID, "GETGRGID",
625 winbindd_getgrgid_send, winbindd_getgrgid_recv },
626 { WINBINDD_GETGRNAM, "GETGRNAM",
627 winbindd_getgrnam_send, winbindd_getgrnam_recv },
628 { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
629 winbindd_getusersids_send, winbindd_getusersids_recv },
630 { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
631 winbindd_lookuprids_send, winbindd_lookuprids_recv },
632 { WINBINDD_SETPWENT, "SETPWENT",
633 winbindd_setpwent_send, winbindd_setpwent_recv },
634 { WINBINDD_GETPWENT, "GETPWENT",
635 winbindd_getpwent_send, winbindd_getpwent_recv },
636 { WINBINDD_ENDPWENT, "ENDPWENT",
637 winbindd_endpwent_send, winbindd_endpwent_recv },
638 { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
639 winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
640 { WINBINDD_GETDCNAME, "GETDCNAME",
641 winbindd_getdcname_send, winbindd_getdcname_recv },
642 { WINBINDD_SETGRENT, "SETGRENT",
643 winbindd_setgrent_send, winbindd_setgrent_recv },
644 { WINBINDD_GETGRENT, "GETGRENT",
645 winbindd_getgrent_send, winbindd_getgrent_recv },
646 { WINBINDD_ENDGRENT, "ENDGRENT",
647 winbindd_endgrent_send, winbindd_endgrent_recv },
648 { WINBINDD_LIST_USERS, "LIST_USERS",
649 winbindd_list_users_send, winbindd_list_users_recv },
650 { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
651 winbindd_list_groups_send, winbindd_list_groups_recv },
652 { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
653 winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
654 { WINBINDD_PING_DC, "PING_DC",
655 winbindd_ping_dc_send, winbindd_ping_dc_recv },
656 { WINBINDD_PAM_AUTH, "PAM_AUTH",
657 winbindd_pam_auth_send, winbindd_pam_auth_recv },
658 { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
659 winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
660 { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
661 winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
662 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
663 winbindd_pam_chng_pswd_auth_crap_send,
664 winbindd_pam_chng_pswd_auth_crap_recv },
665 { WINBINDD_WINS_BYIP, "WINS_BYIP",
666 winbindd_wins_byip_send, winbindd_wins_byip_recv },
667 { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
668 winbindd_wins_byname_send, winbindd_wins_byname_recv },
670 { 0, NULL, NULL, NULL }
673 static struct winbindd_async_dispatch_table async_priv_table[] = {
674 { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
675 winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
676 { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
677 winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
678 { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
679 winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
680 { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
681 winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
683 { 0, NULL, NULL, NULL }
686 static void wb_request_done(struct tevent_req *req);
688 static void process_request(struct winbindd_cli_state *state)
690 struct winbindd_dispatch_table *table = dispatch_table;
691 struct winbindd_async_dispatch_table *atable;
693 state->mem_ctx = talloc_named(state, 0, "winbind request");
694 if (state->mem_ctx == NULL)
697 /* Remember who asked us. */
698 state->pid = state->request->pid;
700 state->cmd_name = "unknown request";
701 state->recv_fn = NULL;
702 state->last_access = time(NULL);
704 /* Process command */
706 for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
707 if (state->request->cmd == atable->cmd) {
712 if ((atable->send_req == NULL) && state->privileged) {
713 for (atable = async_priv_table; atable->send_req;
715 if (state->request->cmd == atable->cmd) {
721 if (atable->send_req != NULL) {
722 struct tevent_req *req;
724 state->cmd_name = atable->cmd_name;
725 state->recv_fn = atable->recv_req;
727 DEBUG(10, ("process_request: Handling async request %d:%s\n",
728 (int)state->pid, state->cmd_name));
730 req = atable->send_req(state->mem_ctx, winbind_event_context(),
731 state, state->request);
733 DEBUG(0, ("process_request: atable->send failed for "
734 "%s\n", atable->cmd_name));
735 request_error(state);
738 tevent_req_set_callback(req, wb_request_done, state);
742 state->response = talloc_zero(state->mem_ctx,
743 struct winbindd_response);
744 if (state->response == NULL) {
745 DEBUG(10, ("talloc failed\n"));
746 remove_client(state);
749 state->response->result = WINBINDD_PENDING;
750 state->response->length = sizeof(struct winbindd_response);
752 for (table = dispatch_table; table->fn; table++) {
753 if (state->request->cmd == table->cmd) {
754 DEBUG(10,("process_request: request fn %s\n",
755 table->winbindd_cmd_name ));
756 state->cmd_name = table->winbindd_cmd_name;
763 DEBUG(10,("process_request: unknown request fn number %d\n",
764 (int)state->request->cmd ));
765 request_error(state);
769 static void wb_request_done(struct tevent_req *req)
771 struct winbindd_cli_state *state = tevent_req_callback_data(
772 req, struct winbindd_cli_state);
775 state->response = talloc_zero(state->mem_ctx,
776 struct winbindd_response);
777 if (state->response == NULL) {
778 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
779 (int)state->pid, state->cmd_name));
780 remove_client(state);
783 state->response->result = WINBINDD_PENDING;
784 state->response->length = sizeof(struct winbindd_response);
786 status = state->recv_fn(req, state->response);
789 DEBUG(10,("wb_request_done[%d:%s]: %s\n",
790 (int)state->pid, state->cmd_name, nt_errstr(status)));
792 if (!NT_STATUS_IS_OK(status)) {
793 request_error(state);
800 * This is the main event loop of winbind requests. It goes through a
801 * state-machine of 3 read/write requests, 4 if you have extra data to send.
803 * An idle winbind client has a read request of 4 bytes outstanding,
804 * finalizing function is request_len_recv, checking the length. request_recv
805 * then processes the packet. The processing function then at some point has
806 * to call request_finished which schedules sending the response.
809 static void request_finished(struct winbindd_cli_state *state);
811 static void winbind_client_request_read(struct tevent_req *req);
812 static void winbind_client_response_written(struct tevent_req *req);
813 static void winbind_client_activity(struct tevent_req *req);
815 static void request_finished(struct winbindd_cli_state *state)
817 struct tevent_req *req;
819 /* free client socket monitoring request */
820 TALLOC_FREE(state->io_req);
822 TALLOC_FREE(state->request);
824 req = wb_resp_write_send(state, winbind_event_context(),
825 state->out_queue, state->sock,
828 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
829 (int)state->pid, state->cmd_name));
830 remove_client(state);
833 tevent_req_set_callback(req, winbind_client_response_written, state);
837 static void winbind_client_response_written(struct tevent_req *req)
839 struct winbindd_cli_state *state = tevent_req_callback_data(
840 req, struct winbindd_cli_state);
844 state->io_req = NULL;
846 ret = wb_resp_write_recv(req, &err);
851 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
852 (int)state->pid, state->cmd_name, strerror(err)));
853 remove_client(state);
857 DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
858 "to client\n", (int)state->pid, state->cmd_name));
860 TALLOC_FREE(state->mem_ctx);
861 state->response = NULL;
862 state->cmd_name = "no request";
863 state->recv_fn = NULL;
865 req = wb_req_read_send(state, winbind_event_context(), state->sock,
866 WINBINDD_MAX_EXTRA_DATA);
868 remove_client(state);
871 tevent_req_set_callback(req, winbind_client_request_read, state);
875 void request_error(struct winbindd_cli_state *state)
877 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
878 state->response->result = WINBINDD_ERROR;
879 request_finished(state);
882 void request_ok(struct winbindd_cli_state *state)
884 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
885 state->response->result = WINBINDD_OK;
886 request_finished(state);
889 /* Process a new connection by adding it to the client connection list */
891 static void new_connection(int listen_sock, bool privileged)
893 struct sockaddr_un sunaddr;
894 struct winbindd_cli_state *state;
895 struct tevent_req *req;
899 /* Accept connection */
901 len = sizeof(sunaddr);
903 sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
906 if (errno != EINTR) {
907 DEBUG(0, ("Failed to accept socket - %s\n",
913 DEBUG(6,("accepted socket %d\n", sock));
915 /* Create new connection structure */
917 if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
924 state->out_queue = tevent_queue_create(state, "winbind client reply");
925 if (state->out_queue == NULL) {
931 state->last_access = time(NULL);
933 state->privileged = privileged;
935 req = wb_req_read_send(state, winbind_event_context(), state->sock,
936 WINBINDD_MAX_EXTRA_DATA);
942 tevent_req_set_callback(req, winbind_client_request_read, state);
945 /* Add to connection list */
947 winbindd_add_client(state);
950 static void winbind_client_request_read(struct tevent_req *req)
952 struct winbindd_cli_state *state = tevent_req_callback_data(
953 req, struct winbindd_cli_state);
957 state->io_req = NULL;
959 ret = wb_req_read_recv(req, state, &state->request, &err);
963 DEBUG(6, ("closing socket %d, client exited\n",
966 DEBUG(2, ("Could not read client request from fd %d: "
967 "%s\n", state->sock, strerror(err)));
971 remove_client(state);
975 req = wait_for_read_send(state, winbind_event_context(), state->sock,
978 DEBUG(0, ("winbind_client_request_read[%d:%s]:"
979 " wait_for_read_send failed - removing client\n",
980 (int)state->pid, state->cmd_name));
981 remove_client(state);
984 tevent_req_set_callback(req, winbind_client_activity, state);
987 process_request(state);
990 static void winbind_client_activity(struct tevent_req *req)
992 struct winbindd_cli_state *state =
993 tevent_req_callback_data(req, struct winbindd_cli_state);
997 has_data = wait_for_read_recv(req, &err);
1000 DEBUG(0, ("winbind_client_activity[%d:%s]:"
1001 "unexpected data from client - removing client\n",
1002 (int)state->pid, state->cmd_name));
1005 DEBUG(6, ("winbind_client_activity[%d:%s]: "
1006 "client has closed connection - removing "
1008 (int)state->pid, state->cmd_name));
1010 DEBUG(2, ("winbind_client_activity[%d:%s]: "
1011 "client socket error (%s) - removing "
1013 (int)state->pid, state->cmd_name,
1018 remove_client(state);
1021 /* Remove a client connection from client connection list */
1023 static void remove_client(struct winbindd_cli_state *state)
1028 /* It's a dead client - hold a funeral */
1030 if (state == NULL) {
1035 * We need to remove a pending wb_req_read_*
1036 * or wb_resp_write_* request before closing the
1039 * This is important as they might have used tevent_add_fd() and we
1040 * use the epoll * backend on linux. So we must remove the tevent_fd
1041 * before closing the fd.
1043 * Otherwise we might hit a race with close_conns_after_fork() (via
1044 * winbindd_reinit_after_fork()) where a file description
1045 * is still open in a child, which means it's still active in
1046 * the parents epoll queue, but the related tevent_fd is already
1047 * already gone in the parent.
1051 TALLOC_FREE(state->io_req);
1053 if (state->sock != -1) {
1054 /* tell client, we are closing ... */
1055 nwritten = write(state->sock, &c, sizeof(c));
1056 if (nwritten == -1) {
1057 DEBUG(2, ("final write to client failed: %s\n",
1067 TALLOC_FREE(state->mem_ctx);
1069 /* Remove from list and free */
1071 winbindd_remove_client(state);
1075 /* Is a client idle? */
1077 static bool client_is_idle(struct winbindd_cli_state *state) {
1078 return (state->request == NULL &&
1079 state->response == NULL &&
1080 !state->pwent_state && !state->grent_state);
1083 /* Shutdown client connection which has been idle for the longest time */
1085 static bool remove_idle_client(void)
1087 struct winbindd_cli_state *state, *remove_state = NULL;
1088 time_t last_access = 0;
1091 for (state = winbindd_client_list(); state; state = state->next) {
1092 if (client_is_idle(state)) {
1094 if (!last_access || state->last_access < last_access) {
1095 last_access = state->last_access;
1096 remove_state = state;
1102 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1103 nidle, remove_state->sock, (unsigned int)remove_state->pid));
1104 remove_client(remove_state);
1112 * Terminate all clients whose requests have taken longer than
1113 * "winbind request timeout" seconds to process, or have been
1114 * idle for more than "winbind request timeout" seconds.
1117 static void remove_timed_out_clients(void)
1119 struct winbindd_cli_state *state, *next = NULL;
1120 time_t curr_time = time(NULL);
1121 int timeout_val = lp_winbind_request_timeout();
1123 for (state = winbindd_client_list(); state; state = next) {
1127 expiry_time = state->last_access + timeout_val;
1129 if (curr_time > expiry_time) {
1130 if (client_is_idle(state)) {
1131 DEBUG(5,("Idle client timed out, "
1132 "shutting down sock %d, pid %u\n",
1134 (unsigned int)state->pid));
1136 DEBUG(5,("Client request timed out, "
1137 "shutting down sock %d, pid %u\n",
1139 (unsigned int)state->pid));
1141 remove_client(state);
1146 struct winbindd_listen_state {
1151 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1152 struct tevent_fd *fde,
1156 struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1157 struct winbindd_listen_state);
1159 while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1160 DEBUG(5,("winbindd: Exceeding %d client "
1161 "connections, removing idle "
1162 "connection.\n", lp_winbind_max_clients()));
1163 if (!remove_idle_client()) {
1164 DEBUG(0,("winbindd: Exceeding %d "
1165 "client connections, no idle "
1166 "connection found\n",
1167 lp_winbind_max_clients()));
1171 remove_timed_out_clients();
1172 new_connection(s->fd, s->privileged);
1176 * Winbindd socket accessor functions
1179 char *get_winbind_priv_pipe_dir(void)
1181 return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1184 static void winbindd_setup_max_fds(void)
1186 int num_fds = MAX_OPEN_FUDGEFACTOR;
1189 num_fds += lp_winbind_max_clients();
1190 /* Add some more to account for 2 sockets open
1191 when the client transitions from unprivileged
1192 to privileged socket
1194 num_fds += lp_winbind_max_clients() / 10;
1196 /* Add one socket per child process
1197 (yeah there are child processes other than the
1198 domain children but only domain children can vary
1201 num_fds += lp_winbind_max_domain_connections() *
1202 (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
1204 actual_fds = set_maxfiles(num_fds);
1206 if (actual_fds < num_fds) {
1207 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1208 "requested %d open files, %d are available.\n",
1209 num_fds, actual_fds));
1213 static bool winbindd_setup_listeners(void)
1215 struct winbindd_listen_state *pub_state = NULL;
1216 struct winbindd_listen_state *priv_state = NULL;
1217 struct tevent_fd *fde;
1221 pub_state = talloc(winbind_event_context(),
1222 struct winbindd_listen_state);
1227 pub_state->privileged = false;
1228 pub_state->fd = create_pipe_sock(
1229 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1230 if (pub_state->fd == -1) {
1233 rc = listen(pub_state->fd, 5);
1238 fde = tevent_add_fd(winbind_event_context(), pub_state, pub_state->fd,
1239 TEVENT_FD_READ, winbindd_listen_fde_handler,
1242 close(pub_state->fd);
1245 tevent_fd_set_auto_close(fde);
1247 priv_state = talloc(winbind_event_context(),
1248 struct winbindd_listen_state);
1253 socket_path = get_winbind_priv_pipe_dir();
1254 if (socket_path == NULL) {
1258 priv_state->privileged = true;
1259 priv_state->fd = create_pipe_sock(
1260 socket_path, WINBINDD_SOCKET_NAME, 0750);
1261 TALLOC_FREE(socket_path);
1262 if (priv_state->fd == -1) {
1265 rc = listen(priv_state->fd, 5);
1270 fde = tevent_add_fd(winbind_event_context(), priv_state,
1271 priv_state->fd, TEVENT_FD_READ,
1272 winbindd_listen_fde_handler, priv_state);
1274 close(priv_state->fd);
1277 tevent_fd_set_auto_close(fde);
1281 TALLOC_FREE(pub_state);
1282 TALLOC_FREE(priv_state);
1286 bool winbindd_use_idmap_cache(void)
1288 return !opt_nocache;
1291 bool winbindd_use_cache(void)
1293 return !opt_nocache;
1296 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1300 /* Setup signal handlers */
1302 if (!winbindd_setup_sig_term_handler(true))
1304 if (!winbindd_setup_stdin_handler(true, foreground))
1306 if (!winbindd_setup_sig_hup_handler(NULL))
1308 if (!winbindd_setup_sig_chld_handler())
1310 if (!winbindd_setup_sig_usr2_handler())
1313 CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
1316 * Ensure all cache and idmap caches are consistent
1317 * and initialized before we startup.
1319 if (!winbindd_cache_validate_and_initialize()) {
1323 /* get broadcast messages */
1325 if (!serverid_register(messaging_server_id(msg_ctx),
1329 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
1333 /* React on 'smbcontrol winbindd reload-config' in the same way
1334 as to SIGHUP signal */
1335 messaging_register(msg_ctx, NULL,
1336 MSG_SMB_CONF_UPDATED, msg_reload_services);
1337 messaging_register(msg_ctx, NULL,
1338 MSG_SHUTDOWN, msg_shutdown);
1340 /* Handle online/offline messages. */
1341 messaging_register(msg_ctx, NULL,
1342 MSG_WINBIND_OFFLINE, winbind_msg_offline);
1343 messaging_register(msg_ctx, NULL,
1344 MSG_WINBIND_ONLINE, winbind_msg_online);
1345 messaging_register(msg_ctx, NULL,
1346 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1348 /* Handle domain online/offline messages for domains */
1349 messaging_register(winbind_messaging_context(), NULL,
1350 MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1351 messaging_register(winbind_messaging_context(), NULL,
1352 MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1354 messaging_register(msg_ctx, NULL,
1355 MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
1357 messaging_register(msg_ctx, NULL,
1358 MSG_WINBIND_VALIDATE_CACHE,
1359 winbind_msg_validate_cache);
1361 messaging_register(msg_ctx, NULL,
1362 MSG_WINBIND_DUMP_DOMAIN_LIST,
1363 winbind_msg_dump_domain_list);
1365 messaging_register(msg_ctx, NULL,
1366 MSG_WINBIND_IP_DROPPED,
1367 winbind_msg_ip_dropped_parent);
1369 /* Register handler for MSG_DEBUG. */
1370 messaging_register(msg_ctx, NULL,
1374 netsamlogon_cache_init(); /* Non-critical */
1376 /* clear the cached list of trusted domains */
1380 if (!init_domain_list()) {
1381 DEBUG(0,("unable to initialize domain list\n"));
1386 init_locator_child();
1388 smb_nscd_flush_user_cache();
1389 smb_nscd_flush_group_cache();
1391 if (lp_allow_trusted_domains()) {
1392 if (tevent_add_timer(winbind_event_context(), NULL, timeval_zero(),
1393 rescan_trusted_domains, NULL) == NULL) {
1394 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1399 status = wb_irpc_register();
1401 if (!NT_STATUS_IS_OK(status)) {
1402 DEBUG(0, ("Could not register IRPC handlers\n"));
1407 struct winbindd_addrchanged_state {
1408 struct addrchange_context *ctx;
1409 struct tevent_context *ev;
1410 struct messaging_context *msg_ctx;
1413 static void winbindd_addr_changed(struct tevent_req *req);
1415 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1416 struct tevent_context *ev,
1417 struct messaging_context *msg_ctx)
1419 struct winbindd_addrchanged_state *state;
1420 struct tevent_req *req;
1423 state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1424 if (state == NULL) {
1425 DEBUG(10, ("talloc failed\n"));
1429 state->msg_ctx = msg_ctx;
1431 status = addrchange_context_create(state, &state->ctx);
1432 if (!NT_STATUS_IS_OK(status)) {
1433 DEBUG(10, ("addrchange_context_create failed: %s\n",
1434 nt_errstr(status)));
1438 req = addrchange_send(state, ev, state->ctx);
1440 DEBUG(0, ("addrchange_send failed\n"));
1444 tevent_req_set_callback(req, winbindd_addr_changed, state);
1447 static void winbindd_addr_changed(struct tevent_req *req)
1449 struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1450 req, struct winbindd_addrchanged_state);
1451 enum addrchange_type type;
1452 struct sockaddr_storage addr;
1455 status = addrchange_recv(req, &type, &addr);
1457 if (!NT_STATUS_IS_OK(status)) {
1458 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1459 nt_errstr(status)));
1463 if (type == ADDRCHANGE_DEL) {
1464 char addrstr[INET6_ADDRSTRLEN];
1467 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1469 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1472 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1474 status = messaging_send(state->msg_ctx,
1475 messaging_server_id(state->msg_ctx),
1476 MSG_WINBIND_IP_DROPPED, &blob);
1477 if (!NT_STATUS_IS_OK(status)) {
1478 DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1479 nt_errstr(status)));
1482 req = addrchange_send(state, state->ev, state->ctx);
1484 DEBUG(0, ("addrchange_send failed\n"));
1488 tevent_req_set_callback(req, winbindd_addr_changed, state);
1493 int main(int argc, const char **argv)
1495 static bool is_daemon = False;
1496 static bool Fork = True;
1497 static bool log_stdout = False;
1498 static bool no_process_group = False;
1502 OPT_NO_PROCESS_GROUP,
1505 struct poptOption long_options[] = {
1507 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1508 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1509 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1510 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1511 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1512 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1523 * Do this before any other talloc operation
1525 talloc_enable_null_tracking();
1526 frame = talloc_stackframe();
1529 * We want total control over the permissions on created files,
1530 * so set our umask to 0.
1534 setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1536 /* glibc (?) likes to print "User defined signal 1" and exit if a
1537 SIGUSR[12] is received before a handler is installed */
1539 CatchSignal(SIGUSR1, SIG_IGN);
1540 CatchSignal(SIGUSR2, SIG_IGN);
1543 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1547 /* Initialise for running in non-root mode */
1551 set_remote_machine_name("winbindd", False);
1553 /* Set environment variable so we don't recursively call ourselves.
1554 This may also be useful interactively. */
1556 if ( !winbind_off() ) {
1557 DEBUG(0,("Failed to disable recusive winbindd calls. Exiting.\n"));
1561 /* Initialise samba/rpc client stuff */
1563 pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1565 while ((opt = poptGetNextOpt(pc)) != -1) {
1567 /* Don't become a daemon */
1579 case OPT_NO_PROCESS_GROUP:
1580 no_process_group = true;
1582 case OPT_LOG_STDOUT:
1589 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1590 poptBadOption(pc, 0), poptStrerror(opt));
1591 poptPrintUsage(pc, stderr, 0);
1596 /* We call dump_core_setup one more time because the command line can
1597 * set the log file or the log-basename and this will influence where
1598 * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1599 * the default value derived from build's prefix. For EOM this value
1600 * is often not related to the path where winbindd is actually run
1603 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1604 if (is_daemon && interactive) {
1605 d_fprintf(stderr,"\nERROR: "
1606 "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1607 poptPrintUsage(pc, stderr, 0);
1611 if (log_stdout && Fork) {
1612 d_fprintf(stderr, "\nERROR: "
1613 "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1614 poptPrintUsage(pc, stderr, 0);
1618 poptFreeContext(pc);
1620 if (!override_logfile) {
1622 if (asprintf(&lfile,"%s/log.winbindd",
1623 get_dyn_LOGFILEBASE()) > 0) {
1624 lp_set_logfile(lfile);
1630 setup_logging("winbindd", DEBUG_STDOUT);
1632 setup_logging("winbindd", DEBUG_FILE);
1636 DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1637 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1639 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1640 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1643 /* After parsing the configuration file we setup the core path one more time
1644 * as the log file might have been set in the configuration and cores's
1645 * path is by default basename(lp_logfile()).
1647 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1649 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1650 && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1651 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1652 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"));
1656 if (!cluster_probe_ok()) {
1660 /* Initialise messaging system */
1662 if (winbind_messaging_context() == NULL) {
1666 if (!reload_services_file(NULL)) {
1667 DEBUG(0, ("error opening config file\n"));
1671 ok = directory_create_or_exist(lp_lock_directory(), 0755);
1673 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1674 lp_lock_directory(), strerror(errno)));
1678 ok = directory_create_or_exist(lp_pid_directory(), 0755);
1680 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1681 lp_pid_directory(), strerror(errno)));
1692 if (!secrets_init()) {
1694 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1698 status = rpccli_pre_open_netlogon_creds();
1699 if (!NT_STATUS_IS_OK(status)) {
1700 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1701 nt_errstr(status)));
1705 /* Unblock all signals we are interested in as they may have been
1706 blocked by the parent process. */
1708 BlockSignals(False, SIGINT);
1709 BlockSignals(False, SIGQUIT);
1710 BlockSignals(False, SIGTERM);
1711 BlockSignals(False, SIGUSR1);
1712 BlockSignals(False, SIGUSR2);
1713 BlockSignals(False, SIGHUP);
1714 BlockSignals(False, SIGCHLD);
1717 become_daemon(Fork, no_process_group, log_stdout);
1719 pidfile_create(lp_pid_directory(), "winbindd");
1723 * If we're interactive we want to set our own process group for
1724 * signal management.
1726 if (interactive && !no_process_group)
1727 setpgid( (pid_t)0, (pid_t)0);
1732 /* Don't use winbindd_reinit_after_fork here as
1733 * we're just starting up and haven't created any
1734 * winbindd-specific resources we must free yet. JRA.
1737 status = reinit_after_fork(winbind_messaging_context(),
1738 winbind_event_context(),
1740 if (!NT_STATUS_IS_OK(status)) {
1741 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1745 * Do not initialize the parent-child-pipe before becoming
1746 * a daemon: this is used to detect a died parent in the child
1749 status = init_before_fork();
1750 if (!NT_STATUS_IS_OK(status)) {
1751 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1754 winbindd_register_handlers(winbind_messaging_context(), !Fork);
1756 if (!messaging_parent_dgm_cleanup_init(winbind_messaging_context())) {
1760 status = init_system_session_info();
1761 if (!NT_STATUS_IS_OK(status)) {
1762 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1765 rpc_lsarpc_init(NULL);
1766 rpc_samr_init(NULL);
1768 winbindd_init_addrchange(NULL, winbind_event_context(),
1769 winbind_messaging_context());
1771 /* setup listen sockets */
1773 if (!winbindd_setup_listeners()) {
1774 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1777 irpc_add_name(winbind_imessaging_context(), "winbind_server");
1782 daemon_ready("winbindd");
1785 /* Loop waiting for requests */
1787 frame = talloc_stackframe();
1789 if (tevent_loop_once(winbind_event_context()) == -1) {
1790 DEBUG(1, ("tevent_loop_once() failed: %s\n",