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