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