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