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