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