winbindd: verify that client has closed the connection
[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 #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                                  true);
977         if (req == NULL) {
978                 DEBUG(0, ("winbind_client_request_read[%d:%s]:"
979                           " wait_for_read_send failed - removing client\n",
980                           (int)state->pid, state->cmd_name));
981                 remove_client(state);
982                 return;
983         }
984         tevent_req_set_callback(req, winbind_client_activity, state);
985         state->io_req = req;
986
987         process_request(state);
988 }
989
990 static void winbind_client_activity(struct tevent_req *req)
991 {
992         struct winbindd_cli_state *state =
993             tevent_req_callback_data(req, struct winbindd_cli_state);
994         int err;
995         bool has_data;
996
997         has_data = wait_for_read_recv(req, &err);
998
999         if (has_data) {
1000                 DEBUG(0, ("winbind_client_activity[%d:%s]:"
1001                           "unexpected data from client - removing client\n",
1002                           (int)state->pid, state->cmd_name));
1003         } else {
1004                 if (err == EPIPE) {
1005                         DEBUG(6, ("winbind_client_activity[%d:%s]: "
1006                                   "client has closed connection - removing "
1007                                   "client\n",
1008                                   (int)state->pid, state->cmd_name));
1009                 } else {
1010                         DEBUG(2, ("winbind_client_activity[%d:%s]: "
1011                                   "client socket error (%s) - removing "
1012                                   "client\n",
1013                                   (int)state->pid, state->cmd_name,
1014                                   strerror(err)));
1015                 }
1016         }
1017
1018         remove_client(state);
1019 }
1020
1021 /* Remove a client connection from client connection list */
1022
1023 static void remove_client(struct winbindd_cli_state *state)
1024 {
1025         char c = 0;
1026         int nwritten;
1027
1028         /* It's a dead client - hold a funeral */
1029
1030         if (state == NULL) {
1031                 return;
1032         }
1033
1034         /*
1035          * We need to remove a pending wb_req_read_*
1036          * or wb_resp_write_* request before closing the
1037          * socket.
1038          *
1039          * This is important as they might have used tevent_add_fd() and we
1040          * use the epoll * backend on linux. So we must remove the tevent_fd
1041          * before closing the fd.
1042          *
1043          * Otherwise we might hit a race with close_conns_after_fork() (via
1044          * winbindd_reinit_after_fork()) where a file description
1045          * is still open in a child, which means it's still active in
1046          * the parents epoll queue, but the related tevent_fd is already
1047          * already gone in the parent.
1048          *
1049          * See bug #11141.
1050          */
1051         TALLOC_FREE(state->io_req);
1052
1053         if (state->sock != -1) {
1054                 /* tell client, we are closing ... */
1055                 nwritten = write(state->sock, &c, sizeof(c));
1056                 if (nwritten == -1) {
1057                         DEBUG(2, ("final write to client failed: %s\n",
1058                                 strerror(errno)));
1059                 }
1060
1061                 /* Close socket */
1062
1063                 close(state->sock);
1064                 state->sock = -1;
1065         }
1066
1067         TALLOC_FREE(state->mem_ctx);
1068
1069         /* Remove from list and free */
1070
1071         winbindd_remove_client(state);
1072         TALLOC_FREE(state);
1073 }
1074
1075 /* Is a client idle? */
1076
1077 static bool client_is_idle(struct winbindd_cli_state *state) {
1078   return (state->request == NULL &&
1079           state->response == NULL &&
1080           !state->pwent_state && !state->grent_state);
1081 }
1082
1083 /* Shutdown client connection which has been idle for the longest time */
1084
1085 static bool remove_idle_client(void)
1086 {
1087         struct winbindd_cli_state *state, *remove_state = NULL;
1088         time_t last_access = 0;
1089         int nidle = 0;
1090
1091         for (state = winbindd_client_list(); state; state = state->next) {
1092                 if (client_is_idle(state)) {
1093                         nidle++;
1094                         if (!last_access || state->last_access < last_access) {
1095                                 last_access = state->last_access;
1096                                 remove_state = state;
1097                         }
1098                 }
1099         }
1100
1101         if (remove_state) {
1102                 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1103                         nidle, remove_state->sock, (unsigned int)remove_state->pid));
1104                 remove_client(remove_state);
1105                 return True;
1106         }
1107
1108         return False;
1109 }
1110
1111 /*
1112  * Terminate all clients whose requests have taken longer than
1113  * "winbind request timeout" seconds to process, or have been
1114  * idle for more than "winbind request timeout" seconds.
1115  */
1116
1117 static void remove_timed_out_clients(void)
1118 {
1119         struct winbindd_cli_state *state, *next = NULL;
1120         time_t curr_time = time(NULL);
1121         int timeout_val = lp_winbind_request_timeout();
1122
1123         for (state = winbindd_client_list(); state; state = next) {
1124                 time_t expiry_time;
1125
1126                 next = state->next;
1127                 expiry_time = state->last_access + timeout_val;
1128
1129                 if (curr_time > expiry_time) {
1130                         if (client_is_idle(state)) {
1131                                 DEBUG(5,("Idle client timed out, "
1132                                         "shutting down sock %d, pid %u\n",
1133                                         state->sock,
1134                                         (unsigned int)state->pid));
1135                         } else {
1136                                 DEBUG(5,("Client request timed out, "
1137                                         "shutting down sock %d, pid %u\n",
1138                                         state->sock,
1139                                         (unsigned int)state->pid));
1140                         }
1141                         remove_client(state);
1142                 }
1143         }
1144 }
1145
1146 struct winbindd_listen_state {
1147         bool privileged;
1148         int fd;
1149 };
1150
1151 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1152                                         struct tevent_fd *fde,
1153                                         uint16_t flags,
1154                                         void *private_data)
1155 {
1156         struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1157                                           struct winbindd_listen_state);
1158
1159         while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1160                 DEBUG(5,("winbindd: Exceeding %d client "
1161                          "connections, removing idle "
1162                          "connection.\n", lp_winbind_max_clients()));
1163                 if (!remove_idle_client()) {
1164                         DEBUG(0,("winbindd: Exceeding %d "
1165                                  "client connections, no idle "
1166                                  "connection found\n",
1167                                  lp_winbind_max_clients()));
1168                         break;
1169                 }
1170         }
1171         remove_timed_out_clients();
1172         new_connection(s->fd, s->privileged);
1173 }
1174
1175 /*
1176  * Winbindd socket accessor functions
1177  */
1178
1179 char *get_winbind_priv_pipe_dir(void)
1180 {
1181         return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1182 }
1183
1184 static void winbindd_setup_max_fds(void)
1185 {
1186         int num_fds = MAX_OPEN_FUDGEFACTOR;
1187         int actual_fds;
1188
1189         num_fds += lp_winbind_max_clients();
1190         /* Add some more to account for 2 sockets open
1191            when the client transitions from unprivileged
1192            to privileged socket
1193         */
1194         num_fds += lp_winbind_max_clients() / 10;
1195
1196         /* Add one socket per child process
1197            (yeah there are child processes other than the
1198            domain children but only domain children can vary
1199            with configuration
1200         */
1201         num_fds += lp_winbind_max_domain_connections() *
1202                    (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
1203
1204         actual_fds = set_maxfiles(num_fds);
1205
1206         if (actual_fds < num_fds) {
1207                 DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1208                           "requested %d open files, %d are available.\n",
1209                           num_fds, actual_fds));
1210         }
1211 }
1212
1213 static bool winbindd_setup_listeners(void)
1214 {
1215         struct winbindd_listen_state *pub_state = NULL;
1216         struct winbindd_listen_state *priv_state = NULL;
1217         struct tevent_fd *fde;
1218         int rc;
1219         char *socket_path;
1220
1221         pub_state = talloc(winbind_event_context(),
1222                            struct winbindd_listen_state);
1223         if (!pub_state) {
1224                 goto failed;
1225         }
1226
1227         pub_state->privileged = false;
1228         pub_state->fd = create_pipe_sock(
1229                 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1230         if (pub_state->fd == -1) {
1231                 goto failed;
1232         }
1233         rc = listen(pub_state->fd, 5);
1234         if (rc < 0) {
1235                 goto failed;
1236         }
1237
1238         fde = tevent_add_fd(winbind_event_context(), pub_state, pub_state->fd,
1239                             TEVENT_FD_READ, winbindd_listen_fde_handler,
1240                             pub_state);
1241         if (fde == NULL) {
1242                 close(pub_state->fd);
1243                 goto failed;
1244         }
1245         tevent_fd_set_auto_close(fde);
1246
1247         priv_state = talloc(winbind_event_context(),
1248                             struct winbindd_listen_state);
1249         if (!priv_state) {
1250                 goto failed;
1251         }
1252
1253         socket_path = get_winbind_priv_pipe_dir();
1254         if (socket_path == NULL) {
1255                 goto failed;
1256         }
1257
1258         priv_state->privileged = true;
1259         priv_state->fd = create_pipe_sock(
1260                 socket_path, WINBINDD_SOCKET_NAME, 0750);
1261         TALLOC_FREE(socket_path);
1262         if (priv_state->fd == -1) {
1263                 goto failed;
1264         }
1265         rc = listen(priv_state->fd, 5);
1266         if (rc < 0) {
1267                 goto failed;
1268         }
1269
1270         fde = tevent_add_fd(winbind_event_context(), priv_state,
1271                             priv_state->fd, TEVENT_FD_READ,
1272                             winbindd_listen_fde_handler, priv_state);
1273         if (fde == NULL) {
1274                 close(priv_state->fd);
1275                 goto failed;
1276         }
1277         tevent_fd_set_auto_close(fde);
1278
1279         return true;
1280 failed:
1281         TALLOC_FREE(pub_state);
1282         TALLOC_FREE(priv_state);
1283         return false;
1284 }
1285
1286 bool winbindd_use_idmap_cache(void)
1287 {
1288         return !opt_nocache;
1289 }
1290
1291 bool winbindd_use_cache(void)
1292 {
1293         return !opt_nocache;
1294 }
1295
1296 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1297                                        bool foreground)
1298 {
1299         NTSTATUS status;
1300         /* Setup signal handlers */
1301
1302         if (!winbindd_setup_sig_term_handler(true))
1303                 exit(1);
1304         if (!winbindd_setup_stdin_handler(true, foreground))
1305                 exit(1);
1306         if (!winbindd_setup_sig_hup_handler(NULL))
1307                 exit(1);
1308         if (!winbindd_setup_sig_chld_handler())
1309                 exit(1);
1310         if (!winbindd_setup_sig_usr2_handler())
1311                 exit(1);
1312
1313         CatchSignal(SIGPIPE, SIG_IGN);                 /* Ignore sigpipe */
1314
1315         /*
1316          * Ensure all cache and idmap caches are consistent
1317          * and initialized before we startup.
1318          */
1319         if (!winbindd_cache_validate_and_initialize()) {
1320                 exit(1);
1321         }
1322
1323         /* get broadcast messages */
1324
1325         if (!serverid_register(messaging_server_id(msg_ctx),
1326                                FLAG_MSG_GENERAL |
1327                                FLAG_MSG_WINBIND |
1328                                FLAG_MSG_DBWRAP)) {
1329                 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
1330                 exit(1);
1331         }
1332
1333         /* React on 'smbcontrol winbindd reload-config' in the same way
1334            as to SIGHUP signal */
1335         messaging_register(msg_ctx, NULL,
1336                            MSG_SMB_CONF_UPDATED, msg_reload_services);
1337         messaging_register(msg_ctx, NULL,
1338                            MSG_SHUTDOWN, msg_shutdown);
1339
1340         /* Handle online/offline messages. */
1341         messaging_register(msg_ctx, NULL,
1342                            MSG_WINBIND_OFFLINE, winbind_msg_offline);
1343         messaging_register(msg_ctx, NULL,
1344                            MSG_WINBIND_ONLINE, winbind_msg_online);
1345         messaging_register(msg_ctx, NULL,
1346                            MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1347
1348         /* Handle domain online/offline messages for domains */
1349         messaging_register(winbind_messaging_context(), NULL,
1350                            MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1351         messaging_register(winbind_messaging_context(), NULL,
1352                            MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1353
1354         messaging_register(msg_ctx, NULL,
1355                            MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
1356
1357         messaging_register(msg_ctx, NULL,
1358                            MSG_WINBIND_VALIDATE_CACHE,
1359                            winbind_msg_validate_cache);
1360
1361         messaging_register(msg_ctx, NULL,
1362                            MSG_WINBIND_DUMP_DOMAIN_LIST,
1363                            winbind_msg_dump_domain_list);
1364
1365         messaging_register(msg_ctx, NULL,
1366                            MSG_WINBIND_IP_DROPPED,
1367                            winbind_msg_ip_dropped_parent);
1368
1369         /* Register handler for MSG_DEBUG. */
1370         messaging_register(msg_ctx, NULL,
1371                            MSG_DEBUG,
1372                            winbind_msg_debug);
1373
1374         netsamlogon_cache_init(); /* Non-critical */
1375
1376         /* clear the cached list of trusted domains */
1377
1378         wcache_tdc_clear();
1379
1380         if (!init_domain_list()) {
1381                 DEBUG(0,("unable to initialize domain list\n"));
1382                 exit(1);
1383         }
1384
1385         init_idmap_child();
1386         init_locator_child();
1387
1388         smb_nscd_flush_user_cache();
1389         smb_nscd_flush_group_cache();
1390
1391         if (lp_allow_trusted_domains()) {
1392                 if (tevent_add_timer(winbind_event_context(), NULL, timeval_zero(),
1393                               rescan_trusted_domains, NULL) == NULL) {
1394                         DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1395                         exit(1);
1396                 }
1397         }
1398
1399         status = wb_irpc_register();
1400
1401         if (!NT_STATUS_IS_OK(status)) {
1402                 DEBUG(0, ("Could not register IRPC handlers\n"));
1403                 exit(1);
1404         }
1405 }
1406
1407 struct winbindd_addrchanged_state {
1408         struct addrchange_context *ctx;
1409         struct tevent_context *ev;
1410         struct messaging_context *msg_ctx;
1411 };
1412
1413 static void winbindd_addr_changed(struct tevent_req *req);
1414
1415 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1416                                      struct tevent_context *ev,
1417                                      struct messaging_context *msg_ctx)
1418 {
1419         struct winbindd_addrchanged_state *state;
1420         struct tevent_req *req;
1421         NTSTATUS status;
1422
1423         state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1424         if (state == NULL) {
1425                 DEBUG(10, ("talloc failed\n"));
1426                 return;
1427         }
1428         state->ev = ev;
1429         state->msg_ctx = msg_ctx;
1430
1431         status = addrchange_context_create(state, &state->ctx);
1432         if (!NT_STATUS_IS_OK(status)) {
1433                 DEBUG(10, ("addrchange_context_create failed: %s\n",
1434                            nt_errstr(status)));
1435                 TALLOC_FREE(state);
1436                 return;
1437         }
1438         req = addrchange_send(state, ev, state->ctx);
1439         if (req == NULL) {
1440                 DEBUG(0, ("addrchange_send failed\n"));
1441                 TALLOC_FREE(state);
1442                 return;
1443         }
1444         tevent_req_set_callback(req, winbindd_addr_changed, state);
1445 }
1446
1447 static void winbindd_addr_changed(struct tevent_req *req)
1448 {
1449         struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1450                 req, struct winbindd_addrchanged_state);
1451         enum addrchange_type type;
1452         struct sockaddr_storage addr;
1453         NTSTATUS status;
1454
1455         status = addrchange_recv(req, &type, &addr);
1456         TALLOC_FREE(req);
1457         if (!NT_STATUS_IS_OK(status)) {
1458                 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1459                            nt_errstr(status)));
1460                 TALLOC_FREE(state);
1461                 return;
1462         }
1463         if (type == ADDRCHANGE_DEL) {
1464                 char addrstr[INET6_ADDRSTRLEN];
1465                 DATA_BLOB blob;
1466
1467                 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1468
1469                 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1470                           addrstr));
1471
1472                 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1473
1474                 status = messaging_send(state->msg_ctx,
1475                                         messaging_server_id(state->msg_ctx),
1476                                         MSG_WINBIND_IP_DROPPED, &blob);
1477                 if (!NT_STATUS_IS_OK(status)) {
1478                         DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1479                                    nt_errstr(status)));
1480                 }
1481         }
1482         req = addrchange_send(state, state->ev, state->ctx);
1483         if (req == NULL) {
1484                 DEBUG(0, ("addrchange_send failed\n"));
1485                 TALLOC_FREE(state);
1486                 return;
1487         }
1488         tevent_req_set_callback(req, winbindd_addr_changed, state);
1489 }
1490
1491 /* Main function */
1492
1493 int main(int argc, const char **argv)
1494 {
1495         static bool is_daemon = False;
1496         static bool Fork = True;
1497         static bool log_stdout = False;
1498         static bool no_process_group = False;
1499         enum {
1500                 OPT_DAEMON = 1000,
1501                 OPT_FORK,
1502                 OPT_NO_PROCESS_GROUP,
1503                 OPT_LOG_STDOUT
1504         };
1505         struct poptOption long_options[] = {
1506                 POPT_AUTOHELP
1507                 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1508                 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1509                 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1510                 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1511                 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1512                 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1513                 POPT_COMMON_SAMBA
1514                 POPT_TABLEEND
1515         };
1516         poptContext pc;
1517         int opt;
1518         TALLOC_CTX *frame;
1519         NTSTATUS status;
1520         bool ok;
1521
1522         /*
1523          * Do this before any other talloc operation
1524          */
1525         talloc_enable_null_tracking();
1526         frame = talloc_stackframe();
1527
1528         /*
1529          * We want total control over the permissions on created files,
1530          * so set our umask to 0.
1531          */
1532         umask(0);
1533
1534         setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1535
1536         /* glibc (?) likes to print "User defined signal 1" and exit if a
1537            SIGUSR[12] is received before a handler is installed */
1538
1539         CatchSignal(SIGUSR1, SIG_IGN);
1540         CatchSignal(SIGUSR2, SIG_IGN);
1541
1542         fault_setup();
1543         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1544
1545         smb_init_locale();
1546
1547         /* Initialise for running in non-root mode */
1548
1549         sec_init();
1550
1551         set_remote_machine_name("winbindd", False);
1552
1553         /* Set environment variable so we don't recursively call ourselves.
1554            This may also be useful interactively. */
1555
1556         if ( !winbind_off() ) {
1557                 DEBUG(0,("Failed to disable recusive winbindd calls.  Exiting.\n"));
1558                 exit(1);
1559         }
1560
1561         /* Initialise samba/rpc client stuff */
1562
1563         pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1564
1565         while ((opt = poptGetNextOpt(pc)) != -1) {
1566                 switch (opt) {
1567                         /* Don't become a daemon */
1568                 case OPT_DAEMON:
1569                         is_daemon = True;
1570                         break;
1571                 case 'i':
1572                         interactive = True;
1573                         log_stdout = True;
1574                         Fork = False;
1575                         break;
1576                 case OPT_FORK:
1577                         Fork = false;
1578                         break;
1579                 case OPT_NO_PROCESS_GROUP:
1580                         no_process_group = true;
1581                         break;
1582                 case OPT_LOG_STDOUT:
1583                         log_stdout = true;
1584                         break;
1585                 case 'n':
1586                         opt_nocache = true;
1587                         break;
1588                 default:
1589                         d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1590                                   poptBadOption(pc, 0), poptStrerror(opt));
1591                         poptPrintUsage(pc, stderr, 0);
1592                         exit(1);
1593                 }
1594         }
1595
1596         /* We call dump_core_setup one more time because the command line can
1597          * set the log file or the log-basename and this will influence where
1598          * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1599          * the default value derived from build's prefix. For EOM this value
1600          * is often not related to the path where winbindd is actually run
1601          * in production.
1602          */
1603         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1604         if (is_daemon && interactive) {
1605                 d_fprintf(stderr,"\nERROR: "
1606                           "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1607                 poptPrintUsage(pc, stderr, 0);
1608                 exit(1);
1609         }
1610
1611         if (log_stdout && Fork) {
1612                 d_fprintf(stderr, "\nERROR: "
1613                           "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1614                 poptPrintUsage(pc, stderr, 0);
1615                 exit(1);
1616         }
1617
1618         poptFreeContext(pc);
1619
1620         if (!override_logfile) {
1621                 char *lfile = NULL;
1622                 if (asprintf(&lfile,"%s/log.winbindd",
1623                                 get_dyn_LOGFILEBASE()) > 0) {
1624                         lp_set_logfile(lfile);
1625                         SAFE_FREE(lfile);
1626                 }
1627         }
1628
1629         if (log_stdout) {
1630                 setup_logging("winbindd", DEBUG_STDOUT);
1631         } else {
1632                 setup_logging("winbindd", DEBUG_FILE);
1633         }
1634         reopen_logs();
1635
1636         DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1637         DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1638
1639         if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1640                 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1641                 exit(1);
1642         }
1643         /* After parsing the configuration file we setup the core path one more time
1644          * as the log file might have been set in the configuration and cores's
1645          * path is by default basename(lp_logfile()).
1646          */
1647         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1648
1649         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1650             && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1651                 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1652                 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"));
1653                 exit(1);
1654         }
1655
1656         if (!cluster_probe_ok()) {
1657                 exit(1);
1658         }
1659
1660         /* Initialise messaging system */
1661
1662         if (winbind_messaging_context() == NULL) {
1663                 exit(1);
1664         }
1665
1666         if (!reload_services_file(NULL)) {
1667                 DEBUG(0, ("error opening config file\n"));
1668                 exit(1);
1669         }
1670
1671         ok = directory_create_or_exist(lp_lock_directory(), 0755);
1672         if (!ok) {
1673                 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1674                           lp_lock_directory(), strerror(errno)));
1675                 exit(1);
1676         }
1677
1678         ok = directory_create_or_exist(lp_pid_directory(), 0755);
1679         if (!ok) {
1680                 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1681                           lp_pid_directory(), strerror(errno)));
1682                 exit(1);
1683         }
1684
1685         /* Setup names. */
1686
1687         if (!init_names())
1688                 exit(1);
1689
1690         load_interfaces();
1691
1692         if (!secrets_init()) {
1693
1694                 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1695                 return False;
1696         }
1697
1698         status = rpccli_pre_open_netlogon_creds();
1699         if (!NT_STATUS_IS_OK(status)) {
1700                 DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1701                           nt_errstr(status)));
1702                 exit(1);
1703         }
1704
1705         /* Unblock all signals we are interested in as they may have been
1706            blocked by the parent process. */
1707
1708         BlockSignals(False, SIGINT);
1709         BlockSignals(False, SIGQUIT);
1710         BlockSignals(False, SIGTERM);
1711         BlockSignals(False, SIGUSR1);
1712         BlockSignals(False, SIGUSR2);
1713         BlockSignals(False, SIGHUP);
1714         BlockSignals(False, SIGCHLD);
1715
1716         if (!interactive)
1717                 become_daemon(Fork, no_process_group, log_stdout);
1718
1719         pidfile_create(lp_pid_directory(), "winbindd");
1720
1721 #if HAVE_SETPGID
1722         /*
1723          * If we're interactive we want to set our own process group for
1724          * signal management.
1725          */
1726         if (interactive && !no_process_group)
1727                 setpgid( (pid_t)0, (pid_t)0);
1728 #endif
1729
1730         TimeInit();
1731
1732         /* Don't use winbindd_reinit_after_fork here as
1733          * we're just starting up and haven't created any
1734          * winbindd-specific resources we must free yet. JRA.
1735          */
1736
1737         status = reinit_after_fork(winbind_messaging_context(),
1738                                    winbind_event_context(),
1739                                    false);
1740         if (!NT_STATUS_IS_OK(status)) {
1741                 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1742         }
1743
1744         /*
1745          * Do not initialize the parent-child-pipe before becoming
1746          * a daemon: this is used to detect a died parent in the child
1747          * process.
1748          */
1749         status = init_before_fork();
1750         if (!NT_STATUS_IS_OK(status)) {
1751                 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1752         }
1753
1754         winbindd_register_handlers(winbind_messaging_context(), !Fork);
1755
1756         if (!messaging_parent_dgm_cleanup_init(winbind_messaging_context())) {
1757                 exit(1);
1758         }
1759
1760         status = init_system_session_info();
1761         if (!NT_STATUS_IS_OK(status)) {
1762                 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1763         }
1764
1765         rpc_lsarpc_init(NULL);
1766         rpc_samr_init(NULL);
1767
1768         winbindd_init_addrchange(NULL, winbind_event_context(),
1769                                  winbind_messaging_context());
1770
1771         /* setup listen sockets */
1772
1773         if (!winbindd_setup_listeners()) {
1774                 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1775         }
1776
1777         irpc_add_name(winbind_imessaging_context(), "winbind_server");
1778
1779         TALLOC_FREE(frame);
1780
1781         if (!interactive) {
1782                 daemon_ready("winbindd");
1783         }
1784
1785         /* Loop waiting for requests */
1786         while (1) {
1787                 frame = talloc_stackframe();
1788
1789                 if (tevent_loop_once(winbind_event_context()) == -1) {
1790                         DEBUG(1, ("tevent_loop_once() failed: %s\n",
1791                                   strerror(errno)));
1792                         return 1;
1793                 }
1794
1795                 TALLOC_FREE(frame);
1796         }
1797
1798         return 0;
1799 }