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