lib: Remove unused serverid.tdb
[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         ret = (uint8_t)winbindd_validate_cache_nobackup();
512         DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
513         messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
514                            (size_t)1);
515         _exit(0);
516 }
517
518 static struct winbindd_dispatch_table {
519         enum winbindd_cmd cmd;
520         void (*fn)(struct winbindd_cli_state *state);
521         const char *winbindd_cmd_name;
522 } dispatch_table[] = {
523
524         /* Enumeration functions */
525
526         { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
527           "LIST_TRUSTDOM" },
528
529         /* Miscellaneous */
530
531         { WINBINDD_INFO, winbindd_info, "INFO" },
532         { WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
533           "INTERFACE_VERSION" },
534         { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
535         { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
536         { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" },
537         { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
538         { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
539           "WINBINDD_PRIV_PIPE_DIR" },
540
541         /* Credential cache access */
542         { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
543         { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
544
545         /* End of list */
546
547         { WINBINDD_NUM_CMDS, NULL, "NONE" }
548 };
549
550 struct winbindd_async_dispatch_table {
551         enum winbindd_cmd cmd;
552         const char *cmd_name;
553         struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
554                                        struct tevent_context *ev,
555                                        struct winbindd_cli_state *cli,
556                                        struct winbindd_request *request);
557         NTSTATUS (*recv_req)(struct tevent_req *req,
558                              struct winbindd_response *presp);
559 };
560
561 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
562         { WINBINDD_PING, "PING",
563           wb_ping_send, wb_ping_recv },
564         { WINBINDD_LOOKUPSID, "LOOKUPSID",
565           winbindd_lookupsid_send, winbindd_lookupsid_recv },
566         { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
567           winbindd_lookupsids_send, winbindd_lookupsids_recv },
568         { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
569           winbindd_lookupname_send, winbindd_lookupname_recv },
570         { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
571           winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
572         { WINBINDD_XIDS_TO_SIDS, "XIDS_TO_SIDS",
573           winbindd_xids_to_sids_send, winbindd_xids_to_sids_recv },
574         { WINBINDD_GETPWSID, "GETPWSID",
575           winbindd_getpwsid_send, winbindd_getpwsid_recv },
576         { WINBINDD_GETPWNAM, "GETPWNAM",
577           winbindd_getpwnam_send, winbindd_getpwnam_recv },
578         { WINBINDD_GETPWUID, "GETPWUID",
579           winbindd_getpwuid_send, winbindd_getpwuid_recv },
580         { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
581           winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
582         { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
583           winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
584         { WINBINDD_GETGROUPS, "GETGROUPS",
585           winbindd_getgroups_send, winbindd_getgroups_recv },
586         { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
587           winbindd_show_sequence_send, winbindd_show_sequence_recv },
588         { WINBINDD_GETGRGID, "GETGRGID",
589           winbindd_getgrgid_send, winbindd_getgrgid_recv },
590         { WINBINDD_GETGRNAM, "GETGRNAM",
591           winbindd_getgrnam_send, winbindd_getgrnam_recv },
592         { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
593           winbindd_getusersids_send, winbindd_getusersids_recv },
594         { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
595           winbindd_lookuprids_send, winbindd_lookuprids_recv },
596         { WINBINDD_SETPWENT, "SETPWENT",
597           winbindd_setpwent_send, winbindd_setpwent_recv },
598         { WINBINDD_GETPWENT, "GETPWENT",
599           winbindd_getpwent_send, winbindd_getpwent_recv },
600         { WINBINDD_ENDPWENT, "ENDPWENT",
601           winbindd_endpwent_send, winbindd_endpwent_recv },
602         { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
603           winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
604         { WINBINDD_GETDCNAME, "GETDCNAME",
605           winbindd_getdcname_send, winbindd_getdcname_recv },
606         { WINBINDD_SETGRENT, "SETGRENT",
607           winbindd_setgrent_send, winbindd_setgrent_recv },
608         { WINBINDD_GETGRENT, "GETGRENT",
609           winbindd_getgrent_send, winbindd_getgrent_recv },
610         { WINBINDD_ENDGRENT, "ENDGRENT",
611           winbindd_endgrent_send, winbindd_endgrent_recv },
612         { WINBINDD_LIST_USERS, "LIST_USERS",
613           winbindd_list_users_send, winbindd_list_users_recv },
614         { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
615           winbindd_list_groups_send, winbindd_list_groups_recv },
616         { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
617           winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
618         { WINBINDD_PING_DC, "PING_DC",
619           winbindd_ping_dc_send, winbindd_ping_dc_recv },
620         { WINBINDD_PAM_AUTH, "PAM_AUTH",
621           winbindd_pam_auth_send, winbindd_pam_auth_recv },
622         { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
623           winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
624         { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
625           winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
626         { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
627           winbindd_pam_chng_pswd_auth_crap_send,
628           winbindd_pam_chng_pswd_auth_crap_recv },
629         { WINBINDD_WINS_BYIP, "WINS_BYIP",
630           winbindd_wins_byip_send, winbindd_wins_byip_recv },
631         { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
632           winbindd_wins_byname_send, winbindd_wins_byname_recv },
633
634         { 0, NULL, NULL, NULL }
635 };
636
637 static struct winbindd_async_dispatch_table async_priv_table[] = {
638         { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
639           winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
640         { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
641           winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
642         { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
643           winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
644         { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
645           winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
646
647         { 0, NULL, NULL, NULL }
648 };
649
650 static void wb_request_done(struct tevent_req *req);
651
652 static void process_request(struct winbindd_cli_state *state)
653 {
654         struct winbindd_dispatch_table *table = dispatch_table;
655         struct winbindd_async_dispatch_table *atable;
656
657         state->mem_ctx = talloc_named(state, 0, "winbind request");
658         if (state->mem_ctx == NULL)
659                 return;
660
661         /* Remember who asked us. */
662         state->pid = state->request->pid;
663
664         state->cmd_name = "unknown request";
665         state->recv_fn = NULL;
666         /* client is newest */
667         winbindd_promote_client(state);
668
669         /* Process command */
670
671         for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
672                 if (state->request->cmd == atable->cmd) {
673                         break;
674                 }
675         }
676
677         if ((atable->send_req == NULL) && state->privileged) {
678                 for (atable = async_priv_table; atable->send_req;
679                      atable += 1) {
680                         if (state->request->cmd == atable->cmd) {
681                                 break;
682                         }
683                 }
684         }
685
686         if (atable->send_req != NULL) {
687                 struct tevent_req *req;
688
689                 state->cmd_name = atable->cmd_name;
690                 state->recv_fn = atable->recv_req;
691
692                 DEBUG(10, ("process_request: Handling async request %d:%s\n",
693                            (int)state->pid, state->cmd_name));
694
695                 req = atable->send_req(state->mem_ctx, server_event_context(),
696                                        state, state->request);
697                 if (req == NULL) {
698                         DEBUG(0, ("process_request: atable->send failed for "
699                                   "%s\n", atable->cmd_name));
700                         request_error(state);
701                         return;
702                 }
703                 tevent_req_set_callback(req, wb_request_done, state);
704                 return;
705         }
706
707         state->response = talloc_zero(state->mem_ctx,
708                                       struct winbindd_response);
709         if (state->response == NULL) {
710                 DEBUG(10, ("talloc failed\n"));
711                 remove_client(state);
712                 return;
713         }
714         state->response->result = WINBINDD_PENDING;
715         state->response->length = sizeof(struct winbindd_response);
716
717         for (table = dispatch_table; table->fn; table++) {
718                 if (state->request->cmd == table->cmd) {
719                         DEBUG(10,("process_request: request fn %s\n",
720                                   table->winbindd_cmd_name ));
721                         state->cmd_name = table->winbindd_cmd_name;
722                         table->fn(state);
723                         break;
724                 }
725         }
726
727         if (!table->fn) {
728                 DEBUG(10,("process_request: unknown request fn number %d\n",
729                           (int)state->request->cmd ));
730                 request_error(state);
731         }
732 }
733
734 static void wb_request_done(struct tevent_req *req)
735 {
736         struct winbindd_cli_state *state = tevent_req_callback_data(
737                 req, struct winbindd_cli_state);
738         NTSTATUS status;
739
740         state->response = talloc_zero(state->mem_ctx,
741                                       struct winbindd_response);
742         if (state->response == NULL) {
743                 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
744                           (int)state->pid, state->cmd_name));
745                 remove_client(state);
746                 return;
747         }
748         state->response->result = WINBINDD_PENDING;
749         state->response->length = sizeof(struct winbindd_response);
750
751         status = state->recv_fn(req, state->response);
752         TALLOC_FREE(req);
753
754         DEBUG(10,("wb_request_done[%d:%s]: %s\n",
755                   (int)state->pid, state->cmd_name, nt_errstr(status)));
756
757         if (!NT_STATUS_IS_OK(status)) {
758                 request_error(state);
759                 return;
760         }
761         request_ok(state);
762 }
763
764 /*
765  * This is the main event loop of winbind requests. It goes through a
766  * state-machine of 3 read/write requests, 4 if you have extra data to send.
767  *
768  * An idle winbind client has a read request of 4 bytes outstanding,
769  * finalizing function is request_len_recv, checking the length. request_recv
770  * then processes the packet. The processing function then at some point has
771  * to call request_finished which schedules sending the response.
772  */
773
774 static void request_finished(struct winbindd_cli_state *state);
775
776 static void winbind_client_request_read(struct tevent_req *req);
777 static void winbind_client_response_written(struct tevent_req *req);
778 static void winbind_client_activity(struct tevent_req *req);
779
780 static void request_finished(struct winbindd_cli_state *state)
781 {
782         struct tevent_req *req;
783
784         /* free client socket monitoring request */
785         TALLOC_FREE(state->io_req);
786
787         TALLOC_FREE(state->request);
788
789         req = wb_resp_write_send(state, server_event_context(),
790                                  state->out_queue, state->sock,
791                                  state->response);
792         if (req == NULL) {
793                 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
794                           (int)state->pid, state->cmd_name));
795                 remove_client(state);
796                 return;
797         }
798         tevent_req_set_callback(req, winbind_client_response_written, state);
799         state->io_req = req;
800 }
801
802 static void winbind_client_response_written(struct tevent_req *req)
803 {
804         struct winbindd_cli_state *state = tevent_req_callback_data(
805                 req, struct winbindd_cli_state);
806         ssize_t ret;
807         int err;
808
809         state->io_req = NULL;
810
811         ret = wb_resp_write_recv(req, &err);
812         TALLOC_FREE(req);
813         if (ret == -1) {
814                 close(state->sock);
815                 state->sock = -1;
816                 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
817                           (int)state->pid, state->cmd_name, strerror(err)));
818                 remove_client(state);
819                 return;
820         }
821
822         DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
823                   "to client\n", (int)state->pid, state->cmd_name));
824
825         TALLOC_FREE(state->mem_ctx);
826         state->response = NULL;
827         state->cmd_name = "no request";
828         state->recv_fn = NULL;
829
830         req = wb_req_read_send(state, server_event_context(), state->sock,
831                                WINBINDD_MAX_EXTRA_DATA);
832         if (req == NULL) {
833                 remove_client(state);
834                 return;
835         }
836         tevent_req_set_callback(req, winbind_client_request_read, state);
837         state->io_req = req;
838 }
839
840 void request_error(struct winbindd_cli_state *state)
841 {
842         SMB_ASSERT(state->response->result == WINBINDD_PENDING);
843         state->response->result = WINBINDD_ERROR;
844         request_finished(state);
845 }
846
847 void request_ok(struct winbindd_cli_state *state)
848 {
849         SMB_ASSERT(state->response->result == WINBINDD_PENDING);
850         state->response->result = WINBINDD_OK;
851         request_finished(state);
852 }
853
854 /* Process a new connection by adding it to the client connection list */
855
856 static void new_connection(int listen_sock, bool privileged)
857 {
858         struct sockaddr_un sunaddr;
859         struct winbindd_cli_state *state;
860         struct tevent_req *req;
861         socklen_t len;
862         int sock;
863
864         /* Accept connection */
865
866         len = sizeof(sunaddr);
867
868         sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
869
870         if (sock == -1) {
871                 if (errno != EINTR) {
872                         DEBUG(0, ("Failed to accept socket - %s\n",
873                                   strerror(errno)));
874                 }
875                 return;
876         }
877
878         DEBUG(6,("accepted socket %d\n", sock));
879
880         /* Create new connection structure */
881
882         if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
883                 close(sock);
884                 return;
885         }
886
887         state->sock = sock;
888
889         state->out_queue = tevent_queue_create(state, "winbind client reply");
890         if (state->out_queue == NULL) {
891                 close(sock);
892                 TALLOC_FREE(state);
893                 return;
894         }
895
896         state->privileged = privileged;
897
898         req = wb_req_read_send(state, server_event_context(), state->sock,
899                                WINBINDD_MAX_EXTRA_DATA);
900         if (req == NULL) {
901                 TALLOC_FREE(state);
902                 close(sock);
903                 return;
904         }
905         tevent_req_set_callback(req, winbind_client_request_read, state);
906         state->io_req = req;
907
908         /* Add to connection list */
909
910         winbindd_add_client(state);
911 }
912
913 static void winbind_client_request_read(struct tevent_req *req)
914 {
915         struct winbindd_cli_state *state = tevent_req_callback_data(
916                 req, struct winbindd_cli_state);
917         ssize_t ret;
918         int err;
919
920         state->io_req = NULL;
921
922         ret = wb_req_read_recv(req, state, &state->request, &err);
923         TALLOC_FREE(req);
924         if (ret == -1) {
925                 if (err == EPIPE) {
926                         DEBUG(6, ("closing socket %d, client exited\n",
927                                   state->sock));
928                 } else {
929                         DEBUG(2, ("Could not read client request from fd %d: "
930                                   "%s\n", state->sock, strerror(err)));
931                 }
932                 close(state->sock);
933                 state->sock = -1;
934                 remove_client(state);
935                 return;
936         }
937
938         req = wait_for_read_send(state, server_event_context(), state->sock,
939                                  true);
940         if (req == NULL) {
941                 DEBUG(0, ("winbind_client_request_read[%d:%s]:"
942                           " wait_for_read_send failed - removing client\n",
943                           (int)state->pid, state->cmd_name));
944                 remove_client(state);
945                 return;
946         }
947         tevent_req_set_callback(req, winbind_client_activity, state);
948         state->io_req = req;
949
950         process_request(state);
951 }
952
953 static void winbind_client_activity(struct tevent_req *req)
954 {
955         struct winbindd_cli_state *state =
956             tevent_req_callback_data(req, struct winbindd_cli_state);
957         int err;
958         bool has_data;
959
960         has_data = wait_for_read_recv(req, &err);
961
962         if (has_data) {
963                 DEBUG(0, ("winbind_client_activity[%d:%s]:"
964                           "unexpected data from client - removing client\n",
965                           (int)state->pid, state->cmd_name));
966         } else {
967                 if (err == EPIPE) {
968                         DEBUG(6, ("winbind_client_activity[%d:%s]: "
969                                   "client has closed connection - removing "
970                                   "client\n",
971                                   (int)state->pid, state->cmd_name));
972                 } else {
973                         DEBUG(2, ("winbind_client_activity[%d:%s]: "
974                                   "client socket error (%s) - removing "
975                                   "client\n",
976                                   (int)state->pid, state->cmd_name,
977                                   strerror(err)));
978                 }
979         }
980
981         remove_client(state);
982 }
983
984 /* Remove a client connection from client connection list */
985
986 static void remove_client(struct winbindd_cli_state *state)
987 {
988         char c = 0;
989         int nwritten;
990
991         /* It's a dead client - hold a funeral */
992
993         if (state == NULL) {
994                 return;
995         }
996
997         /*
998          * We need to remove a pending wb_req_read_*
999          * or wb_resp_write_* request before closing the
1000          * socket.
1001          *
1002          * This is important as they might have used tevent_add_fd() and we
1003          * use the epoll * backend on linux. So we must remove the tevent_fd
1004          * before closing the fd.
1005          *
1006          * Otherwise we might hit a race with close_conns_after_fork() (via
1007          * winbindd_reinit_after_fork()) where a file description
1008          * is still open in a child, which means it's still active in
1009          * the parents epoll queue, but the related tevent_fd is already
1010          * already gone in the parent.
1011          *
1012          * See bug #11141.
1013          */
1014         TALLOC_FREE(state->io_req);
1015
1016         if (state->sock != -1) {
1017                 /* tell client, we are closing ... */
1018                 nwritten = write(state->sock, &c, sizeof(c));
1019                 if (nwritten == -1) {
1020                         DEBUG(2, ("final write to client failed: %s\n",
1021                                 strerror(errno)));
1022                 }
1023
1024                 /* Close socket */
1025
1026                 close(state->sock);
1027                 state->sock = -1;
1028         }
1029
1030         TALLOC_FREE(state->mem_ctx);
1031
1032         /* Remove from list and free */
1033
1034         winbindd_remove_client(state);
1035         TALLOC_FREE(state);
1036 }
1037
1038 /* Is a client idle? */
1039
1040 static bool client_is_idle(struct winbindd_cli_state *state) {
1041   return (state->request == NULL &&
1042           state->response == NULL &&
1043           !state->pwent_state && !state->grent_state);
1044 }
1045
1046 /* Shutdown client connection which has been idle for the longest time */
1047
1048 static bool remove_idle_client(void)
1049 {
1050         struct winbindd_cli_state *state, *remove_state = NULL;
1051         int nidle = 0;
1052
1053         for (state = winbindd_client_list(); state; state = state->next) {
1054                 if (client_is_idle(state)) {
1055                         nidle++;
1056                         /* list is sorted by access time */
1057                         remove_state = state;
1058                 }
1059         }
1060
1061         if (remove_state) {
1062                 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1063                         nidle, remove_state->sock, (unsigned int)remove_state->pid));
1064                 remove_client(remove_state);
1065                 return True;
1066         }
1067
1068         return False;
1069 }
1070
1071 /*
1072  * Terminate all clients whose requests have taken longer than
1073  * "winbind request timeout" seconds to process, or have been
1074  * idle for more than "winbind request timeout" seconds.
1075  */
1076
1077 static void remove_timed_out_clients(void)
1078 {
1079         struct winbindd_cli_state *state, *prev = NULL;
1080         time_t curr_time = time(NULL);
1081         int timeout_val = lp_winbind_request_timeout();
1082
1083         for (state = winbindd_client_list_tail(); state; state = prev) {
1084                 time_t expiry_time;
1085
1086                 prev = winbindd_client_list_prev(state);
1087                 expiry_time = state->last_access + timeout_val;
1088
1089                 if (curr_time <= expiry_time) {
1090                         /* list is sorted, previous clients in
1091                            list are newer */
1092                         break;
1093                 }
1094
1095                 if (client_is_idle(state)) {
1096                         DEBUG(5,("Idle client timed out, "
1097                                  "shutting down sock %d, pid %u\n",
1098                                  state->sock,
1099                                  (unsigned int)state->pid));
1100                 } else {
1101                         DEBUG(5,("Client request timed out, "
1102                                  "shutting down sock %d, pid %u\n",
1103                                  state->sock,
1104                                  (unsigned int)state->pid));
1105                 }
1106
1107                 remove_client(state);
1108         }
1109 }
1110
1111 static void winbindd_scrub_clients_handler(struct tevent_context *ev,
1112                                            struct tevent_timer *te,
1113                                            struct timeval current_time,
1114                                            void *private_data)
1115 {
1116         remove_timed_out_clients();
1117         if (tevent_add_timer(ev, ev,
1118                              timeval_current_ofs(SCRUB_CLIENTS_INTERVAL, 0),
1119                              winbindd_scrub_clients_handler, NULL) == NULL) {
1120                 DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
1121                 exit(1);
1122         }
1123 }
1124
1125 struct winbindd_listen_state {
1126         bool privileged;
1127         int fd;
1128 };
1129
1130 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1131                                         struct tevent_fd *fde,
1132                                         uint16_t flags,
1133                                         void *private_data)
1134 {
1135         struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1136                                           struct winbindd_listen_state);
1137
1138         while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1139                 DEBUG(5,("winbindd: Exceeding %d client "
1140                          "connections, removing idle "
1141                          "connection.\n", lp_winbind_max_clients()));
1142                 if (!remove_idle_client()) {
1143                         DEBUG(0,("winbindd: Exceeding %d "
1144                                  "client connections, no idle "
1145                                  "connection found\n",
1146                                  lp_winbind_max_clients()));
1147                         break;
1148                 }
1149         }
1150         remove_timed_out_clients();
1151         new_connection(s->fd, s->privileged);
1152 }
1153
1154 /*
1155  * Winbindd socket accessor functions
1156  */
1157
1158 char *get_winbind_priv_pipe_dir(void)
1159 {
1160         return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1161 }
1162
1163 static void winbindd_setup_max_fds(void)
1164 {
1165         int num_fds = MAX_OPEN_FUDGEFACTOR;
1166         int actual_fds;
1167
1168         num_fds += lp_winbind_max_clients();
1169         /* Add some more to account for 2 sockets open
1170            when the client transitions from unprivileged
1171            to privileged socket
1172         */
1173         num_fds += lp_winbind_max_clients() / 10;
1174
1175         /* Add one socket per child process
1176            (yeah there are child processes other than the
1177            domain children but only domain children can vary
1178            with configuration
1179         */
1180         num_fds += lp_winbind_max_domain_connections() *
1181                    (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
1182
1183         actual_fds = set_maxfiles(num_fds);
1184
1185         if (actual_fds < num_fds) {
1186                 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1187                           "requested %d open files, %d are available.\n",
1188                           num_fds, actual_fds));
1189         }
1190 }
1191
1192 static bool winbindd_setup_listeners(void)
1193 {
1194         struct winbindd_listen_state *pub_state = NULL;
1195         struct winbindd_listen_state *priv_state = NULL;
1196         struct tevent_fd *fde;
1197         int rc;
1198         char *socket_path;
1199
1200         pub_state = talloc(server_event_context(),
1201                            struct winbindd_listen_state);
1202         if (!pub_state) {
1203                 goto failed;
1204         }
1205
1206         pub_state->privileged = false;
1207         pub_state->fd = create_pipe_sock(
1208                 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1209         if (pub_state->fd == -1) {
1210                 goto failed;
1211         }
1212         rc = listen(pub_state->fd, 5);
1213         if (rc < 0) {
1214                 goto failed;
1215         }
1216
1217         fde = tevent_add_fd(server_event_context(), pub_state, pub_state->fd,
1218                             TEVENT_FD_READ, winbindd_listen_fde_handler,
1219                             pub_state);
1220         if (fde == NULL) {
1221                 close(pub_state->fd);
1222                 goto failed;
1223         }
1224         tevent_fd_set_auto_close(fde);
1225
1226         priv_state = talloc(server_event_context(),
1227                             struct winbindd_listen_state);
1228         if (!priv_state) {
1229                 goto failed;
1230         }
1231
1232         socket_path = get_winbind_priv_pipe_dir();
1233         if (socket_path == NULL) {
1234                 goto failed;
1235         }
1236
1237         priv_state->privileged = true;
1238         priv_state->fd = create_pipe_sock(
1239                 socket_path, WINBINDD_SOCKET_NAME, 0750);
1240         TALLOC_FREE(socket_path);
1241         if (priv_state->fd == -1) {
1242                 goto failed;
1243         }
1244         rc = listen(priv_state->fd, 5);
1245         if (rc < 0) {
1246                 goto failed;
1247         }
1248
1249         fde = tevent_add_fd(server_event_context(), priv_state,
1250                             priv_state->fd, TEVENT_FD_READ,
1251                             winbindd_listen_fde_handler, priv_state);
1252         if (fde == NULL) {
1253                 close(priv_state->fd);
1254                 goto failed;
1255         }
1256         tevent_fd_set_auto_close(fde);
1257
1258         winbindd_scrub_clients_handler(server_event_context(), NULL,
1259                                        timeval_current(), NULL);
1260         return true;
1261 failed:
1262         TALLOC_FREE(pub_state);
1263         TALLOC_FREE(priv_state);
1264         return false;
1265 }
1266
1267 bool winbindd_use_idmap_cache(void)
1268 {
1269         return !opt_nocache;
1270 }
1271
1272 bool winbindd_use_cache(void)
1273 {
1274         return !opt_nocache;
1275 }
1276
1277 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1278                                        bool foreground)
1279 {
1280         NTSTATUS status;
1281         /* Setup signal handlers */
1282
1283         if (!winbindd_setup_sig_term_handler(true))
1284                 exit(1);
1285         if (!winbindd_setup_stdin_handler(true, foreground))
1286                 exit(1);
1287         if (!winbindd_setup_sig_hup_handler(NULL))
1288                 exit(1);
1289         if (!winbindd_setup_sig_chld_handler())
1290                 exit(1);
1291         if (!winbindd_setup_sig_usr2_handler())
1292                 exit(1);
1293
1294         CatchSignal(SIGPIPE, SIG_IGN);                 /* Ignore sigpipe */
1295
1296         /*
1297          * Ensure all cache and idmap caches are consistent
1298          * and initialized before we startup.
1299          */
1300         if (!winbindd_cache_validate_and_initialize()) {
1301                 exit(1);
1302         }
1303
1304         /* React on 'smbcontrol winbindd reload-config' in the same way
1305            as to SIGHUP signal */
1306         messaging_register(msg_ctx, NULL,
1307                            MSG_SMB_CONF_UPDATED, msg_reload_services);
1308         messaging_register(msg_ctx, NULL,
1309                            MSG_SHUTDOWN, msg_shutdown);
1310
1311         /* Handle online/offline messages. */
1312         messaging_register(msg_ctx, NULL,
1313                            MSG_WINBIND_OFFLINE, winbind_msg_offline);
1314         messaging_register(msg_ctx, NULL,
1315                            MSG_WINBIND_ONLINE, winbind_msg_online);
1316         messaging_register(msg_ctx, NULL,
1317                            MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1318
1319         /* Handle domain online/offline messages for domains */
1320         messaging_register(server_messaging_context(), NULL,
1321                            MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1322         messaging_register(server_messaging_context(), NULL,
1323                            MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1324
1325         messaging_register(msg_ctx, NULL,
1326                            MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
1327
1328         messaging_register(msg_ctx, NULL,
1329                            MSG_WINBIND_VALIDATE_CACHE,
1330                            winbind_msg_validate_cache);
1331
1332         messaging_register(msg_ctx, NULL,
1333                            MSG_WINBIND_DUMP_DOMAIN_LIST,
1334                            winbind_msg_dump_domain_list);
1335
1336         messaging_register(msg_ctx, NULL,
1337                            MSG_WINBIND_IP_DROPPED,
1338                            winbind_msg_ip_dropped_parent);
1339
1340         /* Register handler for MSG_DEBUG. */
1341         messaging_register(msg_ctx, NULL,
1342                            MSG_DEBUG,
1343                            winbind_msg_debug);
1344
1345         netsamlogon_cache_init(); /* Non-critical */
1346
1347         /* clear the cached list of trusted domains */
1348
1349         wcache_tdc_clear();
1350
1351         if (!init_domain_list()) {
1352                 DEBUG(0,("unable to initialize domain list\n"));
1353                 exit(1);
1354         }
1355
1356         init_idmap_child();
1357         init_locator_child();
1358
1359         smb_nscd_flush_user_cache();
1360         smb_nscd_flush_group_cache();
1361
1362         if (lp_allow_trusted_domains()) {
1363                 if (tevent_add_timer(server_event_context(), NULL, timeval_zero(),
1364                               rescan_trusted_domains, NULL) == NULL) {
1365                         DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1366                         exit(1);
1367                 }
1368         }
1369
1370         status = wb_irpc_register();
1371
1372         if (!NT_STATUS_IS_OK(status)) {
1373                 DEBUG(0, ("Could not register IRPC handlers\n"));
1374                 exit(1);
1375         }
1376 }
1377
1378 struct winbindd_addrchanged_state {
1379         struct addrchange_context *ctx;
1380         struct tevent_context *ev;
1381         struct messaging_context *msg_ctx;
1382 };
1383
1384 static void winbindd_addr_changed(struct tevent_req *req);
1385
1386 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1387                                      struct tevent_context *ev,
1388                                      struct messaging_context *msg_ctx)
1389 {
1390         struct winbindd_addrchanged_state *state;
1391         struct tevent_req *req;
1392         NTSTATUS status;
1393
1394         state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1395         if (state == NULL) {
1396                 DEBUG(10, ("talloc failed\n"));
1397                 return;
1398         }
1399         state->ev = ev;
1400         state->msg_ctx = msg_ctx;
1401
1402         status = addrchange_context_create(state, &state->ctx);
1403         if (!NT_STATUS_IS_OK(status)) {
1404                 DEBUG(10, ("addrchange_context_create failed: %s\n",
1405                            nt_errstr(status)));
1406                 TALLOC_FREE(state);
1407                 return;
1408         }
1409         req = addrchange_send(state, ev, state->ctx);
1410         if (req == NULL) {
1411                 DEBUG(0, ("addrchange_send failed\n"));
1412                 TALLOC_FREE(state);
1413                 return;
1414         }
1415         tevent_req_set_callback(req, winbindd_addr_changed, state);
1416 }
1417
1418 static void winbindd_addr_changed(struct tevent_req *req)
1419 {
1420         struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1421                 req, struct winbindd_addrchanged_state);
1422         enum addrchange_type type;
1423         struct sockaddr_storage addr;
1424         NTSTATUS status;
1425
1426         status = addrchange_recv(req, &type, &addr);
1427         TALLOC_FREE(req);
1428         if (!NT_STATUS_IS_OK(status)) {
1429                 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1430                            nt_errstr(status)));
1431                 TALLOC_FREE(state);
1432                 return;
1433         }
1434         if (type == ADDRCHANGE_DEL) {
1435                 char addrstr[INET6_ADDRSTRLEN];
1436                 DATA_BLOB blob;
1437
1438                 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1439
1440                 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1441                           addrstr));
1442
1443                 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1444
1445                 status = messaging_send(state->msg_ctx,
1446                                         messaging_server_id(state->msg_ctx),
1447                                         MSG_WINBIND_IP_DROPPED, &blob);
1448                 if (!NT_STATUS_IS_OK(status)) {
1449                         DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1450                                    nt_errstr(status)));
1451                 }
1452         }
1453         req = addrchange_send(state, state->ev, state->ctx);
1454         if (req == NULL) {
1455                 DEBUG(0, ("addrchange_send failed\n"));
1456                 TALLOC_FREE(state);
1457                 return;
1458         }
1459         tevent_req_set_callback(req, winbindd_addr_changed, state);
1460 }
1461
1462 /* Main function */
1463
1464 int main(int argc, const char **argv)
1465 {
1466         static bool is_daemon = False;
1467         static bool Fork = True;
1468         static bool log_stdout = False;
1469         static bool no_process_group = False;
1470         enum {
1471                 OPT_DAEMON = 1000,
1472                 OPT_FORK,
1473                 OPT_NO_PROCESS_GROUP,
1474                 OPT_LOG_STDOUT
1475         };
1476         struct poptOption long_options[] = {
1477                 POPT_AUTOHELP
1478                 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1479                 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1480                 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1481                 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1482                 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1483                 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1484                 POPT_COMMON_SAMBA
1485                 POPT_TABLEEND
1486         };
1487         poptContext pc;
1488         int opt;
1489         TALLOC_CTX *frame;
1490         NTSTATUS status;
1491         bool ok;
1492
1493         /*
1494          * Do this before any other talloc operation
1495          */
1496         talloc_enable_null_tracking();
1497         frame = talloc_stackframe();
1498
1499         /*
1500          * We want total control over the permissions on created files,
1501          * so set our umask to 0.
1502          */
1503         umask(0);
1504
1505         setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1506
1507         /* glibc (?) likes to print "User defined signal 1" and exit if a
1508            SIGUSR[12] is received before a handler is installed */
1509
1510         CatchSignal(SIGUSR1, SIG_IGN);
1511         CatchSignal(SIGUSR2, SIG_IGN);
1512
1513         fault_setup();
1514         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1515
1516         smb_init_locale();
1517
1518         /* Initialise for running in non-root mode */
1519
1520         sec_init();
1521
1522         set_remote_machine_name("winbindd", False);
1523
1524         /* Set environment variable so we don't recursively call ourselves.
1525            This may also be useful interactively. */
1526
1527         if ( !winbind_off() ) {
1528                 DEBUG(0,("Failed to disable recusive winbindd calls.  Exiting.\n"));
1529                 exit(1);
1530         }
1531
1532         /* Initialise samba/rpc client stuff */
1533
1534         pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1535
1536         while ((opt = poptGetNextOpt(pc)) != -1) {
1537                 switch (opt) {
1538                         /* Don't become a daemon */
1539                 case OPT_DAEMON:
1540                         is_daemon = True;
1541                         break;
1542                 case 'i':
1543                         interactive = True;
1544                         log_stdout = True;
1545                         Fork = False;
1546                         break;
1547                 case OPT_FORK:
1548                         Fork = false;
1549                         break;
1550                 case OPT_NO_PROCESS_GROUP:
1551                         no_process_group = true;
1552                         break;
1553                 case OPT_LOG_STDOUT:
1554                         log_stdout = true;
1555                         break;
1556                 case 'n':
1557                         opt_nocache = true;
1558                         break;
1559                 default:
1560                         d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1561                                   poptBadOption(pc, 0), poptStrerror(opt));
1562                         poptPrintUsage(pc, stderr, 0);
1563                         exit(1);
1564                 }
1565         }
1566
1567         /* We call dump_core_setup one more time because the command line can
1568          * set the log file or the log-basename and this will influence where
1569          * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1570          * the default value derived from build's prefix. For EOM this value
1571          * is often not related to the path where winbindd is actually run
1572          * in production.
1573          */
1574         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1575         if (is_daemon && interactive) {
1576                 d_fprintf(stderr,"\nERROR: "
1577                           "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1578                 poptPrintUsage(pc, stderr, 0);
1579                 exit(1);
1580         }
1581
1582         if (log_stdout && Fork) {
1583                 d_fprintf(stderr, "\nERROR: "
1584                           "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1585                 poptPrintUsage(pc, stderr, 0);
1586                 exit(1);
1587         }
1588
1589         poptFreeContext(pc);
1590
1591         if (!override_logfile) {
1592                 char *lfile = NULL;
1593                 if (asprintf(&lfile,"%s/log.winbindd",
1594                                 get_dyn_LOGFILEBASE()) > 0) {
1595                         lp_set_logfile(lfile);
1596                         SAFE_FREE(lfile);
1597                 }
1598         }
1599
1600         if (log_stdout) {
1601                 setup_logging("winbindd", DEBUG_STDOUT);
1602         } else {
1603                 setup_logging("winbindd", DEBUG_FILE);
1604         }
1605         reopen_logs();
1606
1607         DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1608         DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1609
1610         if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1611                 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1612                 exit(1);
1613         }
1614         /* After parsing the configuration file we setup the core path one more time
1615          * as the log file might have been set in the configuration and cores's
1616          * path is by default basename(lp_logfile()).
1617          */
1618         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1619
1620         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1621             && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1622                 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1623                 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"));
1624                 exit(1);
1625         }
1626
1627         if (!cluster_probe_ok()) {
1628                 exit(1);
1629         }
1630
1631         /* Initialise messaging system */
1632
1633         if (server_messaging_context() == NULL) {
1634                 exit(1);
1635         }
1636
1637         if (!reload_services_file(NULL)) {
1638                 DEBUG(0, ("error opening config file\n"));
1639                 exit(1);
1640         }
1641
1642         {
1643                 size_t i;
1644                 const char *idmap_backend;
1645                 const char *invalid_backends[] = {
1646                         "ad", "rfc2307", "rid",
1647                 };
1648
1649                 idmap_backend = lp_idmap_default_backend();
1650                 for (i = 0; i < ARRAY_SIZE(invalid_backends); i++) {
1651                         ok = strequal(idmap_backend, invalid_backends[i]);
1652                         if (ok) {
1653                                 DBG_ERR("FATAL: Invalid idmap backend %s "
1654                                         "configured as the default backend!\n",
1655                                         idmap_backend);
1656                                 exit(1);
1657                         }
1658                 }
1659         }
1660
1661         ok = directory_create_or_exist(lp_lock_directory(), 0755);
1662         if (!ok) {
1663                 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1664                           lp_lock_directory(), strerror(errno)));
1665                 exit(1);
1666         }
1667
1668         ok = directory_create_or_exist(lp_pid_directory(), 0755);
1669         if (!ok) {
1670                 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1671                           lp_pid_directory(), strerror(errno)));
1672                 exit(1);
1673         }
1674
1675         /* Setup names. */
1676
1677         if (!init_names())
1678                 exit(1);
1679
1680         load_interfaces();
1681
1682         if (!secrets_init()) {
1683
1684                 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1685                 return False;
1686         }
1687
1688         status = rpccli_pre_open_netlogon_creds();
1689         if (!NT_STATUS_IS_OK(status)) {
1690                 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1691                           nt_errstr(status)));
1692                 exit(1);
1693         }
1694
1695         /* Unblock all signals we are interested in as they may have been
1696            blocked by the parent process. */
1697
1698         BlockSignals(False, SIGINT);
1699         BlockSignals(False, SIGQUIT);
1700         BlockSignals(False, SIGTERM);
1701         BlockSignals(False, SIGUSR1);
1702         BlockSignals(False, SIGUSR2);
1703         BlockSignals(False, SIGHUP);
1704         BlockSignals(False, SIGCHLD);
1705
1706         if (!interactive)
1707                 become_daemon(Fork, no_process_group, log_stdout);
1708
1709         pidfile_create(lp_pid_directory(), "winbindd");
1710
1711 #if HAVE_SETPGID
1712         /*
1713          * If we're interactive we want to set our own process group for
1714          * signal management.
1715          */
1716         if (interactive && !no_process_group)
1717                 setpgid( (pid_t)0, (pid_t)0);
1718 #endif
1719
1720         TimeInit();
1721
1722         /* Don't use winbindd_reinit_after_fork here as
1723          * we're just starting up and haven't created any
1724          * winbindd-specific resources we must free yet. JRA.
1725          */
1726
1727         status = reinit_after_fork(server_messaging_context(),
1728                                    server_event_context(),
1729                                    false, NULL);
1730         if (!NT_STATUS_IS_OK(status)) {
1731                 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1732         }
1733
1734         /*
1735          * Do not initialize the parent-child-pipe before becoming
1736          * a daemon: this is used to detect a died parent in the child
1737          * process.
1738          */
1739         status = init_before_fork();
1740         if (!NT_STATUS_IS_OK(status)) {
1741                 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1742         }
1743
1744         winbindd_register_handlers(server_messaging_context(), !Fork);
1745
1746         if (!messaging_parent_dgm_cleanup_init(server_messaging_context())) {
1747                 exit(1);
1748         }
1749
1750         status = init_system_session_info();
1751         if (!NT_STATUS_IS_OK(status)) {
1752                 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1753         }
1754
1755         rpc_lsarpc_init(NULL);
1756         rpc_samr_init(NULL);
1757
1758         winbindd_init_addrchange(NULL, server_event_context(),
1759                                  server_messaging_context());
1760
1761         /* setup listen sockets */
1762
1763         if (!winbindd_setup_listeners()) {
1764                 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1765         }
1766
1767         irpc_add_name(winbind_imessaging_context(), "winbind_server");
1768
1769         TALLOC_FREE(frame);
1770
1771         if (!interactive) {
1772                 daemon_ready("winbindd");
1773         }
1774
1775         /* Loop waiting for requests */
1776         while (1) {
1777                 frame = talloc_stackframe();
1778
1779                 if (tevent_loop_once(server_event_context()) == -1) {
1780                         DEBUG(1, ("tevent_loop_once() failed: %s\n",
1781                                   strerror(errno)));
1782                         return 1;
1783                 }
1784
1785                 TALLOC_FREE(frame);
1786         }
1787
1788         return 0;
1789 }