winbind: Remove winbind_messaging_context
[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 #include "libsmb/samlogon_cache.h"
47 #include "libcli/auth/netlogon_creds_cli.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                 struct messaging_context *msg = server_messaging_context();
225                 struct server_id self = messaging_server_id(msg);
226                 serverid_deregister(self);
227                 pidfile_unlink(lp_pid_directory(), "winbindd");
228         }
229
230         exit(0);
231 }
232
233 static void winbindd_sig_term_handler(struct tevent_context *ev,
234                                       struct tevent_signal *se,
235                                       int signum,
236                                       int count,
237                                       void *siginfo,
238                                       void *private_data)
239 {
240         bool *is_parent = talloc_get_type_abort(private_data, bool);
241
242         DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
243                  signum, (int)*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         ret = (uint8_t)winbindd_validate_cache_nobackup();
516         DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
517         messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
518                            (size_t)1);
519         _exit(0);
520 }
521
522 static struct winbindd_dispatch_table {
523         enum winbindd_cmd cmd;
524         void (*fn)(struct winbindd_cli_state *state);
525         const char *winbindd_cmd_name;
526 } dispatch_table[] = {
527
528         /* Enumeration functions */
529
530         { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
531           "LIST_TRUSTDOM" },
532
533         /* Miscellaneous */
534
535         { WINBINDD_INFO, winbindd_info, "INFO" },
536         { WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
537           "INTERFACE_VERSION" },
538         { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
539         { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
540         { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" },
541         { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
542         { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
543           "WINBINDD_PRIV_PIPE_DIR" },
544
545         /* Credential cache access */
546         { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
547         { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
548
549         /* End of list */
550
551         { WINBINDD_NUM_CMDS, NULL, "NONE" }
552 };
553
554 struct winbindd_async_dispatch_table {
555         enum winbindd_cmd cmd;
556         const char *cmd_name;
557         struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
558                                        struct tevent_context *ev,
559                                        struct winbindd_cli_state *cli,
560                                        struct winbindd_request *request);
561         NTSTATUS (*recv_req)(struct tevent_req *req,
562                              struct winbindd_response *presp);
563 };
564
565 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
566         { WINBINDD_PING, "PING",
567           wb_ping_send, wb_ping_recv },
568         { WINBINDD_LOOKUPSID, "LOOKUPSID",
569           winbindd_lookupsid_send, winbindd_lookupsid_recv },
570         { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
571           winbindd_lookupsids_send, winbindd_lookupsids_recv },
572         { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
573           winbindd_lookupname_send, winbindd_lookupname_recv },
574         { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
575           winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
576         { WINBINDD_XIDS_TO_SIDS, "XIDS_TO_SIDS",
577           winbindd_xids_to_sids_send, winbindd_xids_to_sids_recv },
578         { WINBINDD_GETPWSID, "GETPWSID",
579           winbindd_getpwsid_send, winbindd_getpwsid_recv },
580         { WINBINDD_GETPWNAM, "GETPWNAM",
581           winbindd_getpwnam_send, winbindd_getpwnam_recv },
582         { WINBINDD_GETPWUID, "GETPWUID",
583           winbindd_getpwuid_send, winbindd_getpwuid_recv },
584         { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
585           winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
586         { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
587           winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
588         { WINBINDD_GETGROUPS, "GETGROUPS",
589           winbindd_getgroups_send, winbindd_getgroups_recv },
590         { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
591           winbindd_show_sequence_send, winbindd_show_sequence_recv },
592         { WINBINDD_GETGRGID, "GETGRGID",
593           winbindd_getgrgid_send, winbindd_getgrgid_recv },
594         { WINBINDD_GETGRNAM, "GETGRNAM",
595           winbindd_getgrnam_send, winbindd_getgrnam_recv },
596         { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
597           winbindd_getusersids_send, winbindd_getusersids_recv },
598         { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
599           winbindd_lookuprids_send, winbindd_lookuprids_recv },
600         { WINBINDD_SETPWENT, "SETPWENT",
601           winbindd_setpwent_send, winbindd_setpwent_recv },
602         { WINBINDD_GETPWENT, "GETPWENT",
603           winbindd_getpwent_send, winbindd_getpwent_recv },
604         { WINBINDD_ENDPWENT, "ENDPWENT",
605           winbindd_endpwent_send, winbindd_endpwent_recv },
606         { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
607           winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
608         { WINBINDD_GETDCNAME, "GETDCNAME",
609           winbindd_getdcname_send, winbindd_getdcname_recv },
610         { WINBINDD_SETGRENT, "SETGRENT",
611           winbindd_setgrent_send, winbindd_setgrent_recv },
612         { WINBINDD_GETGRENT, "GETGRENT",
613           winbindd_getgrent_send, winbindd_getgrent_recv },
614         { WINBINDD_ENDGRENT, "ENDGRENT",
615           winbindd_endgrent_send, winbindd_endgrent_recv },
616         { WINBINDD_LIST_USERS, "LIST_USERS",
617           winbindd_list_users_send, winbindd_list_users_recv },
618         { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
619           winbindd_list_groups_send, winbindd_list_groups_recv },
620         { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
621           winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
622         { WINBINDD_PING_DC, "PING_DC",
623           winbindd_ping_dc_send, winbindd_ping_dc_recv },
624         { WINBINDD_PAM_AUTH, "PAM_AUTH",
625           winbindd_pam_auth_send, winbindd_pam_auth_recv },
626         { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
627           winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
628         { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
629           winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
630         { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
631           winbindd_pam_chng_pswd_auth_crap_send,
632           winbindd_pam_chng_pswd_auth_crap_recv },
633         { WINBINDD_WINS_BYIP, "WINS_BYIP",
634           winbindd_wins_byip_send, winbindd_wins_byip_recv },
635         { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
636           winbindd_wins_byname_send, winbindd_wins_byname_recv },
637
638         { 0, NULL, NULL, NULL }
639 };
640
641 static struct winbindd_async_dispatch_table async_priv_table[] = {
642         { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
643           winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
644         { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
645           winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
646         { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
647           winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
648         { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
649           winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
650
651         { 0, NULL, NULL, NULL }
652 };
653
654 static void wb_request_done(struct tevent_req *req);
655
656 static void process_request(struct winbindd_cli_state *state)
657 {
658         struct winbindd_dispatch_table *table = dispatch_table;
659         struct winbindd_async_dispatch_table *atable;
660
661         state->mem_ctx = talloc_named(state, 0, "winbind request");
662         if (state->mem_ctx == NULL)
663                 return;
664
665         /* Remember who asked us. */
666         state->pid = state->request->pid;
667
668         state->cmd_name = "unknown request";
669         state->recv_fn = NULL;
670         /* client is newest */
671         winbindd_promote_client(state);
672
673         /* Process command */
674
675         for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
676                 if (state->request->cmd == atable->cmd) {
677                         break;
678                 }
679         }
680
681         if ((atable->send_req == NULL) && state->privileged) {
682                 for (atable = async_priv_table; atable->send_req;
683                      atable += 1) {
684                         if (state->request->cmd == atable->cmd) {
685                                 break;
686                         }
687                 }
688         }
689
690         if (atable->send_req != NULL) {
691                 struct tevent_req *req;
692
693                 state->cmd_name = atable->cmd_name;
694                 state->recv_fn = atable->recv_req;
695
696                 DEBUG(10, ("process_request: Handling async request %d:%s\n",
697                            (int)state->pid, state->cmd_name));
698
699                 req = atable->send_req(state->mem_ctx, server_event_context(),
700                                        state, state->request);
701                 if (req == NULL) {
702                         DEBUG(0, ("process_request: atable->send failed for "
703                                   "%s\n", atable->cmd_name));
704                         request_error(state);
705                         return;
706                 }
707                 tevent_req_set_callback(req, wb_request_done, state);
708                 return;
709         }
710
711         state->response = talloc_zero(state->mem_ctx,
712                                       struct winbindd_response);
713         if (state->response == NULL) {
714                 DEBUG(10, ("talloc failed\n"));
715                 remove_client(state);
716                 return;
717         }
718         state->response->result = WINBINDD_PENDING;
719         state->response->length = sizeof(struct winbindd_response);
720
721         for (table = dispatch_table; table->fn; table++) {
722                 if (state->request->cmd == table->cmd) {
723                         DEBUG(10,("process_request: request fn %s\n",
724                                   table->winbindd_cmd_name ));
725                         state->cmd_name = table->winbindd_cmd_name;
726                         table->fn(state);
727                         break;
728                 }
729         }
730
731         if (!table->fn) {
732                 DEBUG(10,("process_request: unknown request fn number %d\n",
733                           (int)state->request->cmd ));
734                 request_error(state);
735         }
736 }
737
738 static void wb_request_done(struct tevent_req *req)
739 {
740         struct winbindd_cli_state *state = tevent_req_callback_data(
741                 req, struct winbindd_cli_state);
742         NTSTATUS status;
743
744         state->response = talloc_zero(state->mem_ctx,
745                                       struct winbindd_response);
746         if (state->response == NULL) {
747                 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
748                           (int)state->pid, state->cmd_name));
749                 remove_client(state);
750                 return;
751         }
752         state->response->result = WINBINDD_PENDING;
753         state->response->length = sizeof(struct winbindd_response);
754
755         status = state->recv_fn(req, state->response);
756         TALLOC_FREE(req);
757
758         DEBUG(10,("wb_request_done[%d:%s]: %s\n",
759                   (int)state->pid, state->cmd_name, nt_errstr(status)));
760
761         if (!NT_STATUS_IS_OK(status)) {
762                 request_error(state);
763                 return;
764         }
765         request_ok(state);
766 }
767
768 /*
769  * This is the main event loop of winbind requests. It goes through a
770  * state-machine of 3 read/write requests, 4 if you have extra data to send.
771  *
772  * An idle winbind client has a read request of 4 bytes outstanding,
773  * finalizing function is request_len_recv, checking the length. request_recv
774  * then processes the packet. The processing function then at some point has
775  * to call request_finished which schedules sending the response.
776  */
777
778 static void request_finished(struct winbindd_cli_state *state);
779
780 static void winbind_client_request_read(struct tevent_req *req);
781 static void winbind_client_response_written(struct tevent_req *req);
782 static void winbind_client_activity(struct tevent_req *req);
783
784 static void request_finished(struct winbindd_cli_state *state)
785 {
786         struct tevent_req *req;
787
788         /* free client socket monitoring request */
789         TALLOC_FREE(state->io_req);
790
791         TALLOC_FREE(state->request);
792
793         req = wb_resp_write_send(state, server_event_context(),
794                                  state->out_queue, state->sock,
795                                  state->response);
796         if (req == NULL) {
797                 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
798                           (int)state->pid, state->cmd_name));
799                 remove_client(state);
800                 return;
801         }
802         tevent_req_set_callback(req, winbind_client_response_written, state);
803         state->io_req = req;
804 }
805
806 static void winbind_client_response_written(struct tevent_req *req)
807 {
808         struct winbindd_cli_state *state = tevent_req_callback_data(
809                 req, struct winbindd_cli_state);
810         ssize_t ret;
811         int err;
812
813         state->io_req = NULL;
814
815         ret = wb_resp_write_recv(req, &err);
816         TALLOC_FREE(req);
817         if (ret == -1) {
818                 close(state->sock);
819                 state->sock = -1;
820                 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
821                           (int)state->pid, state->cmd_name, strerror(err)));
822                 remove_client(state);
823                 return;
824         }
825
826         DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
827                   "to client\n", (int)state->pid, state->cmd_name));
828
829         TALLOC_FREE(state->mem_ctx);
830         state->response = NULL;
831         state->cmd_name = "no request";
832         state->recv_fn = NULL;
833
834         req = wb_req_read_send(state, server_event_context(), state->sock,
835                                WINBINDD_MAX_EXTRA_DATA);
836         if (req == NULL) {
837                 remove_client(state);
838                 return;
839         }
840         tevent_req_set_callback(req, winbind_client_request_read, state);
841         state->io_req = req;
842 }
843
844 void request_error(struct winbindd_cli_state *state)
845 {
846         SMB_ASSERT(state->response->result == WINBINDD_PENDING);
847         state->response->result = WINBINDD_ERROR;
848         request_finished(state);
849 }
850
851 void request_ok(struct winbindd_cli_state *state)
852 {
853         SMB_ASSERT(state->response->result == WINBINDD_PENDING);
854         state->response->result = WINBINDD_OK;
855         request_finished(state);
856 }
857
858 /* Process a new connection by adding it to the client connection list */
859
860 static void new_connection(int listen_sock, bool privileged)
861 {
862         struct sockaddr_un sunaddr;
863         struct winbindd_cli_state *state;
864         struct tevent_req *req;
865         socklen_t len;
866         int sock;
867
868         /* Accept connection */
869
870         len = sizeof(sunaddr);
871
872         sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
873
874         if (sock == -1) {
875                 if (errno != EINTR) {
876                         DEBUG(0, ("Failed to accept socket - %s\n",
877                                   strerror(errno)));
878                 }
879                 return;
880         }
881
882         DEBUG(6,("accepted socket %d\n", sock));
883
884         /* Create new connection structure */
885
886         if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
887                 close(sock);
888                 return;
889         }
890
891         state->sock = sock;
892
893         state->out_queue = tevent_queue_create(state, "winbind client reply");
894         if (state->out_queue == NULL) {
895                 close(sock);
896                 TALLOC_FREE(state);
897                 return;
898         }
899
900         state->privileged = privileged;
901
902         req = wb_req_read_send(state, server_event_context(), state->sock,
903                                WINBINDD_MAX_EXTRA_DATA);
904         if (req == NULL) {
905                 TALLOC_FREE(state);
906                 close(sock);
907                 return;
908         }
909         tevent_req_set_callback(req, winbind_client_request_read, state);
910         state->io_req = req;
911
912         /* Add to connection list */
913
914         winbindd_add_client(state);
915 }
916
917 static void winbind_client_request_read(struct tevent_req *req)
918 {
919         struct winbindd_cli_state *state = tevent_req_callback_data(
920                 req, struct winbindd_cli_state);
921         ssize_t ret;
922         int err;
923
924         state->io_req = NULL;
925
926         ret = wb_req_read_recv(req, state, &state->request, &err);
927         TALLOC_FREE(req);
928         if (ret == -1) {
929                 if (err == EPIPE) {
930                         DEBUG(6, ("closing socket %d, client exited\n",
931                                   state->sock));
932                 } else {
933                         DEBUG(2, ("Could not read client request from fd %d: "
934                                   "%s\n", state->sock, strerror(err)));
935                 }
936                 close(state->sock);
937                 state->sock = -1;
938                 remove_client(state);
939                 return;
940         }
941
942         req = wait_for_read_send(state, server_event_context(), state->sock,
943                                  true);
944         if (req == NULL) {
945                 DEBUG(0, ("winbind_client_request_read[%d:%s]:"
946                           " wait_for_read_send failed - removing client\n",
947                           (int)state->pid, state->cmd_name));
948                 remove_client(state);
949                 return;
950         }
951         tevent_req_set_callback(req, winbind_client_activity, state);
952         state->io_req = req;
953
954         process_request(state);
955 }
956
957 static void winbind_client_activity(struct tevent_req *req)
958 {
959         struct winbindd_cli_state *state =
960             tevent_req_callback_data(req, struct winbindd_cli_state);
961         int err;
962         bool has_data;
963
964         has_data = wait_for_read_recv(req, &err);
965
966         if (has_data) {
967                 DEBUG(0, ("winbind_client_activity[%d:%s]:"
968                           "unexpected data from client - removing client\n",
969                           (int)state->pid, state->cmd_name));
970         } else {
971                 if (err == EPIPE) {
972                         DEBUG(6, ("winbind_client_activity[%d:%s]: "
973                                   "client has closed connection - removing "
974                                   "client\n",
975                                   (int)state->pid, state->cmd_name));
976                 } else {
977                         DEBUG(2, ("winbind_client_activity[%d:%s]: "
978                                   "client socket error (%s) - removing "
979                                   "client\n",
980                                   (int)state->pid, state->cmd_name,
981                                   strerror(err)));
982                 }
983         }
984
985         remove_client(state);
986 }
987
988 /* Remove a client connection from client connection list */
989
990 static void remove_client(struct winbindd_cli_state *state)
991 {
992         char c = 0;
993         int nwritten;
994
995         /* It's a dead client - hold a funeral */
996
997         if (state == NULL) {
998                 return;
999         }
1000
1001         /*
1002          * We need to remove a pending wb_req_read_*
1003          * or wb_resp_write_* request before closing the
1004          * socket.
1005          *
1006          * This is important as they might have used tevent_add_fd() and we
1007          * use the epoll * backend on linux. So we must remove the tevent_fd
1008          * before closing the fd.
1009          *
1010          * Otherwise we might hit a race with close_conns_after_fork() (via
1011          * winbindd_reinit_after_fork()) where a file description
1012          * is still open in a child, which means it's still active in
1013          * the parents epoll queue, but the related tevent_fd is already
1014          * already gone in the parent.
1015          *
1016          * See bug #11141.
1017          */
1018         TALLOC_FREE(state->io_req);
1019
1020         if (state->sock != -1) {
1021                 /* tell client, we are closing ... */
1022                 nwritten = write(state->sock, &c, sizeof(c));
1023                 if (nwritten == -1) {
1024                         DEBUG(2, ("final write to client failed: %s\n",
1025                                 strerror(errno)));
1026                 }
1027
1028                 /* Close socket */
1029
1030                 close(state->sock);
1031                 state->sock = -1;
1032         }
1033
1034         TALLOC_FREE(state->mem_ctx);
1035
1036         /* Remove from list and free */
1037
1038         winbindd_remove_client(state);
1039         TALLOC_FREE(state);
1040 }
1041
1042 /* Is a client idle? */
1043
1044 static bool client_is_idle(struct winbindd_cli_state *state) {
1045   return (state->request == NULL &&
1046           state->response == NULL &&
1047           !state->pwent_state && !state->grent_state);
1048 }
1049
1050 /* Shutdown client connection which has been idle for the longest time */
1051
1052 static bool remove_idle_client(void)
1053 {
1054         struct winbindd_cli_state *state, *remove_state = NULL;
1055         int nidle = 0;
1056
1057         for (state = winbindd_client_list(); state; state = state->next) {
1058                 if (client_is_idle(state)) {
1059                         nidle++;
1060                         /* list is sorted by access time */
1061                         remove_state = state;
1062                 }
1063         }
1064
1065         if (remove_state) {
1066                 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1067                         nidle, remove_state->sock, (unsigned int)remove_state->pid));
1068                 remove_client(remove_state);
1069                 return True;
1070         }
1071
1072         return False;
1073 }
1074
1075 /*
1076  * Terminate all clients whose requests have taken longer than
1077  * "winbind request timeout" seconds to process, or have been
1078  * idle for more than "winbind request timeout" seconds.
1079  */
1080
1081 static void remove_timed_out_clients(void)
1082 {
1083         struct winbindd_cli_state *state, *prev = NULL;
1084         time_t curr_time = time(NULL);
1085         int timeout_val = lp_winbind_request_timeout();
1086
1087         for (state = winbindd_client_list_tail(); state; state = prev) {
1088                 time_t expiry_time;
1089
1090                 prev = winbindd_client_list_prev(state);
1091                 expiry_time = state->last_access + timeout_val;
1092
1093                 if (curr_time <= expiry_time) {
1094                         /* list is sorted, previous clients in
1095                            list are newer */
1096                         break;
1097                 }
1098
1099                 if (client_is_idle(state)) {
1100                         DEBUG(5,("Idle client timed out, "
1101                                  "shutting down sock %d, pid %u\n",
1102                                  state->sock,
1103                                  (unsigned int)state->pid));
1104                 } else {
1105                         DEBUG(5,("Client request timed out, "
1106                                  "shutting down sock %d, pid %u\n",
1107                                  state->sock,
1108                                  (unsigned int)state->pid));
1109                 }
1110
1111                 remove_client(state);
1112         }
1113 }
1114
1115 static void winbindd_scrub_clients_handler(struct tevent_context *ev,
1116                                            struct tevent_timer *te,
1117                                            struct timeval current_time,
1118                                            void *private_data)
1119 {
1120         remove_timed_out_clients();
1121         if (tevent_add_timer(ev, ev,
1122                              timeval_current_ofs(SCRUB_CLIENTS_INTERVAL, 0),
1123                              winbindd_scrub_clients_handler, NULL) == NULL) {
1124                 DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
1125                 exit(1);
1126         }
1127 }
1128
1129 struct winbindd_listen_state {
1130         bool privileged;
1131         int fd;
1132 };
1133
1134 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1135                                         struct tevent_fd *fde,
1136                                         uint16_t flags,
1137                                         void *private_data)
1138 {
1139         struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1140                                           struct winbindd_listen_state);
1141
1142         while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1143                 DEBUG(5,("winbindd: Exceeding %d client "
1144                          "connections, removing idle "
1145                          "connection.\n", lp_winbind_max_clients()));
1146                 if (!remove_idle_client()) {
1147                         DEBUG(0,("winbindd: Exceeding %d "
1148                                  "client connections, no idle "
1149                                  "connection found\n",
1150                                  lp_winbind_max_clients()));
1151                         break;
1152                 }
1153         }
1154         remove_timed_out_clients();
1155         new_connection(s->fd, s->privileged);
1156 }
1157
1158 /*
1159  * Winbindd socket accessor functions
1160  */
1161
1162 char *get_winbind_priv_pipe_dir(void)
1163 {
1164         return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1165 }
1166
1167 static void winbindd_setup_max_fds(void)
1168 {
1169         int num_fds = MAX_OPEN_FUDGEFACTOR;
1170         int actual_fds;
1171
1172         num_fds += lp_winbind_max_clients();
1173         /* Add some more to account for 2 sockets open
1174            when the client transitions from unprivileged
1175            to privileged socket
1176         */
1177         num_fds += lp_winbind_max_clients() / 10;
1178
1179         /* Add one socket per child process
1180            (yeah there are child processes other than the
1181            domain children but only domain children can vary
1182            with configuration
1183         */
1184         num_fds += lp_winbind_max_domain_connections() *
1185                    (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
1186
1187         actual_fds = set_maxfiles(num_fds);
1188
1189         if (actual_fds < num_fds) {
1190                 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1191                           "requested %d open files, %d are available.\n",
1192                           num_fds, actual_fds));
1193         }
1194 }
1195
1196 static bool winbindd_setup_listeners(void)
1197 {
1198         struct winbindd_listen_state *pub_state = NULL;
1199         struct winbindd_listen_state *priv_state = NULL;
1200         struct tevent_fd *fde;
1201         int rc;
1202         char *socket_path;
1203
1204         pub_state = talloc(server_event_context(),
1205                            struct winbindd_listen_state);
1206         if (!pub_state) {
1207                 goto failed;
1208         }
1209
1210         pub_state->privileged = false;
1211         pub_state->fd = create_pipe_sock(
1212                 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1213         if (pub_state->fd == -1) {
1214                 goto failed;
1215         }
1216         rc = listen(pub_state->fd, 5);
1217         if (rc < 0) {
1218                 goto failed;
1219         }
1220
1221         fde = tevent_add_fd(server_event_context(), pub_state, pub_state->fd,
1222                             TEVENT_FD_READ, winbindd_listen_fde_handler,
1223                             pub_state);
1224         if (fde == NULL) {
1225                 close(pub_state->fd);
1226                 goto failed;
1227         }
1228         tevent_fd_set_auto_close(fde);
1229
1230         priv_state = talloc(server_event_context(),
1231                             struct winbindd_listen_state);
1232         if (!priv_state) {
1233                 goto failed;
1234         }
1235
1236         socket_path = get_winbind_priv_pipe_dir();
1237         if (socket_path == NULL) {
1238                 goto failed;
1239         }
1240
1241         priv_state->privileged = true;
1242         priv_state->fd = create_pipe_sock(
1243                 socket_path, WINBINDD_SOCKET_NAME, 0750);
1244         TALLOC_FREE(socket_path);
1245         if (priv_state->fd == -1) {
1246                 goto failed;
1247         }
1248         rc = listen(priv_state->fd, 5);
1249         if (rc < 0) {
1250                 goto failed;
1251         }
1252
1253         fde = tevent_add_fd(server_event_context(), priv_state,
1254                             priv_state->fd, TEVENT_FD_READ,
1255                             winbindd_listen_fde_handler, priv_state);
1256         if (fde == NULL) {
1257                 close(priv_state->fd);
1258                 goto failed;
1259         }
1260         tevent_fd_set_auto_close(fde);
1261
1262         winbindd_scrub_clients_handler(server_event_context(), NULL,
1263                                        timeval_current(), NULL);
1264         return true;
1265 failed:
1266         TALLOC_FREE(pub_state);
1267         TALLOC_FREE(priv_state);
1268         return false;
1269 }
1270
1271 bool winbindd_use_idmap_cache(void)
1272 {
1273         return !opt_nocache;
1274 }
1275
1276 bool winbindd_use_cache(void)
1277 {
1278         return !opt_nocache;
1279 }
1280
1281 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1282                                        bool foreground)
1283 {
1284         NTSTATUS status;
1285         /* Setup signal handlers */
1286
1287         if (!winbindd_setup_sig_term_handler(true))
1288                 exit(1);
1289         if (!winbindd_setup_stdin_handler(true, foreground))
1290                 exit(1);
1291         if (!winbindd_setup_sig_hup_handler(NULL))
1292                 exit(1);
1293         if (!winbindd_setup_sig_chld_handler())
1294                 exit(1);
1295         if (!winbindd_setup_sig_usr2_handler())
1296                 exit(1);
1297
1298         CatchSignal(SIGPIPE, SIG_IGN);                 /* Ignore sigpipe */
1299
1300         /*
1301          * Ensure all cache and idmap caches are consistent
1302          * and initialized before we startup.
1303          */
1304         if (!winbindd_cache_validate_and_initialize()) {
1305                 exit(1);
1306         }
1307
1308         /* get broadcast messages */
1309
1310         if (!serverid_register(messaging_server_id(msg_ctx),
1311                                FLAG_MSG_GENERAL |
1312                                FLAG_MSG_WINBIND |
1313                                FLAG_MSG_DBWRAP)) {
1314                 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
1315                 exit(1);
1316         }
1317
1318         /* React on 'smbcontrol winbindd reload-config' in the same way
1319            as to SIGHUP signal */
1320         messaging_register(msg_ctx, NULL,
1321                            MSG_SMB_CONF_UPDATED, msg_reload_services);
1322         messaging_register(msg_ctx, NULL,
1323                            MSG_SHUTDOWN, msg_shutdown);
1324
1325         /* Handle online/offline messages. */
1326         messaging_register(msg_ctx, NULL,
1327                            MSG_WINBIND_OFFLINE, winbind_msg_offline);
1328         messaging_register(msg_ctx, NULL,
1329                            MSG_WINBIND_ONLINE, winbind_msg_online);
1330         messaging_register(msg_ctx, NULL,
1331                            MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1332
1333         /* Handle domain online/offline messages for domains */
1334         messaging_register(server_messaging_context(), NULL,
1335                            MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1336         messaging_register(server_messaging_context(), NULL,
1337                            MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1338
1339         messaging_register(msg_ctx, NULL,
1340                            MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
1341
1342         messaging_register(msg_ctx, NULL,
1343                            MSG_WINBIND_VALIDATE_CACHE,
1344                            winbind_msg_validate_cache);
1345
1346         messaging_register(msg_ctx, NULL,
1347                            MSG_WINBIND_DUMP_DOMAIN_LIST,
1348                            winbind_msg_dump_domain_list);
1349
1350         messaging_register(msg_ctx, NULL,
1351                            MSG_WINBIND_IP_DROPPED,
1352                            winbind_msg_ip_dropped_parent);
1353
1354         /* Register handler for MSG_DEBUG. */
1355         messaging_register(msg_ctx, NULL,
1356                            MSG_DEBUG,
1357                            winbind_msg_debug);
1358
1359         netsamlogon_cache_init(); /* Non-critical */
1360
1361         /* clear the cached list of trusted domains */
1362
1363         wcache_tdc_clear();
1364
1365         if (!init_domain_list()) {
1366                 DEBUG(0,("unable to initialize domain list\n"));
1367                 exit(1);
1368         }
1369
1370         init_idmap_child();
1371         init_locator_child();
1372
1373         smb_nscd_flush_user_cache();
1374         smb_nscd_flush_group_cache();
1375
1376         if (lp_allow_trusted_domains()) {
1377                 if (tevent_add_timer(server_event_context(), NULL, timeval_zero(),
1378                               rescan_trusted_domains, NULL) == NULL) {
1379                         DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1380                         exit(1);
1381                 }
1382         }
1383
1384         status = wb_irpc_register();
1385
1386         if (!NT_STATUS_IS_OK(status)) {
1387                 DEBUG(0, ("Could not register IRPC handlers\n"));
1388                 exit(1);
1389         }
1390 }
1391
1392 struct winbindd_addrchanged_state {
1393         struct addrchange_context *ctx;
1394         struct tevent_context *ev;
1395         struct messaging_context *msg_ctx;
1396 };
1397
1398 static void winbindd_addr_changed(struct tevent_req *req);
1399
1400 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1401                                      struct tevent_context *ev,
1402                                      struct messaging_context *msg_ctx)
1403 {
1404         struct winbindd_addrchanged_state *state;
1405         struct tevent_req *req;
1406         NTSTATUS status;
1407
1408         state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1409         if (state == NULL) {
1410                 DEBUG(10, ("talloc failed\n"));
1411                 return;
1412         }
1413         state->ev = ev;
1414         state->msg_ctx = msg_ctx;
1415
1416         status = addrchange_context_create(state, &state->ctx);
1417         if (!NT_STATUS_IS_OK(status)) {
1418                 DEBUG(10, ("addrchange_context_create failed: %s\n",
1419                            nt_errstr(status)));
1420                 TALLOC_FREE(state);
1421                 return;
1422         }
1423         req = addrchange_send(state, ev, state->ctx);
1424         if (req == NULL) {
1425                 DEBUG(0, ("addrchange_send failed\n"));
1426                 TALLOC_FREE(state);
1427                 return;
1428         }
1429         tevent_req_set_callback(req, winbindd_addr_changed, state);
1430 }
1431
1432 static void winbindd_addr_changed(struct tevent_req *req)
1433 {
1434         struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1435                 req, struct winbindd_addrchanged_state);
1436         enum addrchange_type type;
1437         struct sockaddr_storage addr;
1438         NTSTATUS status;
1439
1440         status = addrchange_recv(req, &type, &addr);
1441         TALLOC_FREE(req);
1442         if (!NT_STATUS_IS_OK(status)) {
1443                 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1444                            nt_errstr(status)));
1445                 TALLOC_FREE(state);
1446                 return;
1447         }
1448         if (type == ADDRCHANGE_DEL) {
1449                 char addrstr[INET6_ADDRSTRLEN];
1450                 DATA_BLOB blob;
1451
1452                 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1453
1454                 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1455                           addrstr));
1456
1457                 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1458
1459                 status = messaging_send(state->msg_ctx,
1460                                         messaging_server_id(state->msg_ctx),
1461                                         MSG_WINBIND_IP_DROPPED, &blob);
1462                 if (!NT_STATUS_IS_OK(status)) {
1463                         DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1464                                    nt_errstr(status)));
1465                 }
1466         }
1467         req = addrchange_send(state, state->ev, state->ctx);
1468         if (req == NULL) {
1469                 DEBUG(0, ("addrchange_send failed\n"));
1470                 TALLOC_FREE(state);
1471                 return;
1472         }
1473         tevent_req_set_callback(req, winbindd_addr_changed, state);
1474 }
1475
1476 /* Main function */
1477
1478 int main(int argc, const char **argv)
1479 {
1480         static bool is_daemon = False;
1481         static bool Fork = True;
1482         static bool log_stdout = False;
1483         static bool no_process_group = False;
1484         enum {
1485                 OPT_DAEMON = 1000,
1486                 OPT_FORK,
1487                 OPT_NO_PROCESS_GROUP,
1488                 OPT_LOG_STDOUT
1489         };
1490         struct poptOption long_options[] = {
1491                 POPT_AUTOHELP
1492                 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1493                 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1494                 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1495                 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1496                 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1497                 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1498                 POPT_COMMON_SAMBA
1499                 POPT_TABLEEND
1500         };
1501         poptContext pc;
1502         int opt;
1503         TALLOC_CTX *frame;
1504         NTSTATUS status;
1505         bool ok;
1506
1507         /*
1508          * Do this before any other talloc operation
1509          */
1510         talloc_enable_null_tracking();
1511         frame = talloc_stackframe();
1512
1513         /*
1514          * We want total control over the permissions on created files,
1515          * so set our umask to 0.
1516          */
1517         umask(0);
1518
1519         setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1520
1521         /* glibc (?) likes to print "User defined signal 1" and exit if a
1522            SIGUSR[12] is received before a handler is installed */
1523
1524         CatchSignal(SIGUSR1, SIG_IGN);
1525         CatchSignal(SIGUSR2, SIG_IGN);
1526
1527         fault_setup();
1528         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1529
1530         smb_init_locale();
1531
1532         /* Initialise for running in non-root mode */
1533
1534         sec_init();
1535
1536         set_remote_machine_name("winbindd", False);
1537
1538         /* Set environment variable so we don't recursively call ourselves.
1539            This may also be useful interactively. */
1540
1541         if ( !winbind_off() ) {
1542                 DEBUG(0,("Failed to disable recusive winbindd calls.  Exiting.\n"));
1543                 exit(1);
1544         }
1545
1546         /* Initialise samba/rpc client stuff */
1547
1548         pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1549
1550         while ((opt = poptGetNextOpt(pc)) != -1) {
1551                 switch (opt) {
1552                         /* Don't become a daemon */
1553                 case OPT_DAEMON:
1554                         is_daemon = True;
1555                         break;
1556                 case 'i':
1557                         interactive = True;
1558                         log_stdout = True;
1559                         Fork = False;
1560                         break;
1561                 case OPT_FORK:
1562                         Fork = false;
1563                         break;
1564                 case OPT_NO_PROCESS_GROUP:
1565                         no_process_group = true;
1566                         break;
1567                 case OPT_LOG_STDOUT:
1568                         log_stdout = true;
1569                         break;
1570                 case 'n':
1571                         opt_nocache = true;
1572                         break;
1573                 default:
1574                         d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1575                                   poptBadOption(pc, 0), poptStrerror(opt));
1576                         poptPrintUsage(pc, stderr, 0);
1577                         exit(1);
1578                 }
1579         }
1580
1581         /* We call dump_core_setup one more time because the command line can
1582          * set the log file or the log-basename and this will influence where
1583          * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1584          * the default value derived from build's prefix. For EOM this value
1585          * is often not related to the path where winbindd is actually run
1586          * in production.
1587          */
1588         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1589         if (is_daemon && interactive) {
1590                 d_fprintf(stderr,"\nERROR: "
1591                           "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1592                 poptPrintUsage(pc, stderr, 0);
1593                 exit(1);
1594         }
1595
1596         if (log_stdout && Fork) {
1597                 d_fprintf(stderr, "\nERROR: "
1598                           "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1599                 poptPrintUsage(pc, stderr, 0);
1600                 exit(1);
1601         }
1602
1603         poptFreeContext(pc);
1604
1605         if (!override_logfile) {
1606                 char *lfile = NULL;
1607                 if (asprintf(&lfile,"%s/log.winbindd",
1608                                 get_dyn_LOGFILEBASE()) > 0) {
1609                         lp_set_logfile(lfile);
1610                         SAFE_FREE(lfile);
1611                 }
1612         }
1613
1614         if (log_stdout) {
1615                 setup_logging("winbindd", DEBUG_STDOUT);
1616         } else {
1617                 setup_logging("winbindd", DEBUG_FILE);
1618         }
1619         reopen_logs();
1620
1621         DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1622         DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1623
1624         if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1625                 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1626                 exit(1);
1627         }
1628         /* After parsing the configuration file we setup the core path one more time
1629          * as the log file might have been set in the configuration and cores's
1630          * path is by default basename(lp_logfile()).
1631          */
1632         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1633
1634         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1635             && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1636                 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1637                 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"));
1638                 exit(1);
1639         }
1640
1641         if (!cluster_probe_ok()) {
1642                 exit(1);
1643         }
1644
1645         /* Initialise messaging system */
1646
1647         if (server_messaging_context() == NULL) {
1648                 exit(1);
1649         }
1650
1651         if (!reload_services_file(NULL)) {
1652                 DEBUG(0, ("error opening config file\n"));
1653                 exit(1);
1654         }
1655
1656         {
1657                 size_t i;
1658                 const char *idmap_backend;
1659                 const char *invalid_backends[] = {
1660                         "ad", "rfc2307", "rid",
1661                 };
1662
1663                 idmap_backend = lp_idmap_default_backend();
1664                 for (i = 0; i < ARRAY_SIZE(invalid_backends); i++) {
1665                         ok = strequal(idmap_backend, invalid_backends[i]);
1666                         if (ok) {
1667                                 DBG_ERR("FATAL: Invalid idmap backend %s "
1668                                         "configured as the default backend!\n",
1669                                         idmap_backend);
1670                                 exit(1);
1671                         }
1672                 }
1673         }
1674
1675         ok = directory_create_or_exist(lp_lock_directory(), 0755);
1676         if (!ok) {
1677                 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1678                           lp_lock_directory(), strerror(errno)));
1679                 exit(1);
1680         }
1681
1682         ok = directory_create_or_exist(lp_pid_directory(), 0755);
1683         if (!ok) {
1684                 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1685                           lp_pid_directory(), strerror(errno)));
1686                 exit(1);
1687         }
1688
1689         /* Setup names. */
1690
1691         if (!init_names())
1692                 exit(1);
1693
1694         load_interfaces();
1695
1696         if (!secrets_init()) {
1697
1698                 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1699                 return False;
1700         }
1701
1702         status = rpccli_pre_open_netlogon_creds();
1703         if (!NT_STATUS_IS_OK(status)) {
1704                 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1705                           nt_errstr(status)));
1706                 exit(1);
1707         }
1708
1709         /* Unblock all signals we are interested in as they may have been
1710            blocked by the parent process. */
1711
1712         BlockSignals(False, SIGINT);
1713         BlockSignals(False, SIGQUIT);
1714         BlockSignals(False, SIGTERM);
1715         BlockSignals(False, SIGUSR1);
1716         BlockSignals(False, SIGUSR2);
1717         BlockSignals(False, SIGHUP);
1718         BlockSignals(False, SIGCHLD);
1719
1720         if (!interactive)
1721                 become_daemon(Fork, no_process_group, log_stdout);
1722
1723         pidfile_create(lp_pid_directory(), "winbindd");
1724
1725 #if HAVE_SETPGID
1726         /*
1727          * If we're interactive we want to set our own process group for
1728          * signal management.
1729          */
1730         if (interactive && !no_process_group)
1731                 setpgid( (pid_t)0, (pid_t)0);
1732 #endif
1733
1734         TimeInit();
1735
1736         /* Don't use winbindd_reinit_after_fork here as
1737          * we're just starting up and haven't created any
1738          * winbindd-specific resources we must free yet. JRA.
1739          */
1740
1741         status = reinit_after_fork(server_messaging_context(),
1742                                    server_event_context(),
1743                                    false, NULL);
1744         if (!NT_STATUS_IS_OK(status)) {
1745                 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1746         }
1747
1748         /*
1749          * Do not initialize the parent-child-pipe before becoming
1750          * a daemon: this is used to detect a died parent in the child
1751          * process.
1752          */
1753         status = init_before_fork();
1754         if (!NT_STATUS_IS_OK(status)) {
1755                 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1756         }
1757
1758         winbindd_register_handlers(server_messaging_context(), !Fork);
1759
1760         if (!messaging_parent_dgm_cleanup_init(server_messaging_context())) {
1761                 exit(1);
1762         }
1763
1764         status = init_system_session_info();
1765         if (!NT_STATUS_IS_OK(status)) {
1766                 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1767         }
1768
1769         rpc_lsarpc_init(NULL);
1770         rpc_samr_init(NULL);
1771
1772         winbindd_init_addrchange(NULL, server_event_context(),
1773                                  server_messaging_context());
1774
1775         /* setup listen sockets */
1776
1777         if (!winbindd_setup_listeners()) {
1778                 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1779         }
1780
1781         irpc_add_name(winbind_imessaging_context(), "winbind_server");
1782
1783         TALLOC_FREE(frame);
1784
1785         if (!interactive) {
1786                 daemon_ready("winbindd");
1787         }
1788
1789         /* Loop waiting for requests */
1790         while (1) {
1791                 frame = talloc_stackframe();
1792
1793                 if (tevent_loop_once(server_event_context()) == -1) {
1794                         DEBUG(1, ("tevent_loop_once() failed: %s\n",
1795                                   strerror(errno)));
1796                         return 1;
1797                 }
1798
1799                 TALLOC_FREE(frame);
1800         }
1801
1802         return 0;
1803 }