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