winbindd: winbindd_priv_pipe_dir() -> bool_dispatch_table
[samba.git] / source3 / winbindd / winbindd.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Winbind daemon for ntdom nss module
5
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
10
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.
15
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.
20
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/>.
23 */
24
25 #include "includes.h"
26 #include "popt_common.h"
27 #include "winbindd.h"
28 #include "nsswitch/winbind_client.h"
29 #include "nsswitch/wb_reqtrans.h"
30 #include "ntdomain.h"
31 #include "../librpc/gen_ndr/srv_lsa.h"
32 #include "../librpc/gen_ndr/srv_samr.h"
33 #include "secrets.h"
34 #include "rpc_client/cli_netlogon.h"
35 #include "idmap.h"
36 #include "lib/addrchange.h"
37 #include "auth.h"
38 #include "messages.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"
47 #include "passdb.h"
48
49 #undef DBGC_CLASS
50 #define DBGC_CLASS DBGC_WINBIND
51
52 #define SCRUB_CLIENTS_INTERVAL 5
53
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
58 static bool opt_nocache = False;
59 static bool interactive = False;
60
61 extern bool override_logfile;
62
63 struct imessaging_context *winbind_imessaging_context(void)
64 {
65         static struct imessaging_context *msg = NULL;
66         struct messaging_context *msg_ctx;
67         struct server_id myself;
68         struct loadparm_context *lp_ctx;
69
70         if (msg != NULL) {
71                 return msg;
72         }
73
74         msg_ctx = server_messaging_context();
75         if (msg_ctx == NULL) {
76                 smb_panic("server_messaging_context failed\n");
77         }
78         myself = messaging_server_id(msg_ctx);
79
80         lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
81         if (lp_ctx == NULL) {
82                 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
83         }
84
85         /*
86          * Note we MUST use the NULL context here, not the autofree context,
87          * to avoid side effects in forked children exiting.
88          */
89         msg = imessaging_init(NULL, lp_ctx, myself, server_event_context());
90         talloc_unlink(NULL, lp_ctx);
91
92         if (msg == NULL) {
93                 smb_panic("Could not init winbindd's messaging context.\n");
94         }
95         return msg;
96 }
97
98 /* Reload configuration */
99
100 static bool reload_services_file(const char *lfile)
101 {
102         bool ret;
103
104         if (lp_loaded()) {
105                 char *fname = lp_next_configfile(talloc_tos());
106
107                 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
108                         set_dyn_CONFIGFILE(fname);
109                 }
110                 TALLOC_FREE(fname);
111         }
112
113         /* if this is a child, restore the logfile to the special
114            name - <domain>, idmap, etc. */
115         if (lfile && *lfile) {
116                 lp_set_logfile(lfile);
117         }
118
119         reopen_logs();
120         ret = lp_load_global(get_dyn_CONFIGFILE());
121
122         reopen_logs();
123         load_interfaces();
124         winbindd_setup_max_fds();
125
126         return(ret);
127 }
128
129
130 static void winbindd_status(void)
131 {
132         struct winbindd_cli_state *tmp;
133
134         DEBUG(0, ("winbindd status:\n"));
135
136         /* Print client state information */
137
138         DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
139
140         if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
141                 DEBUG(2, ("\tclient list:\n"));
142                 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
143                         DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
144                                      (unsigned long)tmp->pid, tmp->sock,
145                                      client_is_idle(tmp) ? "idle" : "active"));
146                 }
147         }
148 }
149
150 /* Flush client cache */
151
152 static void flush_caches(void)
153 {
154         /* We need to invalidate cached user list entries on a SIGHUP 
155            otherwise cached access denied errors due to restrict anonymous
156            hang around until the sequence number changes. */
157
158         if (!wcache_invalidate_cache()) {
159                 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
160                 if (!winbindd_cache_validate_and_initialize()) {
161                         exit(1);
162                 }
163         }
164 }
165
166 static void flush_caches_noinit(void)
167 {
168         /*
169          * We need to invalidate cached user list entries on a SIGHUP
170          * otherwise cached access denied errors due to restrict anonymous
171          * hang around until the sequence number changes.
172          * NB
173          * Skip uninitialized domains when flush cache.
174          * If domain is not initialized, it means it is never
175          * used or never become online. look, wcache_invalidate_cache()
176          * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
177          * for unused domains and large traffic for primay domain's DC if there
178          * are many domains..
179          */
180
181         if (!wcache_invalidate_cache_noinit()) {
182                 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
183                 if (!winbindd_cache_validate_and_initialize()) {
184                         exit(1);
185                 }
186         }
187 }
188
189 /* Handle the signal by unlinking socket and exiting */
190
191 static void terminate(bool is_parent)
192 {
193         if (is_parent) {
194                 /* When parent goes away we should
195                  * remove the socket file. Not so
196                  * when children terminate.
197                  */ 
198                 char *path = NULL;
199
200                 if (asprintf(&path, "%s/%s",
201                         lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) {
202                         unlink(path);
203                         SAFE_FREE(path);
204                 }
205         }
206
207         idmap_close();
208
209         gencache_stabilize();
210
211         netlogon_creds_cli_close_global_db();
212
213 #if 0
214         if (interactive) {
215                 TALLOC_CTX *mem_ctx = talloc_init("end_description");
216                 char *description = talloc_describe_all(mem_ctx);
217
218                 DEBUG(3, ("tallocs left:\n%s\n", description));
219                 talloc_destroy(mem_ctx);
220         }
221 #endif
222
223         if (is_parent) {
224                 pidfile_unlink(lp_pid_directory(), "winbindd");
225         }
226
227         exit(0);
228 }
229
230 static void winbindd_sig_term_handler(struct tevent_context *ev,
231                                       struct tevent_signal *se,
232                                       int signum,
233                                       int count,
234                                       void *siginfo,
235                                       void *private_data)
236 {
237         bool *p = talloc_get_type_abort(private_data, bool);
238         bool is_parent = *p;
239
240         TALLOC_FREE(p);
241
242         DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
243                  signum, is_parent));
244         terminate(is_parent);
245 }
246
247 /*
248   handle stdin becoming readable when we are in --foreground mode
249  */
250 static void winbindd_stdin_handler(struct tevent_context *ev,
251                                struct tevent_fd *fde,
252                                uint16_t flags,
253                                void *private_data)
254 {
255         char c;
256         if (read(0, &c, 1) != 1) {
257                 bool *is_parent = talloc_get_type_abort(private_data, bool);
258
259                 /* we have reached EOF on stdin, which means the
260                    parent has exited. Shutdown the server */
261                 DEBUG(0,("EOF on stdin (is_parent=%d)\n",
262                          (int)*is_parent));
263                 terminate(*is_parent);
264         }
265 }
266
267 bool winbindd_setup_sig_term_handler(bool parent)
268 {
269         struct tevent_signal *se;
270         bool *is_parent;
271
272         is_parent = talloc(server_event_context(), bool);
273         if (!is_parent) {
274                 return false;
275         }
276
277         *is_parent = parent;
278
279         se = tevent_add_signal(server_event_context(),
280                                is_parent,
281                                SIGTERM, 0,
282                                winbindd_sig_term_handler,
283                                is_parent);
284         if (!se) {
285                 DEBUG(0,("failed to setup SIGTERM handler"));
286                 talloc_free(is_parent);
287                 return false;
288         }
289
290         se = tevent_add_signal(server_event_context(),
291                                is_parent,
292                                SIGINT, 0,
293                                winbindd_sig_term_handler,
294                                is_parent);
295         if (!se) {
296                 DEBUG(0,("failed to setup SIGINT handler"));
297                 talloc_free(is_parent);
298                 return false;
299         }
300
301         se = tevent_add_signal(server_event_context(),
302                                is_parent,
303                                SIGQUIT, 0,
304                                winbindd_sig_term_handler,
305                                is_parent);
306         if (!se) {
307                 DEBUG(0,("failed to setup SIGINT handler"));
308                 talloc_free(is_parent);
309                 return false;
310         }
311
312         return true;
313 }
314
315 bool winbindd_setup_stdin_handler(bool parent, bool foreground)
316 {
317         bool *is_parent;
318
319         if (foreground) {
320                 struct stat st;
321
322                 is_parent = talloc(server_event_context(), bool);
323                 if (!is_parent) {
324                         return false;
325                 }
326
327                 *is_parent = parent;
328
329                 /* if we are running in the foreground then look for
330                    EOF on stdin, and exit if it happens. This allows
331                    us to die if the parent process dies
332                    Only do this on a pipe or socket, no other device.
333                 */
334                 if (fstat(0, &st) != 0) {
335                         return false;
336                 }
337                 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
338                         tevent_add_fd(server_event_context(),
339                                         is_parent,
340                                         0,
341                                         TEVENT_FD_READ,
342                                         winbindd_stdin_handler,
343                                         is_parent);
344                 }
345         }
346
347         return true;
348 }
349
350 static void winbindd_sig_hup_handler(struct tevent_context *ev,
351                                      struct tevent_signal *se,
352                                      int signum,
353                                      int count,
354                                      void *siginfo,
355                                      void *private_data)
356 {
357         const char *file = (const char *)private_data;
358
359         DEBUG(1,("Reloading services after SIGHUP\n"));
360         flush_caches_noinit();
361         reload_services_file(file);
362 }
363
364 bool winbindd_setup_sig_hup_handler(const char *lfile)
365 {
366         struct tevent_signal *se;
367         char *file = NULL;
368
369         if (lfile) {
370                 file = talloc_strdup(server_event_context(),
371                                      lfile);
372                 if (!file) {
373                         return false;
374                 }
375         }
376
377         se = tevent_add_signal(server_event_context(),
378                                server_event_context(),
379                                SIGHUP, 0,
380                                winbindd_sig_hup_handler,
381                                file);
382         if (!se) {
383                 return false;
384         }
385
386         return true;
387 }
388
389 static void winbindd_sig_chld_handler(struct tevent_context *ev,
390                                       struct tevent_signal *se,
391                                       int signum,
392                                       int count,
393                                       void *siginfo,
394                                       void *private_data)
395 {
396         pid_t pid;
397
398         while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
399                 winbind_child_died(pid);
400         }
401 }
402
403 static bool winbindd_setup_sig_chld_handler(void)
404 {
405         struct tevent_signal *se;
406
407         se = tevent_add_signal(server_event_context(),
408                                server_event_context(),
409                                SIGCHLD, 0,
410                                winbindd_sig_chld_handler,
411                                NULL);
412         if (!se) {
413                 return false;
414         }
415
416         return true;
417 }
418
419 static void winbindd_sig_usr2_handler(struct tevent_context *ev,
420                                       struct tevent_signal *se,
421                                       int signum,
422                                       int count,
423                                       void *siginfo,
424                                       void *private_data)
425 {
426         winbindd_status();
427 }
428
429 static bool winbindd_setup_sig_usr2_handler(void)
430 {
431         struct tevent_signal *se;
432
433         se = tevent_add_signal(server_event_context(),
434                                server_event_context(),
435                                SIGUSR2, 0,
436                                winbindd_sig_usr2_handler,
437                                NULL);
438         if (!se) {
439                 return false;
440         }
441
442         return true;
443 }
444
445 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
446 static void msg_reload_services(struct messaging_context *msg,
447                                 void *private_data,
448                                 uint32_t msg_type,
449                                 struct server_id server_id,
450                                 DATA_BLOB *data)
451 {
452         /* Flush various caches */
453         flush_caches();
454         reload_services_file((const char *) private_data);
455 }
456
457 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
458 static void msg_shutdown(struct messaging_context *msg,
459                          void *private_data,
460                          uint32_t msg_type,
461                          struct server_id server_id,
462                          DATA_BLOB *data)
463 {
464         /* only the parent waits for this message */
465         DEBUG(0,("Got shutdown message\n"));
466         terminate(true);
467 }
468
469
470 static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
471                                        void *private_data,
472                                        uint32_t msg_type,
473                                        struct server_id server_id,
474                                        DATA_BLOB *data)
475 {
476         uint8_t ret;
477         pid_t child_pid;
478         NTSTATUS status;
479
480         DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
481                    "message.\n"));
482
483         /*
484          * call the validation code from a child:
485          * so we don't block the main winbindd and the validation
486          * code can safely use fork/waitpid...
487          */
488         child_pid = fork();
489
490         if (child_pid == -1) {
491                 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
492                           strerror(errno)));
493                 return;
494         }
495
496         if (child_pid != 0) {
497                 /* parent */
498                 DEBUG(5, ("winbind_msg_validate_cache: child created with "
499                           "pid %d.\n", (int)child_pid));
500                 return;
501         }
502
503         /* child */
504
505         status = winbindd_reinit_after_fork(NULL, NULL);
506         if (!NT_STATUS_IS_OK(status)) {
507                 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
508                           nt_errstr(status)));
509                 _exit(0);
510         }
511
512         /* install default SIGCHLD handler: validation code uses fork/waitpid */
513         CatchSignal(SIGCHLD, SIG_DFL);
514
515         setproctitle("validate cache child");
516
517         ret = (uint8_t)winbindd_validate_cache_nobackup();
518         DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
519         messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
520                            (size_t)1);
521         _exit(0);
522 }
523
524 static struct winbindd_dispatch_table {
525         enum winbindd_cmd cmd;
526         void (*fn)(struct winbindd_cli_state *state);
527         const char *winbindd_cmd_name;
528 } dispatch_table[] = {
529
530         /* Enumeration functions */
531
532         { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
533           "LIST_TRUSTDOM" },
534
535         /* Miscellaneous */
536
537         { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
538         /* Credential cache access */
539
540         /* End of list */
541
542         { WINBINDD_NUM_CMDS, NULL, "NONE" }
543 };
544
545 static struct winbindd_bool_dispatch_table {
546         enum winbindd_cmd cmd;
547         bool (*fn)(struct winbindd_cli_state *state);
548         const char *cmd_name;
549 } bool_dispatch_table[] = {
550         { WINBINDD_INTERFACE_VERSION,
551           winbindd_interface_version,
552           "INTERFACE_VERSION" },
553         { WINBINDD_INFO,
554           winbindd_info,
555           "INFO" },
556         { WINBINDD_PING,
557           winbindd_ping,
558           "PING" },
559         { WINBINDD_DOMAIN_NAME,
560           winbindd_domain_name,
561           "DOMAIN_NAME" },
562         { WINBINDD_NETBIOS_NAME,
563           winbindd_netbios_name,
564           "NETBIOS_NAME" },
565         { WINBINDD_DC_INFO,
566           winbindd_dc_info,
567           "DC_INFO" },
568         { WINBINDD_CCACHE_NTLMAUTH,
569           winbindd_ccache_ntlm_auth,
570           "NTLMAUTH" },
571         { WINBINDD_CCACHE_SAVE,
572           winbindd_ccache_save,
573           "CCACHE_SAVE" },
574         { WINBINDD_PRIV_PIPE_DIR,
575           winbindd_priv_pipe_dir,
576           "WINBINDD_PRIV_PIPE_DIR" },
577 };
578
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);
588 };
589
590 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
591         { WINBINDD_LOOKUPSID, "LOOKUPSID",
592           winbindd_lookupsid_send, winbindd_lookupsid_recv },
593         { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
594           winbindd_lookupsids_send, winbindd_lookupsids_recv },
595         { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
596           winbindd_lookupname_send, winbindd_lookupname_recv },
597         { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
598           winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
599         { WINBINDD_XIDS_TO_SIDS, "XIDS_TO_SIDS",
600           winbindd_xids_to_sids_send, winbindd_xids_to_sids_recv },
601         { WINBINDD_GETPWSID, "GETPWSID",
602           winbindd_getpwsid_send, winbindd_getpwsid_recv },
603         { WINBINDD_GETPWNAM, "GETPWNAM",
604           winbindd_getpwnam_send, winbindd_getpwnam_recv },
605         { WINBINDD_GETPWUID, "GETPWUID",
606           winbindd_getpwuid_send, winbindd_getpwuid_recv },
607         { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
608           winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
609         { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
610           winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
611         { WINBINDD_GETGROUPS, "GETGROUPS",
612           winbindd_getgroups_send, winbindd_getgroups_recv },
613         { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
614           winbindd_show_sequence_send, winbindd_show_sequence_recv },
615         { WINBINDD_GETGRGID, "GETGRGID",
616           winbindd_getgrgid_send, winbindd_getgrgid_recv },
617         { WINBINDD_GETGRNAM, "GETGRNAM",
618           winbindd_getgrnam_send, winbindd_getgrnam_recv },
619         { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
620           winbindd_getusersids_send, winbindd_getusersids_recv },
621         { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
622           winbindd_lookuprids_send, winbindd_lookuprids_recv },
623         { WINBINDD_SETPWENT, "SETPWENT",
624           winbindd_setpwent_send, winbindd_setpwent_recv },
625         { WINBINDD_GETPWENT, "GETPWENT",
626           winbindd_getpwent_send, winbindd_getpwent_recv },
627         { WINBINDD_ENDPWENT, "ENDPWENT",
628           winbindd_endpwent_send, winbindd_endpwent_recv },
629         { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
630           winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
631         { WINBINDD_GETDCNAME, "GETDCNAME",
632           winbindd_getdcname_send, winbindd_getdcname_recv },
633         { WINBINDD_SETGRENT, "SETGRENT",
634           winbindd_setgrent_send, winbindd_setgrent_recv },
635         { WINBINDD_GETGRENT, "GETGRENT",
636           winbindd_getgrent_send, winbindd_getgrent_recv },
637         { WINBINDD_ENDGRENT, "ENDGRENT",
638           winbindd_endgrent_send, winbindd_endgrent_recv },
639         { WINBINDD_LIST_USERS, "LIST_USERS",
640           winbindd_list_users_send, winbindd_list_users_recv },
641         { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
642           winbindd_list_groups_send, winbindd_list_groups_recv },
643         { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
644           winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
645         { WINBINDD_PING_DC, "PING_DC",
646           winbindd_ping_dc_send, winbindd_ping_dc_recv },
647         { WINBINDD_PAM_AUTH, "PAM_AUTH",
648           winbindd_pam_auth_send, winbindd_pam_auth_recv },
649         { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
650           winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
651         { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
652           winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
653         { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
654           winbindd_pam_chng_pswd_auth_crap_send,
655           winbindd_pam_chng_pswd_auth_crap_recv },
656         { WINBINDD_WINS_BYIP, "WINS_BYIP",
657           winbindd_wins_byip_send, winbindd_wins_byip_recv },
658         { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
659           winbindd_wins_byname_send, winbindd_wins_byname_recv },
660
661         { 0, NULL, NULL, NULL }
662 };
663
664 static struct winbindd_async_dispatch_table async_priv_table[] = {
665         { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
666           winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
667         { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
668           winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
669         { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
670           winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
671         { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
672           winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
673
674         { 0, NULL, NULL, NULL }
675 };
676
677 static void wb_request_done(struct tevent_req *req);
678
679 static void process_request(struct winbindd_cli_state *state)
680 {
681         struct winbindd_dispatch_table *table = dispatch_table;
682         struct winbindd_async_dispatch_table *atable;
683         size_t i;
684         bool ok;
685
686         state->mem_ctx = talloc_named(state, 0, "winbind request");
687         if (state->mem_ctx == NULL)
688                 return;
689
690         /* Remember who asked us. */
691         state->pid = state->request->pid;
692
693         state->cmd_name = "unknown request";
694         state->recv_fn = NULL;
695         /* client is newest */
696         winbindd_promote_client(state);
697
698         /* Process command */
699
700         for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
701                 if (state->request->cmd == atable->cmd) {
702                         break;
703                 }
704         }
705
706         if ((atable->send_req == NULL) && state->privileged) {
707                 for (atable = async_priv_table; atable->send_req;
708                      atable += 1) {
709                         if (state->request->cmd == atable->cmd) {
710                                 break;
711                         }
712                 }
713         }
714
715         if (atable->send_req != NULL) {
716                 struct tevent_req *req;
717
718                 state->cmd_name = atable->cmd_name;
719                 state->recv_fn = atable->recv_req;
720
721                 DEBUG(10, ("process_request: Handling async request %d:%s\n",
722                            (int)state->pid, state->cmd_name));
723
724                 req = atable->send_req(state->mem_ctx, server_event_context(),
725                                        state, state->request);
726                 if (req == NULL) {
727                         DEBUG(0, ("process_request: atable->send failed for "
728                                   "%s\n", atable->cmd_name));
729                         request_error(state);
730                         return;
731                 }
732                 tevent_req_set_callback(req, wb_request_done, state);
733                 return;
734         }
735
736         state->response = talloc_zero(state->mem_ctx,
737                                       struct winbindd_response);
738         if (state->response == NULL) {
739                 DEBUG(10, ("talloc failed\n"));
740                 remove_client(state);
741                 return;
742         }
743         state->response->result = WINBINDD_PENDING;
744         state->response->length = sizeof(struct winbindd_response);
745
746         for (table = dispatch_table; table->fn; table++) {
747                 if (state->request->cmd == table->cmd) {
748                         DEBUG(10,("process_request: request fn %s\n",
749                                   table->winbindd_cmd_name ));
750                         state->cmd_name = table->winbindd_cmd_name;
751                         table->fn(state);
752                         return;
753                 }
754         }
755
756         for (i=0; i<ARRAY_SIZE(bool_dispatch_table); i++) {
757                 if (bool_dispatch_table[i].cmd == state->request->cmd) {
758                         break;
759                 }
760         }
761
762         if (i == ARRAY_SIZE(bool_dispatch_table)) {
763                 DEBUG(10,("process_request: unknown request fn number %d\n",
764                           (int)state->request->cmd ));
765                 request_error(state);
766                 return;
767         }
768
769         DBG_DEBUG("process_request: request fn %s\n",
770                   bool_dispatch_table[i].cmd_name);
771
772         ok = bool_dispatch_table[i].fn(state);
773
774         if (ok) {
775                 request_ok(state);
776         } else {
777                 request_error(state);
778         }
779 }
780
781 static void wb_request_done(struct tevent_req *req)
782 {
783         struct winbindd_cli_state *state = tevent_req_callback_data(
784                 req, struct winbindd_cli_state);
785         NTSTATUS status;
786
787         state->response = talloc_zero(state->mem_ctx,
788                                       struct winbindd_response);
789         if (state->response == NULL) {
790                 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
791                           (int)state->pid, state->cmd_name));
792                 remove_client(state);
793                 return;
794         }
795         state->response->result = WINBINDD_PENDING;
796         state->response->length = sizeof(struct winbindd_response);
797
798         status = state->recv_fn(req, state->response);
799         TALLOC_FREE(req);
800
801         DEBUG(10,("wb_request_done[%d:%s]: %s\n",
802                   (int)state->pid, state->cmd_name, nt_errstr(status)));
803
804         if (!NT_STATUS_IS_OK(status)) {
805                 request_error(state);
806                 return;
807         }
808         request_ok(state);
809 }
810
811 /*
812  * This is the main event loop of winbind requests. It goes through a
813  * state-machine of 3 read/write requests, 4 if you have extra data to send.
814  *
815  * An idle winbind client has a read request of 4 bytes outstanding,
816  * finalizing function is request_len_recv, checking the length. request_recv
817  * then processes the packet. The processing function then at some point has
818  * to call request_finished which schedules sending the response.
819  */
820
821 static void request_finished(struct winbindd_cli_state *state);
822
823 static void winbind_client_request_read(struct tevent_req *req);
824 static void winbind_client_response_written(struct tevent_req *req);
825 static void winbind_client_activity(struct tevent_req *req);
826
827 static void request_finished(struct winbindd_cli_state *state)
828 {
829         struct tevent_req *req;
830
831         /* free client socket monitoring request */
832         TALLOC_FREE(state->io_req);
833
834         TALLOC_FREE(state->request);
835
836         req = wb_resp_write_send(state, server_event_context(),
837                                  state->out_queue, state->sock,
838                                  state->response);
839         if (req == NULL) {
840                 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
841                           (int)state->pid, state->cmd_name));
842                 remove_client(state);
843                 return;
844         }
845         tevent_req_set_callback(req, winbind_client_response_written, state);
846         state->io_req = req;
847 }
848
849 static void winbind_client_response_written(struct tevent_req *req)
850 {
851         struct winbindd_cli_state *state = tevent_req_callback_data(
852                 req, struct winbindd_cli_state);
853         ssize_t ret;
854         int err;
855
856         state->io_req = NULL;
857
858         ret = wb_resp_write_recv(req, &err);
859         TALLOC_FREE(req);
860         if (ret == -1) {
861                 close(state->sock);
862                 state->sock = -1;
863                 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
864                           (int)state->pid, state->cmd_name, strerror(err)));
865                 remove_client(state);
866                 return;
867         }
868
869         DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
870                   "to client\n", (int)state->pid, state->cmd_name));
871
872         TALLOC_FREE(state->mem_ctx);
873         state->response = NULL;
874         state->cmd_name = "no request";
875         state->recv_fn = NULL;
876
877         req = wb_req_read_send(state, server_event_context(), state->sock,
878                                WINBINDD_MAX_EXTRA_DATA);
879         if (req == NULL) {
880                 remove_client(state);
881                 return;
882         }
883         tevent_req_set_callback(req, winbind_client_request_read, state);
884         state->io_req = req;
885 }
886
887 void request_error(struct winbindd_cli_state *state)
888 {
889         SMB_ASSERT(state->response->result == WINBINDD_PENDING);
890         state->response->result = WINBINDD_ERROR;
891         request_finished(state);
892 }
893
894 void request_ok(struct winbindd_cli_state *state)
895 {
896         SMB_ASSERT(state->response->result == WINBINDD_PENDING);
897         state->response->result = WINBINDD_OK;
898         request_finished(state);
899 }
900
901 /* Process a new connection by adding it to the client connection list */
902
903 static void new_connection(int listen_sock, bool privileged)
904 {
905         struct sockaddr_un sunaddr;
906         struct winbindd_cli_state *state;
907         struct tevent_req *req;
908         socklen_t len;
909         int sock;
910
911         /* Accept connection */
912
913         len = sizeof(sunaddr);
914
915         sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
916
917         if (sock == -1) {
918                 if (errno != EINTR) {
919                         DEBUG(0, ("Failed to accept socket - %s\n",
920                                   strerror(errno)));
921                 }
922                 return;
923         }
924         smb_set_close_on_exec(sock);
925
926         DEBUG(6,("accepted socket %d\n", sock));
927
928         /* Create new connection structure */
929
930         if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
931                 close(sock);
932                 return;
933         }
934
935         state->sock = sock;
936
937         state->out_queue = tevent_queue_create(state, "winbind client reply");
938         if (state->out_queue == NULL) {
939                 close(sock);
940                 TALLOC_FREE(state);
941                 return;
942         }
943
944         state->privileged = privileged;
945
946         req = wb_req_read_send(state, server_event_context(), state->sock,
947                                WINBINDD_MAX_EXTRA_DATA);
948         if (req == NULL) {
949                 TALLOC_FREE(state);
950                 close(sock);
951                 return;
952         }
953         tevent_req_set_callback(req, winbind_client_request_read, state);
954         state->io_req = req;
955
956         /* Add to connection list */
957
958         winbindd_add_client(state);
959 }
960
961 static void winbind_client_request_read(struct tevent_req *req)
962 {
963         struct winbindd_cli_state *state = tevent_req_callback_data(
964                 req, struct winbindd_cli_state);
965         ssize_t ret;
966         int err;
967
968         state->io_req = NULL;
969
970         ret = wb_req_read_recv(req, state, &state->request, &err);
971         TALLOC_FREE(req);
972         if (ret == -1) {
973                 if (err == EPIPE) {
974                         DEBUG(6, ("closing socket %d, client exited\n",
975                                   state->sock));
976                 } else {
977                         DEBUG(2, ("Could not read client request from fd %d: "
978                                   "%s\n", state->sock, strerror(err)));
979                 }
980                 close(state->sock);
981                 state->sock = -1;
982                 remove_client(state);
983                 return;
984         }
985
986         req = wait_for_read_send(state, server_event_context(), state->sock,
987                                  true);
988         if (req == NULL) {
989                 DEBUG(0, ("winbind_client_request_read[%d:%s]:"
990                           " wait_for_read_send failed - removing client\n",
991                           (int)state->pid, state->cmd_name));
992                 remove_client(state);
993                 return;
994         }
995         tevent_req_set_callback(req, winbind_client_activity, state);
996         state->io_req = req;
997
998         process_request(state);
999 }
1000
1001 static void winbind_client_activity(struct tevent_req *req)
1002 {
1003         struct winbindd_cli_state *state =
1004             tevent_req_callback_data(req, struct winbindd_cli_state);
1005         int err;
1006         bool has_data;
1007
1008         has_data = wait_for_read_recv(req, &err);
1009
1010         if (has_data) {
1011                 DEBUG(0, ("winbind_client_activity[%d:%s]:"
1012                           "unexpected data from client - removing client\n",
1013                           (int)state->pid, state->cmd_name));
1014         } else {
1015                 if (err == EPIPE) {
1016                         DEBUG(6, ("winbind_client_activity[%d:%s]: "
1017                                   "client has closed connection - removing "
1018                                   "client\n",
1019                                   (int)state->pid, state->cmd_name));
1020                 } else {
1021                         DEBUG(2, ("winbind_client_activity[%d:%s]: "
1022                                   "client socket error (%s) - removing "
1023                                   "client\n",
1024                                   (int)state->pid, state->cmd_name,
1025                                   strerror(err)));
1026                 }
1027         }
1028
1029         remove_client(state);
1030 }
1031
1032 /* Remove a client connection from client connection list */
1033
1034 static void remove_client(struct winbindd_cli_state *state)
1035 {
1036         char c = 0;
1037         int nwritten;
1038
1039         /* It's a dead client - hold a funeral */
1040
1041         if (state == NULL) {
1042                 return;
1043         }
1044
1045         /*
1046          * We need to remove a pending wb_req_read_*
1047          * or wb_resp_write_* request before closing the
1048          * socket.
1049          *
1050          * This is important as they might have used tevent_add_fd() and we
1051          * use the epoll * backend on linux. So we must remove the tevent_fd
1052          * before closing the fd.
1053          *
1054          * Otherwise we might hit a race with close_conns_after_fork() (via
1055          * winbindd_reinit_after_fork()) where a file description
1056          * is still open in a child, which means it's still active in
1057          * the parents epoll queue, but the related tevent_fd is already
1058          * already gone in the parent.
1059          *
1060          * See bug #11141.
1061          */
1062         TALLOC_FREE(state->io_req);
1063
1064         if (state->sock != -1) {
1065                 /* tell client, we are closing ... */
1066                 nwritten = write(state->sock, &c, sizeof(c));
1067                 if (nwritten == -1) {
1068                         DEBUG(2, ("final write to client failed: %s\n",
1069                                 strerror(errno)));
1070                 }
1071
1072                 /* Close socket */
1073
1074                 close(state->sock);
1075                 state->sock = -1;
1076         }
1077
1078         TALLOC_FREE(state->mem_ctx);
1079
1080         /* Remove from list and free */
1081
1082         winbindd_remove_client(state);
1083         TALLOC_FREE(state);
1084 }
1085
1086 /* Is a client idle? */
1087
1088 static bool client_is_idle(struct winbindd_cli_state *state) {
1089   return (state->request == NULL &&
1090           state->response == NULL &&
1091           !state->pwent_state && !state->grent_state);
1092 }
1093
1094 /* Shutdown client connection which has been idle for the longest time */
1095
1096 static bool remove_idle_client(void)
1097 {
1098         struct winbindd_cli_state *state, *remove_state = NULL;
1099         int nidle = 0;
1100
1101         for (state = winbindd_client_list(); state; state = state->next) {
1102                 if (client_is_idle(state)) {
1103                         nidle++;
1104                         /* list is sorted by access time */
1105                         remove_state = state;
1106                 }
1107         }
1108
1109         if (remove_state) {
1110                 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1111                         nidle, remove_state->sock, (unsigned int)remove_state->pid));
1112                 remove_client(remove_state);
1113                 return True;
1114         }
1115
1116         return False;
1117 }
1118
1119 /*
1120  * Terminate all clients whose requests have taken longer than
1121  * "winbind request timeout" seconds to process, or have been
1122  * idle for more than "winbind request timeout" seconds.
1123  */
1124
1125 static void remove_timed_out_clients(void)
1126 {
1127         struct winbindd_cli_state *state, *prev = NULL;
1128         time_t curr_time = time(NULL);
1129         int timeout_val = lp_winbind_request_timeout();
1130
1131         for (state = winbindd_client_list_tail(); state; state = prev) {
1132                 time_t expiry_time;
1133
1134                 prev = winbindd_client_list_prev(state);
1135                 expiry_time = state->last_access + timeout_val;
1136
1137                 if (curr_time <= expiry_time) {
1138                         /* list is sorted, previous clients in
1139                            list are newer */
1140                         break;
1141                 }
1142
1143                 if (client_is_idle(state)) {
1144                         DEBUG(5,("Idle client timed out, "
1145                                  "shutting down sock %d, pid %u\n",
1146                                  state->sock,
1147                                  (unsigned int)state->pid));
1148                 } else {
1149                         DEBUG(5,("Client request timed out, "
1150                                  "shutting down sock %d, pid %u\n",
1151                                  state->sock,
1152                                  (unsigned int)state->pid));
1153                 }
1154
1155                 remove_client(state);
1156         }
1157 }
1158
1159 static void winbindd_scrub_clients_handler(struct tevent_context *ev,
1160                                            struct tevent_timer *te,
1161                                            struct timeval current_time,
1162                                            void *private_data)
1163 {
1164         remove_timed_out_clients();
1165         if (tevent_add_timer(ev, ev,
1166                              timeval_current_ofs(SCRUB_CLIENTS_INTERVAL, 0),
1167                              winbindd_scrub_clients_handler, NULL) == NULL) {
1168                 DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
1169                 exit(1);
1170         }
1171 }
1172
1173 struct winbindd_listen_state {
1174         bool privileged;
1175         int fd;
1176 };
1177
1178 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1179                                         struct tevent_fd *fde,
1180                                         uint16_t flags,
1181                                         void *private_data)
1182 {
1183         struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1184                                           struct winbindd_listen_state);
1185
1186         while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1187                 DEBUG(5,("winbindd: Exceeding %d client "
1188                          "connections, removing idle "
1189                          "connection.\n", lp_winbind_max_clients()));
1190                 if (!remove_idle_client()) {
1191                         DEBUG(0,("winbindd: Exceeding %d "
1192                                  "client connections, no idle "
1193                                  "connection found\n",
1194                                  lp_winbind_max_clients()));
1195                         break;
1196                 }
1197         }
1198         remove_timed_out_clients();
1199         new_connection(s->fd, s->privileged);
1200 }
1201
1202 /*
1203  * Winbindd socket accessor functions
1204  */
1205
1206 char *get_winbind_priv_pipe_dir(void)
1207 {
1208         return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1209 }
1210
1211 static void winbindd_setup_max_fds(void)
1212 {
1213         int num_fds = MAX_OPEN_FUDGEFACTOR;
1214         int actual_fds;
1215
1216         num_fds += lp_winbind_max_clients();
1217         /* Add some more to account for 2 sockets open
1218            when the client transitions from unprivileged
1219            to privileged socket
1220         */
1221         num_fds += lp_winbind_max_clients() / 10;
1222
1223         /* Add one socket per child process
1224            (yeah there are child processes other than the
1225            domain children but only domain children can vary
1226            with configuration
1227         */
1228         num_fds += lp_winbind_max_domain_connections() *
1229                    (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
1230
1231         actual_fds = set_maxfiles(num_fds);
1232
1233         if (actual_fds < num_fds) {
1234                 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1235                           "requested %d open files, %d are available.\n",
1236                           num_fds, actual_fds));
1237         }
1238 }
1239
1240 static bool winbindd_setup_listeners(void)
1241 {
1242         struct winbindd_listen_state *pub_state = NULL;
1243         struct winbindd_listen_state *priv_state = NULL;
1244         struct tevent_fd *fde;
1245         int rc;
1246         char *socket_path;
1247
1248         pub_state = talloc(server_event_context(),
1249                            struct winbindd_listen_state);
1250         if (!pub_state) {
1251                 goto failed;
1252         }
1253
1254         pub_state->privileged = false;
1255         pub_state->fd = create_pipe_sock(
1256                 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1257         if (pub_state->fd == -1) {
1258                 goto failed;
1259         }
1260         rc = listen(pub_state->fd, 5);
1261         if (rc < 0) {
1262                 goto failed;
1263         }
1264
1265         fde = tevent_add_fd(server_event_context(), pub_state, pub_state->fd,
1266                             TEVENT_FD_READ, winbindd_listen_fde_handler,
1267                             pub_state);
1268         if (fde == NULL) {
1269                 close(pub_state->fd);
1270                 goto failed;
1271         }
1272         tevent_fd_set_auto_close(fde);
1273
1274         priv_state = talloc(server_event_context(),
1275                             struct winbindd_listen_state);
1276         if (!priv_state) {
1277                 goto failed;
1278         }
1279
1280         socket_path = get_winbind_priv_pipe_dir();
1281         if (socket_path == NULL) {
1282                 goto failed;
1283         }
1284
1285         priv_state->privileged = true;
1286         priv_state->fd = create_pipe_sock(
1287                 socket_path, WINBINDD_SOCKET_NAME, 0750);
1288         TALLOC_FREE(socket_path);
1289         if (priv_state->fd == -1) {
1290                 goto failed;
1291         }
1292         rc = listen(priv_state->fd, 5);
1293         if (rc < 0) {
1294                 goto failed;
1295         }
1296
1297         fde = tevent_add_fd(server_event_context(), priv_state,
1298                             priv_state->fd, TEVENT_FD_READ,
1299                             winbindd_listen_fde_handler, priv_state);
1300         if (fde == NULL) {
1301                 close(priv_state->fd);
1302                 goto failed;
1303         }
1304         tevent_fd_set_auto_close(fde);
1305
1306         winbindd_scrub_clients_handler(server_event_context(), NULL,
1307                                        timeval_current(), NULL);
1308         return true;
1309 failed:
1310         TALLOC_FREE(pub_state);
1311         TALLOC_FREE(priv_state);
1312         return false;
1313 }
1314
1315 bool winbindd_use_idmap_cache(void)
1316 {
1317         return !opt_nocache;
1318 }
1319
1320 bool winbindd_use_cache(void)
1321 {
1322         return !opt_nocache;
1323 }
1324
1325 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1326                                        bool foreground)
1327 {
1328         bool scan_trusts = true;
1329         NTSTATUS status;
1330         /* Setup signal handlers */
1331
1332         if (!winbindd_setup_sig_term_handler(true))
1333                 exit(1);
1334         if (!winbindd_setup_stdin_handler(true, foreground))
1335                 exit(1);
1336         if (!winbindd_setup_sig_hup_handler(NULL))
1337                 exit(1);
1338         if (!winbindd_setup_sig_chld_handler())
1339                 exit(1);
1340         if (!winbindd_setup_sig_usr2_handler())
1341                 exit(1);
1342
1343         CatchSignal(SIGPIPE, SIG_IGN);                 /* Ignore sigpipe */
1344
1345         /*
1346          * Ensure all cache and idmap caches are consistent
1347          * and initialized before we startup.
1348          */
1349         if (!winbindd_cache_validate_and_initialize()) {
1350                 exit(1);
1351         }
1352
1353         /* React on 'smbcontrol winbindd reload-config' in the same way
1354            as to SIGHUP signal */
1355         messaging_register(msg_ctx, NULL,
1356                            MSG_SMB_CONF_UPDATED, msg_reload_services);
1357         messaging_register(msg_ctx, NULL,
1358                            MSG_SHUTDOWN, msg_shutdown);
1359
1360         /* Handle online/offline messages. */
1361         messaging_register(msg_ctx, NULL,
1362                            MSG_WINBIND_OFFLINE, winbind_msg_offline);
1363         messaging_register(msg_ctx, NULL,
1364                            MSG_WINBIND_ONLINE, winbind_msg_online);
1365         messaging_register(msg_ctx, NULL,
1366                            MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1367
1368         /* Handle domain online/offline messages for domains */
1369         messaging_register(server_messaging_context(), NULL,
1370                            MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1371         messaging_register(server_messaging_context(), NULL,
1372                            MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1373
1374         messaging_register(msg_ctx, NULL,
1375                            MSG_WINBIND_VALIDATE_CACHE,
1376                            winbind_msg_validate_cache);
1377
1378         messaging_register(msg_ctx, NULL,
1379                            MSG_WINBIND_DUMP_DOMAIN_LIST,
1380                            winbind_msg_dump_domain_list);
1381
1382         messaging_register(msg_ctx, NULL,
1383                            MSG_WINBIND_IP_DROPPED,
1384                            winbind_msg_ip_dropped_parent);
1385
1386         /* Register handler for MSG_DEBUG. */
1387         messaging_register(msg_ctx, NULL,
1388                            MSG_DEBUG,
1389                            winbind_msg_debug);
1390
1391         messaging_register(msg_ctx, NULL,
1392                            MSG_WINBIND_DISCONNECT_DC,
1393                            winbind_disconnect_dc_parent);
1394
1395         netsamlogon_cache_init(); /* Non-critical */
1396
1397         /* clear the cached list of trusted domains */
1398
1399         wcache_tdc_clear();
1400
1401         if (!init_domain_list()) {
1402                 DEBUG(0,("unable to initialize domain list\n"));
1403                 exit(1);
1404         }
1405
1406         init_idmap_child();
1407         init_locator_child();
1408
1409         smb_nscd_flush_user_cache();
1410         smb_nscd_flush_group_cache();
1411
1412         if (!lp_winbind_scan_trusted_domains()) {
1413                 scan_trusts = false;
1414         }
1415
1416         if (!lp_allow_trusted_domains()) {
1417                 scan_trusts = false;
1418         }
1419
1420         if (IS_DC) {
1421                 scan_trusts = false;
1422         }
1423
1424         if (scan_trusts) {
1425                 if (tevent_add_timer(server_event_context(), NULL, timeval_zero(),
1426                               rescan_trusted_domains, NULL) == NULL) {
1427                         DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1428                         exit(1);
1429                 }
1430         }
1431
1432         status = wb_irpc_register();
1433
1434         if (!NT_STATUS_IS_OK(status)) {
1435                 DEBUG(0, ("Could not register IRPC handlers\n"));
1436                 exit(1);
1437         }
1438 }
1439
1440 struct winbindd_addrchanged_state {
1441         struct addrchange_context *ctx;
1442         struct tevent_context *ev;
1443         struct messaging_context *msg_ctx;
1444 };
1445
1446 static void winbindd_addr_changed(struct tevent_req *req);
1447
1448 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1449                                      struct tevent_context *ev,
1450                                      struct messaging_context *msg_ctx)
1451 {
1452         struct winbindd_addrchanged_state *state;
1453         struct tevent_req *req;
1454         NTSTATUS status;
1455
1456         state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1457         if (state == NULL) {
1458                 DEBUG(10, ("talloc failed\n"));
1459                 return;
1460         }
1461         state->ev = ev;
1462         state->msg_ctx = msg_ctx;
1463
1464         status = addrchange_context_create(state, &state->ctx);
1465         if (!NT_STATUS_IS_OK(status)) {
1466                 DEBUG(10, ("addrchange_context_create failed: %s\n",
1467                            nt_errstr(status)));
1468                 TALLOC_FREE(state);
1469                 return;
1470         }
1471         req = addrchange_send(state, ev, state->ctx);
1472         if (req == NULL) {
1473                 DEBUG(0, ("addrchange_send failed\n"));
1474                 TALLOC_FREE(state);
1475                 return;
1476         }
1477         tevent_req_set_callback(req, winbindd_addr_changed, state);
1478 }
1479
1480 static void winbindd_addr_changed(struct tevent_req *req)
1481 {
1482         struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1483                 req, struct winbindd_addrchanged_state);
1484         enum addrchange_type type;
1485         struct sockaddr_storage addr;
1486         NTSTATUS status;
1487
1488         status = addrchange_recv(req, &type, &addr);
1489         TALLOC_FREE(req);
1490         if (!NT_STATUS_IS_OK(status)) {
1491                 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1492                            nt_errstr(status)));
1493                 TALLOC_FREE(state);
1494                 return;
1495         }
1496         if (type == ADDRCHANGE_DEL) {
1497                 char addrstr[INET6_ADDRSTRLEN];
1498                 DATA_BLOB blob;
1499
1500                 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1501
1502                 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1503                           addrstr));
1504
1505                 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1506
1507                 status = messaging_send(state->msg_ctx,
1508                                         messaging_server_id(state->msg_ctx),
1509                                         MSG_WINBIND_IP_DROPPED, &blob);
1510                 if (!NT_STATUS_IS_OK(status)) {
1511                         DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1512                                    nt_errstr(status)));
1513                 }
1514         }
1515         req = addrchange_send(state, state->ev, state->ctx);
1516         if (req == NULL) {
1517                 DEBUG(0, ("addrchange_send failed\n"));
1518                 TALLOC_FREE(state);
1519                 return;
1520         }
1521         tevent_req_set_callback(req, winbindd_addr_changed, state);
1522 }
1523
1524 /* Main function */
1525
1526 int main(int argc, const char **argv)
1527 {
1528         static bool is_daemon = False;
1529         static bool Fork = True;
1530         static bool log_stdout = False;
1531         static bool no_process_group = False;
1532         enum {
1533                 OPT_DAEMON = 1000,
1534                 OPT_FORK,
1535                 OPT_NO_PROCESS_GROUP,
1536                 OPT_LOG_STDOUT
1537         };
1538         struct poptOption long_options[] = {
1539                 POPT_AUTOHELP
1540                 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1541                 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1542                 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1543                 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1544                 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1545                 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1546                 POPT_COMMON_SAMBA
1547                 POPT_TABLEEND
1548         };
1549         poptContext pc;
1550         int opt;
1551         TALLOC_CTX *frame;
1552         NTSTATUS status;
1553         bool ok;
1554
1555         setproctitle_init(argc, discard_const(argv), environ);
1556
1557         /*
1558          * Do this before any other talloc operation
1559          */
1560         talloc_enable_null_tracking();
1561         frame = talloc_stackframe();
1562
1563         /*
1564          * We want total control over the permissions on created files,
1565          * so set our umask to 0.
1566          */
1567         umask(0);
1568
1569         setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1570
1571         /* glibc (?) likes to print "User defined signal 1" and exit if a
1572            SIGUSR[12] is received before a handler is installed */
1573
1574         CatchSignal(SIGUSR1, SIG_IGN);
1575         CatchSignal(SIGUSR2, SIG_IGN);
1576
1577         fault_setup();
1578         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1579
1580         smb_init_locale();
1581
1582         /* Initialise for running in non-root mode */
1583
1584         sec_init();
1585
1586         set_remote_machine_name("winbindd", False);
1587
1588         /* Set environment variable so we don't recursively call ourselves.
1589            This may also be useful interactively. */
1590
1591         if ( !winbind_off() ) {
1592                 DEBUG(0,("Failed to disable recusive winbindd calls.  Exiting.\n"));
1593                 exit(1);
1594         }
1595
1596         /* Initialise samba/rpc client stuff */
1597
1598         pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1599
1600         while ((opt = poptGetNextOpt(pc)) != -1) {
1601                 switch (opt) {
1602                         /* Don't become a daemon */
1603                 case OPT_DAEMON:
1604                         is_daemon = True;
1605                         break;
1606                 case 'i':
1607                         interactive = True;
1608                         log_stdout = True;
1609                         Fork = False;
1610                         break;
1611                 case OPT_FORK:
1612                         Fork = false;
1613                         break;
1614                 case OPT_NO_PROCESS_GROUP:
1615                         no_process_group = true;
1616                         break;
1617                 case OPT_LOG_STDOUT:
1618                         log_stdout = true;
1619                         break;
1620                 case 'n':
1621                         opt_nocache = true;
1622                         break;
1623                 default:
1624                         d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1625                                   poptBadOption(pc, 0), poptStrerror(opt));
1626                         poptPrintUsage(pc, stderr, 0);
1627                         exit(1);
1628                 }
1629         }
1630
1631         /* We call dump_core_setup one more time because the command line can
1632          * set the log file or the log-basename and this will influence where
1633          * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1634          * the default value derived from build's prefix. For EOM this value
1635          * is often not related to the path where winbindd is actually run
1636          * in production.
1637          */
1638         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1639         if (is_daemon && interactive) {
1640                 d_fprintf(stderr,"\nERROR: "
1641                           "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1642                 poptPrintUsage(pc, stderr, 0);
1643                 exit(1);
1644         }
1645
1646         if (log_stdout && Fork) {
1647                 d_fprintf(stderr, "\nERROR: "
1648                           "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1649                 poptPrintUsage(pc, stderr, 0);
1650                 exit(1);
1651         }
1652
1653         poptFreeContext(pc);
1654
1655         if (!override_logfile) {
1656                 char *lfile = NULL;
1657                 if (asprintf(&lfile,"%s/log.winbindd",
1658                                 get_dyn_LOGFILEBASE()) > 0) {
1659                         lp_set_logfile(lfile);
1660                         SAFE_FREE(lfile);
1661                 }
1662         }
1663
1664         if (log_stdout) {
1665                 setup_logging("winbindd", DEBUG_STDOUT);
1666         } else {
1667                 setup_logging("winbindd", DEBUG_FILE);
1668         }
1669         reopen_logs();
1670
1671         DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1672         DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1673
1674         if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1675                 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1676                 exit(1);
1677         }
1678         /* After parsing the configuration file we setup the core path one more time
1679          * as the log file might have been set in the configuration and cores's
1680          * path is by default basename(lp_logfile()).
1681          */
1682         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1683
1684         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1685             && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1686                 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1687                 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"));
1688                 exit(1);
1689         }
1690
1691         if (!cluster_probe_ok()) {
1692                 exit(1);
1693         }
1694
1695         /* Initialise messaging system */
1696
1697         if (server_messaging_context() == NULL) {
1698                 exit(1);
1699         }
1700
1701         if (!reload_services_file(NULL)) {
1702                 DEBUG(0, ("error opening config file\n"));
1703                 exit(1);
1704         }
1705
1706         {
1707                 size_t i;
1708                 const char *idmap_backend;
1709                 const char *invalid_backends[] = {
1710                         "ad", "rfc2307", "rid",
1711                 };
1712
1713                 idmap_backend = lp_idmap_default_backend();
1714                 for (i = 0; i < ARRAY_SIZE(invalid_backends); i++) {
1715                         ok = strequal(idmap_backend, invalid_backends[i]);
1716                         if (ok) {
1717                                 DBG_ERR("FATAL: Invalid idmap backend %s "
1718                                         "configured as the default backend!\n",
1719                                         idmap_backend);
1720                                 exit(1);
1721                         }
1722                 }
1723         }
1724
1725         ok = directory_create_or_exist(lp_lock_directory(), 0755);
1726         if (!ok) {
1727                 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1728                           lp_lock_directory(), strerror(errno)));
1729                 exit(1);
1730         }
1731
1732         ok = directory_create_or_exist(lp_pid_directory(), 0755);
1733         if (!ok) {
1734                 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1735                           lp_pid_directory(), strerror(errno)));
1736                 exit(1);
1737         }
1738
1739         /* Setup names. */
1740
1741         if (!init_names())
1742                 exit(1);
1743
1744         load_interfaces();
1745
1746         if (!secrets_init()) {
1747
1748                 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1749                 return False;
1750         }
1751
1752         status = rpccli_pre_open_netlogon_creds();
1753         if (!NT_STATUS_IS_OK(status)) {
1754                 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1755                           nt_errstr(status)));
1756                 exit(1);
1757         }
1758
1759         /* Unblock all signals we are interested in as they may have been
1760            blocked by the parent process. */
1761
1762         BlockSignals(False, SIGINT);
1763         BlockSignals(False, SIGQUIT);
1764         BlockSignals(False, SIGTERM);
1765         BlockSignals(False, SIGUSR1);
1766         BlockSignals(False, SIGUSR2);
1767         BlockSignals(False, SIGHUP);
1768         BlockSignals(False, SIGCHLD);
1769
1770         if (!interactive)
1771                 become_daemon(Fork, no_process_group, log_stdout);
1772
1773         pidfile_create(lp_pid_directory(), "winbindd");
1774
1775 #if HAVE_SETPGID
1776         /*
1777          * If we're interactive we want to set our own process group for
1778          * signal management.
1779          */
1780         if (interactive && !no_process_group)
1781                 setpgid( (pid_t)0, (pid_t)0);
1782 #endif
1783
1784         TimeInit();
1785
1786         /* Don't use winbindd_reinit_after_fork here as
1787          * we're just starting up and haven't created any
1788          * winbindd-specific resources we must free yet. JRA.
1789          */
1790
1791         status = reinit_after_fork(server_messaging_context(),
1792                                    server_event_context(),
1793                                    false, NULL);
1794         if (!NT_STATUS_IS_OK(status)) {
1795                 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1796         }
1797         initialize_password_db(true, server_event_context());
1798
1799         /*
1800          * Do not initialize the parent-child-pipe before becoming
1801          * a daemon: this is used to detect a died parent in the child
1802          * process.
1803          */
1804         status = init_before_fork();
1805         if (!NT_STATUS_IS_OK(status)) {
1806                 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1807         }
1808
1809         winbindd_register_handlers(server_messaging_context(), !Fork);
1810
1811         if (!messaging_parent_dgm_cleanup_init(server_messaging_context())) {
1812                 exit(1);
1813         }
1814
1815         status = init_system_session_info(NULL);
1816         if (!NT_STATUS_IS_OK(status)) {
1817                 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1818         }
1819
1820         rpc_lsarpc_init(NULL);
1821         rpc_samr_init(NULL);
1822
1823         winbindd_init_addrchange(NULL, server_event_context(),
1824                                  server_messaging_context());
1825
1826         /* setup listen sockets */
1827
1828         if (!winbindd_setup_listeners()) {
1829                 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1830         }
1831
1832         irpc_add_name(winbind_imessaging_context(), "winbind_server");
1833
1834         TALLOC_FREE(frame);
1835
1836         if (!interactive) {
1837                 daemon_ready("winbindd");
1838         }
1839
1840         gpupdate_init();
1841
1842         /* Loop waiting for requests */
1843         while (1) {
1844                 frame = talloc_stackframe();
1845
1846                 if (tevent_loop_once(server_event_context()) == -1) {
1847                         DEBUG(1, ("tevent_loop_once() failed: %s\n",
1848                                   strerror(errno)));
1849                         return 1;
1850                 }
1851
1852                 TALLOC_FREE(frame);
1853         }
1854
1855         return 0;
1856 }