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);
57 static void request_ok(struct winbindd_cli_state *state);
59 static bool opt_nocache = False;
60 static bool interactive = False;
62 extern bool override_logfile;
64 struct imessaging_context *winbind_imessaging_context(void)
66 static struct imessaging_context *msg = NULL;
67 struct messaging_context *msg_ctx;
68 struct server_id myself;
69 struct loadparm_context *lp_ctx;
75 msg_ctx = server_messaging_context();
76 if (msg_ctx == NULL) {
77 smb_panic("server_messaging_context failed\n");
79 myself = messaging_server_id(msg_ctx);
81 lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
83 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
87 * Note we MUST use the NULL context here, not the autofree context,
88 * to avoid side effects in forked children exiting.
90 msg = imessaging_init(NULL, lp_ctx, myself, server_event_context());
91 talloc_unlink(NULL, lp_ctx);
94 smb_panic("Could not init winbindd's messaging context.\n");
99 /* Reload configuration */
101 static bool reload_services_file(const char *lfile)
106 char *fname = lp_next_configfile(talloc_tos());
108 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
109 set_dyn_CONFIGFILE(fname);
114 /* if this is a child, restore the logfile to the special
115 name - <domain>, idmap, etc. */
116 if (lfile && *lfile) {
117 lp_set_logfile(lfile);
121 ret = lp_load_global(get_dyn_CONFIGFILE());
125 winbindd_setup_max_fds();
131 static void winbindd_status(void)
133 struct winbindd_cli_state *tmp;
135 DEBUG(0, ("winbindd status:\n"));
137 /* Print client state information */
139 DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
141 if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
142 DEBUG(2, ("\tclient list:\n"));
143 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
144 DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
145 (unsigned long)tmp->pid, tmp->sock,
146 client_is_idle(tmp) ? "idle" : "active"));
151 /* Flush client cache */
153 static void flush_caches(void)
155 /* We need to invalidate cached user list entries on a SIGHUP
156 otherwise cached access denied errors due to restrict anonymous
157 hang around until the sequence number changes. */
159 if (!wcache_invalidate_cache()) {
160 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
161 if (!winbindd_cache_validate_and_initialize()) {
167 static void flush_caches_noinit(void)
170 * We need to invalidate cached user list entries on a SIGHUP
171 * otherwise cached access denied errors due to restrict anonymous
172 * hang around until the sequence number changes.
174 * Skip uninitialized domains when flush cache.
175 * If domain is not initialized, it means it is never
176 * used or never become online. look, wcache_invalidate_cache()
177 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
178 * for unused domains and large traffic for primay domain's DC if there
182 if (!wcache_invalidate_cache_noinit()) {
183 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
184 if (!winbindd_cache_validate_and_initialize()) {
190 /* Handle the signal by unlinking socket and exiting */
192 static void terminate(bool is_parent)
195 /* When parent goes away we should
196 * remove the socket file. Not so
197 * when children terminate.
201 if (asprintf(&path, "%s/%s",
202 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) {
210 gencache_stabilize();
212 netlogon_creds_cli_close_global_db();
216 TALLOC_CTX *mem_ctx = talloc_init("end_description");
217 char *description = talloc_describe_all(mem_ctx);
219 DEBUG(3, ("tallocs left:\n%s\n", description));
220 talloc_destroy(mem_ctx);
225 pidfile_unlink(lp_pid_directory(), "winbindd");
231 static void winbindd_sig_term_handler(struct tevent_context *ev,
232 struct tevent_signal *se,
238 bool *p = talloc_get_type_abort(private_data, bool);
243 DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
245 terminate(is_parent);
249 handle stdin becoming readable when we are in --foreground mode
251 static void winbindd_stdin_handler(struct tevent_context *ev,
252 struct tevent_fd *fde,
257 if (read(0, &c, 1) != 1) {
258 bool *is_parent = talloc_get_type_abort(private_data, bool);
260 /* we have reached EOF on stdin, which means the
261 parent has exited. Shutdown the server */
262 DEBUG(0,("EOF on stdin (is_parent=%d)\n",
264 terminate(*is_parent);
268 bool winbindd_setup_sig_term_handler(bool parent)
270 struct tevent_signal *se;
273 is_parent = talloc(server_event_context(), bool);
280 se = tevent_add_signal(server_event_context(),
283 winbindd_sig_term_handler,
286 DEBUG(0,("failed to setup SIGTERM handler"));
287 talloc_free(is_parent);
291 se = tevent_add_signal(server_event_context(),
294 winbindd_sig_term_handler,
297 DEBUG(0,("failed to setup SIGINT handler"));
298 talloc_free(is_parent);
302 se = tevent_add_signal(server_event_context(),
305 winbindd_sig_term_handler,
308 DEBUG(0,("failed to setup SIGINT handler"));
309 talloc_free(is_parent);
316 bool winbindd_setup_stdin_handler(bool parent, bool foreground)
323 is_parent = talloc(server_event_context(), bool);
330 /* if we are running in the foreground then look for
331 EOF on stdin, and exit if it happens. This allows
332 us to die if the parent process dies
333 Only do this on a pipe or socket, no other device.
335 if (fstat(0, &st) != 0) {
338 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
339 tevent_add_fd(server_event_context(),
343 winbindd_stdin_handler,
351 static void winbindd_sig_hup_handler(struct tevent_context *ev,
352 struct tevent_signal *se,
358 const char *file = (const char *)private_data;
360 DEBUG(1,("Reloading services after SIGHUP\n"));
361 flush_caches_noinit();
362 reload_services_file(file);
365 bool winbindd_setup_sig_hup_handler(const char *lfile)
367 struct tevent_signal *se;
371 file = talloc_strdup(server_event_context(),
378 se = tevent_add_signal(server_event_context(),
379 server_event_context(),
381 winbindd_sig_hup_handler,
390 static void winbindd_sig_chld_handler(struct tevent_context *ev,
391 struct tevent_signal *se,
399 while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
400 winbind_child_died(pid);
404 static bool winbindd_setup_sig_chld_handler(void)
406 struct tevent_signal *se;
408 se = tevent_add_signal(server_event_context(),
409 server_event_context(),
411 winbindd_sig_chld_handler,
420 static void winbindd_sig_usr2_handler(struct tevent_context *ev,
421 struct tevent_signal *se,
430 static bool winbindd_setup_sig_usr2_handler(void)
432 struct tevent_signal *se;
434 se = tevent_add_signal(server_event_context(),
435 server_event_context(),
437 winbindd_sig_usr2_handler,
446 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
447 static void msg_reload_services(struct messaging_context *msg,
450 struct server_id server_id,
453 /* Flush various caches */
455 reload_services_file((const char *) private_data);
458 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
459 static void msg_shutdown(struct messaging_context *msg,
462 struct server_id server_id,
465 /* only the parent waits for this message */
466 DEBUG(0,("Got shutdown message\n"));
471 static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
474 struct server_id server_id,
481 DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
485 * call the validation code from a child:
486 * so we don't block the main winbindd and the validation
487 * code can safely use fork/waitpid...
491 if (child_pid == -1) {
492 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
497 if (child_pid != 0) {
499 DEBUG(5, ("winbind_msg_validate_cache: child created with "
500 "pid %d.\n", (int)child_pid));
506 status = winbindd_reinit_after_fork(NULL, NULL);
507 if (!NT_STATUS_IS_OK(status)) {
508 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
513 /* install default SIGCHLD handler: validation code uses fork/waitpid */
514 CatchSignal(SIGCHLD, SIG_DFL);
516 setproctitle("validate cache child");
518 ret = (uint8_t)winbindd_validate_cache_nobackup();
519 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
520 messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
525 static struct winbindd_bool_dispatch_table {
526 enum winbindd_cmd cmd;
527 bool (*fn)(struct winbindd_cli_state *state);
528 const char *cmd_name;
529 } bool_dispatch_table[] = {
530 { WINBINDD_INTERFACE_VERSION,
531 winbindd_interface_version,
532 "INTERFACE_VERSION" },
539 { WINBINDD_DOMAIN_NAME,
540 winbindd_domain_name,
542 { WINBINDD_NETBIOS_NAME,
543 winbindd_netbios_name,
548 { WINBINDD_CCACHE_NTLMAUTH,
549 winbindd_ccache_ntlm_auth,
551 { WINBINDD_CCACHE_SAVE,
552 winbindd_ccache_save,
554 { WINBINDD_PRIV_PIPE_DIR,
555 winbindd_priv_pipe_dir,
556 "WINBINDD_PRIV_PIPE_DIR" },
557 { WINBINDD_LIST_TRUSTDOM,
558 winbindd_list_trusted_domains,
562 struct winbindd_async_dispatch_table {
563 enum winbindd_cmd cmd;
564 const char *cmd_name;
565 struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
566 struct tevent_context *ev,
567 struct winbindd_cli_state *cli,
568 struct winbindd_request *request);
569 NTSTATUS (*recv_req)(struct tevent_req *req,
570 struct winbindd_response *presp);
573 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
574 { WINBINDD_LOOKUPSID, "LOOKUPSID",
575 winbindd_lookupsid_send, winbindd_lookupsid_recv },
576 { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
577 winbindd_lookupsids_send, winbindd_lookupsids_recv },
578 { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
579 winbindd_lookupname_send, winbindd_lookupname_recv },
580 { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
581 winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
582 { WINBINDD_XIDS_TO_SIDS, "XIDS_TO_SIDS",
583 winbindd_xids_to_sids_send, winbindd_xids_to_sids_recv },
584 { WINBINDD_GETPWSID, "GETPWSID",
585 winbindd_getpwsid_send, winbindd_getpwsid_recv },
586 { WINBINDD_GETPWNAM, "GETPWNAM",
587 winbindd_getpwnam_send, winbindd_getpwnam_recv },
588 { WINBINDD_GETPWUID, "GETPWUID",
589 winbindd_getpwuid_send, winbindd_getpwuid_recv },
590 { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
591 winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
592 { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
593 winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
594 { WINBINDD_GETGROUPS, "GETGROUPS",
595 winbindd_getgroups_send, winbindd_getgroups_recv },
596 { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
597 winbindd_show_sequence_send, winbindd_show_sequence_recv },
598 { WINBINDD_GETGRGID, "GETGRGID",
599 winbindd_getgrgid_send, winbindd_getgrgid_recv },
600 { WINBINDD_GETGRNAM, "GETGRNAM",
601 winbindd_getgrnam_send, winbindd_getgrnam_recv },
602 { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
603 winbindd_getusersids_send, winbindd_getusersids_recv },
604 { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
605 winbindd_lookuprids_send, winbindd_lookuprids_recv },
606 { WINBINDD_SETPWENT, "SETPWENT",
607 winbindd_setpwent_send, winbindd_setpwent_recv },
608 { WINBINDD_GETPWENT, "GETPWENT",
609 winbindd_getpwent_send, winbindd_getpwent_recv },
610 { WINBINDD_ENDPWENT, "ENDPWENT",
611 winbindd_endpwent_send, winbindd_endpwent_recv },
612 { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
613 winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
614 { WINBINDD_GETDCNAME, "GETDCNAME",
615 winbindd_getdcname_send, winbindd_getdcname_recv },
616 { WINBINDD_SETGRENT, "SETGRENT",
617 winbindd_setgrent_send, winbindd_setgrent_recv },
618 { WINBINDD_GETGRENT, "GETGRENT",
619 winbindd_getgrent_send, winbindd_getgrent_recv },
620 { WINBINDD_ENDGRENT, "ENDGRENT",
621 winbindd_endgrent_send, winbindd_endgrent_recv },
622 { WINBINDD_LIST_USERS, "LIST_USERS",
623 winbindd_list_users_send, winbindd_list_users_recv },
624 { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
625 winbindd_list_groups_send, winbindd_list_groups_recv },
626 { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
627 winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
628 { WINBINDD_PING_DC, "PING_DC",
629 winbindd_ping_dc_send, winbindd_ping_dc_recv },
630 { WINBINDD_PAM_AUTH, "PAM_AUTH",
631 winbindd_pam_auth_send, winbindd_pam_auth_recv },
632 { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
633 winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
634 { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
635 winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
636 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
637 winbindd_pam_chng_pswd_auth_crap_send,
638 winbindd_pam_chng_pswd_auth_crap_recv },
639 { WINBINDD_WINS_BYIP, "WINS_BYIP",
640 winbindd_wins_byip_send, winbindd_wins_byip_recv },
641 { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
642 winbindd_wins_byname_send, winbindd_wins_byname_recv },
643 { WINBINDD_DOMAIN_INFO, "DOMAIN_INFO",
644 winbindd_domain_info_send, winbindd_domain_info_recv },
646 { 0, NULL, NULL, NULL }
649 static struct winbindd_async_dispatch_table async_priv_table[] = {
650 { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
651 winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
652 { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
653 winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
654 { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
655 winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
656 { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
657 winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
659 { 0, NULL, NULL, NULL }
662 static void wb_request_done(struct tevent_req *req);
664 static void process_request(struct winbindd_cli_state *state)
666 struct winbindd_async_dispatch_table *atable;
670 state->mem_ctx = talloc_named(state, 0, "winbind request");
671 if (state->mem_ctx == NULL)
674 /* Remember who asked us. */
675 state->pid = state->request->pid;
677 state->cmd_name = "unknown request";
678 state->recv_fn = NULL;
679 /* client is newest */
680 winbindd_promote_client(state);
682 /* Process command */
684 for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
685 if (state->request->cmd == atable->cmd) {
690 if ((atable->send_req == NULL) && state->privileged) {
691 for (atable = async_priv_table; atable->send_req;
693 if (state->request->cmd == atable->cmd) {
699 if (atable->send_req != NULL) {
700 struct tevent_req *req;
702 state->cmd_name = atable->cmd_name;
703 state->recv_fn = atable->recv_req;
705 DEBUG(10, ("process_request: Handling async request %d:%s\n",
706 (int)state->pid, state->cmd_name));
708 req = atable->send_req(state->mem_ctx, server_event_context(),
709 state, state->request);
711 DEBUG(0, ("process_request: atable->send failed for "
712 "%s\n", atable->cmd_name));
713 request_error(state);
716 tevent_req_set_callback(req, wb_request_done, state);
720 state->response = talloc_zero(state->mem_ctx,
721 struct winbindd_response);
722 if (state->response == NULL) {
723 DEBUG(10, ("talloc failed\n"));
724 remove_client(state);
727 state->response->result = WINBINDD_PENDING;
728 state->response->length = sizeof(struct winbindd_response);
730 for (i=0; i<ARRAY_SIZE(bool_dispatch_table); i++) {
731 if (bool_dispatch_table[i].cmd == state->request->cmd) {
736 if (i == ARRAY_SIZE(bool_dispatch_table)) {
737 DEBUG(10,("process_request: unknown request fn number %d\n",
738 (int)state->request->cmd ));
739 request_error(state);
743 DBG_DEBUG("process_request: request fn %s\n",
744 bool_dispatch_table[i].cmd_name);
746 ok = bool_dispatch_table[i].fn(state);
751 request_error(state);
755 static void wb_request_done(struct tevent_req *req)
757 struct winbindd_cli_state *state = tevent_req_callback_data(
758 req, struct winbindd_cli_state);
761 state->response = talloc_zero(state->mem_ctx,
762 struct winbindd_response);
763 if (state->response == NULL) {
764 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
765 (int)state->pid, state->cmd_name));
766 remove_client(state);
769 state->response->result = WINBINDD_PENDING;
770 state->response->length = sizeof(struct winbindd_response);
772 status = state->recv_fn(req, state->response);
775 DEBUG(10,("wb_request_done[%d:%s]: %s\n",
776 (int)state->pid, state->cmd_name, nt_errstr(status)));
778 if (!NT_STATUS_IS_OK(status)) {
779 request_error(state);
786 * This is the main event loop of winbind requests. It goes through a
787 * state-machine of 3 read/write requests, 4 if you have extra data to send.
789 * An idle winbind client has a read request of 4 bytes outstanding,
790 * finalizing function is request_len_recv, checking the length. request_recv
791 * then processes the packet. The processing function then at some point has
792 * to call request_finished which schedules sending the response.
795 static void request_finished(struct winbindd_cli_state *state);
797 static void winbind_client_request_read(struct tevent_req *req);
798 static void winbind_client_response_written(struct tevent_req *req);
799 static void winbind_client_activity(struct tevent_req *req);
801 static void request_finished(struct winbindd_cli_state *state)
803 struct tevent_req *req;
805 /* free client socket monitoring request */
806 TALLOC_FREE(state->io_req);
808 TALLOC_FREE(state->request);
810 req = wb_resp_write_send(state, server_event_context(),
811 state->out_queue, state->sock,
814 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
815 (int)state->pid, state->cmd_name));
816 remove_client(state);
819 tevent_req_set_callback(req, winbind_client_response_written, state);
823 static void winbind_client_response_written(struct tevent_req *req)
825 struct winbindd_cli_state *state = tevent_req_callback_data(
826 req, struct winbindd_cli_state);
830 state->io_req = NULL;
832 ret = wb_resp_write_recv(req, &err);
837 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
838 (int)state->pid, state->cmd_name, strerror(err)));
839 remove_client(state);
843 DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
844 "to client\n", (int)state->pid, state->cmd_name));
846 TALLOC_FREE(state->mem_ctx);
847 state->response = NULL;
848 state->cmd_name = "no request";
849 state->recv_fn = NULL;
851 req = wb_req_read_send(state, server_event_context(), state->sock,
852 WINBINDD_MAX_EXTRA_DATA);
854 remove_client(state);
857 tevent_req_set_callback(req, winbind_client_request_read, state);
861 void request_error(struct winbindd_cli_state *state)
863 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
864 state->response->result = WINBINDD_ERROR;
865 request_finished(state);
868 static void request_ok(struct winbindd_cli_state *state)
870 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
871 state->response->result = WINBINDD_OK;
872 request_finished(state);
875 /* Process a new connection by adding it to the client connection list */
877 static void new_connection(int listen_sock, bool privileged)
879 struct sockaddr_un sunaddr;
880 struct winbindd_cli_state *state;
881 struct tevent_req *req;
885 /* Accept connection */
887 len = sizeof(sunaddr);
889 sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
892 if (errno != EINTR) {
893 DEBUG(0, ("Failed to accept socket - %s\n",
898 smb_set_close_on_exec(sock);
900 DEBUG(6,("accepted socket %d\n", sock));
902 /* Create new connection structure */
904 if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
911 state->out_queue = tevent_queue_create(state, "winbind client reply");
912 if (state->out_queue == NULL) {
918 state->privileged = privileged;
920 req = wb_req_read_send(state, server_event_context(), state->sock,
921 WINBINDD_MAX_EXTRA_DATA);
927 tevent_req_set_callback(req, winbind_client_request_read, state);
930 /* Add to connection list */
932 winbindd_add_client(state);
935 static void winbind_client_request_read(struct tevent_req *req)
937 struct winbindd_cli_state *state = tevent_req_callback_data(
938 req, struct winbindd_cli_state);
942 state->io_req = NULL;
944 ret = wb_req_read_recv(req, state, &state->request, &err);
948 DEBUG(6, ("closing socket %d, client exited\n",
951 DEBUG(2, ("Could not read client request from fd %d: "
952 "%s\n", state->sock, strerror(err)));
956 remove_client(state);
960 req = wait_for_read_send(state, server_event_context(), state->sock,
963 DEBUG(0, ("winbind_client_request_read[%d:%s]:"
964 " wait_for_read_send failed - removing client\n",
965 (int)state->pid, state->cmd_name));
966 remove_client(state);
969 tevent_req_set_callback(req, winbind_client_activity, state);
972 process_request(state);
975 static void winbind_client_activity(struct tevent_req *req)
977 struct winbindd_cli_state *state =
978 tevent_req_callback_data(req, struct winbindd_cli_state);
982 has_data = wait_for_read_recv(req, &err);
985 DEBUG(0, ("winbind_client_activity[%d:%s]:"
986 "unexpected data from client - removing client\n",
987 (int)state->pid, state->cmd_name));
990 DEBUG(6, ("winbind_client_activity[%d:%s]: "
991 "client has closed connection - removing "
993 (int)state->pid, state->cmd_name));
995 DEBUG(2, ("winbind_client_activity[%d:%s]: "
996 "client socket error (%s) - removing "
998 (int)state->pid, state->cmd_name,
1003 remove_client(state);
1006 /* Remove a client connection from client connection list */
1008 static void remove_client(struct winbindd_cli_state *state)
1013 /* It's a dead client - hold a funeral */
1015 if (state == NULL) {
1020 * We need to remove a pending wb_req_read_*
1021 * or wb_resp_write_* request before closing the
1024 * This is important as they might have used tevent_add_fd() and we
1025 * use the epoll * backend on linux. So we must remove the tevent_fd
1026 * before closing the fd.
1028 * Otherwise we might hit a race with close_conns_after_fork() (via
1029 * winbindd_reinit_after_fork()) where a file description
1030 * is still open in a child, which means it's still active in
1031 * the parents epoll queue, but the related tevent_fd is already
1032 * already gone in the parent.
1036 TALLOC_FREE(state->io_req);
1038 if (state->sock != -1) {
1039 /* tell client, we are closing ... */
1040 nwritten = write(state->sock, &c, sizeof(c));
1041 if (nwritten == -1) {
1042 DEBUG(2, ("final write to client failed: %s\n",
1052 TALLOC_FREE(state->mem_ctx);
1054 /* Remove from list and free */
1056 winbindd_remove_client(state);
1060 /* Is a client idle? */
1062 static bool client_is_idle(struct winbindd_cli_state *state) {
1063 return (state->request == NULL &&
1064 state->response == NULL &&
1065 !state->pwent_state && !state->grent_state);
1068 /* Shutdown client connection which has been idle for the longest time */
1070 static bool remove_idle_client(void)
1072 struct winbindd_cli_state *state, *remove_state = NULL;
1075 for (state = winbindd_client_list(); state; state = state->next) {
1076 if (client_is_idle(state)) {
1078 /* list is sorted by access time */
1079 remove_state = state;
1084 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1085 nidle, remove_state->sock, (unsigned int)remove_state->pid));
1086 remove_client(remove_state);
1094 * Terminate all clients whose requests have taken longer than
1095 * "winbind request timeout" seconds to process, or have been
1096 * idle for more than "winbind request timeout" seconds.
1099 static void remove_timed_out_clients(void)
1101 struct winbindd_cli_state *state, *prev = NULL;
1102 time_t curr_time = time(NULL);
1103 int timeout_val = lp_winbind_request_timeout();
1105 for (state = winbindd_client_list_tail(); state; state = prev) {
1108 prev = winbindd_client_list_prev(state);
1109 expiry_time = state->last_access + timeout_val;
1111 if (curr_time <= expiry_time) {
1112 /* list is sorted, previous clients in
1117 if (client_is_idle(state)) {
1118 DEBUG(5,("Idle client timed out, "
1119 "shutting down sock %d, pid %u\n",
1121 (unsigned int)state->pid));
1123 DEBUG(5,("Client request timed out, "
1124 "shutting down sock %d, pid %u\n",
1126 (unsigned int)state->pid));
1129 remove_client(state);
1133 static void winbindd_scrub_clients_handler(struct tevent_context *ev,
1134 struct tevent_timer *te,
1135 struct timeval current_time,
1138 remove_timed_out_clients();
1139 if (tevent_add_timer(ev, ev,
1140 timeval_current_ofs(SCRUB_CLIENTS_INTERVAL, 0),
1141 winbindd_scrub_clients_handler, NULL) == NULL) {
1142 DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
1147 struct winbindd_listen_state {
1152 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1153 struct tevent_fd *fde,
1157 struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1158 struct winbindd_listen_state);
1160 while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1161 DEBUG(5,("winbindd: Exceeding %d client "
1162 "connections, removing idle "
1163 "connection.\n", lp_winbind_max_clients()));
1164 if (!remove_idle_client()) {
1165 DEBUG(0,("winbindd: Exceeding %d "
1166 "client connections, no idle "
1167 "connection found\n",
1168 lp_winbind_max_clients()));
1172 remove_timed_out_clients();
1173 new_connection(s->fd, s->privileged);
1177 * Winbindd socket accessor functions
1180 char *get_winbind_priv_pipe_dir(void)
1182 return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1185 static void winbindd_setup_max_fds(void)
1187 int num_fds = MAX_OPEN_FUDGEFACTOR;
1190 num_fds += lp_winbind_max_clients();
1191 /* Add some more to account for 2 sockets open
1192 when the client transitions from unprivileged
1193 to privileged socket
1195 num_fds += lp_winbind_max_clients() / 10;
1197 /* Add one socket per child process
1198 (yeah there are child processes other than the
1199 domain children but only domain children can vary
1202 num_fds += lp_winbind_max_domain_connections() *
1203 (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
1205 actual_fds = set_maxfiles(num_fds);
1207 if (actual_fds < num_fds) {
1208 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1209 "requested %d open files, %d are available.\n",
1210 num_fds, actual_fds));
1214 static bool winbindd_setup_listeners(void)
1216 struct winbindd_listen_state *pub_state = NULL;
1217 struct winbindd_listen_state *priv_state = NULL;
1218 struct tevent_fd *fde;
1222 pub_state = talloc(server_event_context(),
1223 struct winbindd_listen_state);
1228 pub_state->privileged = false;
1229 pub_state->fd = create_pipe_sock(
1230 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1231 if (pub_state->fd == -1) {
1234 rc = listen(pub_state->fd, 5);
1239 fde = tevent_add_fd(server_event_context(), pub_state, pub_state->fd,
1240 TEVENT_FD_READ, winbindd_listen_fde_handler,
1243 close(pub_state->fd);
1246 tevent_fd_set_auto_close(fde);
1248 priv_state = talloc(server_event_context(),
1249 struct winbindd_listen_state);
1254 socket_path = get_winbind_priv_pipe_dir();
1255 if (socket_path == NULL) {
1259 priv_state->privileged = true;
1260 priv_state->fd = create_pipe_sock(
1261 socket_path, WINBINDD_SOCKET_NAME, 0750);
1262 TALLOC_FREE(socket_path);
1263 if (priv_state->fd == -1) {
1266 rc = listen(priv_state->fd, 5);
1271 fde = tevent_add_fd(server_event_context(), priv_state,
1272 priv_state->fd, TEVENT_FD_READ,
1273 winbindd_listen_fde_handler, priv_state);
1275 close(priv_state->fd);
1278 tevent_fd_set_auto_close(fde);
1280 winbindd_scrub_clients_handler(server_event_context(), NULL,
1281 timeval_current(), NULL);
1284 TALLOC_FREE(pub_state);
1285 TALLOC_FREE(priv_state);
1289 bool winbindd_use_idmap_cache(void)
1291 return !opt_nocache;
1294 bool winbindd_use_cache(void)
1296 return !opt_nocache;
1299 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1302 bool scan_trusts = true;
1304 /* Setup signal handlers */
1306 if (!winbindd_setup_sig_term_handler(true))
1308 if (!winbindd_setup_stdin_handler(true, foreground))
1310 if (!winbindd_setup_sig_hup_handler(NULL))
1312 if (!winbindd_setup_sig_chld_handler())
1314 if (!winbindd_setup_sig_usr2_handler())
1317 CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
1320 * Ensure all cache and idmap caches are consistent
1321 * and initialized before we startup.
1323 if (!winbindd_cache_validate_and_initialize()) {
1327 /* React on 'smbcontrol winbindd reload-config' in the same way
1328 as to SIGHUP signal */
1329 messaging_register(msg_ctx, NULL,
1330 MSG_SMB_CONF_UPDATED, msg_reload_services);
1331 messaging_register(msg_ctx, NULL,
1332 MSG_SHUTDOWN, msg_shutdown);
1334 /* Handle online/offline messages. */
1335 messaging_register(msg_ctx, NULL,
1336 MSG_WINBIND_OFFLINE, winbind_msg_offline);
1337 messaging_register(msg_ctx, NULL,
1338 MSG_WINBIND_ONLINE, winbind_msg_online);
1339 messaging_register(msg_ctx, NULL,
1340 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1342 /* Handle domain online/offline messages for domains */
1343 messaging_register(server_messaging_context(), NULL,
1344 MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1345 messaging_register(server_messaging_context(), NULL,
1346 MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1348 messaging_register(msg_ctx, NULL,
1349 MSG_WINBIND_VALIDATE_CACHE,
1350 winbind_msg_validate_cache);
1352 messaging_register(msg_ctx, NULL,
1353 MSG_WINBIND_DUMP_DOMAIN_LIST,
1354 winbind_msg_dump_domain_list);
1356 messaging_register(msg_ctx, NULL,
1357 MSG_WINBIND_IP_DROPPED,
1358 winbind_msg_ip_dropped_parent);
1360 /* Register handler for MSG_DEBUG. */
1361 messaging_register(msg_ctx, NULL,
1365 messaging_register(msg_ctx, NULL,
1366 MSG_WINBIND_DISCONNECT_DC,
1367 winbind_disconnect_dc_parent);
1369 netsamlogon_cache_init(); /* Non-critical */
1371 /* clear the cached list of trusted domains */
1375 if (!init_domain_list()) {
1376 DEBUG(0,("unable to initialize domain list\n"));
1381 init_locator_child();
1383 smb_nscd_flush_user_cache();
1384 smb_nscd_flush_group_cache();
1386 if (!lp_winbind_scan_trusted_domains()) {
1387 scan_trusts = false;
1390 if (!lp_allow_trusted_domains()) {
1391 scan_trusts = false;
1395 scan_trusts = false;
1399 if (tevent_add_timer(server_event_context(), NULL, timeval_zero(),
1400 rescan_trusted_domains, NULL) == NULL) {
1401 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1406 status = wb_irpc_register();
1408 if (!NT_STATUS_IS_OK(status)) {
1409 DEBUG(0, ("Could not register IRPC handlers\n"));
1414 struct winbindd_addrchanged_state {
1415 struct addrchange_context *ctx;
1416 struct tevent_context *ev;
1417 struct messaging_context *msg_ctx;
1420 static void winbindd_addr_changed(struct tevent_req *req);
1422 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1423 struct tevent_context *ev,
1424 struct messaging_context *msg_ctx)
1426 struct winbindd_addrchanged_state *state;
1427 struct tevent_req *req;
1430 state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1431 if (state == NULL) {
1432 DEBUG(10, ("talloc failed\n"));
1436 state->msg_ctx = msg_ctx;
1438 status = addrchange_context_create(state, &state->ctx);
1439 if (!NT_STATUS_IS_OK(status)) {
1440 DEBUG(10, ("addrchange_context_create failed: %s\n",
1441 nt_errstr(status)));
1445 req = addrchange_send(state, ev, state->ctx);
1447 DEBUG(0, ("addrchange_send failed\n"));
1451 tevent_req_set_callback(req, winbindd_addr_changed, state);
1454 static void winbindd_addr_changed(struct tevent_req *req)
1456 struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1457 req, struct winbindd_addrchanged_state);
1458 enum addrchange_type type;
1459 struct sockaddr_storage addr;
1462 status = addrchange_recv(req, &type, &addr);
1464 if (!NT_STATUS_IS_OK(status)) {
1465 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1466 nt_errstr(status)));
1470 if (type == ADDRCHANGE_DEL) {
1471 char addrstr[INET6_ADDRSTRLEN];
1474 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1476 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1479 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1481 status = messaging_send(state->msg_ctx,
1482 messaging_server_id(state->msg_ctx),
1483 MSG_WINBIND_IP_DROPPED, &blob);
1484 if (!NT_STATUS_IS_OK(status)) {
1485 DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1486 nt_errstr(status)));
1489 req = addrchange_send(state, state->ev, state->ctx);
1491 DEBUG(0, ("addrchange_send failed\n"));
1495 tevent_req_set_callback(req, winbindd_addr_changed, state);
1500 int main(int argc, const char **argv)
1502 static bool is_daemon = False;
1503 static bool Fork = True;
1504 static bool log_stdout = False;
1505 static bool no_process_group = False;
1509 OPT_NO_PROCESS_GROUP,
1512 struct poptOption long_options[] = {
1514 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1515 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1516 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1517 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1518 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1519 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1529 setproctitle_init(argc, discard_const(argv), environ);
1532 * Do this before any other talloc operation
1534 talloc_enable_null_tracking();
1535 frame = talloc_stackframe();
1538 * We want total control over the permissions on created files,
1539 * so set our umask to 0.
1543 setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1545 /* glibc (?) likes to print "User defined signal 1" and exit if a
1546 SIGUSR[12] is received before a handler is installed */
1548 CatchSignal(SIGUSR1, SIG_IGN);
1549 CatchSignal(SIGUSR2, SIG_IGN);
1552 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1556 /* Initialise for running in non-root mode */
1560 set_remote_machine_name("winbindd", False);
1562 /* Set environment variable so we don't recursively call ourselves.
1563 This may also be useful interactively. */
1565 if ( !winbind_off() ) {
1566 DEBUG(0,("Failed to disable recusive winbindd calls. Exiting.\n"));
1570 /* Initialise samba/rpc client stuff */
1572 pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1574 while ((opt = poptGetNextOpt(pc)) != -1) {
1576 /* Don't become a daemon */
1588 case OPT_NO_PROCESS_GROUP:
1589 no_process_group = true;
1591 case OPT_LOG_STDOUT:
1598 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1599 poptBadOption(pc, 0), poptStrerror(opt));
1600 poptPrintUsage(pc, stderr, 0);
1605 /* We call dump_core_setup one more time because the command line can
1606 * set the log file or the log-basename and this will influence where
1607 * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1608 * the default value derived from build's prefix. For EOM this value
1609 * is often not related to the path where winbindd is actually run
1612 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1613 if (is_daemon && interactive) {
1614 d_fprintf(stderr,"\nERROR: "
1615 "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1616 poptPrintUsage(pc, stderr, 0);
1620 if (log_stdout && Fork) {
1621 d_fprintf(stderr, "\nERROR: "
1622 "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1623 poptPrintUsage(pc, stderr, 0);
1627 poptFreeContext(pc);
1629 if (!override_logfile) {
1631 if (asprintf(&lfile,"%s/log.winbindd",
1632 get_dyn_LOGFILEBASE()) > 0) {
1633 lp_set_logfile(lfile);
1639 setup_logging("winbindd", DEBUG_STDOUT);
1641 setup_logging("winbindd", DEBUG_FILE);
1645 DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1646 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1648 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1649 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1652 /* After parsing the configuration file we setup the core path one more time
1653 * as the log file might have been set in the configuration and cores's
1654 * path is by default basename(lp_logfile()).
1656 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1658 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1659 && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1660 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1661 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"));
1665 if (!cluster_probe_ok()) {
1669 /* Initialise messaging system */
1671 if (server_messaging_context() == NULL) {
1675 if (!reload_services_file(NULL)) {
1676 DEBUG(0, ("error opening config file\n"));
1682 const char *idmap_backend;
1683 const char *invalid_backends[] = {
1684 "ad", "rfc2307", "rid",
1687 idmap_backend = lp_idmap_default_backend();
1688 for (i = 0; i < ARRAY_SIZE(invalid_backends); i++) {
1689 ok = strequal(idmap_backend, invalid_backends[i]);
1691 DBG_ERR("FATAL: Invalid idmap backend %s "
1692 "configured as the default backend!\n",
1699 ok = directory_create_or_exist(lp_lock_directory(), 0755);
1701 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1702 lp_lock_directory(), strerror(errno)));
1706 ok = directory_create_or_exist(lp_pid_directory(), 0755);
1708 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1709 lp_pid_directory(), strerror(errno)));
1720 if (!secrets_init()) {
1722 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1726 status = rpccli_pre_open_netlogon_creds();
1727 if (!NT_STATUS_IS_OK(status)) {
1728 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1729 nt_errstr(status)));
1733 /* Unblock all signals we are interested in as they may have been
1734 blocked by the parent process. */
1736 BlockSignals(False, SIGINT);
1737 BlockSignals(False, SIGQUIT);
1738 BlockSignals(False, SIGTERM);
1739 BlockSignals(False, SIGUSR1);
1740 BlockSignals(False, SIGUSR2);
1741 BlockSignals(False, SIGHUP);
1742 BlockSignals(False, SIGCHLD);
1745 become_daemon(Fork, no_process_group, log_stdout);
1747 pidfile_create(lp_pid_directory(), "winbindd");
1751 * If we're interactive we want to set our own process group for
1752 * signal management.
1754 if (interactive && !no_process_group)
1755 setpgid( (pid_t)0, (pid_t)0);
1760 /* Don't use winbindd_reinit_after_fork here as
1761 * we're just starting up and haven't created any
1762 * winbindd-specific resources we must free yet. JRA.
1765 status = reinit_after_fork(server_messaging_context(),
1766 server_event_context(),
1768 if (!NT_STATUS_IS_OK(status)) {
1769 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1771 initialize_password_db(true, server_event_context());
1774 * Do not initialize the parent-child-pipe before becoming
1775 * a daemon: this is used to detect a died parent in the child
1778 status = init_before_fork();
1779 if (!NT_STATUS_IS_OK(status)) {
1780 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1783 winbindd_register_handlers(server_messaging_context(), !Fork);
1785 if (!messaging_parent_dgm_cleanup_init(server_messaging_context())) {
1789 status = init_system_session_info(NULL);
1790 if (!NT_STATUS_IS_OK(status)) {
1791 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1794 rpc_lsarpc_init(NULL);
1795 rpc_samr_init(NULL);
1797 winbindd_init_addrchange(NULL, server_event_context(),
1798 server_messaging_context());
1800 /* setup listen sockets */
1802 if (!winbindd_setup_listeners()) {
1803 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1806 irpc_add_name(winbind_imessaging_context(), "winbind_server");
1811 daemon_ready("winbindd");
1816 /* Loop waiting for requests */
1818 frame = talloc_stackframe();
1820 if (tevent_loop_once(server_event_context()) == -1) {
1821 DEBUG(1, ("tevent_loop_once() failed: %s\n",