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