winbindd: avoid automatic enumerating trusts on DCs
[kai/samba-autobuild/.git] / source3 / winbindd / winbindd.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Winbind daemon for ntdom nss module
5
6    Copyright (C) by Tim Potter 2000-2002
7    Copyright (C) Andrew Tridgell 2002
8    Copyright (C) Jelmer Vernooij 2003
9    Copyright (C) Volker Lendecke 2004
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "popt_common.h"
27 #include "winbindd.h"
28 #include "nsswitch/winbind_client.h"
29 #include "nsswitch/wb_reqtrans.h"
30 #include "ntdomain.h"
31 #include "../librpc/gen_ndr/srv_lsa.h"
32 #include "../librpc/gen_ndr/srv_samr.h"
33 #include "secrets.h"
34 #include "rpc_client/cli_netlogon.h"
35 #include "idmap.h"
36 #include "lib/addrchange.h"
37 #include "auth.h"
38 #include "messages.h"
39 #include "../lib/util/pidfile.h"
40 #include "util_cluster.h"
41 #include "source4/lib/messaging/irpc.h"
42 #include "source4/lib/messaging/messaging.h"
43 #include "lib/param/param.h"
44 #include "lib/async_req/async_sock.h"
45 #include "libsmb/samlogon_cache.h"
46 #include "libcli/auth/netlogon_creds_cli.h"
47
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         bool scan_trusts = true;
1284         NTSTATUS status;
1285         /* Setup signal handlers */
1286
1287         if (!winbindd_setup_sig_term_handler(true))
1288                 exit(1);
1289         if (!winbindd_setup_stdin_handler(true, foreground))
1290                 exit(1);
1291         if (!winbindd_setup_sig_hup_handler(NULL))
1292                 exit(1);
1293         if (!winbindd_setup_sig_chld_handler())
1294                 exit(1);
1295         if (!winbindd_setup_sig_usr2_handler())
1296                 exit(1);
1297
1298         CatchSignal(SIGPIPE, SIG_IGN);                 /* Ignore sigpipe */
1299
1300         /*
1301          * Ensure all cache and idmap caches are consistent
1302          * and initialized before we startup.
1303          */
1304         if (!winbindd_cache_validate_and_initialize()) {
1305                 exit(1);
1306         }
1307
1308         /* React on 'smbcontrol winbindd reload-config' in the same way
1309            as to SIGHUP signal */
1310         messaging_register(msg_ctx, NULL,
1311                            MSG_SMB_CONF_UPDATED, msg_reload_services);
1312         messaging_register(msg_ctx, NULL,
1313                            MSG_SHUTDOWN, msg_shutdown);
1314
1315         /* Handle online/offline messages. */
1316         messaging_register(msg_ctx, NULL,
1317                            MSG_WINBIND_OFFLINE, winbind_msg_offline);
1318         messaging_register(msg_ctx, NULL,
1319                            MSG_WINBIND_ONLINE, winbind_msg_online);
1320         messaging_register(msg_ctx, NULL,
1321                            MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1322
1323         /* Handle domain online/offline messages for domains */
1324         messaging_register(server_messaging_context(), NULL,
1325                            MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1326         messaging_register(server_messaging_context(), NULL,
1327                            MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1328
1329         messaging_register(msg_ctx, NULL,
1330                            MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
1331
1332         messaging_register(msg_ctx, NULL,
1333                            MSG_WINBIND_VALIDATE_CACHE,
1334                            winbind_msg_validate_cache);
1335
1336         messaging_register(msg_ctx, NULL,
1337                            MSG_WINBIND_DUMP_DOMAIN_LIST,
1338                            winbind_msg_dump_domain_list);
1339
1340         messaging_register(msg_ctx, NULL,
1341                            MSG_WINBIND_IP_DROPPED,
1342                            winbind_msg_ip_dropped_parent);
1343
1344         /* Register handler for MSG_DEBUG. */
1345         messaging_register(msg_ctx, NULL,
1346                            MSG_DEBUG,
1347                            winbind_msg_debug);
1348
1349         netsamlogon_cache_init(); /* Non-critical */
1350
1351         /* clear the cached list of trusted domains */
1352
1353         wcache_tdc_clear();
1354
1355         if (!init_domain_list()) {
1356                 DEBUG(0,("unable to initialize domain list\n"));
1357                 exit(1);
1358         }
1359
1360         init_idmap_child();
1361         init_locator_child();
1362
1363         smb_nscd_flush_user_cache();
1364         smb_nscd_flush_group_cache();
1365
1366         if (!lp_allow_trusted_domains()) {
1367                 scan_trusts = false;
1368         }
1369
1370         if (IS_DC) {
1371                 scan_trusts = false;
1372         }
1373
1374         if (scan_trusts) {
1375                 if (tevent_add_timer(server_event_context(), NULL, timeval_zero(),
1376                               rescan_trusted_domains, NULL) == NULL) {
1377                         DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1378                         exit(1);
1379                 }
1380         }
1381
1382         status = wb_irpc_register();
1383
1384         if (!NT_STATUS_IS_OK(status)) {
1385                 DEBUG(0, ("Could not register IRPC handlers\n"));
1386                 exit(1);
1387         }
1388 }
1389
1390 struct winbindd_addrchanged_state {
1391         struct addrchange_context *ctx;
1392         struct tevent_context *ev;
1393         struct messaging_context *msg_ctx;
1394 };
1395
1396 static void winbindd_addr_changed(struct tevent_req *req);
1397
1398 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1399                                      struct tevent_context *ev,
1400                                      struct messaging_context *msg_ctx)
1401 {
1402         struct winbindd_addrchanged_state *state;
1403         struct tevent_req *req;
1404         NTSTATUS status;
1405
1406         state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1407         if (state == NULL) {
1408                 DEBUG(10, ("talloc failed\n"));
1409                 return;
1410         }
1411         state->ev = ev;
1412         state->msg_ctx = msg_ctx;
1413
1414         status = addrchange_context_create(state, &state->ctx);
1415         if (!NT_STATUS_IS_OK(status)) {
1416                 DEBUG(10, ("addrchange_context_create failed: %s\n",
1417                            nt_errstr(status)));
1418                 TALLOC_FREE(state);
1419                 return;
1420         }
1421         req = addrchange_send(state, ev, state->ctx);
1422         if (req == NULL) {
1423                 DEBUG(0, ("addrchange_send failed\n"));
1424                 TALLOC_FREE(state);
1425                 return;
1426         }
1427         tevent_req_set_callback(req, winbindd_addr_changed, state);
1428 }
1429
1430 static void winbindd_addr_changed(struct tevent_req *req)
1431 {
1432         struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1433                 req, struct winbindd_addrchanged_state);
1434         enum addrchange_type type;
1435         struct sockaddr_storage addr;
1436         NTSTATUS status;
1437
1438         status = addrchange_recv(req, &type, &addr);
1439         TALLOC_FREE(req);
1440         if (!NT_STATUS_IS_OK(status)) {
1441                 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1442                            nt_errstr(status)));
1443                 TALLOC_FREE(state);
1444                 return;
1445         }
1446         if (type == ADDRCHANGE_DEL) {
1447                 char addrstr[INET6_ADDRSTRLEN];
1448                 DATA_BLOB blob;
1449
1450                 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1451
1452                 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1453                           addrstr));
1454
1455                 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1456
1457                 status = messaging_send(state->msg_ctx,
1458                                         messaging_server_id(state->msg_ctx),
1459                                         MSG_WINBIND_IP_DROPPED, &blob);
1460                 if (!NT_STATUS_IS_OK(status)) {
1461                         DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1462                                    nt_errstr(status)));
1463                 }
1464         }
1465         req = addrchange_send(state, state->ev, state->ctx);
1466         if (req == NULL) {
1467                 DEBUG(0, ("addrchange_send failed\n"));
1468                 TALLOC_FREE(state);
1469                 return;
1470         }
1471         tevent_req_set_callback(req, winbindd_addr_changed, state);
1472 }
1473
1474 /* Main function */
1475
1476 int main(int argc, const char **argv)
1477 {
1478         static bool is_daemon = False;
1479         static bool Fork = True;
1480         static bool log_stdout = False;
1481         static bool no_process_group = False;
1482         enum {
1483                 OPT_DAEMON = 1000,
1484                 OPT_FORK,
1485                 OPT_NO_PROCESS_GROUP,
1486                 OPT_LOG_STDOUT
1487         };
1488         struct poptOption long_options[] = {
1489                 POPT_AUTOHELP
1490                 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1491                 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1492                 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1493                 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1494                 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1495                 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1496                 POPT_COMMON_SAMBA
1497                 POPT_TABLEEND
1498         };
1499         poptContext pc;
1500         int opt;
1501         TALLOC_CTX *frame;
1502         NTSTATUS status;
1503         bool ok;
1504
1505         setproctitle_init(argc, discard_const(argv), environ);
1506
1507         /*
1508          * Do this before any other talloc operation
1509          */
1510         talloc_enable_null_tracking();
1511         frame = talloc_stackframe();
1512
1513         /*
1514          * We want total control over the permissions on created files,
1515          * so set our umask to 0.
1516          */
1517         umask(0);
1518
1519         setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1520
1521         /* glibc (?) likes to print "User defined signal 1" and exit if a
1522            SIGUSR[12] is received before a handler is installed */
1523
1524         CatchSignal(SIGUSR1, SIG_IGN);
1525         CatchSignal(SIGUSR2, SIG_IGN);
1526
1527         fault_setup();
1528         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1529
1530         smb_init_locale();
1531
1532         /* Initialise for running in non-root mode */
1533
1534         sec_init();
1535
1536         set_remote_machine_name("winbindd", False);
1537
1538         /* Set environment variable so we don't recursively call ourselves.
1539            This may also be useful interactively. */
1540
1541         if ( !winbind_off() ) {
1542                 DEBUG(0,("Failed to disable recusive winbindd calls.  Exiting.\n"));
1543                 exit(1);
1544         }
1545
1546         /* Initialise samba/rpc client stuff */
1547
1548         pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1549
1550         while ((opt = poptGetNextOpt(pc)) != -1) {
1551                 switch (opt) {
1552                         /* Don't become a daemon */
1553                 case OPT_DAEMON:
1554                         is_daemon = True;
1555                         break;
1556                 case 'i':
1557                         interactive = True;
1558                         log_stdout = True;
1559                         Fork = False;
1560                         break;
1561                 case OPT_FORK:
1562                         Fork = false;
1563                         break;
1564                 case OPT_NO_PROCESS_GROUP:
1565                         no_process_group = true;
1566                         break;
1567                 case OPT_LOG_STDOUT:
1568                         log_stdout = true;
1569                         break;
1570                 case 'n':
1571                         opt_nocache = true;
1572                         break;
1573                 default:
1574                         d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1575                                   poptBadOption(pc, 0), poptStrerror(opt));
1576                         poptPrintUsage(pc, stderr, 0);
1577                         exit(1);
1578                 }
1579         }
1580
1581         /* We call dump_core_setup one more time because the command line can
1582          * set the log file or the log-basename and this will influence where
1583          * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1584          * the default value derived from build's prefix. For EOM this value
1585          * is often not related to the path where winbindd is actually run
1586          * in production.
1587          */
1588         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1589         if (is_daemon && interactive) {
1590                 d_fprintf(stderr,"\nERROR: "
1591                           "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1592                 poptPrintUsage(pc, stderr, 0);
1593                 exit(1);
1594         }
1595
1596         if (log_stdout && Fork) {
1597                 d_fprintf(stderr, "\nERROR: "
1598                           "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1599                 poptPrintUsage(pc, stderr, 0);
1600                 exit(1);
1601         }
1602
1603         poptFreeContext(pc);
1604
1605         if (!override_logfile) {
1606                 char *lfile = NULL;
1607                 if (asprintf(&lfile,"%s/log.winbindd",
1608                                 get_dyn_LOGFILEBASE()) > 0) {
1609                         lp_set_logfile(lfile);
1610                         SAFE_FREE(lfile);
1611                 }
1612         }
1613
1614         if (log_stdout) {
1615                 setup_logging("winbindd", DEBUG_STDOUT);
1616         } else {
1617                 setup_logging("winbindd", DEBUG_FILE);
1618         }
1619         reopen_logs();
1620
1621         DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1622         DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1623
1624         if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1625                 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1626                 exit(1);
1627         }
1628         /* After parsing the configuration file we setup the core path one more time
1629          * as the log file might have been set in the configuration and cores's
1630          * path is by default basename(lp_logfile()).
1631          */
1632         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1633
1634         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1635             && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1636                 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1637                 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"));
1638                 exit(1);
1639         }
1640
1641         if (!cluster_probe_ok()) {
1642                 exit(1);
1643         }
1644
1645         /* Initialise messaging system */
1646
1647         if (server_messaging_context() == NULL) {
1648                 exit(1);
1649         }
1650
1651         if (!reload_services_file(NULL)) {
1652                 DEBUG(0, ("error opening config file\n"));
1653                 exit(1);
1654         }
1655
1656         {
1657                 size_t i;
1658                 const char *idmap_backend;
1659                 const char *invalid_backends[] = {
1660                         "ad", "rfc2307", "rid",
1661                 };
1662
1663                 idmap_backend = lp_idmap_default_backend();
1664                 for (i = 0; i < ARRAY_SIZE(invalid_backends); i++) {
1665                         ok = strequal(idmap_backend, invalid_backends[i]);
1666                         if (ok) {
1667                                 DBG_ERR("FATAL: Invalid idmap backend %s "
1668                                         "configured as the default backend!\n",
1669                                         idmap_backend);
1670                                 exit(1);
1671                         }
1672                 }
1673         }
1674
1675         ok = directory_create_or_exist(lp_lock_directory(), 0755);
1676         if (!ok) {
1677                 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1678                           lp_lock_directory(), strerror(errno)));
1679                 exit(1);
1680         }
1681
1682         ok = directory_create_or_exist(lp_pid_directory(), 0755);
1683         if (!ok) {
1684                 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1685                           lp_pid_directory(), strerror(errno)));
1686                 exit(1);
1687         }
1688
1689         /* Setup names. */
1690
1691         if (!init_names())
1692                 exit(1);
1693
1694         load_interfaces();
1695
1696         if (!secrets_init()) {
1697
1698                 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1699                 return False;
1700         }
1701
1702         status = rpccli_pre_open_netlogon_creds();
1703         if (!NT_STATUS_IS_OK(status)) {
1704                 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1705                           nt_errstr(status)));
1706                 exit(1);
1707         }
1708
1709         /* Unblock all signals we are interested in as they may have been
1710            blocked by the parent process. */
1711
1712         BlockSignals(False, SIGINT);
1713         BlockSignals(False, SIGQUIT);
1714         BlockSignals(False, SIGTERM);
1715         BlockSignals(False, SIGUSR1);
1716         BlockSignals(False, SIGUSR2);
1717         BlockSignals(False, SIGHUP);
1718         BlockSignals(False, SIGCHLD);
1719
1720         if (!interactive)
1721                 become_daemon(Fork, no_process_group, log_stdout);
1722
1723         pidfile_create(lp_pid_directory(), "winbindd");
1724
1725 #if HAVE_SETPGID
1726         /*
1727          * If we're interactive we want to set our own process group for
1728          * signal management.
1729          */
1730         if (interactive && !no_process_group)
1731                 setpgid( (pid_t)0, (pid_t)0);
1732 #endif
1733
1734         TimeInit();
1735
1736         /* Don't use winbindd_reinit_after_fork here as
1737          * we're just starting up and haven't created any
1738          * winbindd-specific resources we must free yet. JRA.
1739          */
1740
1741         status = reinit_after_fork(server_messaging_context(),
1742                                    server_event_context(),
1743                                    false, NULL);
1744         if (!NT_STATUS_IS_OK(status)) {
1745                 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1746         }
1747
1748         /*
1749          * Do not initialize the parent-child-pipe before becoming
1750          * a daemon: this is used to detect a died parent in the child
1751          * process.
1752          */
1753         status = init_before_fork();
1754         if (!NT_STATUS_IS_OK(status)) {
1755                 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1756         }
1757
1758         winbindd_register_handlers(server_messaging_context(), !Fork);
1759
1760         if (!messaging_parent_dgm_cleanup_init(server_messaging_context())) {
1761                 exit(1);
1762         }
1763
1764         status = init_system_session_info();
1765         if (!NT_STATUS_IS_OK(status)) {
1766                 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1767         }
1768
1769         rpc_lsarpc_init(NULL);
1770         rpc_samr_init(NULL);
1771
1772         winbindd_init_addrchange(NULL, server_event_context(),
1773                                  server_messaging_context());
1774
1775         /* setup listen sockets */
1776
1777         if (!winbindd_setup_listeners()) {
1778                 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1779         }
1780
1781         irpc_add_name(winbind_imessaging_context(), "winbind_server");
1782
1783         TALLOC_FREE(frame);
1784
1785         if (!interactive) {
1786                 daemon_ready("winbindd");
1787         }
1788
1789         /* Loop waiting for requests */
1790         while (1) {
1791                 frame = talloc_stackframe();
1792
1793                 if (tevent_loop_once(server_event_context()) == -1) {
1794                         DEBUG(1, ("tevent_loop_once() failed: %s\n",
1795                                   strerror(errno)));
1796                         return 1;
1797                 }
1798
1799                 TALLOC_FREE(frame);
1800         }
1801
1802         return 0;
1803 }