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"
49 #define DBGC_CLASS DBGC_WINBIND
51 #define SCRUB_CLIENTS_INTERVAL 5
53 static bool client_is_idle(struct winbindd_cli_state *state);
54 static void remove_client(struct winbindd_cli_state *state);
55 static void winbindd_setup_max_fds(void);
57 static bool opt_nocache = False;
58 static bool interactive = False;
60 extern bool override_logfile;
62 struct imessaging_context *winbind_imessaging_context(void)
64 static struct imessaging_context *msg = NULL;
65 struct messaging_context *msg_ctx;
66 struct server_id myself;
67 struct loadparm_context *lp_ctx;
73 msg_ctx = server_messaging_context();
74 if (msg_ctx == NULL) {
75 smb_panic("server_messaging_context failed\n");
77 myself = messaging_server_id(msg_ctx);
79 lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
81 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
85 * Note we MUST use the NULL context here, not the autofree context,
86 * to avoid side effects in forked children exiting.
88 msg = imessaging_init(NULL, lp_ctx, myself, server_event_context());
89 talloc_unlink(NULL, lp_ctx);
92 smb_panic("Could not init winbindd's messaging context.\n");
97 /* Reload configuration */
99 static bool reload_services_file(const char *lfile)
104 char *fname = lp_next_configfile(talloc_tos());
106 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
107 set_dyn_CONFIGFILE(fname);
112 /* if this is a child, restore the logfile to the special
113 name - <domain>, idmap, etc. */
114 if (lfile && *lfile) {
115 lp_set_logfile(lfile);
119 ret = lp_load_global(get_dyn_CONFIGFILE());
123 winbindd_setup_max_fds();
129 static void winbindd_status(void)
131 struct winbindd_cli_state *tmp;
133 DEBUG(0, ("winbindd status:\n"));
135 /* Print client state information */
137 DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
139 if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
140 DEBUG(2, ("\tclient list:\n"));
141 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
142 DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
143 (unsigned long)tmp->pid, tmp->sock,
144 client_is_idle(tmp) ? "idle" : "active"));
149 /* Flush client cache */
151 static void flush_caches(void)
153 /* We need to invalidate cached user list entries on a SIGHUP
154 otherwise cached access denied errors due to restrict anonymous
155 hang around until the sequence number changes. */
157 if (!wcache_invalidate_cache()) {
158 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
159 if (!winbindd_cache_validate_and_initialize()) {
165 static void flush_caches_noinit(void)
168 * We need to invalidate cached user list entries on a SIGHUP
169 * otherwise cached access denied errors due to restrict anonymous
170 * hang around until the sequence number changes.
172 * Skip uninitialized domains when flush cache.
173 * If domain is not initialized, it means it is never
174 * used or never become online. look, wcache_invalidate_cache()
175 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
176 * for unused domains and large traffic for primay domain's DC if there
180 if (!wcache_invalidate_cache_noinit()) {
181 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
182 if (!winbindd_cache_validate_and_initialize()) {
188 /* Handle the signal by unlinking socket and exiting */
190 static void terminate(bool is_parent)
193 /* When parent goes away we should
194 * remove the socket file. Not so
195 * when children terminate.
199 if (asprintf(&path, "%s/%s",
200 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) {
208 gencache_stabilize();
210 netlogon_creds_cli_close_global_db();
214 TALLOC_CTX *mem_ctx = talloc_init("end_description");
215 char *description = talloc_describe_all(mem_ctx);
217 DEBUG(3, ("tallocs left:\n%s\n", description));
218 talloc_destroy(mem_ctx);
223 pidfile_unlink(lp_pid_directory(), "winbindd");
229 static void winbindd_sig_term_handler(struct tevent_context *ev,
230 struct tevent_signal *se,
236 bool *is_parent = talloc_get_type_abort(private_data, bool);
238 DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
239 signum, (int)*is_parent));
240 terminate(*is_parent);
244 handle stdin becoming readable when we are in --foreground mode
246 static void winbindd_stdin_handler(struct tevent_context *ev,
247 struct tevent_fd *fde,
252 if (read(0, &c, 1) != 1) {
253 bool *is_parent = talloc_get_type_abort(private_data, bool);
255 /* we have reached EOF on stdin, which means the
256 parent has exited. Shutdown the server */
257 DEBUG(0,("EOF on stdin (is_parent=%d)\n",
259 terminate(*is_parent);
263 bool winbindd_setup_sig_term_handler(bool parent)
265 struct tevent_signal *se;
268 is_parent = talloc(server_event_context(), bool);
275 se = tevent_add_signal(server_event_context(),
278 winbindd_sig_term_handler,
281 DEBUG(0,("failed to setup SIGTERM handler"));
282 talloc_free(is_parent);
286 se = tevent_add_signal(server_event_context(),
289 winbindd_sig_term_handler,
292 DEBUG(0,("failed to setup SIGINT handler"));
293 talloc_free(is_parent);
297 se = tevent_add_signal(server_event_context(),
300 winbindd_sig_term_handler,
303 DEBUG(0,("failed to setup SIGINT handler"));
304 talloc_free(is_parent);
311 bool winbindd_setup_stdin_handler(bool parent, bool foreground)
318 is_parent = talloc(server_event_context(), bool);
325 /* if we are running in the foreground then look for
326 EOF on stdin, and exit if it happens. This allows
327 us to die if the parent process dies
328 Only do this on a pipe or socket, no other device.
330 if (fstat(0, &st) != 0) {
333 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
334 tevent_add_fd(server_event_context(),
338 winbindd_stdin_handler,
346 static void winbindd_sig_hup_handler(struct tevent_context *ev,
347 struct tevent_signal *se,
353 const char *file = (const char *)private_data;
355 DEBUG(1,("Reloading services after SIGHUP\n"));
356 flush_caches_noinit();
357 reload_services_file(file);
360 bool winbindd_setup_sig_hup_handler(const char *lfile)
362 struct tevent_signal *se;
366 file = talloc_strdup(server_event_context(),
373 se = tevent_add_signal(server_event_context(),
374 server_event_context(),
376 winbindd_sig_hup_handler,
385 static void winbindd_sig_chld_handler(struct tevent_context *ev,
386 struct tevent_signal *se,
394 while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
395 winbind_child_died(pid);
399 static bool winbindd_setup_sig_chld_handler(void)
401 struct tevent_signal *se;
403 se = tevent_add_signal(server_event_context(),
404 server_event_context(),
406 winbindd_sig_chld_handler,
415 static void winbindd_sig_usr2_handler(struct tevent_context *ev,
416 struct tevent_signal *se,
425 static bool winbindd_setup_sig_usr2_handler(void)
427 struct tevent_signal *se;
429 se = tevent_add_signal(server_event_context(),
430 server_event_context(),
432 winbindd_sig_usr2_handler,
441 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
442 static void msg_reload_services(struct messaging_context *msg,
445 struct server_id server_id,
448 /* Flush various caches */
450 reload_services_file((const char *) private_data);
453 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
454 static void msg_shutdown(struct messaging_context *msg,
457 struct server_id server_id,
460 /* only the parent waits for this message */
461 DEBUG(0,("Got shutdown message\n"));
466 static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
469 struct server_id server_id,
476 DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
480 * call the validation code from a child:
481 * so we don't block the main winbindd and the validation
482 * code can safely use fork/waitpid...
486 if (child_pid == -1) {
487 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
492 if (child_pid != 0) {
494 DEBUG(5, ("winbind_msg_validate_cache: child created with "
495 "pid %d.\n", (int)child_pid));
501 status = winbindd_reinit_after_fork(NULL, NULL);
502 if (!NT_STATUS_IS_OK(status)) {
503 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
508 /* install default SIGCHLD handler: validation code uses fork/waitpid */
509 CatchSignal(SIGCHLD, SIG_DFL);
511 setproctitle("validate cache child");
513 ret = (uint8_t)winbindd_validate_cache_nobackup();
514 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
515 messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
520 static struct winbindd_dispatch_table {
521 enum winbindd_cmd cmd;
522 void (*fn)(struct winbindd_cli_state *state);
523 const char *winbindd_cmd_name;
524 } dispatch_table[] = {
526 /* Enumeration functions */
528 { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
533 { WINBINDD_INFO, winbindd_info, "INFO" },
534 { WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
535 "INTERFACE_VERSION" },
536 { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
537 { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
538 { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" },
539 { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
540 { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
541 "WINBINDD_PRIV_PIPE_DIR" },
543 /* Credential cache access */
544 { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
545 { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
549 { WINBINDD_NUM_CMDS, NULL, "NONE" }
552 struct winbindd_async_dispatch_table {
553 enum winbindd_cmd cmd;
554 const char *cmd_name;
555 struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
556 struct tevent_context *ev,
557 struct winbindd_cli_state *cli,
558 struct winbindd_request *request);
559 NTSTATUS (*recv_req)(struct tevent_req *req,
560 struct winbindd_response *presp);
563 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
564 { WINBINDD_PING, "PING",
565 wb_ping_send, wb_ping_recv },
566 { WINBINDD_LOOKUPSID, "LOOKUPSID",
567 winbindd_lookupsid_send, winbindd_lookupsid_recv },
568 { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
569 winbindd_lookupsids_send, winbindd_lookupsids_recv },
570 { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
571 winbindd_lookupname_send, winbindd_lookupname_recv },
572 { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
573 winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
574 { WINBINDD_XIDS_TO_SIDS, "XIDS_TO_SIDS",
575 winbindd_xids_to_sids_send, winbindd_xids_to_sids_recv },
576 { WINBINDD_GETPWSID, "GETPWSID",
577 winbindd_getpwsid_send, winbindd_getpwsid_recv },
578 { WINBINDD_GETPWNAM, "GETPWNAM",
579 winbindd_getpwnam_send, winbindd_getpwnam_recv },
580 { WINBINDD_GETPWUID, "GETPWUID",
581 winbindd_getpwuid_send, winbindd_getpwuid_recv },
582 { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
583 winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
584 { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
585 winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
586 { WINBINDD_GETGROUPS, "GETGROUPS",
587 winbindd_getgroups_send, winbindd_getgroups_recv },
588 { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
589 winbindd_show_sequence_send, winbindd_show_sequence_recv },
590 { WINBINDD_GETGRGID, "GETGRGID",
591 winbindd_getgrgid_send, winbindd_getgrgid_recv },
592 { WINBINDD_GETGRNAM, "GETGRNAM",
593 winbindd_getgrnam_send, winbindd_getgrnam_recv },
594 { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
595 winbindd_getusersids_send, winbindd_getusersids_recv },
596 { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
597 winbindd_lookuprids_send, winbindd_lookuprids_recv },
598 { WINBINDD_SETPWENT, "SETPWENT",
599 winbindd_setpwent_send, winbindd_setpwent_recv },
600 { WINBINDD_GETPWENT, "GETPWENT",
601 winbindd_getpwent_send, winbindd_getpwent_recv },
602 { WINBINDD_ENDPWENT, "ENDPWENT",
603 winbindd_endpwent_send, winbindd_endpwent_recv },
604 { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
605 winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
606 { WINBINDD_GETDCNAME, "GETDCNAME",
607 winbindd_getdcname_send, winbindd_getdcname_recv },
608 { WINBINDD_SETGRENT, "SETGRENT",
609 winbindd_setgrent_send, winbindd_setgrent_recv },
610 { WINBINDD_GETGRENT, "GETGRENT",
611 winbindd_getgrent_send, winbindd_getgrent_recv },
612 { WINBINDD_ENDGRENT, "ENDGRENT",
613 winbindd_endgrent_send, winbindd_endgrent_recv },
614 { WINBINDD_LIST_USERS, "LIST_USERS",
615 winbindd_list_users_send, winbindd_list_users_recv },
616 { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
617 winbindd_list_groups_send, winbindd_list_groups_recv },
618 { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
619 winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
620 { WINBINDD_PING_DC, "PING_DC",
621 winbindd_ping_dc_send, winbindd_ping_dc_recv },
622 { WINBINDD_PAM_AUTH, "PAM_AUTH",
623 winbindd_pam_auth_send, winbindd_pam_auth_recv },
624 { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
625 winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
626 { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
627 winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
628 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
629 winbindd_pam_chng_pswd_auth_crap_send,
630 winbindd_pam_chng_pswd_auth_crap_recv },
631 { WINBINDD_WINS_BYIP, "WINS_BYIP",
632 winbindd_wins_byip_send, winbindd_wins_byip_recv },
633 { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
634 winbindd_wins_byname_send, winbindd_wins_byname_recv },
636 { 0, NULL, NULL, NULL }
639 static struct winbindd_async_dispatch_table async_priv_table[] = {
640 { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
641 winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
642 { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
643 winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
644 { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
645 winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
646 { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
647 winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
649 { 0, NULL, NULL, NULL }
652 static void wb_request_done(struct tevent_req *req);
654 static void process_request(struct winbindd_cli_state *state)
656 struct winbindd_dispatch_table *table = dispatch_table;
657 struct winbindd_async_dispatch_table *atable;
659 state->mem_ctx = talloc_named(state, 0, "winbind request");
660 if (state->mem_ctx == NULL)
663 /* Remember who asked us. */
664 state->pid = state->request->pid;
666 state->cmd_name = "unknown request";
667 state->recv_fn = NULL;
668 /* client is newest */
669 winbindd_promote_client(state);
671 /* Process command */
673 for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
674 if (state->request->cmd == atable->cmd) {
679 if ((atable->send_req == NULL) && state->privileged) {
680 for (atable = async_priv_table; atable->send_req;
682 if (state->request->cmd == atable->cmd) {
688 if (atable->send_req != NULL) {
689 struct tevent_req *req;
691 state->cmd_name = atable->cmd_name;
692 state->recv_fn = atable->recv_req;
694 DEBUG(10, ("process_request: Handling async request %d:%s\n",
695 (int)state->pid, state->cmd_name));
697 req = atable->send_req(state->mem_ctx, server_event_context(),
698 state, state->request);
700 DEBUG(0, ("process_request: atable->send failed for "
701 "%s\n", atable->cmd_name));
702 request_error(state);
705 tevent_req_set_callback(req, wb_request_done, state);
709 state->response = talloc_zero(state->mem_ctx,
710 struct winbindd_response);
711 if (state->response == NULL) {
712 DEBUG(10, ("talloc failed\n"));
713 remove_client(state);
716 state->response->result = WINBINDD_PENDING;
717 state->response->length = sizeof(struct winbindd_response);
719 for (table = dispatch_table; table->fn; table++) {
720 if (state->request->cmd == table->cmd) {
721 DEBUG(10,("process_request: request fn %s\n",
722 table->winbindd_cmd_name ));
723 state->cmd_name = table->winbindd_cmd_name;
730 DEBUG(10,("process_request: unknown request fn number %d\n",
731 (int)state->request->cmd ));
732 request_error(state);
736 static void wb_request_done(struct tevent_req *req)
738 struct winbindd_cli_state *state = tevent_req_callback_data(
739 req, struct winbindd_cli_state);
742 state->response = talloc_zero(state->mem_ctx,
743 struct winbindd_response);
744 if (state->response == NULL) {
745 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
746 (int)state->pid, state->cmd_name));
747 remove_client(state);
750 state->response->result = WINBINDD_PENDING;
751 state->response->length = sizeof(struct winbindd_response);
753 status = state->recv_fn(req, state->response);
756 DEBUG(10,("wb_request_done[%d:%s]: %s\n",
757 (int)state->pid, state->cmd_name, nt_errstr(status)));
759 if (!NT_STATUS_IS_OK(status)) {
760 request_error(state);
767 * This is the main event loop of winbind requests. It goes through a
768 * state-machine of 3 read/write requests, 4 if you have extra data to send.
770 * An idle winbind client has a read request of 4 bytes outstanding,
771 * finalizing function is request_len_recv, checking the length. request_recv
772 * then processes the packet. The processing function then at some point has
773 * to call request_finished which schedules sending the response.
776 static void request_finished(struct winbindd_cli_state *state);
778 static void winbind_client_request_read(struct tevent_req *req);
779 static void winbind_client_response_written(struct tevent_req *req);
780 static void winbind_client_activity(struct tevent_req *req);
782 static void request_finished(struct winbindd_cli_state *state)
784 struct tevent_req *req;
786 /* free client socket monitoring request */
787 TALLOC_FREE(state->io_req);
789 TALLOC_FREE(state->request);
791 req = wb_resp_write_send(state, server_event_context(),
792 state->out_queue, state->sock,
795 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
796 (int)state->pid, state->cmd_name));
797 remove_client(state);
800 tevent_req_set_callback(req, winbind_client_response_written, state);
804 static void winbind_client_response_written(struct tevent_req *req)
806 struct winbindd_cli_state *state = tevent_req_callback_data(
807 req, struct winbindd_cli_state);
811 state->io_req = NULL;
813 ret = wb_resp_write_recv(req, &err);
818 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
819 (int)state->pid, state->cmd_name, strerror(err)));
820 remove_client(state);
824 DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
825 "to client\n", (int)state->pid, state->cmd_name));
827 TALLOC_FREE(state->mem_ctx);
828 state->response = NULL;
829 state->cmd_name = "no request";
830 state->recv_fn = NULL;
832 req = wb_req_read_send(state, server_event_context(), state->sock,
833 WINBINDD_MAX_EXTRA_DATA);
835 remove_client(state);
838 tevent_req_set_callback(req, winbind_client_request_read, state);
842 void request_error(struct winbindd_cli_state *state)
844 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
845 state->response->result = WINBINDD_ERROR;
846 request_finished(state);
849 void request_ok(struct winbindd_cli_state *state)
851 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
852 state->response->result = WINBINDD_OK;
853 request_finished(state);
856 /* Process a new connection by adding it to the client connection list */
858 static void new_connection(int listen_sock, bool privileged)
860 struct sockaddr_un sunaddr;
861 struct winbindd_cli_state *state;
862 struct tevent_req *req;
866 /* Accept connection */
868 len = sizeof(sunaddr);
870 sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
873 if (errno != EINTR) {
874 DEBUG(0, ("Failed to accept socket - %s\n",
879 smb_set_close_on_exec(sock);
881 DEBUG(6,("accepted socket %d\n", sock));
883 /* Create new connection structure */
885 if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
892 state->out_queue = tevent_queue_create(state, "winbind client reply");
893 if (state->out_queue == NULL) {
899 state->privileged = privileged;
901 req = wb_req_read_send(state, server_event_context(), state->sock,
902 WINBINDD_MAX_EXTRA_DATA);
908 tevent_req_set_callback(req, winbind_client_request_read, state);
911 /* Add to connection list */
913 winbindd_add_client(state);
916 static void winbind_client_request_read(struct tevent_req *req)
918 struct winbindd_cli_state *state = tevent_req_callback_data(
919 req, struct winbindd_cli_state);
923 state->io_req = NULL;
925 ret = wb_req_read_recv(req, state, &state->request, &err);
929 DEBUG(6, ("closing socket %d, client exited\n",
932 DEBUG(2, ("Could not read client request from fd %d: "
933 "%s\n", state->sock, strerror(err)));
937 remove_client(state);
941 req = wait_for_read_send(state, server_event_context(), state->sock,
944 DEBUG(0, ("winbind_client_request_read[%d:%s]:"
945 " wait_for_read_send failed - removing client\n",
946 (int)state->pid, state->cmd_name));
947 remove_client(state);
950 tevent_req_set_callback(req, winbind_client_activity, state);
953 process_request(state);
956 static void winbind_client_activity(struct tevent_req *req)
958 struct winbindd_cli_state *state =
959 tevent_req_callback_data(req, struct winbindd_cli_state);
963 has_data = wait_for_read_recv(req, &err);
966 DEBUG(0, ("winbind_client_activity[%d:%s]:"
967 "unexpected data from client - removing client\n",
968 (int)state->pid, state->cmd_name));
971 DEBUG(6, ("winbind_client_activity[%d:%s]: "
972 "client has closed connection - removing "
974 (int)state->pid, state->cmd_name));
976 DEBUG(2, ("winbind_client_activity[%d:%s]: "
977 "client socket error (%s) - removing "
979 (int)state->pid, state->cmd_name,
984 remove_client(state);
987 /* Remove a client connection from client connection list */
989 static void remove_client(struct winbindd_cli_state *state)
994 /* It's a dead client - hold a funeral */
1001 * We need to remove a pending wb_req_read_*
1002 * or wb_resp_write_* request before closing the
1005 * This is important as they might have used tevent_add_fd() and we
1006 * use the epoll * backend on linux. So we must remove the tevent_fd
1007 * before closing the fd.
1009 * Otherwise we might hit a race with close_conns_after_fork() (via
1010 * winbindd_reinit_after_fork()) where a file description
1011 * is still open in a child, which means it's still active in
1012 * the parents epoll queue, but the related tevent_fd is already
1013 * already gone in the parent.
1017 TALLOC_FREE(state->io_req);
1019 if (state->sock != -1) {
1020 /* tell client, we are closing ... */
1021 nwritten = write(state->sock, &c, sizeof(c));
1022 if (nwritten == -1) {
1023 DEBUG(2, ("final write to client failed: %s\n",
1033 TALLOC_FREE(state->mem_ctx);
1035 /* Remove from list and free */
1037 winbindd_remove_client(state);
1041 /* Is a client idle? */
1043 static bool client_is_idle(struct winbindd_cli_state *state) {
1044 return (state->request == NULL &&
1045 state->response == NULL &&
1046 !state->pwent_state && !state->grent_state);
1049 /* Shutdown client connection which has been idle for the longest time */
1051 static bool remove_idle_client(void)
1053 struct winbindd_cli_state *state, *remove_state = NULL;
1056 for (state = winbindd_client_list(); state; state = state->next) {
1057 if (client_is_idle(state)) {
1059 /* list is sorted by access time */
1060 remove_state = state;
1065 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1066 nidle, remove_state->sock, (unsigned int)remove_state->pid));
1067 remove_client(remove_state);
1075 * Terminate all clients whose requests have taken longer than
1076 * "winbind request timeout" seconds to process, or have been
1077 * idle for more than "winbind request timeout" seconds.
1080 static void remove_timed_out_clients(void)
1082 struct winbindd_cli_state *state, *prev = NULL;
1083 time_t curr_time = time(NULL);
1084 int timeout_val = lp_winbind_request_timeout();
1086 for (state = winbindd_client_list_tail(); state; state = prev) {
1089 prev = winbindd_client_list_prev(state);
1090 expiry_time = state->last_access + timeout_val;
1092 if (curr_time <= expiry_time) {
1093 /* list is sorted, previous clients in
1098 if (client_is_idle(state)) {
1099 DEBUG(5,("Idle client timed out, "
1100 "shutting down sock %d, pid %u\n",
1102 (unsigned int)state->pid));
1104 DEBUG(5,("Client request timed out, "
1105 "shutting down sock %d, pid %u\n",
1107 (unsigned int)state->pid));
1110 remove_client(state);
1114 static void winbindd_scrub_clients_handler(struct tevent_context *ev,
1115 struct tevent_timer *te,
1116 struct timeval current_time,
1119 remove_timed_out_clients();
1120 if (tevent_add_timer(ev, ev,
1121 timeval_current_ofs(SCRUB_CLIENTS_INTERVAL, 0),
1122 winbindd_scrub_clients_handler, NULL) == NULL) {
1123 DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
1128 struct winbindd_listen_state {
1133 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1134 struct tevent_fd *fde,
1138 struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1139 struct winbindd_listen_state);
1141 while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1142 DEBUG(5,("winbindd: Exceeding %d client "
1143 "connections, removing idle "
1144 "connection.\n", lp_winbind_max_clients()));
1145 if (!remove_idle_client()) {
1146 DEBUG(0,("winbindd: Exceeding %d "
1147 "client connections, no idle "
1148 "connection found\n",
1149 lp_winbind_max_clients()));
1153 remove_timed_out_clients();
1154 new_connection(s->fd, s->privileged);
1158 * Winbindd socket accessor functions
1161 char *get_winbind_priv_pipe_dir(void)
1163 return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1166 static void winbindd_setup_max_fds(void)
1168 int num_fds = MAX_OPEN_FUDGEFACTOR;
1171 num_fds += lp_winbind_max_clients();
1172 /* Add some more to account for 2 sockets open
1173 when the client transitions from unprivileged
1174 to privileged socket
1176 num_fds += lp_winbind_max_clients() / 10;
1178 /* Add one socket per child process
1179 (yeah there are child processes other than the
1180 domain children but only domain children can vary
1183 num_fds += lp_winbind_max_domain_connections() *
1184 (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
1186 actual_fds = set_maxfiles(num_fds);
1188 if (actual_fds < num_fds) {
1189 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1190 "requested %d open files, %d are available.\n",
1191 num_fds, actual_fds));
1195 static bool winbindd_setup_listeners(void)
1197 struct winbindd_listen_state *pub_state = NULL;
1198 struct winbindd_listen_state *priv_state = NULL;
1199 struct tevent_fd *fde;
1203 pub_state = talloc(server_event_context(),
1204 struct winbindd_listen_state);
1209 pub_state->privileged = false;
1210 pub_state->fd = create_pipe_sock(
1211 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1212 if (pub_state->fd == -1) {
1215 rc = listen(pub_state->fd, 5);
1220 fde = tevent_add_fd(server_event_context(), pub_state, pub_state->fd,
1221 TEVENT_FD_READ, winbindd_listen_fde_handler,
1224 close(pub_state->fd);
1227 tevent_fd_set_auto_close(fde);
1229 priv_state = talloc(server_event_context(),
1230 struct winbindd_listen_state);
1235 socket_path = get_winbind_priv_pipe_dir();
1236 if (socket_path == NULL) {
1240 priv_state->privileged = true;
1241 priv_state->fd = create_pipe_sock(
1242 socket_path, WINBINDD_SOCKET_NAME, 0750);
1243 TALLOC_FREE(socket_path);
1244 if (priv_state->fd == -1) {
1247 rc = listen(priv_state->fd, 5);
1252 fde = tevent_add_fd(server_event_context(), priv_state,
1253 priv_state->fd, TEVENT_FD_READ,
1254 winbindd_listen_fde_handler, priv_state);
1256 close(priv_state->fd);
1259 tevent_fd_set_auto_close(fde);
1261 winbindd_scrub_clients_handler(server_event_context(), NULL,
1262 timeval_current(), NULL);
1265 TALLOC_FREE(pub_state);
1266 TALLOC_FREE(priv_state);
1270 bool winbindd_use_idmap_cache(void)
1272 return !opt_nocache;
1275 bool winbindd_use_cache(void)
1277 return !opt_nocache;
1280 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1283 bool scan_trusts = true;
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 /* React on 'smbcontrol winbindd reload-config' in the same way
1309 as to SIGHUP signal */
1310 messaging_register(msg_ctx, NULL,
1311 MSG_SMB_CONF_UPDATED, msg_reload_services);
1312 messaging_register(msg_ctx, NULL,
1313 MSG_SHUTDOWN, msg_shutdown);
1315 /* Handle online/offline messages. */
1316 messaging_register(msg_ctx, NULL,
1317 MSG_WINBIND_OFFLINE, winbind_msg_offline);
1318 messaging_register(msg_ctx, NULL,
1319 MSG_WINBIND_ONLINE, winbind_msg_online);
1320 messaging_register(msg_ctx, NULL,
1321 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1323 /* Handle domain online/offline messages for domains */
1324 messaging_register(server_messaging_context(), NULL,
1325 MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1326 messaging_register(server_messaging_context(), NULL,
1327 MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1329 messaging_register(msg_ctx, NULL,
1330 MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
1332 messaging_register(msg_ctx, NULL,
1333 MSG_WINBIND_VALIDATE_CACHE,
1334 winbind_msg_validate_cache);
1336 messaging_register(msg_ctx, NULL,
1337 MSG_WINBIND_DUMP_DOMAIN_LIST,
1338 winbind_msg_dump_domain_list);
1340 messaging_register(msg_ctx, NULL,
1341 MSG_WINBIND_IP_DROPPED,
1342 winbind_msg_ip_dropped_parent);
1344 /* Register handler for MSG_DEBUG. */
1345 messaging_register(msg_ctx, NULL,
1349 netsamlogon_cache_init(); /* Non-critical */
1351 /* clear the cached list of trusted domains */
1355 if (!init_domain_list()) {
1356 DEBUG(0,("unable to initialize domain list\n"));
1361 init_locator_child();
1363 smb_nscd_flush_user_cache();
1364 smb_nscd_flush_group_cache();
1366 if (!lp_winbind_scan_trusted_domains()) {
1367 scan_trusts = false;
1370 if (!lp_allow_trusted_domains()) {
1371 scan_trusts = false;
1375 scan_trusts = false;
1379 if (tevent_add_timer(server_event_context(), NULL, timeval_zero(),
1380 rescan_trusted_domains, NULL) == NULL) {
1381 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1386 status = wb_irpc_register();
1388 if (!NT_STATUS_IS_OK(status)) {
1389 DEBUG(0, ("Could not register IRPC handlers\n"));
1394 struct winbindd_addrchanged_state {
1395 struct addrchange_context *ctx;
1396 struct tevent_context *ev;
1397 struct messaging_context *msg_ctx;
1400 static void winbindd_addr_changed(struct tevent_req *req);
1402 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1403 struct tevent_context *ev,
1404 struct messaging_context *msg_ctx)
1406 struct winbindd_addrchanged_state *state;
1407 struct tevent_req *req;
1410 state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1411 if (state == NULL) {
1412 DEBUG(10, ("talloc failed\n"));
1416 state->msg_ctx = msg_ctx;
1418 status = addrchange_context_create(state, &state->ctx);
1419 if (!NT_STATUS_IS_OK(status)) {
1420 DEBUG(10, ("addrchange_context_create failed: %s\n",
1421 nt_errstr(status)));
1425 req = addrchange_send(state, ev, state->ctx);
1427 DEBUG(0, ("addrchange_send failed\n"));
1431 tevent_req_set_callback(req, winbindd_addr_changed, state);
1434 static void winbindd_addr_changed(struct tevent_req *req)
1436 struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1437 req, struct winbindd_addrchanged_state);
1438 enum addrchange_type type;
1439 struct sockaddr_storage addr;
1442 status = addrchange_recv(req, &type, &addr);
1444 if (!NT_STATUS_IS_OK(status)) {
1445 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1446 nt_errstr(status)));
1450 if (type == ADDRCHANGE_DEL) {
1451 char addrstr[INET6_ADDRSTRLEN];
1454 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1456 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1459 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1461 status = messaging_send(state->msg_ctx,
1462 messaging_server_id(state->msg_ctx),
1463 MSG_WINBIND_IP_DROPPED, &blob);
1464 if (!NT_STATUS_IS_OK(status)) {
1465 DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1466 nt_errstr(status)));
1469 req = addrchange_send(state, state->ev, state->ctx);
1471 DEBUG(0, ("addrchange_send failed\n"));
1475 tevent_req_set_callback(req, winbindd_addr_changed, state);
1480 int main(int argc, const char **argv)
1482 static bool is_daemon = False;
1483 static bool Fork = True;
1484 static bool log_stdout = False;
1485 static bool no_process_group = False;
1489 OPT_NO_PROCESS_GROUP,
1492 struct poptOption long_options[] = {
1494 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1495 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1496 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1497 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1498 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1499 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1509 setproctitle_init(argc, discard_const(argv), environ);
1512 * Do this before any other talloc operation
1514 talloc_enable_null_tracking();
1515 frame = talloc_stackframe();
1518 * We want total control over the permissions on created files,
1519 * so set our umask to 0.
1523 setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1525 /* glibc (?) likes to print "User defined signal 1" and exit if a
1526 SIGUSR[12] is received before a handler is installed */
1528 CatchSignal(SIGUSR1, SIG_IGN);
1529 CatchSignal(SIGUSR2, SIG_IGN);
1532 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1536 /* Initialise for running in non-root mode */
1540 set_remote_machine_name("winbindd", False);
1542 /* Set environment variable so we don't recursively call ourselves.
1543 This may also be useful interactively. */
1545 if ( !winbind_off() ) {
1546 DEBUG(0,("Failed to disable recusive winbindd calls. Exiting.\n"));
1550 /* Initialise samba/rpc client stuff */
1552 pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1554 while ((opt = poptGetNextOpt(pc)) != -1) {
1556 /* Don't become a daemon */
1568 case OPT_NO_PROCESS_GROUP:
1569 no_process_group = true;
1571 case OPT_LOG_STDOUT:
1578 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1579 poptBadOption(pc, 0), poptStrerror(opt));
1580 poptPrintUsage(pc, stderr, 0);
1585 /* We call dump_core_setup one more time because the command line can
1586 * set the log file or the log-basename and this will influence where
1587 * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1588 * the default value derived from build's prefix. For EOM this value
1589 * is often not related to the path where winbindd is actually run
1592 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1593 if (is_daemon && interactive) {
1594 d_fprintf(stderr,"\nERROR: "
1595 "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1596 poptPrintUsage(pc, stderr, 0);
1600 if (log_stdout && Fork) {
1601 d_fprintf(stderr, "\nERROR: "
1602 "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1603 poptPrintUsage(pc, stderr, 0);
1607 poptFreeContext(pc);
1609 if (!override_logfile) {
1611 if (asprintf(&lfile,"%s/log.winbindd",
1612 get_dyn_LOGFILEBASE()) > 0) {
1613 lp_set_logfile(lfile);
1619 setup_logging("winbindd", DEBUG_STDOUT);
1621 setup_logging("winbindd", DEBUG_FILE);
1625 DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1626 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1628 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1629 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1632 /* After parsing the configuration file we setup the core path one more time
1633 * as the log file might have been set in the configuration and cores's
1634 * path is by default basename(lp_logfile()).
1636 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1638 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1639 && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1640 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1641 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"));
1645 if (!cluster_probe_ok()) {
1649 /* Initialise messaging system */
1651 if (server_messaging_context() == NULL) {
1655 if (!reload_services_file(NULL)) {
1656 DEBUG(0, ("error opening config file\n"));
1662 const char *idmap_backend;
1663 const char *invalid_backends[] = {
1664 "ad", "rfc2307", "rid",
1667 idmap_backend = lp_idmap_default_backend();
1668 for (i = 0; i < ARRAY_SIZE(invalid_backends); i++) {
1669 ok = strequal(idmap_backend, invalid_backends[i]);
1671 DBG_ERR("FATAL: Invalid idmap backend %s "
1672 "configured as the default backend!\n",
1679 ok = directory_create_or_exist(lp_lock_directory(), 0755);
1681 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1682 lp_lock_directory(), strerror(errno)));
1686 ok = directory_create_or_exist(lp_pid_directory(), 0755);
1688 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1689 lp_pid_directory(), strerror(errno)));
1700 if (!secrets_init()) {
1702 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1706 status = rpccli_pre_open_netlogon_creds();
1707 if (!NT_STATUS_IS_OK(status)) {
1708 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1709 nt_errstr(status)));
1713 /* Unblock all signals we are interested in as they may have been
1714 blocked by the parent process. */
1716 BlockSignals(False, SIGINT);
1717 BlockSignals(False, SIGQUIT);
1718 BlockSignals(False, SIGTERM);
1719 BlockSignals(False, SIGUSR1);
1720 BlockSignals(False, SIGUSR2);
1721 BlockSignals(False, SIGHUP);
1722 BlockSignals(False, SIGCHLD);
1725 become_daemon(Fork, no_process_group, log_stdout);
1727 pidfile_create(lp_pid_directory(), "winbindd");
1731 * If we're interactive we want to set our own process group for
1732 * signal management.
1734 if (interactive && !no_process_group)
1735 setpgid( (pid_t)0, (pid_t)0);
1740 /* Don't use winbindd_reinit_after_fork here as
1741 * we're just starting up and haven't created any
1742 * winbindd-specific resources we must free yet. JRA.
1745 status = reinit_after_fork(server_messaging_context(),
1746 server_event_context(),
1748 if (!NT_STATUS_IS_OK(status)) {
1749 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1753 * Do not initialize the parent-child-pipe before becoming
1754 * a daemon: this is used to detect a died parent in the child
1757 status = init_before_fork();
1758 if (!NT_STATUS_IS_OK(status)) {
1759 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1762 winbindd_register_handlers(server_messaging_context(), !Fork);
1764 if (!messaging_parent_dgm_cleanup_init(server_messaging_context())) {
1768 status = init_system_session_info();
1769 if (!NT_STATUS_IS_OK(status)) {
1770 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1773 rpc_lsarpc_init(NULL);
1774 rpc_samr_init(NULL);
1776 winbindd_init_addrchange(NULL, server_event_context(),
1777 server_messaging_context());
1779 /* setup listen sockets */
1781 if (!winbindd_setup_listeners()) {
1782 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1785 irpc_add_name(winbind_imessaging_context(), "winbind_server");
1790 daemon_ready("winbindd");
1795 /* Loop waiting for requests */
1797 frame = talloc_stackframe();
1799 if (tevent_loop_once(server_event_context()) == -1) {
1800 DEBUG(1, ("tevent_loop_once() failed: %s\n",