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