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