smbd/winbindd: Do an early check if ctdbd is functional
[mat/samba.git] / source3 / winbindd / winbindd.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Winbind daemon for ntdom nss module
5
6    Copyright (C) by Tim Potter 2000-2002
7    Copyright (C) Andrew Tridgell 2002
8    Copyright (C) Jelmer Vernooij 2003
9    Copyright (C) Volker Lendecke 2004
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26 #include "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 "idmap.h"
35 #include "lib/addrchange.h"
36 #include "serverid.h"
37 #include "auth.h"
38 #include "messages.h"
39 #include "../lib/util/pidfile.h"
40 #include "ctdbd_conn.h"
41
42 #undef DBGC_CLASS
43 #define DBGC_CLASS DBGC_WINBIND
44
45 static bool client_is_idle(struct winbindd_cli_state *state);
46 static void remove_client(struct winbindd_cli_state *state);
47
48 static bool opt_nocache = False;
49 static bool interactive = False;
50
51 extern bool override_logfile;
52
53 struct tevent_context *winbind_event_context(void)
54 {
55         static struct tevent_context *ev = NULL;
56
57         if (ev != NULL) {
58                 return ev;
59         }
60
61         /*
62          * Note we MUST use the NULL context here, not the autofree context,
63          * to avoid side effects in forked children exiting.
64          */
65         ev = samba_tevent_context_init(NULL);
66         if (ev == NULL) {
67                 smb_panic("Could not init winbindd's messaging context.\n");
68         }
69         return ev;
70 }
71
72 struct messaging_context *winbind_messaging_context(void)
73 {
74         static struct messaging_context *msg = NULL;
75
76         if (msg != NULL) {
77                 return msg;
78         }
79
80         /*
81          * Note we MUST use the NULL context here, not the autofree context,
82          * to avoid side effects in forked children exiting.
83          */
84         msg = messaging_init(NULL, winbind_event_context());
85         if (msg == NULL) {
86                 smb_panic("Could not init winbindd's messaging context.\n");
87         }
88         return msg;
89 }
90
91 /* Reload configuration */
92
93 static bool reload_services_file(const char *lfile)
94 {
95         bool ret;
96
97         if (lp_loaded()) {
98                 char *fname = lp_configfile(talloc_tos());
99
100                 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
101                         set_dyn_CONFIGFILE(fname);
102                 }
103                 TALLOC_FREE(fname);
104         }
105
106         /* if this is a child, restore the logfile to the special
107            name - <domain>, idmap, etc. */
108         if (lfile && *lfile) {
109                 lp_set_logfile(lfile);
110         }
111
112         reopen_logs();
113         ret = lp_load_global(get_dyn_CONFIGFILE());
114
115         reopen_logs();
116         load_interfaces();
117
118         return(ret);
119 }
120
121
122 static void winbindd_status(void)
123 {
124         struct winbindd_cli_state *tmp;
125
126         DEBUG(0, ("winbindd status:\n"));
127
128         /* Print client state information */
129
130         DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
131
132         if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
133                 DEBUG(2, ("\tclient list:\n"));
134                 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
135                         DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
136                                      (unsigned long)tmp->pid, tmp->sock,
137                                      client_is_idle(tmp) ? "idle" : "active"));
138                 }
139         }
140 }
141
142 /* Flush client cache */
143
144 static void flush_caches(void)
145 {
146         /* We need to invalidate cached user list entries on a SIGHUP 
147            otherwise cached access denied errors due to restrict anonymous
148            hang around until the sequence number changes. */
149
150         if (!wcache_invalidate_cache()) {
151                 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
152                 if (!winbindd_cache_validate_and_initialize()) {
153                         exit(1);
154                 }
155         }
156 }
157
158 static void flush_caches_noinit(void)
159 {
160         /*
161          * We need to invalidate cached user list entries on a SIGHUP
162          * otherwise cached access denied errors due to restrict anonymous
163          * hang around until the sequence number changes.
164          * NB
165          * Skip uninitialized domains when flush cache.
166          * If domain is not initialized, it means it is never
167          * used or never become online. look, wcache_invalidate_cache()
168          * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
169          * for unused domains and large traffic for primay domain's DC if there
170          * are many domains..
171          */
172
173         if (!wcache_invalidate_cache_noinit()) {
174                 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
175                 if (!winbindd_cache_validate_and_initialize()) {
176                         exit(1);
177                 }
178         }
179 }
180
181 /* Handle the signal by unlinking socket and exiting */
182
183 static void terminate(bool is_parent)
184 {
185         if (is_parent) {
186                 /* When parent goes away we should
187                  * remove the socket file. Not so
188                  * when children terminate.
189                  */ 
190                 char *path = NULL;
191
192                 if (asprintf(&path, "%s/%s",
193                         lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) {
194                         unlink(path);
195                         SAFE_FREE(path);
196                 }
197         }
198
199         idmap_close();
200
201         trustdom_cache_shutdown();
202
203         gencache_stabilize();
204
205 #if 0
206         if (interactive) {
207                 TALLOC_CTX *mem_ctx = talloc_init("end_description");
208                 char *description = talloc_describe_all(mem_ctx);
209
210                 DEBUG(3, ("tallocs left:\n%s\n", description));
211                 talloc_destroy(mem_ctx);
212         }
213 #endif
214
215         if (is_parent) {
216                 struct messaging_context *msg = winbind_messaging_context();
217                 struct server_id self = messaging_server_id(msg);
218                 serverid_deregister(self);
219                 pidfile_unlink(lp_piddir(), "winbindd");
220         }
221
222         exit(0);
223 }
224
225 static void winbindd_sig_term_handler(struct tevent_context *ev,
226                                       struct tevent_signal *se,
227                                       int signum,
228                                       int count,
229                                       void *siginfo,
230                                       void *private_data)
231 {
232         bool *is_parent = talloc_get_type_abort(private_data, bool);
233
234         DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
235                  signum, (int)*is_parent));
236         terminate(*is_parent);
237 }
238
239 /*
240   handle stdin becoming readable when we are in --foreground mode
241  */
242 static void winbindd_stdin_handler(struct tevent_context *ev,
243                                struct tevent_fd *fde,
244                                uint16_t flags,
245                                void *private_data)
246 {
247         char c;
248         if (read(0, &c, 1) != 1) {
249                 bool *is_parent = talloc_get_type_abort(private_data, bool);
250
251                 /* we have reached EOF on stdin, which means the
252                    parent has exited. Shutdown the server */
253                 DEBUG(0,("EOF on stdin (is_parent=%d)\n",
254                          (int)*is_parent));
255                 terminate(*is_parent);
256         }
257 }
258
259 bool winbindd_setup_sig_term_handler(bool parent)
260 {
261         struct tevent_signal *se;
262         bool *is_parent;
263
264         is_parent = talloc(winbind_event_context(), bool);
265         if (!is_parent) {
266                 return false;
267         }
268
269         *is_parent = parent;
270
271         se = tevent_add_signal(winbind_event_context(),
272                                is_parent,
273                                SIGTERM, 0,
274                                winbindd_sig_term_handler,
275                                is_parent);
276         if (!se) {
277                 DEBUG(0,("failed to setup SIGTERM handler"));
278                 talloc_free(is_parent);
279                 return false;
280         }
281
282         se = tevent_add_signal(winbind_event_context(),
283                                is_parent,
284                                SIGINT, 0,
285                                winbindd_sig_term_handler,
286                                is_parent);
287         if (!se) {
288                 DEBUG(0,("failed to setup SIGINT handler"));
289                 talloc_free(is_parent);
290                 return false;
291         }
292
293         se = tevent_add_signal(winbind_event_context(),
294                                is_parent,
295                                SIGQUIT, 0,
296                                winbindd_sig_term_handler,
297                                is_parent);
298         if (!se) {
299                 DEBUG(0,("failed to setup SIGINT handler"));
300                 talloc_free(is_parent);
301                 return false;
302         }
303
304         return true;
305 }
306
307 bool winbindd_setup_stdin_handler(bool parent, bool foreground)
308 {
309         bool *is_parent;
310
311         if (foreground) {
312                 struct stat st;
313
314                 is_parent = talloc(winbind_event_context(), bool);
315                 if (!is_parent) {
316                         return false;
317                 }
318
319                 *is_parent = parent;
320
321                 /* if we are running in the foreground then look for
322                    EOF on stdin, and exit if it happens. This allows
323                    us to die if the parent process dies
324                    Only do this on a pipe or socket, no other device.
325                 */
326                 if (fstat(0, &st) != 0) {
327                         return false;
328                 }
329                 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
330                         tevent_add_fd(winbind_event_context(),
331                                         is_parent,
332                                         0,
333                                         TEVENT_FD_READ,
334                                         winbindd_stdin_handler,
335                                         is_parent);
336                 }
337         }
338
339         return true;
340 }
341
342 static void winbindd_sig_hup_handler(struct tevent_context *ev,
343                                      struct tevent_signal *se,
344                                      int signum,
345                                      int count,
346                                      void *siginfo,
347                                      void *private_data)
348 {
349         const char *file = (const char *)private_data;
350
351         DEBUG(1,("Reloading services after SIGHUP\n"));
352         flush_caches_noinit();
353         reload_services_file(file);
354 }
355
356 bool winbindd_setup_sig_hup_handler(const char *lfile)
357 {
358         struct tevent_signal *se;
359         char *file = NULL;
360
361         if (lfile) {
362                 file = talloc_strdup(winbind_event_context(),
363                                      lfile);
364                 if (!file) {
365                         return false;
366                 }
367         }
368
369         se = tevent_add_signal(winbind_event_context(),
370                                winbind_event_context(),
371                                SIGHUP, 0,
372                                winbindd_sig_hup_handler,
373                                file);
374         if (!se) {
375                 return false;
376         }
377
378         return true;
379 }
380
381 static void winbindd_sig_chld_handler(struct tevent_context *ev,
382                                       struct tevent_signal *se,
383                                       int signum,
384                                       int count,
385                                       void *siginfo,
386                                       void *private_data)
387 {
388         pid_t pid;
389
390         while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) {
391                 winbind_child_died(pid);
392         }
393 }
394
395 static bool winbindd_setup_sig_chld_handler(void)
396 {
397         struct tevent_signal *se;
398
399         se = tevent_add_signal(winbind_event_context(),
400                                winbind_event_context(),
401                                SIGCHLD, 0,
402                                winbindd_sig_chld_handler,
403                                NULL);
404         if (!se) {
405                 return false;
406         }
407
408         return true;
409 }
410
411 static void winbindd_sig_usr2_handler(struct tevent_context *ev,
412                                       struct tevent_signal *se,
413                                       int signum,
414                                       int count,
415                                       void *siginfo,
416                                       void *private_data)
417 {
418         winbindd_status();
419 }
420
421 static bool winbindd_setup_sig_usr2_handler(void)
422 {
423         struct tevent_signal *se;
424
425         se = tevent_add_signal(winbind_event_context(),
426                                winbind_event_context(),
427                                SIGUSR2, 0,
428                                winbindd_sig_usr2_handler,
429                                NULL);
430         if (!se) {
431                 return false;
432         }
433
434         return true;
435 }
436
437 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
438 static void msg_reload_services(struct messaging_context *msg,
439                                 void *private_data,
440                                 uint32_t msg_type,
441                                 struct server_id server_id,
442                                 DATA_BLOB *data)
443 {
444         /* Flush various caches */
445         flush_caches();
446         reload_services_file((const char *) private_data);
447 }
448
449 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
450 static void msg_shutdown(struct messaging_context *msg,
451                          void *private_data,
452                          uint32_t msg_type,
453                          struct server_id server_id,
454                          DATA_BLOB *data)
455 {
456         /* only the parent waits for this message */
457         DEBUG(0,("Got shutdown message\n"));
458         terminate(true);
459 }
460
461
462 static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
463                                        void *private_data,
464                                        uint32_t msg_type,
465                                        struct server_id server_id,
466                                        DATA_BLOB *data)
467 {
468         uint8 ret;
469         pid_t child_pid;
470         NTSTATUS status;
471
472         DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
473                    "message.\n"));
474
475         /*
476          * call the validation code from a child:
477          * so we don't block the main winbindd and the validation
478          * code can safely use fork/waitpid...
479          */
480         child_pid = fork();
481
482         if (child_pid == -1) {
483                 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
484                           strerror(errno)));
485                 return;
486         }
487
488         if (child_pid != 0) {
489                 /* parent */
490                 DEBUG(5, ("winbind_msg_validate_cache: child created with "
491                           "pid %d.\n", (int)child_pid));
492                 return;
493         }
494
495         /* child */
496
497         status = winbindd_reinit_after_fork(NULL, NULL);
498         if (!NT_STATUS_IS_OK(status)) {
499                 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
500                           nt_errstr(status)));
501                 _exit(0);
502         }
503
504         /* install default SIGCHLD handler: validation code uses fork/waitpid */
505         CatchSignal(SIGCHLD, SIG_DFL);
506
507         ret = (uint8)winbindd_validate_cache_nobackup();
508         DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
509         messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
510                            (size_t)1);
511         _exit(0);
512 }
513
514 static struct winbindd_dispatch_table {
515         enum winbindd_cmd cmd;
516         void (*fn)(struct winbindd_cli_state *state);
517         const char *winbindd_cmd_name;
518 } dispatch_table[] = {
519
520         /* Enumeration functions */
521
522         { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
523           "LIST_TRUSTDOM" },
524
525         /* Miscellaneous */
526
527         { WINBINDD_INFO, winbindd_info, "INFO" },
528         { WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
529           "INTERFACE_VERSION" },
530         { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
531         { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
532         { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" },
533         { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
534         { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
535           "WINBINDD_PRIV_PIPE_DIR" },
536
537         /* Credential cache access */
538         { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
539         { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
540
541         /* End of list */
542
543         { WINBINDD_NUM_CMDS, NULL, "NONE" }
544 };
545
546 struct winbindd_async_dispatch_table {
547         enum winbindd_cmd cmd;
548         const char *cmd_name;
549         struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
550                                        struct tevent_context *ev,
551                                        struct winbindd_cli_state *cli,
552                                        struct winbindd_request *request);
553         NTSTATUS (*recv_req)(struct tevent_req *req,
554                              struct winbindd_response *presp);
555 };
556
557 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
558         { WINBINDD_PING, "PING",
559           wb_ping_send, wb_ping_recv },
560         { WINBINDD_LOOKUPSID, "LOOKUPSID",
561           winbindd_lookupsid_send, winbindd_lookupsid_recv },
562         { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
563           winbindd_lookupsids_send, winbindd_lookupsids_recv },
564         { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
565           winbindd_lookupname_send, winbindd_lookupname_recv },
566         { WINBINDD_SID_TO_UID, "SID_TO_UID",
567           winbindd_sid_to_uid_send, winbindd_sid_to_uid_recv },
568         { WINBINDD_SID_TO_GID, "SID_TO_GID",
569           winbindd_sid_to_gid_send, winbindd_sid_to_gid_recv },
570         { WINBINDD_UID_TO_SID, "UID_TO_SID",
571           winbindd_uid_to_sid_send, winbindd_uid_to_sid_recv },
572         { WINBINDD_GID_TO_SID, "GID_TO_SID",
573           winbindd_gid_to_sid_send, winbindd_gid_to_sid_recv },
574         { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
575           winbindd_sids_to_xids_send, winbindd_sids_to_xids_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         state->last_access = time(NULL);
669
670         /* Process command */
671
672         for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
673                 if (state->request->cmd == atable->cmd) {
674                         break;
675                 }
676         }
677
678         if ((atable->send_req == NULL) && state->privileged) {
679                 for (atable = async_priv_table; atable->send_req;
680                      atable += 1) {
681                         if (state->request->cmd == atable->cmd) {
682                                 break;
683                         }
684                 }
685         }
686
687         if (atable->send_req != NULL) {
688                 struct tevent_req *req;
689
690                 state->cmd_name = atable->cmd_name;
691                 state->recv_fn = atable->recv_req;
692
693                 DEBUG(10, ("process_request: Handling async request %d:%s\n",
694                            (int)state->pid, state->cmd_name));
695
696                 req = atable->send_req(state->mem_ctx, winbind_event_context(),
697                                        state, state->request);
698                 if (req == NULL) {
699                         DEBUG(0, ("process_request: atable->send failed for "
700                                   "%s\n", atable->cmd_name));
701                         request_error(state);
702                         return;
703                 }
704                 tevent_req_set_callback(req, wb_request_done, state);
705                 return;
706         }
707
708         state->response = talloc_zero(state->mem_ctx,
709                                       struct winbindd_response);
710         if (state->response == NULL) {
711                 DEBUG(10, ("talloc failed\n"));
712                 remove_client(state);
713                 return;
714         }
715         state->response->result = WINBINDD_PENDING;
716         state->response->length = sizeof(struct winbindd_response);
717
718         for (table = dispatch_table; table->fn; table++) {
719                 if (state->request->cmd == table->cmd) {
720                         DEBUG(10,("process_request: request fn %s\n",
721                                   table->winbindd_cmd_name ));
722                         state->cmd_name = table->winbindd_cmd_name;
723                         table->fn(state);
724                         break;
725                 }
726         }
727
728         if (!table->fn) {
729                 DEBUG(10,("process_request: unknown request fn number %d\n",
730                           (int)state->request->cmd ));
731                 request_error(state);
732         }
733 }
734
735 static void wb_request_done(struct tevent_req *req)
736 {
737         struct winbindd_cli_state *state = tevent_req_callback_data(
738                 req, struct winbindd_cli_state);
739         NTSTATUS status;
740
741         state->response = talloc_zero(state->mem_ctx,
742                                       struct winbindd_response);
743         if (state->response == NULL) {
744                 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
745                           (int)state->pid, state->cmd_name));
746                 remove_client(state);
747                 return;
748         }
749         state->response->result = WINBINDD_PENDING;
750         state->response->length = sizeof(struct winbindd_response);
751
752         status = state->recv_fn(req, state->response);
753         TALLOC_FREE(req);
754
755         DEBUG(10,("wb_request_done[%d:%s]: %s\n",
756                   (int)state->pid, state->cmd_name, nt_errstr(status)));
757
758         if (!NT_STATUS_IS_OK(status)) {
759                 request_error(state);
760                 return;
761         }
762         request_ok(state);
763 }
764
765 /*
766  * This is the main event loop of winbind requests. It goes through a
767  * state-machine of 3 read/write requests, 4 if you have extra data to send.
768  *
769  * An idle winbind client has a read request of 4 bytes outstanding,
770  * finalizing function is request_len_recv, checking the length. request_recv
771  * then processes the packet. The processing function then at some point has
772  * to call request_finished which schedules sending the response.
773  */
774
775 static void request_finished(struct winbindd_cli_state *state);
776
777 static void winbind_client_request_read(struct tevent_req *req);
778 static void winbind_client_response_written(struct tevent_req *req);
779
780 static void request_finished(struct winbindd_cli_state *state)
781 {
782         struct tevent_req *req;
783
784         TALLOC_FREE(state->request);
785
786         req = wb_resp_write_send(state, winbind_event_context(),
787                                  state->out_queue, state->sock,
788                                  state->response);
789         if (req == NULL) {
790                 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
791                           (int)state->pid, state->cmd_name));
792                 remove_client(state);
793                 return;
794         }
795         tevent_req_set_callback(req, winbind_client_response_written, state);
796 }
797
798 static void winbind_client_response_written(struct tevent_req *req)
799 {
800         struct winbindd_cli_state *state = tevent_req_callback_data(
801                 req, struct winbindd_cli_state);
802         ssize_t ret;
803         int err;
804
805         ret = wb_resp_write_recv(req, &err);
806         TALLOC_FREE(req);
807         if (ret == -1) {
808                 close(state->sock);
809                 state->sock = -1;
810                 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
811                           (int)state->pid, state->cmd_name, strerror(err)));
812                 remove_client(state);
813                 return;
814         }
815
816         DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
817                   "to client\n", (int)state->pid, state->cmd_name));
818
819         TALLOC_FREE(state->mem_ctx);
820         state->response = NULL;
821         state->cmd_name = "no request";
822         state->recv_fn = NULL;
823
824         req = wb_req_read_send(state, winbind_event_context(), state->sock,
825                                WINBINDD_MAX_EXTRA_DATA);
826         if (req == NULL) {
827                 remove_client(state);
828                 return;
829         }
830         tevent_req_set_callback(req, winbind_client_request_read, state);
831 }
832
833 void request_error(struct winbindd_cli_state *state)
834 {
835         SMB_ASSERT(state->response->result == WINBINDD_PENDING);
836         state->response->result = WINBINDD_ERROR;
837         request_finished(state);
838 }
839
840 void request_ok(struct winbindd_cli_state *state)
841 {
842         SMB_ASSERT(state->response->result == WINBINDD_PENDING);
843         state->response->result = WINBINDD_OK;
844         request_finished(state);
845 }
846
847 /* Process a new connection by adding it to the client connection list */
848
849 static void new_connection(int listen_sock, bool privileged)
850 {
851         struct sockaddr_un sunaddr;
852         struct winbindd_cli_state *state;
853         struct tevent_req *req;
854         socklen_t len;
855         int sock;
856
857         /* Accept connection */
858
859         len = sizeof(sunaddr);
860
861         sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
862
863         if (sock == -1) {
864                 if (errno != EINTR) {
865                         DEBUG(0, ("Failed to accept socket - %s\n",
866                                   strerror(errno)));
867                 }
868                 return;
869         }
870
871         DEBUG(6,("accepted socket %d\n", sock));
872
873         /* Create new connection structure */
874
875         if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
876                 close(sock);
877                 return;
878         }
879
880         state->sock = sock;
881
882         state->out_queue = tevent_queue_create(state, "winbind client reply");
883         if (state->out_queue == NULL) {
884                 close(sock);
885                 TALLOC_FREE(state);
886                 return;
887         }
888
889         state->last_access = time(NULL);        
890
891         state->privileged = privileged;
892
893         req = wb_req_read_send(state, winbind_event_context(), state->sock,
894                                WINBINDD_MAX_EXTRA_DATA);
895         if (req == NULL) {
896                 TALLOC_FREE(state);
897                 close(sock);
898                 return;
899         }
900         tevent_req_set_callback(req, winbind_client_request_read, state);
901
902         /* Add to connection list */
903
904         winbindd_add_client(state);
905 }
906
907 static void winbind_client_request_read(struct tevent_req *req)
908 {
909         struct winbindd_cli_state *state = tevent_req_callback_data(
910                 req, struct winbindd_cli_state);
911         ssize_t ret;
912         int err;
913
914         ret = wb_req_read_recv(req, state, &state->request, &err);
915         TALLOC_FREE(req);
916         if (ret == -1) {
917                 if (err == EPIPE) {
918                         DEBUG(6, ("closing socket %d, client exited\n",
919                                   state->sock));
920                 } else {
921                         DEBUG(2, ("Could not read client request from fd %d: "
922                                   "%s\n", state->sock, strerror(err)));
923                 }
924                 close(state->sock);
925                 state->sock = -1;
926                 remove_client(state);
927                 return;
928         }
929         process_request(state);
930 }
931
932 /* Remove a client connection from client connection list */
933
934 static void remove_client(struct winbindd_cli_state *state)
935 {
936         char c = 0;
937         int nwritten;
938
939         /* It's a dead client - hold a funeral */
940
941         if (state == NULL) {
942                 return;
943         }
944
945         if (state->sock != -1) {
946                 /* tell client, we are closing ... */
947                 nwritten = write(state->sock, &c, sizeof(c));
948                 if (nwritten == -1) {
949                         DEBUG(2, ("final write to client failed: %s\n",
950                                 strerror(errno)));
951                 }
952
953                 /* Close socket */
954
955                 close(state->sock);
956                 state->sock = -1;
957         }
958
959         TALLOC_FREE(state->mem_ctx);
960
961         /* Remove from list and free */
962
963         winbindd_remove_client(state);
964         TALLOC_FREE(state);
965 }
966
967 /* Is a client idle? */
968
969 static bool client_is_idle(struct winbindd_cli_state *state) {
970   return (state->request == NULL &&
971           state->response == NULL &&
972           !state->pwent_state && !state->grent_state);
973 }
974
975 /* Shutdown client connection which has been idle for the longest time */
976
977 static bool remove_idle_client(void)
978 {
979         struct winbindd_cli_state *state, *remove_state = NULL;
980         time_t last_access = 0;
981         int nidle = 0;
982
983         for (state = winbindd_client_list(); state; state = state->next) {
984                 if (client_is_idle(state)) {
985                         nidle++;
986                         if (!last_access || state->last_access < last_access) {
987                                 last_access = state->last_access;
988                                 remove_state = state;
989                         }
990                 }
991         }
992
993         if (remove_state) {
994                 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
995                         nidle, remove_state->sock, (unsigned int)remove_state->pid));
996                 remove_client(remove_state);
997                 return True;
998         }
999
1000         return False;
1001 }
1002
1003 struct winbindd_listen_state {
1004         bool privileged;
1005         int fd;
1006 };
1007
1008 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1009                                         struct tevent_fd *fde,
1010                                         uint16_t flags,
1011                                         void *private_data)
1012 {
1013         struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1014                                           struct winbindd_listen_state);
1015
1016         while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1017                 DEBUG(5,("winbindd: Exceeding %d client "
1018                          "connections, removing idle "
1019                          "connection.\n", lp_winbind_max_clients()));
1020                 if (!remove_idle_client()) {
1021                         DEBUG(0,("winbindd: Exceeding %d "
1022                                  "client connections, no idle "
1023                                  "connection found\n",
1024                                  lp_winbind_max_clients()));
1025                         break;
1026                 }
1027         }
1028         new_connection(s->fd, s->privileged);
1029 }
1030
1031 /*
1032  * Winbindd socket accessor functions
1033  */
1034
1035 char *get_winbind_priv_pipe_dir(void)
1036 {
1037         return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1038 }
1039
1040 static bool winbindd_setup_listeners(void)
1041 {
1042         struct winbindd_listen_state *pub_state = NULL;
1043         struct winbindd_listen_state *priv_state = NULL;
1044         struct tevent_fd *fde;
1045         int rc;
1046
1047         pub_state = talloc(winbind_event_context(),
1048                            struct winbindd_listen_state);
1049         if (!pub_state) {
1050                 goto failed;
1051         }
1052
1053         pub_state->privileged = false;
1054         pub_state->fd = create_pipe_sock(
1055                 lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1056         if (pub_state->fd == -1) {
1057                 goto failed;
1058         }
1059         rc = listen(pub_state->fd, 5);
1060         if (rc < 0) {
1061                 goto failed;
1062         }
1063
1064         fde = tevent_add_fd(winbind_event_context(), pub_state, pub_state->fd,
1065                             TEVENT_FD_READ, winbindd_listen_fde_handler,
1066                             pub_state);
1067         if (fde == NULL) {
1068                 close(pub_state->fd);
1069                 goto failed;
1070         }
1071         tevent_fd_set_auto_close(fde);
1072
1073         priv_state = talloc(winbind_event_context(),
1074                             struct winbindd_listen_state);
1075         if (!priv_state) {
1076                 goto failed;
1077         }
1078
1079         priv_state->privileged = true;
1080         priv_state->fd = create_pipe_sock(
1081                 get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);
1082         if (priv_state->fd == -1) {
1083                 goto failed;
1084         }
1085         rc = listen(priv_state->fd, 5);
1086         if (rc < 0) {
1087                 goto failed;
1088         }
1089
1090         fde = tevent_add_fd(winbind_event_context(), priv_state,
1091                             priv_state->fd, TEVENT_FD_READ,
1092                             winbindd_listen_fde_handler, priv_state);
1093         if (fde == NULL) {
1094                 close(priv_state->fd);
1095                 goto failed;
1096         }
1097         tevent_fd_set_auto_close(fde);
1098
1099         return true;
1100 failed:
1101         TALLOC_FREE(pub_state);
1102         TALLOC_FREE(priv_state);
1103         return false;
1104 }
1105
1106 bool winbindd_use_idmap_cache(void)
1107 {
1108         return !opt_nocache;
1109 }
1110
1111 bool winbindd_use_cache(void)
1112 {
1113         return !opt_nocache;
1114 }
1115
1116 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1117                                        bool foreground)
1118 {
1119         /* Setup signal handlers */
1120
1121         if (!winbindd_setup_sig_term_handler(true))
1122                 exit(1);
1123         if (!winbindd_setup_stdin_handler(true, foreground))
1124                 exit(1);
1125         if (!winbindd_setup_sig_hup_handler(NULL))
1126                 exit(1);
1127         if (!winbindd_setup_sig_chld_handler())
1128                 exit(1);
1129         if (!winbindd_setup_sig_usr2_handler())
1130                 exit(1);
1131
1132         CatchSignal(SIGPIPE, SIG_IGN);                 /* Ignore sigpipe */
1133
1134         /*
1135          * Ensure all cache and idmap caches are consistent
1136          * and initialized before we startup.
1137          */
1138         if (!winbindd_cache_validate_and_initialize()) {
1139                 exit(1);
1140         }
1141
1142         /* get broadcast messages */
1143
1144         if (!serverid_register(messaging_server_id(msg_ctx),
1145                                FLAG_MSG_GENERAL |
1146                                FLAG_MSG_WINBIND |
1147                                FLAG_MSG_DBWRAP)) {
1148                 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
1149                 exit(1);
1150         }
1151
1152         /* React on 'smbcontrol winbindd reload-config' in the same way
1153            as to SIGHUP signal */
1154         messaging_register(msg_ctx, NULL,
1155                            MSG_SMB_CONF_UPDATED, msg_reload_services);
1156         messaging_register(msg_ctx, NULL,
1157                            MSG_SHUTDOWN, msg_shutdown);
1158
1159         /* Handle online/offline messages. */
1160         messaging_register(msg_ctx, NULL,
1161                            MSG_WINBIND_OFFLINE, winbind_msg_offline);
1162         messaging_register(msg_ctx, NULL,
1163                            MSG_WINBIND_ONLINE, winbind_msg_online);
1164         messaging_register(msg_ctx, NULL,
1165                            MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1166
1167         /* Handle domain online/offline messages for domains */
1168         messaging_register(winbind_messaging_context(), NULL,
1169                            MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1170         messaging_register(winbind_messaging_context(), NULL,
1171                            MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1172
1173         messaging_register(msg_ctx, NULL,
1174                            MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
1175
1176         messaging_register(msg_ctx, NULL,
1177                            MSG_WINBIND_VALIDATE_CACHE,
1178                            winbind_msg_validate_cache);
1179
1180         messaging_register(msg_ctx, NULL,
1181                            MSG_WINBIND_DUMP_DOMAIN_LIST,
1182                            winbind_msg_dump_domain_list);
1183
1184         messaging_register(msg_ctx, NULL,
1185                            MSG_WINBIND_IP_DROPPED,
1186                            winbind_msg_ip_dropped_parent);
1187
1188         /* Register handler for MSG_DEBUG. */
1189         messaging_register(msg_ctx, NULL,
1190                            MSG_DEBUG,
1191                            winbind_msg_debug);
1192
1193         netsamlogon_cache_init(); /* Non-critical */
1194
1195         /* clear the cached list of trusted domains */
1196
1197         wcache_tdc_clear();
1198
1199         if (!init_domain_list()) {
1200                 DEBUG(0,("unable to initialize domain list\n"));
1201                 exit(1);
1202         }
1203
1204         init_idmap_child();
1205         init_locator_child();
1206
1207         smb_nscd_flush_user_cache();
1208         smb_nscd_flush_group_cache();
1209
1210         if (lp_allow_trusted_domains()) {
1211                 if (tevent_add_timer(winbind_event_context(), NULL, timeval_zero(),
1212                               rescan_trusted_domains, NULL) == NULL) {
1213                         DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1214                         exit(1);
1215                 }
1216         }
1217
1218 }
1219
1220 struct winbindd_addrchanged_state {
1221         struct addrchange_context *ctx;
1222         struct tevent_context *ev;
1223         struct messaging_context *msg_ctx;
1224 };
1225
1226 static void winbindd_addr_changed(struct tevent_req *req);
1227
1228 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1229                                      struct tevent_context *ev,
1230                                      struct messaging_context *msg_ctx)
1231 {
1232         struct winbindd_addrchanged_state *state;
1233         struct tevent_req *req;
1234         NTSTATUS status;
1235
1236         state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1237         if (state == NULL) {
1238                 DEBUG(10, ("talloc failed\n"));
1239                 return;
1240         }
1241         state->ev = ev;
1242         state->msg_ctx = msg_ctx;
1243
1244         status = addrchange_context_create(state, &state->ctx);
1245         if (!NT_STATUS_IS_OK(status)) {
1246                 DEBUG(10, ("addrchange_context_create failed: %s\n",
1247                            nt_errstr(status)));
1248                 TALLOC_FREE(state);
1249                 return;
1250         }
1251         req = addrchange_send(state, ev, state->ctx);
1252         if (req == NULL) {
1253                 DEBUG(0, ("addrchange_send failed\n"));
1254                 TALLOC_FREE(state);
1255                 return;
1256         }
1257         tevent_req_set_callback(req, winbindd_addr_changed, state);
1258 }
1259
1260 static void winbindd_addr_changed(struct tevent_req *req)
1261 {
1262         struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1263                 req, struct winbindd_addrchanged_state);
1264         enum addrchange_type type;
1265         struct sockaddr_storage addr;
1266         NTSTATUS status;
1267
1268         status = addrchange_recv(req, &type, &addr);
1269         TALLOC_FREE(req);
1270         if (!NT_STATUS_IS_OK(status)) {
1271                 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1272                            nt_errstr(status)));
1273                 TALLOC_FREE(state);
1274                 return;
1275         }
1276         if (type == ADDRCHANGE_DEL) {
1277                 char addrstr[INET6_ADDRSTRLEN];
1278                 DATA_BLOB blob;
1279
1280                 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1281
1282                 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1283                           addrstr));
1284
1285                 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1286
1287                 status = messaging_send(state->msg_ctx,
1288                                         messaging_server_id(state->msg_ctx),
1289                                         MSG_WINBIND_IP_DROPPED, &blob);
1290                 if (!NT_STATUS_IS_OK(status)) {
1291                         DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1292                                    nt_errstr(status)));
1293                 }
1294         }
1295         req = addrchange_send(state, state->ev, state->ctx);
1296         if (req == NULL) {
1297                 DEBUG(0, ("addrchange_send failed\n"));
1298                 TALLOC_FREE(state);
1299                 return;
1300         }
1301         tevent_req_set_callback(req, winbindd_addr_changed, state);
1302 }
1303
1304 /* Main function */
1305
1306 int main(int argc, char **argv, char **envp)
1307 {
1308         static bool is_daemon = False;
1309         static bool Fork = True;
1310         static bool log_stdout = False;
1311         static bool no_process_group = False;
1312         enum {
1313                 OPT_DAEMON = 1000,
1314                 OPT_FORK,
1315                 OPT_NO_PROCESS_GROUP,
1316                 OPT_LOG_STDOUT
1317         };
1318         struct poptOption long_options[] = {
1319                 POPT_AUTOHELP
1320                 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1321                 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1322                 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1323                 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1324                 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1325                 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1326                 POPT_COMMON_SAMBA
1327                 POPT_TABLEEND
1328         };
1329         poptContext pc;
1330         int opt;
1331         TALLOC_CTX *frame;
1332         NTSTATUS status;
1333         bool ok;
1334
1335         /*
1336          * Do this before any other talloc operation
1337          */
1338         talloc_enable_null_tracking();
1339         frame = talloc_stackframe();
1340
1341         /*
1342          * We want total control over the permissions on created files,
1343          * so set our umask to 0.
1344          */
1345         umask(0);
1346
1347         setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1348
1349         /* glibc (?) likes to print "User defined signal 1" and exit if a
1350            SIGUSR[12] is received before a handler is installed */
1351
1352         CatchSignal(SIGUSR1, SIG_IGN);
1353         CatchSignal(SIGUSR2, SIG_IGN);
1354
1355         fault_setup();
1356         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1357
1358         load_case_tables();
1359
1360         /* Initialise for running in non-root mode */
1361
1362         sec_init();
1363
1364         set_remote_machine_name("winbindd", False);
1365
1366         /* Set environment variable so we don't recursively call ourselves.
1367            This may also be useful interactively. */
1368
1369         if ( !winbind_off() ) {
1370                 DEBUG(0,("Failed to disable recusive winbindd calls.  Exiting.\n"));
1371                 exit(1);
1372         }
1373
1374         /* Initialise samba/rpc client stuff */
1375
1376         pc = poptGetContext("winbindd", argc, (const char **)argv, long_options, 0);
1377
1378         while ((opt = poptGetNextOpt(pc)) != -1) {
1379                 switch (opt) {
1380                         /* Don't become a daemon */
1381                 case OPT_DAEMON:
1382                         is_daemon = True;
1383                         break;
1384                 case 'i':
1385                         interactive = True;
1386                         log_stdout = True;
1387                         Fork = False;
1388                         break;
1389                 case OPT_FORK:
1390                         Fork = false;
1391                         break;
1392                 case OPT_NO_PROCESS_GROUP:
1393                         no_process_group = true;
1394                         break;
1395                 case OPT_LOG_STDOUT:
1396                         log_stdout = true;
1397                         break;
1398                 case 'n':
1399                         opt_nocache = true;
1400                         break;
1401                 default:
1402                         d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1403                                   poptBadOption(pc, 0), poptStrerror(opt));
1404                         poptPrintUsage(pc, stderr, 0);
1405                         exit(1);
1406                 }
1407         }
1408
1409         /* We call dump_core_setup one more time because the command line can
1410          * set the log file or the log-basename and this will influence where
1411          * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1412          * the default value derived from build's prefix. For EOM this value
1413          * is often not related to the path where winbindd is actually run
1414          * in production.
1415          */
1416         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1417         if (is_daemon && interactive) {
1418                 d_fprintf(stderr,"\nERROR: "
1419                           "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1420                 poptPrintUsage(pc, stderr, 0);
1421                 exit(1);
1422         }
1423
1424         if (log_stdout && Fork) {
1425                 d_fprintf(stderr, "\nERROR: "
1426                           "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1427                 poptPrintUsage(pc, stderr, 0);
1428                 exit(1);
1429         }
1430
1431         poptFreeContext(pc);
1432
1433         if (!override_logfile) {
1434                 char *lfile = NULL;
1435                 if (asprintf(&lfile,"%s/log.winbindd",
1436                                 get_dyn_LOGFILEBASE()) > 0) {
1437                         lp_set_logfile(lfile);
1438                         SAFE_FREE(lfile);
1439                 }
1440         }
1441
1442         if (log_stdout) {
1443                 setup_logging("winbindd", DEBUG_STDOUT);
1444         } else {
1445                 setup_logging("winbindd", DEBUG_FILE);
1446         }
1447         reopen_logs();
1448
1449         DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1450         DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1451
1452         if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1453                 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1454                 exit(1);
1455         }
1456         /* After parsing the configuration file we setup the core path one more time
1457          * as the log file might have been set in the configuration and cores's
1458          * path is by default basename(lp_logfile()).
1459          */
1460         dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1461
1462         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
1463                 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1464                 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"));
1465                 exit(1);
1466         }
1467
1468         if (lp_clustering()) {
1469                 NTSTATUS status;
1470
1471                 status = ctdbd_probe();
1472                 if (!NT_STATUS_IS_OK(status)) {
1473                         DEBUG(0, ("clustering=yes but ctdbd connect failed: "
1474                                   "%s\n", nt_errstr(status)));
1475                         exit(1);
1476                 }
1477         }
1478
1479         /* Initialise messaging system */
1480
1481         if (winbind_messaging_context() == NULL) {
1482                 exit(1);
1483         }
1484
1485         if (!reload_services_file(NULL)) {
1486                 DEBUG(0, ("error opening config file\n"));
1487                 exit(1);
1488         }
1489
1490         ok = directory_create_or_exist(lp_lockdir(), geteuid(), 0755);
1491         if (!ok) {
1492                 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1493                           lp_lockdir(), strerror(errno)));
1494                 exit(1);
1495         }
1496
1497         ok = directory_create_or_exist(lp_piddir(), geteuid(), 0755);
1498         if (!ok) {
1499                 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1500                           lp_piddir(), strerror(errno)));
1501                 exit(1);
1502         }
1503
1504         /* Setup names. */
1505
1506         if (!init_names())
1507                 exit(1);
1508
1509         load_interfaces();
1510
1511         if (!secrets_init()) {
1512
1513                 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1514                 return False;
1515         }
1516
1517         /* Unblock all signals we are interested in as they may have been
1518            blocked by the parent process. */
1519
1520         BlockSignals(False, SIGINT);
1521         BlockSignals(False, SIGQUIT);
1522         BlockSignals(False, SIGTERM);
1523         BlockSignals(False, SIGUSR1);
1524         BlockSignals(False, SIGUSR2);
1525         BlockSignals(False, SIGHUP);
1526         BlockSignals(False, SIGCHLD);
1527
1528         if (!interactive)
1529                 become_daemon(Fork, no_process_group, log_stdout);
1530
1531         pidfile_create(lp_piddir(), "winbindd");
1532
1533 #if HAVE_SETPGID
1534         /*
1535          * If we're interactive we want to set our own process group for
1536          * signal management.
1537          */
1538         if (interactive && !no_process_group)
1539                 setpgid( (pid_t)0, (pid_t)0);
1540 #endif
1541
1542         TimeInit();
1543
1544         /* Don't use winbindd_reinit_after_fork here as
1545          * we're just starting up and haven't created any
1546          * winbindd-specific resources we must free yet. JRA.
1547          */
1548
1549         status = reinit_after_fork(winbind_messaging_context(),
1550                                    winbind_event_context(),
1551                                    false);
1552         if (!NT_STATUS_IS_OK(status)) {
1553                 DEBUG(0,("reinit_after_fork() failed\n"));
1554                 exit(1);
1555         }
1556
1557         /*
1558          * Do not initialize the parent-child-pipe before becoming
1559          * a daemon: this is used to detect a died parent in the child
1560          * process.
1561          */
1562         status = init_before_fork();
1563         if (!NT_STATUS_IS_OK(status)) {
1564                 DEBUG(0, ("init_before_fork failed: %s\n", nt_errstr(status)));
1565                 exit(1);
1566         }
1567
1568         winbindd_register_handlers(winbind_messaging_context(), !Fork);
1569
1570         status = init_system_session_info();
1571         if (!NT_STATUS_IS_OK(status)) {
1572                 DEBUG(1, ("ERROR: failed to setup system user info: %s.\n",
1573                           nt_errstr(status)));
1574                 exit(1);
1575         }
1576
1577         rpc_lsarpc_init(NULL);
1578         rpc_samr_init(NULL);
1579
1580         winbindd_init_addrchange(NULL, winbind_event_context(),
1581                                  winbind_messaging_context());
1582
1583         /* setup listen sockets */
1584
1585         if (!winbindd_setup_listeners()) {
1586                 DEBUG(0,("winbindd_setup_listeners() failed\n"));
1587                 exit(1);
1588         }
1589
1590         TALLOC_FREE(frame);
1591         /* Loop waiting for requests */
1592         while (1) {
1593                 frame = talloc_stackframe();
1594
1595                 if (tevent_loop_once(winbind_event_context()) == -1) {
1596                         DEBUG(1, ("tevent_loop_once() failed: %s\n",
1597                                   strerror(errno)));
1598                         return 1;
1599                 }
1600
1601                 TALLOC_FREE(frame);
1602         }
1603
1604         return 0;
1605 }