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