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"
47 #define DBGC_CLASS DBGC_WINBIND
49 static bool client_is_idle(struct winbindd_cli_state *state);
50 static void remove_client(struct winbindd_cli_state *state);
51 static void winbindd_setup_max_fds(void);
53 static bool opt_nocache = False;
54 static bool interactive = False;
56 extern bool override_logfile;
58 struct tevent_context *winbind_event_context(void)
60 static struct tevent_context *ev = NULL;
67 * Note we MUST use the NULL context here, not the autofree context,
68 * to avoid side effects in forked children exiting.
70 ev = samba_tevent_context_init(NULL);
72 smb_panic("Could not init winbindd's messaging context.\n");
77 struct messaging_context *winbind_messaging_context(void)
79 static struct messaging_context *msg = NULL;
86 * Note we MUST use the NULL context here, not the autofree context,
87 * to avoid side effects in forked children exiting.
89 msg = messaging_init(NULL, winbind_event_context());
91 smb_panic("Could not init winbindd's messaging context.\n");
96 struct imessaging_context *winbind_imessaging_context(void)
98 static struct imessaging_context *msg = NULL;
99 struct loadparm_context *lp_ctx;
105 lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
106 if (lp_ctx == NULL) {
107 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
111 * Note we MUST use the NULL context here, not the autofree context,
112 * to avoid side effects in forked children exiting.
114 msg = imessaging_init(NULL, lp_ctx, procid_self(), winbind_event_context(), false);
115 talloc_unlink(NULL, lp_ctx);
118 smb_panic("Could not init winbindd's messaging context.\n");
123 /* Reload configuration */
125 static bool reload_services_file(const char *lfile)
130 char *fname = lp_next_configfile(talloc_tos());
132 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
133 set_dyn_CONFIGFILE(fname);
138 /* if this is a child, restore the logfile to the special
139 name - <domain>, idmap, etc. */
140 if (lfile && *lfile) {
141 lp_set_logfile(lfile);
145 ret = lp_load_global(get_dyn_CONFIGFILE());
149 winbindd_setup_max_fds();
155 static void winbindd_status(void)
157 struct winbindd_cli_state *tmp;
159 DEBUG(0, ("winbindd status:\n"));
161 /* Print client state information */
163 DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
165 if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
166 DEBUG(2, ("\tclient list:\n"));
167 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
168 DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
169 (unsigned long)tmp->pid, tmp->sock,
170 client_is_idle(tmp) ? "idle" : "active"));
175 /* Flush client cache */
177 static void flush_caches(void)
179 /* We need to invalidate cached user list entries on a SIGHUP
180 otherwise cached access denied errors due to restrict anonymous
181 hang around until the sequence number changes. */
183 if (!wcache_invalidate_cache()) {
184 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
185 if (!winbindd_cache_validate_and_initialize()) {
191 static void flush_caches_noinit(void)
194 * We need to invalidate cached user list entries on a SIGHUP
195 * otherwise cached access denied errors due to restrict anonymous
196 * hang around until the sequence number changes.
198 * Skip uninitialized domains when flush cache.
199 * If domain is not initialized, it means it is never
200 * used or never become online. look, wcache_invalidate_cache()
201 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
202 * for unused domains and large traffic for primay domain's DC if there
206 if (!wcache_invalidate_cache_noinit()) {
207 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
208 if (!winbindd_cache_validate_and_initialize()) {
214 /* Handle the signal by unlinking socket and exiting */
216 static void terminate(bool is_parent)
219 /* When parent goes away we should
220 * remove the socket file. Not so
221 * when children terminate.
225 if (asprintf(&path, "%s/%s",
226 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) {
234 trustdom_cache_shutdown();
236 gencache_stabilize();
240 TALLOC_CTX *mem_ctx = talloc_init("end_description");
241 char *description = talloc_describe_all(mem_ctx);
243 DEBUG(3, ("tallocs left:\n%s\n", description));
244 talloc_destroy(mem_ctx);
249 struct messaging_context *msg = winbind_messaging_context();
250 struct server_id self = messaging_server_id(msg);
251 serverid_deregister(self);
252 pidfile_unlink(lp_pid_directory(), "winbindd");
258 static void winbindd_sig_term_handler(struct tevent_context *ev,
259 struct tevent_signal *se,
265 bool *is_parent = talloc_get_type_abort(private_data, bool);
267 DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
268 signum, (int)*is_parent));
269 terminate(*is_parent);
273 handle stdin becoming readable when we are in --foreground mode
275 static void winbindd_stdin_handler(struct tevent_context *ev,
276 struct tevent_fd *fde,
281 if (read(0, &c, 1) != 1) {
282 bool *is_parent = talloc_get_type_abort(private_data, bool);
284 /* we have reached EOF on stdin, which means the
285 parent has exited. Shutdown the server */
286 DEBUG(0,("EOF on stdin (is_parent=%d)\n",
288 terminate(*is_parent);
292 bool winbindd_setup_sig_term_handler(bool parent)
294 struct tevent_signal *se;
297 is_parent = talloc(winbind_event_context(), bool);
304 se = tevent_add_signal(winbind_event_context(),
307 winbindd_sig_term_handler,
310 DEBUG(0,("failed to setup SIGTERM handler"));
311 talloc_free(is_parent);
315 se = tevent_add_signal(winbind_event_context(),
318 winbindd_sig_term_handler,
321 DEBUG(0,("failed to setup SIGINT handler"));
322 talloc_free(is_parent);
326 se = tevent_add_signal(winbind_event_context(),
329 winbindd_sig_term_handler,
332 DEBUG(0,("failed to setup SIGINT handler"));
333 talloc_free(is_parent);
340 bool winbindd_setup_stdin_handler(bool parent, bool foreground)
347 is_parent = talloc(winbind_event_context(), bool);
354 /* if we are running in the foreground then look for
355 EOF on stdin, and exit if it happens. This allows
356 us to die if the parent process dies
357 Only do this on a pipe or socket, no other device.
359 if (fstat(0, &st) != 0) {
362 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
363 tevent_add_fd(winbind_event_context(),
367 winbindd_stdin_handler,
375 static void winbindd_sig_hup_handler(struct tevent_context *ev,
376 struct tevent_signal *se,
382 const char *file = (const char *)private_data;
384 DEBUG(1,("Reloading services after SIGHUP\n"));
385 flush_caches_noinit();
386 reload_services_file(file);
389 bool winbindd_setup_sig_hup_handler(const char *lfile)
391 struct tevent_signal *se;
395 file = talloc_strdup(winbind_event_context(),
402 se = tevent_add_signal(winbind_event_context(),
403 winbind_event_context(),
405 winbindd_sig_hup_handler,
414 static void winbindd_sig_chld_handler(struct tevent_context *ev,
415 struct tevent_signal *se,
423 while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) {
424 winbind_child_died(pid);
428 static bool winbindd_setup_sig_chld_handler(void)
430 struct tevent_signal *se;
432 se = tevent_add_signal(winbind_event_context(),
433 winbind_event_context(),
435 winbindd_sig_chld_handler,
444 static void winbindd_sig_usr2_handler(struct tevent_context *ev,
445 struct tevent_signal *se,
454 static bool winbindd_setup_sig_usr2_handler(void)
456 struct tevent_signal *se;
458 se = tevent_add_signal(winbind_event_context(),
459 winbind_event_context(),
461 winbindd_sig_usr2_handler,
470 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
471 static void msg_reload_services(struct messaging_context *msg,
474 struct server_id server_id,
477 /* Flush various caches */
479 reload_services_file((const char *) private_data);
482 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
483 static void msg_shutdown(struct messaging_context *msg,
486 struct server_id server_id,
489 /* only the parent waits for this message */
490 DEBUG(0,("Got shutdown message\n"));
495 static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
498 struct server_id server_id,
505 DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
509 * call the validation code from a child:
510 * so we don't block the main winbindd and the validation
511 * code can safely use fork/waitpid...
515 if (child_pid == -1) {
516 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
521 if (child_pid != 0) {
523 DEBUG(5, ("winbind_msg_validate_cache: child created with "
524 "pid %d.\n", (int)child_pid));
530 status = winbindd_reinit_after_fork(NULL, NULL);
531 if (!NT_STATUS_IS_OK(status)) {
532 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
537 /* install default SIGCHLD handler: validation code uses fork/waitpid */
538 CatchSignal(SIGCHLD, SIG_DFL);
540 ret = (uint8_t)winbindd_validate_cache_nobackup();
541 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
542 messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
547 static struct winbindd_dispatch_table {
548 enum winbindd_cmd cmd;
549 void (*fn)(struct winbindd_cli_state *state);
550 const char *winbindd_cmd_name;
551 } dispatch_table[] = {
553 /* Enumeration functions */
555 { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
560 { WINBINDD_INFO, winbindd_info, "INFO" },
561 { WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
562 "INTERFACE_VERSION" },
563 { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
564 { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
565 { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" },
566 { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
567 { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
568 "WINBINDD_PRIV_PIPE_DIR" },
570 /* Credential cache access */
571 { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
572 { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
576 { WINBINDD_NUM_CMDS, NULL, "NONE" }
579 struct winbindd_async_dispatch_table {
580 enum winbindd_cmd cmd;
581 const char *cmd_name;
582 struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
583 struct tevent_context *ev,
584 struct winbindd_cli_state *cli,
585 struct winbindd_request *request);
586 NTSTATUS (*recv_req)(struct tevent_req *req,
587 struct winbindd_response *presp);
590 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
591 { WINBINDD_PING, "PING",
592 wb_ping_send, wb_ping_recv },
593 { WINBINDD_LOOKUPSID, "LOOKUPSID",
594 winbindd_lookupsid_send, winbindd_lookupsid_recv },
595 { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
596 winbindd_lookupsids_send, winbindd_lookupsids_recv },
597 { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
598 winbindd_lookupname_send, winbindd_lookupname_recv },
599 { WINBINDD_SID_TO_UID, "SID_TO_UID",
600 winbindd_sid_to_uid_send, winbindd_sid_to_uid_recv },
601 { WINBINDD_SID_TO_GID, "SID_TO_GID",
602 winbindd_sid_to_gid_send, winbindd_sid_to_gid_recv },
603 { WINBINDD_UID_TO_SID, "UID_TO_SID",
604 winbindd_uid_to_sid_send, winbindd_uid_to_sid_recv },
605 { WINBINDD_GID_TO_SID, "GID_TO_SID",
606 winbindd_gid_to_sid_send, winbindd_gid_to_sid_recv },
607 { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
608 winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
609 { WINBINDD_GETPWSID, "GETPWSID",
610 winbindd_getpwsid_send, winbindd_getpwsid_recv },
611 { WINBINDD_GETPWNAM, "GETPWNAM",
612 winbindd_getpwnam_send, winbindd_getpwnam_recv },
613 { WINBINDD_GETPWUID, "GETPWUID",
614 winbindd_getpwuid_send, winbindd_getpwuid_recv },
615 { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
616 winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
617 { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
618 winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
619 { WINBINDD_GETGROUPS, "GETGROUPS",
620 winbindd_getgroups_send, winbindd_getgroups_recv },
621 { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
622 winbindd_show_sequence_send, winbindd_show_sequence_recv },
623 { WINBINDD_GETGRGID, "GETGRGID",
624 winbindd_getgrgid_send, winbindd_getgrgid_recv },
625 { WINBINDD_GETGRNAM, "GETGRNAM",
626 winbindd_getgrnam_send, winbindd_getgrnam_recv },
627 { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
628 winbindd_getusersids_send, winbindd_getusersids_recv },
629 { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
630 winbindd_lookuprids_send, winbindd_lookuprids_recv },
631 { WINBINDD_SETPWENT, "SETPWENT",
632 winbindd_setpwent_send, winbindd_setpwent_recv },
633 { WINBINDD_GETPWENT, "GETPWENT",
634 winbindd_getpwent_send, winbindd_getpwent_recv },
635 { WINBINDD_ENDPWENT, "ENDPWENT",
636 winbindd_endpwent_send, winbindd_endpwent_recv },
637 { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
638 winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
639 { WINBINDD_GETDCNAME, "GETDCNAME",
640 winbindd_getdcname_send, winbindd_getdcname_recv },
641 { WINBINDD_SETGRENT, "SETGRENT",
642 winbindd_setgrent_send, winbindd_setgrent_recv },
643 { WINBINDD_GETGRENT, "GETGRENT",
644 winbindd_getgrent_send, winbindd_getgrent_recv },
645 { WINBINDD_ENDGRENT, "ENDGRENT",
646 winbindd_endgrent_send, winbindd_endgrent_recv },
647 { WINBINDD_LIST_USERS, "LIST_USERS",
648 winbindd_list_users_send, winbindd_list_users_recv },
649 { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
650 winbindd_list_groups_send, winbindd_list_groups_recv },
651 { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
652 winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
653 { WINBINDD_PING_DC, "PING_DC",
654 winbindd_ping_dc_send, winbindd_ping_dc_recv },
655 { WINBINDD_PAM_AUTH, "PAM_AUTH",
656 winbindd_pam_auth_send, winbindd_pam_auth_recv },
657 { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
658 winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
659 { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
660 winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
661 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
662 winbindd_pam_chng_pswd_auth_crap_send,
663 winbindd_pam_chng_pswd_auth_crap_recv },
664 { WINBINDD_WINS_BYIP, "WINS_BYIP",
665 winbindd_wins_byip_send, winbindd_wins_byip_recv },
666 { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
667 winbindd_wins_byname_send, winbindd_wins_byname_recv },
669 { 0, NULL, NULL, NULL }
672 static struct winbindd_async_dispatch_table async_priv_table[] = {
673 { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
674 winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
675 { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
676 winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
677 { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
678 winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
679 { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
680 winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
682 { 0, NULL, NULL, NULL }
685 static void wb_request_done(struct tevent_req *req);
687 static void process_request(struct winbindd_cli_state *state)
689 struct winbindd_dispatch_table *table = dispatch_table;
690 struct winbindd_async_dispatch_table *atable;
692 state->mem_ctx = talloc_named(state, 0, "winbind request");
693 if (state->mem_ctx == NULL)
696 /* Remember who asked us. */
697 state->pid = state->request->pid;
699 state->cmd_name = "unknown request";
700 state->recv_fn = NULL;
701 state->last_access = time(NULL);
703 /* Process command */
705 for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
706 if (state->request->cmd == atable->cmd) {
711 if ((atable->send_req == NULL) && state->privileged) {
712 for (atable = async_priv_table; atable->send_req;
714 if (state->request->cmd == atable->cmd) {
720 if (atable->send_req != NULL) {
721 struct tevent_req *req;
723 state->cmd_name = atable->cmd_name;
724 state->recv_fn = atable->recv_req;
726 DEBUG(10, ("process_request: Handling async request %d:%s\n",
727 (int)state->pid, state->cmd_name));
729 req = atable->send_req(state->mem_ctx, winbind_event_context(),
730 state, state->request);
732 DEBUG(0, ("process_request: atable->send failed for "
733 "%s\n", atable->cmd_name));
734 request_error(state);
737 tevent_req_set_callback(req, wb_request_done, state);
741 state->response = talloc_zero(state->mem_ctx,
742 struct winbindd_response);
743 if (state->response == NULL) {
744 DEBUG(10, ("talloc failed\n"));
745 remove_client(state);
748 state->response->result = WINBINDD_PENDING;
749 state->response->length = sizeof(struct winbindd_response);
751 for (table = dispatch_table; table->fn; table++) {
752 if (state->request->cmd == table->cmd) {
753 DEBUG(10,("process_request: request fn %s\n",
754 table->winbindd_cmd_name ));
755 state->cmd_name = table->winbindd_cmd_name;
762 DEBUG(10,("process_request: unknown request fn number %d\n",
763 (int)state->request->cmd ));
764 request_error(state);
768 static void wb_request_done(struct tevent_req *req)
770 struct winbindd_cli_state *state = tevent_req_callback_data(
771 req, struct winbindd_cli_state);
774 state->response = talloc_zero(state->mem_ctx,
775 struct winbindd_response);
776 if (state->response == NULL) {
777 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
778 (int)state->pid, state->cmd_name));
779 remove_client(state);
782 state->response->result = WINBINDD_PENDING;
783 state->response->length = sizeof(struct winbindd_response);
785 status = state->recv_fn(req, state->response);
788 DEBUG(10,("wb_request_done[%d:%s]: %s\n",
789 (int)state->pid, state->cmd_name, nt_errstr(status)));
791 if (!NT_STATUS_IS_OK(status)) {
792 request_error(state);
799 * This is the main event loop of winbind requests. It goes through a
800 * state-machine of 3 read/write requests, 4 if you have extra data to send.
802 * An idle winbind client has a read request of 4 bytes outstanding,
803 * finalizing function is request_len_recv, checking the length. request_recv
804 * then processes the packet. The processing function then at some point has
805 * to call request_finished which schedules sending the response.
808 static void request_finished(struct winbindd_cli_state *state);
810 static void winbind_client_request_read(struct tevent_req *req);
811 static void winbind_client_response_written(struct tevent_req *req);
813 static void request_finished(struct winbindd_cli_state *state)
815 struct tevent_req *req;
817 TALLOC_FREE(state->request);
819 req = wb_resp_write_send(state, winbind_event_context(),
820 state->out_queue, state->sock,
823 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
824 (int)state->pid, state->cmd_name));
825 remove_client(state);
828 tevent_req_set_callback(req, winbind_client_response_written, state);
832 static void winbind_client_response_written(struct tevent_req *req)
834 struct winbindd_cli_state *state = tevent_req_callback_data(
835 req, struct winbindd_cli_state);
839 state->io_req = NULL;
841 ret = wb_resp_write_recv(req, &err);
846 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
847 (int)state->pid, state->cmd_name, strerror(err)));
848 remove_client(state);
852 DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
853 "to client\n", (int)state->pid, state->cmd_name));
855 TALLOC_FREE(state->mem_ctx);
856 state->response = NULL;
857 state->cmd_name = "no request";
858 state->recv_fn = NULL;
860 req = wb_req_read_send(state, winbind_event_context(), state->sock,
861 WINBINDD_MAX_EXTRA_DATA);
863 remove_client(state);
866 tevent_req_set_callback(req, winbind_client_request_read, state);
870 void request_error(struct winbindd_cli_state *state)
872 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
873 state->response->result = WINBINDD_ERROR;
874 request_finished(state);
877 void request_ok(struct winbindd_cli_state *state)
879 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
880 state->response->result = WINBINDD_OK;
881 request_finished(state);
884 /* Process a new connection by adding it to the client connection list */
886 static void new_connection(int listen_sock, bool privileged)
888 struct sockaddr_un sunaddr;
889 struct winbindd_cli_state *state;
890 struct tevent_req *req;
894 /* Accept connection */
896 len = sizeof(sunaddr);
898 sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
901 if (errno != EINTR) {
902 DEBUG(0, ("Failed to accept socket - %s\n",
908 DEBUG(6,("accepted socket %d\n", sock));
910 /* Create new connection structure */
912 if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
919 state->out_queue = tevent_queue_create(state, "winbind client reply");
920 if (state->out_queue == NULL) {
926 state->last_access = time(NULL);
928 state->privileged = privileged;
930 req = wb_req_read_send(state, winbind_event_context(), state->sock,
931 WINBINDD_MAX_EXTRA_DATA);
937 tevent_req_set_callback(req, winbind_client_request_read, state);
940 /* Add to connection list */
942 winbindd_add_client(state);
945 static void winbind_client_request_read(struct tevent_req *req)
947 struct winbindd_cli_state *state = tevent_req_callback_data(
948 req, struct winbindd_cli_state);
952 state->io_req = NULL;
954 ret = wb_req_read_recv(req, state, &state->request, &err);
958 DEBUG(6, ("closing socket %d, client exited\n",
961 DEBUG(2, ("Could not read client request from fd %d: "
962 "%s\n", state->sock, strerror(err)));
966 remove_client(state);
969 process_request(state);
972 /* Remove a client connection from client connection list */
974 static void remove_client(struct winbindd_cli_state *state)
979 /* It's a dead client - hold a funeral */
986 * We need to remove a pending wb_req_read_*
987 * or wb_resp_write_* request before closing the
990 * This is important as they might have used tevent_add_fd() and we
991 * use the epoll * backend on linux. So we must remove the tevent_fd
992 * before closing the fd.
994 * Otherwise we might hit a race with close_conns_after_fork() (via
995 * winbindd_reinit_after_fork()) where a file description
996 * is still open in a child, which means it's still active in
997 * the parents epoll queue, but the related tevent_fd is already
998 * already gone in the parent.
1002 TALLOC_FREE(state->io_req);
1004 if (state->sock != -1) {
1005 /* tell client, we are closing ... */
1006 nwritten = write(state->sock, &c, sizeof(c));
1007 if (nwritten == -1) {
1008 DEBUG(2, ("final write to client failed: %s\n",
1018 TALLOC_FREE(state->mem_ctx);
1020 /* Remove from list and free */
1022 winbindd_remove_client(state);
1026 /* Is a client idle? */
1028 static bool client_is_idle(struct winbindd_cli_state *state) {
1029 return (state->request == NULL &&
1030 state->response == NULL &&
1031 !state->pwent_state && !state->grent_state);
1034 /* Shutdown client connection which has been idle for the longest time */
1036 static bool remove_idle_client(void)
1038 struct winbindd_cli_state *state, *remove_state = NULL;
1039 time_t last_access = 0;
1042 for (state = winbindd_client_list(); state; state = state->next) {
1043 if (client_is_idle(state)) {
1045 if (!last_access || state->last_access < last_access) {
1046 last_access = state->last_access;
1047 remove_state = state;
1053 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1054 nidle, remove_state->sock, (unsigned int)remove_state->pid));
1055 remove_client(remove_state);
1063 * Terminate all clients whose requests have taken longer than
1064 * "winbind request timeout" seconds to process, or have been
1065 * idle for more than "winbind request timeout" seconds.
1068 static void remove_timed_out_clients(void)
1070 struct winbindd_cli_state *state, *next = NULL;
1071 time_t curr_time = time(NULL);
1072 int timeout_val = lp_winbind_request_timeout();
1074 for (state = winbindd_client_list(); state; state = next) {
1078 expiry_time = state->last_access + timeout_val;
1080 if (curr_time > expiry_time) {
1081 if (client_is_idle(state)) {
1082 DEBUG(5,("Idle client timed out, "
1083 "shutting down sock %d, pid %u\n",
1085 (unsigned int)state->pid));
1087 DEBUG(5,("Client request timed out, "
1088 "shutting down sock %d, pid %u\n",
1090 (unsigned int)state->pid));
1092 remove_client(state);
1097 struct winbindd_listen_state {
1102 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1103 struct tevent_fd *fde,
1107 struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1108 struct winbindd_listen_state);
1110 while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1111 DEBUG(5,("winbindd: Exceeding %d client "
1112 "connections, removing idle "
1113 "connection.\n", lp_winbind_max_clients()));
1114 if (!remove_idle_client()) {
1115 DEBUG(0,("winbindd: Exceeding %d "
1116 "client connections, no idle "
1117 "connection found\n",
1118 lp_winbind_max_clients()));
1122 remove_timed_out_clients();
1123 new_connection(s->fd, s->privileged);
1127 * Winbindd socket accessor functions
1130 char *get_winbind_priv_pipe_dir(void)
1132 return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1135 static void winbindd_setup_max_fds(void)
1137 int num_fds = MAX_OPEN_FUDGEFACTOR;
1140 num_fds += lp_winbind_max_clients();
1141 /* Add some more to account for 2 sockets open
1142 when the client transitions from unprivileged
1143 to privileged socket
1145 num_fds += lp_winbind_max_clients() / 10;
1147 /* Add one socket per child process
1148 (yeah there are child processes other than the
1149 domain children but only domain children can vary
1152 num_fds += lp_winbind_max_domain_connections() *
1153 (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
1155 actual_fds = set_maxfiles(num_fds);
1157 if (actual_fds < num_fds) {
1158 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1159 "requested %d open files, %d are available.\n",
1160 num_fds, actual_fds));
1164 static bool winbindd_setup_listeners(void)
1166 struct winbindd_listen_state *pub_state = NULL;
1167 struct winbindd_listen_state *priv_state = NULL;
1168 struct tevent_fd *fde;
1172 pub_state = talloc(winbind_event_context(),
1173 struct winbindd_listen_state);
1178 pub_state->privileged = false;
1179 pub_state->fd = create_pipe_sock(
1180 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1181 if (pub_state->fd == -1) {
1184 rc = listen(pub_state->fd, 5);
1189 fde = tevent_add_fd(winbind_event_context(), pub_state, pub_state->fd,
1190 TEVENT_FD_READ, winbindd_listen_fde_handler,
1193 close(pub_state->fd);
1196 tevent_fd_set_auto_close(fde);
1198 priv_state = talloc(winbind_event_context(),
1199 struct winbindd_listen_state);
1204 socket_path = get_winbind_priv_pipe_dir();
1205 if (socket_path == NULL) {
1209 priv_state->privileged = true;
1210 priv_state->fd = create_pipe_sock(
1211 socket_path, WINBINDD_SOCKET_NAME, 0750);
1212 TALLOC_FREE(socket_path);
1213 if (priv_state->fd == -1) {
1216 rc = listen(priv_state->fd, 5);
1221 fde = tevent_add_fd(winbind_event_context(), priv_state,
1222 priv_state->fd, TEVENT_FD_READ,
1223 winbindd_listen_fde_handler, priv_state);
1225 close(priv_state->fd);
1228 tevent_fd_set_auto_close(fde);
1232 TALLOC_FREE(pub_state);
1233 TALLOC_FREE(priv_state);
1237 bool winbindd_use_idmap_cache(void)
1239 return !opt_nocache;
1242 bool winbindd_use_cache(void)
1244 return !opt_nocache;
1247 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1251 /* Setup signal handlers */
1253 if (!winbindd_setup_sig_term_handler(true))
1255 if (!winbindd_setup_stdin_handler(true, foreground))
1257 if (!winbindd_setup_sig_hup_handler(NULL))
1259 if (!winbindd_setup_sig_chld_handler())
1261 if (!winbindd_setup_sig_usr2_handler())
1264 CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
1267 * Ensure all cache and idmap caches are consistent
1268 * and initialized before we startup.
1270 if (!winbindd_cache_validate_and_initialize()) {
1274 /* get broadcast messages */
1276 if (!serverid_register(messaging_server_id(msg_ctx),
1280 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
1284 /* React on 'smbcontrol winbindd reload-config' in the same way
1285 as to SIGHUP signal */
1286 messaging_register(msg_ctx, NULL,
1287 MSG_SMB_CONF_UPDATED, msg_reload_services);
1288 messaging_register(msg_ctx, NULL,
1289 MSG_SHUTDOWN, msg_shutdown);
1291 /* Handle online/offline messages. */
1292 messaging_register(msg_ctx, NULL,
1293 MSG_WINBIND_OFFLINE, winbind_msg_offline);
1294 messaging_register(msg_ctx, NULL,
1295 MSG_WINBIND_ONLINE, winbind_msg_online);
1296 messaging_register(msg_ctx, NULL,
1297 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1299 /* Handle domain online/offline messages for domains */
1300 messaging_register(winbind_messaging_context(), NULL,
1301 MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1302 messaging_register(winbind_messaging_context(), NULL,
1303 MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1305 messaging_register(msg_ctx, NULL,
1306 MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
1308 messaging_register(msg_ctx, NULL,
1309 MSG_WINBIND_VALIDATE_CACHE,
1310 winbind_msg_validate_cache);
1312 messaging_register(msg_ctx, NULL,
1313 MSG_WINBIND_DUMP_DOMAIN_LIST,
1314 winbind_msg_dump_domain_list);
1316 messaging_register(msg_ctx, NULL,
1317 MSG_WINBIND_IP_DROPPED,
1318 winbind_msg_ip_dropped_parent);
1320 /* Register handler for MSG_DEBUG. */
1321 messaging_register(msg_ctx, NULL,
1325 netsamlogon_cache_init(); /* Non-critical */
1327 /* clear the cached list of trusted domains */
1331 if (!init_domain_list()) {
1332 DEBUG(0,("unable to initialize domain list\n"));
1337 init_locator_child();
1339 smb_nscd_flush_user_cache();
1340 smb_nscd_flush_group_cache();
1342 if (lp_allow_trusted_domains()) {
1343 if (tevent_add_timer(winbind_event_context(), NULL, timeval_zero(),
1344 rescan_trusted_domains, NULL) == NULL) {
1345 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1350 status = wb_irpc_register();
1352 if (!NT_STATUS_IS_OK(status)) {
1353 DEBUG(0, ("Could not register IRPC handlers\n"));
1358 struct winbindd_addrchanged_state {
1359 struct addrchange_context *ctx;
1360 struct tevent_context *ev;
1361 struct messaging_context *msg_ctx;
1364 static void winbindd_addr_changed(struct tevent_req *req);
1366 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1367 struct tevent_context *ev,
1368 struct messaging_context *msg_ctx)
1370 struct winbindd_addrchanged_state *state;
1371 struct tevent_req *req;
1374 state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1375 if (state == NULL) {
1376 DEBUG(10, ("talloc failed\n"));
1380 state->msg_ctx = msg_ctx;
1382 status = addrchange_context_create(state, &state->ctx);
1383 if (!NT_STATUS_IS_OK(status)) {
1384 DEBUG(10, ("addrchange_context_create failed: %s\n",
1385 nt_errstr(status)));
1389 req = addrchange_send(state, ev, state->ctx);
1391 DEBUG(0, ("addrchange_send failed\n"));
1395 tevent_req_set_callback(req, winbindd_addr_changed, state);
1398 static void winbindd_addr_changed(struct tevent_req *req)
1400 struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1401 req, struct winbindd_addrchanged_state);
1402 enum addrchange_type type;
1403 struct sockaddr_storage addr;
1406 status = addrchange_recv(req, &type, &addr);
1408 if (!NT_STATUS_IS_OK(status)) {
1409 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1410 nt_errstr(status)));
1414 if (type == ADDRCHANGE_DEL) {
1415 char addrstr[INET6_ADDRSTRLEN];
1418 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1420 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1423 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1425 status = messaging_send(state->msg_ctx,
1426 messaging_server_id(state->msg_ctx),
1427 MSG_WINBIND_IP_DROPPED, &blob);
1428 if (!NT_STATUS_IS_OK(status)) {
1429 DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1430 nt_errstr(status)));
1433 req = addrchange_send(state, state->ev, state->ctx);
1435 DEBUG(0, ("addrchange_send failed\n"));
1439 tevent_req_set_callback(req, winbindd_addr_changed, state);
1444 int main(int argc, const char **argv)
1446 static bool is_daemon = False;
1447 static bool Fork = True;
1448 static bool log_stdout = False;
1449 static bool no_process_group = False;
1453 OPT_NO_PROCESS_GROUP,
1456 struct poptOption long_options[] = {
1458 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1459 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1460 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1461 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1462 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1463 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1474 * Do this before any other talloc operation
1476 talloc_enable_null_tracking();
1477 frame = talloc_stackframe();
1480 * We want total control over the permissions on created files,
1481 * so set our umask to 0.
1485 setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1487 /* glibc (?) likes to print "User defined signal 1" and exit if a
1488 SIGUSR[12] is received before a handler is installed */
1490 CatchSignal(SIGUSR1, SIG_IGN);
1491 CatchSignal(SIGUSR2, SIG_IGN);
1494 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1498 /* Initialise for running in non-root mode */
1502 set_remote_machine_name("winbindd", False);
1504 /* Set environment variable so we don't recursively call ourselves.
1505 This may also be useful interactively. */
1507 if ( !winbind_off() ) {
1508 DEBUG(0,("Failed to disable recusive winbindd calls. Exiting.\n"));
1512 /* Initialise samba/rpc client stuff */
1514 pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1516 while ((opt = poptGetNextOpt(pc)) != -1) {
1518 /* Don't become a daemon */
1530 case OPT_NO_PROCESS_GROUP:
1531 no_process_group = true;
1533 case OPT_LOG_STDOUT:
1540 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1541 poptBadOption(pc, 0), poptStrerror(opt));
1542 poptPrintUsage(pc, stderr, 0);
1547 /* We call dump_core_setup one more time because the command line can
1548 * set the log file or the log-basename and this will influence where
1549 * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1550 * the default value derived from build's prefix. For EOM this value
1551 * is often not related to the path where winbindd is actually run
1554 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1555 if (is_daemon && interactive) {
1556 d_fprintf(stderr,"\nERROR: "
1557 "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1558 poptPrintUsage(pc, stderr, 0);
1562 if (log_stdout && Fork) {
1563 d_fprintf(stderr, "\nERROR: "
1564 "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1565 poptPrintUsage(pc, stderr, 0);
1569 poptFreeContext(pc);
1571 if (!override_logfile) {
1573 if (asprintf(&lfile,"%s/log.winbindd",
1574 get_dyn_LOGFILEBASE()) > 0) {
1575 lp_set_logfile(lfile);
1581 setup_logging("winbindd", DEBUG_STDOUT);
1583 setup_logging("winbindd", DEBUG_FILE);
1587 DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1588 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1590 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1591 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1594 /* After parsing the configuration file we setup the core path one more time
1595 * as the log file might have been set in the configuration and cores's
1596 * path is by default basename(lp_logfile()).
1598 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1600 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1601 && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1602 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1603 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"));
1607 if (!cluster_probe_ok()) {
1611 /* Initialise messaging system */
1613 if (winbind_messaging_context() == NULL) {
1617 if (!reload_services_file(NULL)) {
1618 DEBUG(0, ("error opening config file\n"));
1622 ok = directory_create_or_exist(lp_lock_directory(), 0755);
1624 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1625 lp_lock_directory(), strerror(errno)));
1629 ok = directory_create_or_exist(lp_pid_directory(), 0755);
1631 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1632 lp_pid_directory(), strerror(errno)));
1643 if (!secrets_init()) {
1645 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1649 status = rpccli_pre_open_netlogon_creds();
1650 if (!NT_STATUS_IS_OK(status)) {
1651 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1652 nt_errstr(status)));
1656 /* Unblock all signals we are interested in as they may have been
1657 blocked by the parent process. */
1659 BlockSignals(False, SIGINT);
1660 BlockSignals(False, SIGQUIT);
1661 BlockSignals(False, SIGTERM);
1662 BlockSignals(False, SIGUSR1);
1663 BlockSignals(False, SIGUSR2);
1664 BlockSignals(False, SIGHUP);
1665 BlockSignals(False, SIGCHLD);
1668 become_daemon(Fork, no_process_group, log_stdout);
1670 pidfile_create(lp_pid_directory(), "winbindd");
1674 * If we're interactive we want to set our own process group for
1675 * signal management.
1677 if (interactive && !no_process_group)
1678 setpgid( (pid_t)0, (pid_t)0);
1683 /* Don't use winbindd_reinit_after_fork here as
1684 * we're just starting up and haven't created any
1685 * winbindd-specific resources we must free yet. JRA.
1688 status = reinit_after_fork(winbind_messaging_context(),
1689 winbind_event_context(),
1691 if (!NT_STATUS_IS_OK(status)) {
1692 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1696 * Do not initialize the parent-child-pipe before becoming
1697 * a daemon: this is used to detect a died parent in the child
1700 status = init_before_fork();
1701 if (!NT_STATUS_IS_OK(status)) {
1702 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1705 winbindd_register_handlers(winbind_messaging_context(), !Fork);
1707 if (!messaging_parent_dgm_cleanup_init(winbind_messaging_context())) {
1711 status = init_system_session_info();
1712 if (!NT_STATUS_IS_OK(status)) {
1713 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1716 rpc_lsarpc_init(NULL);
1717 rpc_samr_init(NULL);
1719 winbindd_init_addrchange(NULL, winbind_event_context(),
1720 winbind_messaging_context());
1722 /* setup listen sockets */
1724 if (!winbindd_setup_listeners()) {
1725 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1728 irpc_add_name(winbind_imessaging_context(), "winbind_server");
1733 daemon_ready("winbindd");
1736 /* Loop waiting for requests */
1738 frame = talloc_stackframe();
1740 if (tevent_loop_once(winbind_event_context()) == -1) {
1741 DEBUG(1, ("tevent_loop_once() failed: %s\n",