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