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