s4:librpc/rpc: let dcerpc_ship_next_request() use DCERPC_AUTH_PAD_ALIGNMENT define
[Samba.git] / source3 / winbindd / winbindd.c
blob2c94f49cf19d106c8b4eedf60c76a4a8a958e6db
1 /*
2 Unix SMB/CIFS implementation.
4 Winbind daemon for ntdom nss module
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
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.
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.
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/>.
25 #include "includes.h"
26 #include "popt_common.h"
27 #include "winbindd.h"
28 #include "nsswitch/winbind_client.h"
29 #include "nsswitch/wb_reqtrans.h"
30 #include "ntdomain.h"
31 #include "../librpc/gen_ndr/srv_lsa.h"
32 #include "../librpc/gen_ndr/srv_samr.h"
33 #include "secrets.h"
34 #include "idmap.h"
35 #include "lib/addrchange.h"
36 #include "serverid.h"
37 #include "auth.h"
38 #include "messages.h"
39 #include "../lib/util/pidfile.h"
41 #undef DBGC_CLASS
42 #define DBGC_CLASS DBGC_WINBIND
44 static bool client_is_idle(struct winbindd_cli_state *state);
45 static void remove_client(struct winbindd_cli_state *state);
47 static bool opt_nocache = False;
48 static bool interactive = False;
50 extern bool override_logfile;
52 struct tevent_context *winbind_event_context(void)
54 static struct tevent_context *ev = NULL;
56 if (ev != NULL) {
57 return ev;
61 * Note we MUST use the NULL context here, not the autofree context,
62 * to avoid side effects in forked children exiting.
64 ev = samba_tevent_context_init(NULL);
65 if (ev == NULL) {
66 smb_panic("Could not init winbindd's messaging context.\n");
68 return ev;
71 struct messaging_context *winbind_messaging_context(void)
73 static struct messaging_context *msg = NULL;
75 if (msg != NULL) {
76 return msg;
80 * Note we MUST use the NULL context here, not the autofree context,
81 * to avoid side effects in forked children exiting.
83 msg = messaging_init(NULL, winbind_event_context());
84 if (msg == NULL) {
85 smb_panic("Could not init winbindd's messaging context.\n");
87 return msg;
90 /* Reload configuration */
92 static bool reload_services_file(const char *lfile)
94 bool ret;
96 if (lp_loaded()) {
97 char *fname = lp_configfile(talloc_tos());
99 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
100 set_dyn_CONFIGFILE(fname);
102 TALLOC_FREE(fname);
105 /* if this is a child, restore the logfile to the special
106 name - <domain>, idmap, etc. */
107 if (lfile && *lfile) {
108 lp_set_logfile(lfile);
111 reopen_logs();
112 ret = lp_load_global(get_dyn_CONFIGFILE());
114 reopen_logs();
115 load_interfaces();
117 return(ret);
121 static void winbindd_status(void)
123 struct winbindd_cli_state *tmp;
125 DEBUG(0, ("winbindd status:\n"));
127 /* Print client state information */
129 DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
131 if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
132 DEBUG(2, ("\tclient list:\n"));
133 for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
134 DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
135 (unsigned long)tmp->pid, tmp->sock,
136 client_is_idle(tmp) ? "idle" : "active"));
141 /* Flush client cache */
143 static void flush_caches(void)
145 /* We need to invalidate cached user list entries on a SIGHUP
146 otherwise cached access denied errors due to restrict anonymous
147 hang around until the sequence number changes. */
149 if (!wcache_invalidate_cache()) {
150 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
151 if (!winbindd_cache_validate_and_initialize()) {
152 exit(1);
157 static void flush_caches_noinit(void)
160 * We need to invalidate cached user list entries on a SIGHUP
161 * otherwise cached access denied errors due to restrict anonymous
162 * hang around until the sequence number changes.
163 * NB
164 * Skip uninitialized domains when flush cache.
165 * If domain is not initialized, it means it is never
166 * used or never become online. look, wcache_invalidate_cache()
167 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
168 * for unused domains and large traffic for primay domain's DC if there
169 * are many domains..
172 if (!wcache_invalidate_cache_noinit()) {
173 DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
174 if (!winbindd_cache_validate_and_initialize()) {
175 exit(1);
180 /* Handle the signal by unlinking socket and exiting */
182 static void terminate(bool is_parent)
184 if (is_parent) {
185 /* When parent goes away we should
186 * remove the socket file. Not so
187 * when children terminate.
189 char *path = NULL;
191 if (asprintf(&path, "%s/%s",
192 get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME) > 0) {
193 unlink(path);
194 SAFE_FREE(path);
198 idmap_close();
200 trustdom_cache_shutdown();
202 gencache_stabilize();
204 #if 0
205 if (interactive) {
206 TALLOC_CTX *mem_ctx = talloc_init("end_description");
207 char *description = talloc_describe_all(mem_ctx);
209 DEBUG(3, ("tallocs left:\n%s\n", description));
210 talloc_destroy(mem_ctx);
212 #endif
214 if (is_parent) {
215 struct messaging_context *msg = winbind_messaging_context();
216 struct server_id self = messaging_server_id(msg);
217 serverid_deregister(self);
218 pidfile_unlink(lp_piddir(), "winbindd");
221 exit(0);
224 static void winbindd_sig_term_handler(struct tevent_context *ev,
225 struct tevent_signal *se,
226 int signum,
227 int count,
228 void *siginfo,
229 void *private_data)
231 bool *is_parent = talloc_get_type_abort(private_data, bool);
233 DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
234 signum, (int)*is_parent));
235 terminate(*is_parent);
239 handle stdin becoming readable when we are in --foreground mode
241 static void winbindd_stdin_handler(struct tevent_context *ev,
242 struct tevent_fd *fde,
243 uint16_t flags,
244 void *private_data)
246 char c;
247 if (read(0, &c, 1) != 1) {
248 bool *is_parent = talloc_get_type_abort(private_data, bool);
250 /* we have reached EOF on stdin, which means the
251 parent has exited. Shutdown the server */
252 DEBUG(0,("EOF on stdin (is_parent=%d)\n",
253 (int)*is_parent));
254 terminate(*is_parent);
258 bool winbindd_setup_sig_term_handler(bool parent)
260 struct tevent_signal *se;
261 bool *is_parent;
263 is_parent = talloc(winbind_event_context(), bool);
264 if (!is_parent) {
265 return false;
268 *is_parent = parent;
270 se = tevent_add_signal(winbind_event_context(),
271 is_parent,
272 SIGTERM, 0,
273 winbindd_sig_term_handler,
274 is_parent);
275 if (!se) {
276 DEBUG(0,("failed to setup SIGTERM handler"));
277 talloc_free(is_parent);
278 return false;
281 se = tevent_add_signal(winbind_event_context(),
282 is_parent,
283 SIGINT, 0,
284 winbindd_sig_term_handler,
285 is_parent);
286 if (!se) {
287 DEBUG(0,("failed to setup SIGINT handler"));
288 talloc_free(is_parent);
289 return false;
292 se = tevent_add_signal(winbind_event_context(),
293 is_parent,
294 SIGQUIT, 0,
295 winbindd_sig_term_handler,
296 is_parent);
297 if (!se) {
298 DEBUG(0,("failed to setup SIGINT handler"));
299 talloc_free(is_parent);
300 return false;
303 return true;
306 bool winbindd_setup_stdin_handler(bool parent, bool foreground)
308 bool *is_parent;
310 if (foreground) {
311 struct stat st;
313 is_parent = talloc(winbind_event_context(), bool);
314 if (!is_parent) {
315 return false;
318 *is_parent = parent;
320 /* if we are running in the foreground then look for
321 EOF on stdin, and exit if it happens. This allows
322 us to die if the parent process dies
323 Only do this on a pipe or socket, no other device.
325 if (fstat(0, &st) != 0) {
326 return false;
328 if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
329 tevent_add_fd(winbind_event_context(),
330 is_parent,
332 TEVENT_FD_READ,
333 winbindd_stdin_handler,
334 is_parent);
338 return true;
341 static void winbindd_sig_hup_handler(struct tevent_context *ev,
342 struct tevent_signal *se,
343 int signum,
344 int count,
345 void *siginfo,
346 void *private_data)
348 const char *file = (const char *)private_data;
350 DEBUG(1,("Reloading services after SIGHUP\n"));
351 flush_caches_noinit();
352 reload_services_file(file);
355 bool winbindd_setup_sig_hup_handler(const char *lfile)
357 struct tevent_signal *se;
358 char *file = NULL;
360 if (lfile) {
361 file = talloc_strdup(winbind_event_context(),
362 lfile);
363 if (!file) {
364 return false;
368 se = tevent_add_signal(winbind_event_context(),
369 winbind_event_context(),
370 SIGHUP, 0,
371 winbindd_sig_hup_handler,
372 file);
373 if (!se) {
374 return false;
377 return true;
380 static void winbindd_sig_chld_handler(struct tevent_context *ev,
381 struct tevent_signal *se,
382 int signum,
383 int count,
384 void *siginfo,
385 void *private_data)
387 pid_t pid;
389 while ((pid = sys_waitpid(-1, NULL, WNOHANG)) > 0) {
390 winbind_child_died(pid);
394 static bool winbindd_setup_sig_chld_handler(void)
396 struct tevent_signal *se;
398 se = tevent_add_signal(winbind_event_context(),
399 winbind_event_context(),
400 SIGCHLD, 0,
401 winbindd_sig_chld_handler,
402 NULL);
403 if (!se) {
404 return false;
407 return true;
410 static void winbindd_sig_usr2_handler(struct tevent_context *ev,
411 struct tevent_signal *se,
412 int signum,
413 int count,
414 void *siginfo,
415 void *private_data)
417 winbindd_status();
420 static bool winbindd_setup_sig_usr2_handler(void)
422 struct tevent_signal *se;
424 se = tevent_add_signal(winbind_event_context(),
425 winbind_event_context(),
426 SIGUSR2, 0,
427 winbindd_sig_usr2_handler,
428 NULL);
429 if (!se) {
430 return false;
433 return true;
436 /* React on 'smbcontrol winbindd reload-config' in the same way as on SIGHUP*/
437 static void msg_reload_services(struct messaging_context *msg,
438 void *private_data,
439 uint32_t msg_type,
440 struct server_id server_id,
441 DATA_BLOB *data)
443 /* Flush various caches */
444 flush_caches();
445 reload_services_file((const char *) private_data);
448 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
449 static void msg_shutdown(struct messaging_context *msg,
450 void *private_data,
451 uint32_t msg_type,
452 struct server_id server_id,
453 DATA_BLOB *data)
455 /* only the parent waits for this message */
456 DEBUG(0,("Got shutdown message\n"));
457 terminate(true);
461 static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
462 void *private_data,
463 uint32_t msg_type,
464 struct server_id server_id,
465 DATA_BLOB *data)
467 uint8 ret;
468 pid_t child_pid;
469 NTSTATUS status;
471 DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
472 "message.\n"));
475 * call the validation code from a child:
476 * so we don't block the main winbindd and the validation
477 * code can safely use fork/waitpid...
479 child_pid = fork();
481 if (child_pid == -1) {
482 DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
483 strerror(errno)));
484 return;
487 if (child_pid != 0) {
488 /* parent */
489 DEBUG(5, ("winbind_msg_validate_cache: child created with "
490 "pid %d.\n", (int)child_pid));
491 return;
494 /* child */
496 status = winbindd_reinit_after_fork(NULL, NULL);
497 if (!NT_STATUS_IS_OK(status)) {
498 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
499 nt_errstr(status)));
500 _exit(0);
503 /* install default SIGCHLD handler: validation code uses fork/waitpid */
504 CatchSignal(SIGCHLD, SIG_DFL);
506 ret = (uint8)winbindd_validate_cache_nobackup();
507 DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
508 messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
509 (size_t)1);
510 _exit(0);
513 static struct winbindd_dispatch_table {
514 enum winbindd_cmd cmd;
515 void (*fn)(struct winbindd_cli_state *state);
516 const char *winbindd_cmd_name;
517 } dispatch_table[] = {
519 /* Enumeration functions */
521 { WINBINDD_LIST_TRUSTDOM, winbindd_list_trusted_domains,
522 "LIST_TRUSTDOM" },
524 /* Miscellaneous */
526 { WINBINDD_INFO, winbindd_info, "INFO" },
527 { WINBINDD_INTERFACE_VERSION, winbindd_interface_version,
528 "INTERFACE_VERSION" },
529 { WINBINDD_DOMAIN_NAME, winbindd_domain_name, "DOMAIN_NAME" },
530 { WINBINDD_DOMAIN_INFO, winbindd_domain_info, "DOMAIN_INFO" },
531 { WINBINDD_DC_INFO, winbindd_dc_info, "DC_INFO" },
532 { WINBINDD_NETBIOS_NAME, winbindd_netbios_name, "NETBIOS_NAME" },
533 { WINBINDD_PRIV_PIPE_DIR, winbindd_priv_pipe_dir,
534 "WINBINDD_PRIV_PIPE_DIR" },
536 /* Credential cache access */
537 { WINBINDD_CCACHE_NTLMAUTH, winbindd_ccache_ntlm_auth, "NTLMAUTH" },
538 { WINBINDD_CCACHE_SAVE, winbindd_ccache_save, "CCACHE_SAVE" },
540 /* End of list */
542 { WINBINDD_NUM_CMDS, NULL, "NONE" }
545 struct winbindd_async_dispatch_table {
546 enum winbindd_cmd cmd;
547 const char *cmd_name;
548 struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
549 struct tevent_context *ev,
550 struct winbindd_cli_state *cli,
551 struct winbindd_request *request);
552 NTSTATUS (*recv_req)(struct tevent_req *req,
553 struct winbindd_response *presp);
556 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
557 { WINBINDD_PING, "PING",
558 wb_ping_send, wb_ping_recv },
559 { WINBINDD_LOOKUPSID, "LOOKUPSID",
560 winbindd_lookupsid_send, winbindd_lookupsid_recv },
561 { WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
562 winbindd_lookupsids_send, winbindd_lookupsids_recv },
563 { WINBINDD_LOOKUPNAME, "LOOKUPNAME",
564 winbindd_lookupname_send, winbindd_lookupname_recv },
565 { WINBINDD_SID_TO_UID, "SID_TO_UID",
566 winbindd_sid_to_uid_send, winbindd_sid_to_uid_recv },
567 { WINBINDD_SID_TO_GID, "SID_TO_GID",
568 winbindd_sid_to_gid_send, winbindd_sid_to_gid_recv },
569 { WINBINDD_UID_TO_SID, "UID_TO_SID",
570 winbindd_uid_to_sid_send, winbindd_uid_to_sid_recv },
571 { WINBINDD_GID_TO_SID, "GID_TO_SID",
572 winbindd_gid_to_sid_send, winbindd_gid_to_sid_recv },
573 { WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
574 winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
575 { WINBINDD_GETPWSID, "GETPWSID",
576 winbindd_getpwsid_send, winbindd_getpwsid_recv },
577 { WINBINDD_GETPWNAM, "GETPWNAM",
578 winbindd_getpwnam_send, winbindd_getpwnam_recv },
579 { WINBINDD_GETPWUID, "GETPWUID",
580 winbindd_getpwuid_send, winbindd_getpwuid_recv },
581 { WINBINDD_GETSIDALIASES, "GETSIDALIASES",
582 winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
583 { WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
584 winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
585 { WINBINDD_GETGROUPS, "GETGROUPS",
586 winbindd_getgroups_send, winbindd_getgroups_recv },
587 { WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
588 winbindd_show_sequence_send, winbindd_show_sequence_recv },
589 { WINBINDD_GETGRGID, "GETGRGID",
590 winbindd_getgrgid_send, winbindd_getgrgid_recv },
591 { WINBINDD_GETGRNAM, "GETGRNAM",
592 winbindd_getgrnam_send, winbindd_getgrnam_recv },
593 { WINBINDD_GETUSERSIDS, "GETUSERSIDS",
594 winbindd_getusersids_send, winbindd_getusersids_recv },
595 { WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
596 winbindd_lookuprids_send, winbindd_lookuprids_recv },
597 { WINBINDD_SETPWENT, "SETPWENT",
598 winbindd_setpwent_send, winbindd_setpwent_recv },
599 { WINBINDD_GETPWENT, "GETPWENT",
600 winbindd_getpwent_send, winbindd_getpwent_recv },
601 { WINBINDD_ENDPWENT, "ENDPWENT",
602 winbindd_endpwent_send, winbindd_endpwent_recv },
603 { WINBINDD_DSGETDCNAME, "DSGETDCNAME",
604 winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
605 { WINBINDD_GETDCNAME, "GETDCNAME",
606 winbindd_getdcname_send, winbindd_getdcname_recv },
607 { WINBINDD_SETGRENT, "SETGRENT",
608 winbindd_setgrent_send, winbindd_setgrent_recv },
609 { WINBINDD_GETGRENT, "GETGRENT",
610 winbindd_getgrent_send, winbindd_getgrent_recv },
611 { WINBINDD_ENDGRENT, "ENDGRENT",
612 winbindd_endgrent_send, winbindd_endgrent_recv },
613 { WINBINDD_LIST_USERS, "LIST_USERS",
614 winbindd_list_users_send, winbindd_list_users_recv },
615 { WINBINDD_LIST_GROUPS, "LIST_GROUPS",
616 winbindd_list_groups_send, winbindd_list_groups_recv },
617 { WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
618 winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
619 { WINBINDD_PING_DC, "PING_DC",
620 winbindd_ping_dc_send, winbindd_ping_dc_recv },
621 { WINBINDD_PAM_AUTH, "PAM_AUTH",
622 winbindd_pam_auth_send, winbindd_pam_auth_recv },
623 { WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
624 winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
625 { WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
626 winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
627 { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
628 winbindd_pam_chng_pswd_auth_crap_send,
629 winbindd_pam_chng_pswd_auth_crap_recv },
630 { WINBINDD_WINS_BYIP, "WINS_BYIP",
631 winbindd_wins_byip_send, winbindd_wins_byip_recv },
632 { WINBINDD_WINS_BYNAME, "WINS_BYNAME",
633 winbindd_wins_byname_send, winbindd_wins_byname_recv },
635 { 0, NULL, NULL, NULL }
638 static struct winbindd_async_dispatch_table async_priv_table[] = {
639 { WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
640 winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
641 { WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
642 winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
643 { WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
644 winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
645 { WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
646 winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
648 { 0, NULL, NULL, NULL }
651 static void wb_request_done(struct tevent_req *req);
653 static void process_request(struct winbindd_cli_state *state)
655 struct winbindd_dispatch_table *table = dispatch_table;
656 struct winbindd_async_dispatch_table *atable;
658 state->mem_ctx = talloc_named(state, 0, "winbind request");
659 if (state->mem_ctx == NULL)
660 return;
662 /* Remember who asked us. */
663 state->pid = state->request->pid;
665 state->cmd_name = "unknown request";
666 state->recv_fn = NULL;
667 state->last_access = time(NULL);
669 /* Process command */
671 for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
672 if (state->request->cmd == atable->cmd) {
673 break;
677 if ((atable->send_req == NULL) && state->privileged) {
678 for (atable = async_priv_table; atable->send_req;
679 atable += 1) {
680 if (state->request->cmd == atable->cmd) {
681 break;
686 if (atable->send_req != NULL) {
687 struct tevent_req *req;
689 state->cmd_name = atable->cmd_name;
690 state->recv_fn = atable->recv_req;
692 DEBUG(10, ("process_request: Handling async request %d:%s\n",
693 (int)state->pid, state->cmd_name));
695 req = atable->send_req(state->mem_ctx, winbind_event_context(),
696 state, state->request);
697 if (req == NULL) {
698 DEBUG(0, ("process_request: atable->send failed for "
699 "%s\n", atable->cmd_name));
700 request_error(state);
701 return;
703 tevent_req_set_callback(req, wb_request_done, state);
704 return;
707 state->response = talloc_zero(state->mem_ctx,
708 struct winbindd_response);
709 if (state->response == NULL) {
710 DEBUG(10, ("talloc failed\n"));
711 remove_client(state);
712 return;
714 state->response->result = WINBINDD_PENDING;
715 state->response->length = sizeof(struct winbindd_response);
717 for (table = dispatch_table; table->fn; table++) {
718 if (state->request->cmd == table->cmd) {
719 DEBUG(10,("process_request: request fn %s\n",
720 table->winbindd_cmd_name ));
721 state->cmd_name = table->winbindd_cmd_name;
722 table->fn(state);
723 break;
727 if (!table->fn) {
728 DEBUG(10,("process_request: unknown request fn number %d\n",
729 (int)state->request->cmd ));
730 request_error(state);
734 static void wb_request_done(struct tevent_req *req)
736 struct winbindd_cli_state *state = tevent_req_callback_data(
737 req, struct winbindd_cli_state);
738 NTSTATUS status;
740 state->response = talloc_zero(state->mem_ctx,
741 struct winbindd_response);
742 if (state->response == NULL) {
743 DEBUG(0, ("wb_request_done[%d:%s]: talloc_zero failed - removing client\n",
744 (int)state->pid, state->cmd_name));
745 remove_client(state);
746 return;
748 state->response->result = WINBINDD_PENDING;
749 state->response->length = sizeof(struct winbindd_response);
751 status = state->recv_fn(req, state->response);
752 TALLOC_FREE(req);
754 DEBUG(10,("wb_request_done[%d:%s]: %s\n",
755 (int)state->pid, state->cmd_name, nt_errstr(status)));
757 if (!NT_STATUS_IS_OK(status)) {
758 request_error(state);
759 return;
761 request_ok(state);
765 * This is the main event loop of winbind requests. It goes through a
766 * state-machine of 3 read/write requests, 4 if you have extra data to send.
768 * An idle winbind client has a read request of 4 bytes outstanding,
769 * finalizing function is request_len_recv, checking the length. request_recv
770 * then processes the packet. The processing function then at some point has
771 * to call request_finished which schedules sending the response.
774 static void request_finished(struct winbindd_cli_state *state);
776 static void winbind_client_request_read(struct tevent_req *req);
777 static void winbind_client_response_written(struct tevent_req *req);
779 static void request_finished(struct winbindd_cli_state *state)
781 struct tevent_req *req;
783 TALLOC_FREE(state->request);
785 req = wb_resp_write_send(state, winbind_event_context(),
786 state->out_queue, state->sock,
787 state->response);
788 if (req == NULL) {
789 DEBUG(10,("request_finished[%d:%s]: wb_resp_write_send() failed\n",
790 (int)state->pid, state->cmd_name));
791 remove_client(state);
792 return;
794 tevent_req_set_callback(req, winbind_client_response_written, state);
795 state->io_req = req;
798 static void winbind_client_response_written(struct tevent_req *req)
800 struct winbindd_cli_state *state = tevent_req_callback_data(
801 req, struct winbindd_cli_state);
802 ssize_t ret;
803 int err;
805 state->io_req = NULL;
807 ret = wb_resp_write_recv(req, &err);
808 TALLOC_FREE(req);
809 if (ret == -1) {
810 close(state->sock);
811 state->sock = -1;
812 DEBUG(2, ("Could not write response[%d:%s] to client: %s\n",
813 (int)state->pid, state->cmd_name, strerror(err)));
814 remove_client(state);
815 return;
818 DEBUG(10,("winbind_client_response_written[%d:%s]: delivered response "
819 "to client\n", (int)state->pid, state->cmd_name));
821 TALLOC_FREE(state->mem_ctx);
822 state->response = NULL;
823 state->cmd_name = "no request";
824 state->recv_fn = NULL;
826 req = wb_req_read_send(state, winbind_event_context(), state->sock,
827 WINBINDD_MAX_EXTRA_DATA);
828 if (req == NULL) {
829 remove_client(state);
830 return;
832 tevent_req_set_callback(req, winbind_client_request_read, state);
833 state->io_req = req;
836 void request_error(struct winbindd_cli_state *state)
838 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
839 state->response->result = WINBINDD_ERROR;
840 request_finished(state);
843 void request_ok(struct winbindd_cli_state *state)
845 SMB_ASSERT(state->response->result == WINBINDD_PENDING);
846 state->response->result = WINBINDD_OK;
847 request_finished(state);
850 /* Process a new connection by adding it to the client connection list */
852 static void new_connection(int listen_sock, bool privileged)
854 struct sockaddr_un sunaddr;
855 struct winbindd_cli_state *state;
856 struct tevent_req *req;
857 socklen_t len;
858 int sock;
860 /* Accept connection */
862 len = sizeof(sunaddr);
864 sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
866 if (sock == -1) {
867 if (errno != EINTR) {
868 DEBUG(0, ("Failed to accept socket - %s\n",
869 strerror(errno)));
871 return;
874 DEBUG(6,("accepted socket %d\n", sock));
876 /* Create new connection structure */
878 if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
879 close(sock);
880 return;
883 state->sock = sock;
885 state->out_queue = tevent_queue_create(state, "winbind client reply");
886 if (state->out_queue == NULL) {
887 close(sock);
888 TALLOC_FREE(state);
889 return;
892 state->last_access = time(NULL);
894 state->privileged = privileged;
896 req = wb_req_read_send(state, winbind_event_context(), state->sock,
897 WINBINDD_MAX_EXTRA_DATA);
898 if (req == NULL) {
899 TALLOC_FREE(state);
900 close(sock);
901 return;
903 tevent_req_set_callback(req, winbind_client_request_read, state);
904 state->io_req = req;
906 /* Add to connection list */
908 winbindd_add_client(state);
911 static void winbind_client_request_read(struct tevent_req *req)
913 struct winbindd_cli_state *state = tevent_req_callback_data(
914 req, struct winbindd_cli_state);
915 ssize_t ret;
916 int err;
918 state->io_req = NULL;
920 ret = wb_req_read_recv(req, state, &state->request, &err);
921 TALLOC_FREE(req);
922 if (ret == -1) {
923 if (err == EPIPE) {
924 DEBUG(6, ("closing socket %d, client exited\n",
925 state->sock));
926 } else {
927 DEBUG(2, ("Could not read client request from fd %d: "
928 "%s\n", state->sock, strerror(err)));
930 close(state->sock);
931 state->sock = -1;
932 remove_client(state);
933 return;
935 process_request(state);
938 /* Remove a client connection from client connection list */
940 static void remove_client(struct winbindd_cli_state *state)
942 char c = 0;
943 int nwritten;
945 /* It's a dead client - hold a funeral */
947 if (state == NULL) {
948 return;
952 * We need to remove a pending wb_req_read_*
953 * or wb_resp_write_* request before closing the
954 * socket.
956 * This is important as they might have used tevent_add_fd() and we
957 * use the epoll * backend on linux. So we must remove the tevent_fd
958 * before closing the fd.
960 * Otherwise we might hit a race with close_conns_after_fork() (via
961 * winbindd_reinit_after_fork()) where a file description
962 * is still open in a child, which means it's still active in
963 * the parents epoll queue, but the related tevent_fd is already
964 * already gone in the parent.
966 * See bug #11141.
968 TALLOC_FREE(state->io_req);
970 if (state->sock != -1) {
971 /* tell client, we are closing ... */
972 nwritten = write(state->sock, &c, sizeof(c));
973 if (nwritten == -1) {
974 DEBUG(2, ("final write to client failed: %s\n",
975 strerror(errno)));
978 /* Close socket */
980 close(state->sock);
981 state->sock = -1;
984 TALLOC_FREE(state->mem_ctx);
986 /* Remove from list and free */
988 winbindd_remove_client(state);
989 TALLOC_FREE(state);
992 /* Is a client idle? */
994 static bool client_is_idle(struct winbindd_cli_state *state) {
995 return (state->request == NULL &&
996 state->response == NULL &&
997 !state->pwent_state && !state->grent_state);
1000 /* Shutdown client connection which has been idle for the longest time */
1002 static bool remove_idle_client(void)
1004 struct winbindd_cli_state *state, *remove_state = NULL;
1005 time_t last_access = 0;
1006 int nidle = 0;
1008 for (state = winbindd_client_list(); state; state = state->next) {
1009 if (client_is_idle(state)) {
1010 nidle++;
1011 if (!last_access || state->last_access < last_access) {
1012 last_access = state->last_access;
1013 remove_state = state;
1018 if (remove_state) {
1019 DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1020 nidle, remove_state->sock, (unsigned int)remove_state->pid));
1021 remove_client(remove_state);
1022 return True;
1025 return False;
1029 * Terminate all clients whose requests have taken longer than
1030 * "winbind request timeout" seconds to process, or have been
1031 * idle for more than "winbind request timeout" seconds.
1034 static void remove_timed_out_clients(void)
1036 struct winbindd_cli_state *state, *next = NULL;
1037 time_t curr_time = time(NULL);
1038 int timeout_val = lp_winbind_request_timeout();
1040 for (state = winbindd_client_list(); state; state = next) {
1041 time_t expiry_time;
1043 next = state->next;
1044 expiry_time = state->last_access + timeout_val;
1046 if (curr_time > expiry_time) {
1047 if (client_is_idle(state)) {
1048 DEBUG(5,("Idle client timed out, "
1049 "shutting down sock %d, pid %u\n",
1050 state->sock,
1051 (unsigned int)state->pid));
1052 } else {
1053 DEBUG(5,("Client request timed out, "
1054 "shutting down sock %d, pid %u\n",
1055 state->sock,
1056 (unsigned int)state->pid));
1058 remove_client(state);
1063 struct winbindd_listen_state {
1064 bool privileged;
1065 int fd;
1068 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1069 struct tevent_fd *fde,
1070 uint16_t flags,
1071 void *private_data)
1073 struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1074 struct winbindd_listen_state);
1076 while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1077 DEBUG(5,("winbindd: Exceeding %d client "
1078 "connections, removing idle "
1079 "connection.\n", lp_winbind_max_clients()));
1080 if (!remove_idle_client()) {
1081 DEBUG(0,("winbindd: Exceeding %d "
1082 "client connections, no idle "
1083 "connection found\n",
1084 lp_winbind_max_clients()));
1085 break;
1088 remove_timed_out_clients();
1089 new_connection(s->fd, s->privileged);
1093 * Winbindd socket accessor functions
1096 const char *get_winbind_pipe_dir(void)
1098 return lp_parm_const_string(-1, "winbindd", "socket dir", get_dyn_WINBINDD_SOCKET_DIR());
1101 char *get_winbind_priv_pipe_dir(void)
1103 return state_path(WINBINDD_PRIV_SOCKET_SUBDIR);
1106 static bool winbindd_setup_listeners(void)
1108 struct winbindd_listen_state *pub_state = NULL;
1109 struct winbindd_listen_state *priv_state = NULL;
1110 struct tevent_fd *fde;
1111 int rc;
1113 pub_state = talloc(winbind_event_context(),
1114 struct winbindd_listen_state);
1115 if (!pub_state) {
1116 goto failed;
1119 pub_state->privileged = false;
1120 pub_state->fd = create_pipe_sock(
1121 get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME, 0755);
1122 if (pub_state->fd == -1) {
1123 goto failed;
1125 rc = listen(pub_state->fd, 5);
1126 if (rc < 0) {
1127 goto failed;
1130 fde = tevent_add_fd(winbind_event_context(), pub_state, pub_state->fd,
1131 TEVENT_FD_READ, winbindd_listen_fde_handler,
1132 pub_state);
1133 if (fde == NULL) {
1134 close(pub_state->fd);
1135 goto failed;
1137 tevent_fd_set_auto_close(fde);
1139 priv_state = talloc(winbind_event_context(),
1140 struct winbindd_listen_state);
1141 if (!priv_state) {
1142 goto failed;
1145 priv_state->privileged = true;
1146 priv_state->fd = create_pipe_sock(
1147 get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);
1148 if (priv_state->fd == -1) {
1149 goto failed;
1151 rc = listen(priv_state->fd, 5);
1152 if (rc < 0) {
1153 goto failed;
1156 fde = tevent_add_fd(winbind_event_context(), priv_state,
1157 priv_state->fd, TEVENT_FD_READ,
1158 winbindd_listen_fde_handler, priv_state);
1159 if (fde == NULL) {
1160 close(priv_state->fd);
1161 goto failed;
1163 tevent_fd_set_auto_close(fde);
1165 return true;
1166 failed:
1167 TALLOC_FREE(pub_state);
1168 TALLOC_FREE(priv_state);
1169 return false;
1172 bool winbindd_use_idmap_cache(void)
1174 return !opt_nocache;
1177 bool winbindd_use_cache(void)
1179 return !opt_nocache;
1182 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1183 bool foreground)
1185 /* Setup signal handlers */
1187 if (!winbindd_setup_sig_term_handler(true))
1188 exit(1);
1189 if (!winbindd_setup_stdin_handler(true, foreground))
1190 exit(1);
1191 if (!winbindd_setup_sig_hup_handler(NULL))
1192 exit(1);
1193 if (!winbindd_setup_sig_chld_handler())
1194 exit(1);
1195 if (!winbindd_setup_sig_usr2_handler())
1196 exit(1);
1198 CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */
1201 * Ensure all cache and idmap caches are consistent
1202 * and initialized before we startup.
1204 if (!winbindd_cache_validate_and_initialize()) {
1205 exit(1);
1208 /* get broadcast messages */
1210 if (!serverid_register(messaging_server_id(msg_ctx),
1211 FLAG_MSG_GENERAL |
1212 FLAG_MSG_WINBIND |
1213 FLAG_MSG_DBWRAP)) {
1214 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
1215 exit(1);
1218 /* React on 'smbcontrol winbindd reload-config' in the same way
1219 as to SIGHUP signal */
1220 messaging_register(msg_ctx, NULL,
1221 MSG_SMB_CONF_UPDATED, msg_reload_services);
1222 messaging_register(msg_ctx, NULL,
1223 MSG_SHUTDOWN, msg_shutdown);
1225 /* Handle online/offline messages. */
1226 messaging_register(msg_ctx, NULL,
1227 MSG_WINBIND_OFFLINE, winbind_msg_offline);
1228 messaging_register(msg_ctx, NULL,
1229 MSG_WINBIND_ONLINE, winbind_msg_online);
1230 messaging_register(msg_ctx, NULL,
1231 MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1233 /* Handle domain online/offline messages for domains */
1234 messaging_register(winbind_messaging_context(), NULL,
1235 MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1236 messaging_register(winbind_messaging_context(), NULL,
1237 MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1239 messaging_register(msg_ctx, NULL,
1240 MSG_DUMP_EVENT_LIST, winbind_msg_dump_event_list);
1242 messaging_register(msg_ctx, NULL,
1243 MSG_WINBIND_VALIDATE_CACHE,
1244 winbind_msg_validate_cache);
1246 messaging_register(msg_ctx, NULL,
1247 MSG_WINBIND_DUMP_DOMAIN_LIST,
1248 winbind_msg_dump_domain_list);
1250 messaging_register(msg_ctx, NULL,
1251 MSG_WINBIND_IP_DROPPED,
1252 winbind_msg_ip_dropped_parent);
1254 /* Register handler for MSG_DEBUG. */
1255 messaging_register(msg_ctx, NULL,
1256 MSG_DEBUG,
1257 winbind_msg_debug);
1259 netsamlogon_cache_init(); /* Non-critical */
1261 /* clear the cached list of trusted domains */
1263 wcache_tdc_clear();
1265 if (!init_domain_list()) {
1266 DEBUG(0,("unable to initialize domain list\n"));
1267 exit(1);
1270 init_idmap_child();
1271 init_locator_child();
1273 smb_nscd_flush_user_cache();
1274 smb_nscd_flush_group_cache();
1276 if (lp_allow_trusted_domains()) {
1277 if (tevent_add_timer(winbind_event_context(), NULL, timeval_zero(),
1278 rescan_trusted_domains, NULL) == NULL) {
1279 DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1280 exit(1);
1286 struct winbindd_addrchanged_state {
1287 struct addrchange_context *ctx;
1288 struct tevent_context *ev;
1289 struct messaging_context *msg_ctx;
1292 static void winbindd_addr_changed(struct tevent_req *req);
1294 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1295 struct tevent_context *ev,
1296 struct messaging_context *msg_ctx)
1298 struct winbindd_addrchanged_state *state;
1299 struct tevent_req *req;
1300 NTSTATUS status;
1302 state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1303 if (state == NULL) {
1304 DEBUG(10, ("talloc failed\n"));
1305 return;
1307 state->ev = ev;
1308 state->msg_ctx = msg_ctx;
1310 status = addrchange_context_create(state, &state->ctx);
1311 if (!NT_STATUS_IS_OK(status)) {
1312 DEBUG(10, ("addrchange_context_create failed: %s\n",
1313 nt_errstr(status)));
1314 TALLOC_FREE(state);
1315 return;
1317 req = addrchange_send(state, ev, state->ctx);
1318 if (req == NULL) {
1319 DEBUG(0, ("addrchange_send failed\n"));
1320 TALLOC_FREE(state);
1321 return;
1323 tevent_req_set_callback(req, winbindd_addr_changed, state);
1326 static void winbindd_addr_changed(struct tevent_req *req)
1328 struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1329 req, struct winbindd_addrchanged_state);
1330 enum addrchange_type type;
1331 struct sockaddr_storage addr;
1332 NTSTATUS status;
1334 status = addrchange_recv(req, &type, &addr);
1335 TALLOC_FREE(req);
1336 if (!NT_STATUS_IS_OK(status)) {
1337 DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1338 nt_errstr(status)));
1339 TALLOC_FREE(state);
1340 return;
1342 if (type == ADDRCHANGE_DEL) {
1343 char addrstr[INET6_ADDRSTRLEN];
1344 DATA_BLOB blob;
1346 print_sockaddr(addrstr, sizeof(addrstr), &addr);
1348 DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1349 addrstr));
1351 blob = data_blob_const(addrstr, strlen(addrstr)+1);
1353 status = messaging_send(state->msg_ctx,
1354 messaging_server_id(state->msg_ctx),
1355 MSG_WINBIND_IP_DROPPED, &blob);
1356 if (!NT_STATUS_IS_OK(status)) {
1357 DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1358 nt_errstr(status)));
1361 req = addrchange_send(state, state->ev, state->ctx);
1362 if (req == NULL) {
1363 DEBUG(0, ("addrchange_send failed\n"));
1364 TALLOC_FREE(state);
1365 return;
1367 tevent_req_set_callback(req, winbindd_addr_changed, state);
1370 /* Main function */
1372 int main(int argc, char **argv, char **envp)
1374 static bool is_daemon = False;
1375 static bool Fork = True;
1376 static bool log_stdout = False;
1377 static bool no_process_group = False;
1378 enum {
1379 OPT_DAEMON = 1000,
1380 OPT_FORK,
1381 OPT_NO_PROCESS_GROUP,
1382 OPT_LOG_STDOUT
1384 struct poptOption long_options[] = {
1385 POPT_AUTOHELP
1386 { "stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
1387 { "foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Daemon in foreground mode" },
1388 { "no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
1389 { "daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
1390 { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" },
1391 { "no-caching", 'n', POPT_ARG_NONE, NULL, 'n', "Disable caching" },
1392 POPT_COMMON_SAMBA
1393 POPT_COMMON_DYNCONFIG
1394 POPT_TABLEEND
1396 poptContext pc;
1397 int opt;
1398 TALLOC_CTX *frame;
1399 NTSTATUS status;
1400 bool ok;
1403 * Do this before any other talloc operation
1405 talloc_enable_null_tracking();
1406 frame = talloc_stackframe();
1409 * We want total control over the permissions on created files,
1410 * so set our umask to 0.
1412 umask(0);
1414 setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1416 /* glibc (?) likes to print "User defined signal 1" and exit if a
1417 SIGUSR[12] is received before a handler is installed */
1419 CatchSignal(SIGUSR1, SIG_IGN);
1420 CatchSignal(SIGUSR2, SIG_IGN);
1422 fault_setup();
1423 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1425 load_case_tables();
1427 /* Initialise for running in non-root mode */
1429 sec_init();
1431 set_remote_machine_name("winbindd", False);
1433 /* Set environment variable so we don't recursively call ourselves.
1434 This may also be useful interactively. */
1436 if ( !winbind_off() ) {
1437 DEBUG(0,("Failed to disable recusive winbindd calls. Exiting.\n"));
1438 exit(1);
1441 /* Initialise samba/rpc client stuff */
1443 pc = poptGetContext("winbindd", argc, (const char **)argv, long_options, 0);
1445 while ((opt = poptGetNextOpt(pc)) != -1) {
1446 switch (opt) {
1447 /* Don't become a daemon */
1448 case OPT_DAEMON:
1449 is_daemon = True;
1450 break;
1451 case 'i':
1452 interactive = True;
1453 log_stdout = True;
1454 Fork = False;
1455 break;
1456 case OPT_FORK:
1457 Fork = false;
1458 break;
1459 case OPT_NO_PROCESS_GROUP:
1460 no_process_group = true;
1461 break;
1462 case OPT_LOG_STDOUT:
1463 log_stdout = true;
1464 break;
1465 case 'n':
1466 opt_nocache = true;
1467 break;
1468 default:
1469 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1470 poptBadOption(pc, 0), poptStrerror(opt));
1471 poptPrintUsage(pc, stderr, 0);
1472 exit(1);
1476 /* We call dump_core_setup one more time because the command line can
1477 * set the log file or the log-basename and this will influence where
1478 * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1479 * the default value derived from build's prefix. For EOM this value
1480 * is often not related to the path where winbindd is actually run
1481 * in production.
1483 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1484 if (is_daemon && interactive) {
1485 d_fprintf(stderr,"\nERROR: "
1486 "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1487 poptPrintUsage(pc, stderr, 0);
1488 exit(1);
1491 if (log_stdout && Fork) {
1492 d_fprintf(stderr, "\nERROR: "
1493 "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1494 poptPrintUsage(pc, stderr, 0);
1495 exit(1);
1498 poptFreeContext(pc);
1500 if (!override_logfile) {
1501 char *lfile = NULL;
1502 if (asprintf(&lfile,"%s/log.winbindd",
1503 get_dyn_LOGFILEBASE()) > 0) {
1504 lp_set_logfile(lfile);
1505 SAFE_FREE(lfile);
1509 if (log_stdout) {
1510 setup_logging("winbindd", DEBUG_STDOUT);
1511 } else {
1512 setup_logging("winbindd", DEBUG_FILE);
1514 reopen_logs();
1516 DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1517 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1519 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1520 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1521 exit(1);
1523 /* After parsing the configuration file we setup the core path one more time
1524 * as the log file might have been set in the configuration and cores's
1525 * path is by default basename(lp_logfile()).
1527 dump_core_setup("winbindd", lp_logfile(talloc_tos()));
1529 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
1530 DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1531 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"));
1532 exit(1);
1535 /* Initialise messaging system */
1537 if (winbind_messaging_context() == NULL) {
1538 exit(1);
1541 if (!reload_services_file(NULL)) {
1542 DEBUG(0, ("error opening config file\n"));
1543 exit(1);
1546 ok = directory_create_or_exist(lp_lockdir(), geteuid(), 0755);
1547 if (!ok) {
1548 DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1549 lp_lockdir(), strerror(errno)));
1550 exit(1);
1553 ok = directory_create_or_exist(lp_piddir(), geteuid(), 0755);
1554 if (!ok) {
1555 DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1556 lp_piddir(), strerror(errno)));
1557 exit(1);
1560 /* Setup names. */
1562 if (!init_names())
1563 exit(1);
1565 load_interfaces();
1567 if (!secrets_init()) {
1569 DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1570 return False;
1573 /* Unblock all signals we are interested in as they may have been
1574 blocked by the parent process. */
1576 BlockSignals(False, SIGINT);
1577 BlockSignals(False, SIGQUIT);
1578 BlockSignals(False, SIGTERM);
1579 BlockSignals(False, SIGUSR1);
1580 BlockSignals(False, SIGUSR2);
1581 BlockSignals(False, SIGHUP);
1582 BlockSignals(False, SIGCHLD);
1584 if (!interactive)
1585 become_daemon(Fork, no_process_group, log_stdout);
1587 pidfile_create(lp_piddir(), "winbindd");
1589 #if HAVE_SETPGID
1591 * If we're interactive we want to set our own process group for
1592 * signal management.
1594 if (interactive && !no_process_group)
1595 setpgid( (pid_t)0, (pid_t)0);
1596 #endif
1598 TimeInit();
1600 /* Don't use winbindd_reinit_after_fork here as
1601 * we're just starting up and haven't created any
1602 * winbindd-specific resources we must free yet. JRA.
1605 status = reinit_after_fork(winbind_messaging_context(),
1606 winbind_event_context(),
1607 false);
1608 if (!NT_STATUS_IS_OK(status)) {
1609 exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1613 * Do not initialize the parent-child-pipe before becoming
1614 * a daemon: this is used to detect a died parent in the child
1615 * process.
1617 status = init_before_fork();
1618 if (!NT_STATUS_IS_OK(status)) {
1619 exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1622 winbindd_register_handlers(winbind_messaging_context(), !Fork);
1624 status = init_system_session_info();
1625 if (!NT_STATUS_IS_OK(status)) {
1626 exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1629 rpc_lsarpc_init(NULL);
1630 rpc_samr_init(NULL);
1632 winbindd_init_addrchange(NULL, winbind_event_context(),
1633 winbind_messaging_context());
1635 /* setup listen sockets */
1637 if (!winbindd_setup_listeners()) {
1638 exit_daemon("Winbindd failed to setup listeners", EPIPE);
1641 TALLOC_FREE(frame);
1643 if (!interactive) {
1644 daemon_ready("winbindd");
1647 /* Loop waiting for requests */
1648 while (1) {
1649 frame = talloc_stackframe();
1651 if (tevent_loop_once(winbind_event_context()) == -1) {
1652 DEBUG(1, ("tevent_loop_once() failed: %s\n",
1653 strerror(errno)));
1654 return 1;
1657 TALLOC_FREE(frame);
1660 return 0;