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