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