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