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