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 "auth.h"
38 #include "messages.h"
39 #include "../lib/util/pidfile.h"
40 #include "util_cluster.h"
41 #include "source4/lib/messaging/irpc.h"
42 #include "source4/lib/messaging/messaging.h"
43 #include "lib/param/param.h"
44 #include "lib/async_req/async_sock.h"
45 #include "libsmb/samlogon_cache.h"
46 #include "libcli/auth/netlogon_creds_cli.h"
47 #include "passdb.h"
48 #include "lib/util/tevent_req_profile.h"
49 #include "lib/gencache.h"
50 
51 #undef DBGC_CLASS
52 #define DBGC_CLASS DBGC_WINBIND
53 
54 #define SCRUB_CLIENTS_INTERVAL 5
55 
56 static bool client_is_idle(struct winbindd_cli_state *state);
57 static void remove_client(struct winbindd_cli_state *state);
58 static void winbindd_setup_max_fds(void);
59 
60 static bool opt_nocache = False;
61 static bool interactive = False;
62 
63 extern bool override_logfile;
64 
winbind_imessaging_context(void)65 struct imessaging_context *winbind_imessaging_context(void)
66 {
67 	static struct imessaging_context *msg = NULL;
68 	struct messaging_context *msg_ctx;
69 	struct server_id myself;
70 	struct loadparm_context *lp_ctx;
71 
72 	if (msg != NULL) {
73 		return msg;
74 	}
75 
76 	msg_ctx = global_messaging_context();
77 	if (msg_ctx == NULL) {
78 		smb_panic("global_messaging_context failed\n");
79 	}
80 	myself = messaging_server_id(msg_ctx);
81 
82 	lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
83 	if (lp_ctx == NULL) {
84 		smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
85 	}
86 
87 	/*
88 	 * Note we MUST use the NULL context here, not the autofree context,
89 	 * to avoid side effects in forked children exiting.
90 	 */
91 	msg = imessaging_init(NULL, lp_ctx, myself, global_event_context());
92 	talloc_unlink(NULL, lp_ctx);
93 
94 	if (msg == NULL) {
95 		smb_panic("Could not init winbindd's messaging context.\n");
96 	}
97 	return msg;
98 }
99 
100 /* Reload configuration */
101 
winbindd_reload_services_file(const char * lfile)102 bool winbindd_reload_services_file(const char *lfile)
103 {
104 	const struct loadparm_substitution *lp_sub =
105 		loadparm_s3_global_substitution();
106 	bool ret;
107 
108 	if (lp_loaded()) {
109 		char *fname = lp_next_configfile(talloc_tos(), lp_sub);
110 
111 		if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
112 			set_dyn_CONFIGFILE(fname);
113 		}
114 		TALLOC_FREE(fname);
115 	}
116 
117 	reopen_logs();
118 	ret = lp_load_global(get_dyn_CONFIGFILE());
119 
120 	/* if this is a child, restore the logfile to the special
121 	   name - <domain>, idmap, etc. */
122 	if (lfile && *lfile) {
123 		lp_set_logfile(lfile);
124 	}
125 
126 	reopen_logs();
127 	load_interfaces();
128 	winbindd_setup_max_fds();
129 
130 	return(ret);
131 }
132 
133 
winbindd_status(void)134 static void winbindd_status(void)
135 {
136 	struct winbindd_cli_state *tmp;
137 
138 	DEBUG(0, ("winbindd status:\n"));
139 
140 	/* Print client state information */
141 
142 	DEBUG(0, ("\t%d clients currently active\n", winbindd_num_clients()));
143 
144 	if (DEBUGLEVEL >= 2 && winbindd_num_clients()) {
145 		DEBUG(2, ("\tclient list:\n"));
146 		for(tmp = winbindd_client_list(); tmp; tmp = tmp->next) {
147 			DEBUGADD(2, ("\t\tpid %lu, sock %d (%s)\n",
148 				     (unsigned long)tmp->pid, tmp->sock,
149 				     client_is_idle(tmp) ? "idle" : "active"));
150 		}
151 	}
152 }
153 
154 /* Flush client cache */
155 
winbindd_flush_caches(void)156 void winbindd_flush_caches(void)
157 {
158 	/* We need to invalidate cached user list entries on a SIGHUP
159            otherwise cached access denied errors due to restrict anonymous
160            hang around until the sequence number changes. */
161 
162 	if (!wcache_invalidate_cache()) {
163 		DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
164 		if (!winbindd_cache_validate_and_initialize()) {
165 			exit(1);
166 		}
167 	}
168 }
169 
flush_caches_noinit(void)170 static void flush_caches_noinit(void)
171 {
172 	/*
173 	 * We need to invalidate cached user list entries on a SIGHUP
174          * otherwise cached access denied errors due to restrict anonymous
175          * hang around until the sequence number changes.
176 	 * NB
177 	 * Skip uninitialized domains when flush cache.
178 	 * If domain is not initialized, it means it is never
179 	 * used or never become online. look, wcache_invalidate_cache()
180 	 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
181 	 * for unused domains and large traffic for primay domain's DC if there
182 	 * are many domains..
183 	 */
184 
185 	if (!wcache_invalidate_cache_noinit()) {
186 		DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
187 		if (!winbindd_cache_validate_and_initialize()) {
188 			exit(1);
189 		}
190 	}
191 }
192 
193 /* Handle the signal by unlinking socket and exiting */
194 
terminate(bool is_parent)195 static void terminate(bool is_parent)
196 {
197 	if (is_parent) {
198 		/* When parent goes away we should
199 		 * remove the socket file. Not so
200 		 * when children terminate.
201 		 */
202 		char *path = NULL;
203 
204 		if (asprintf(&path, "%s/%s",
205 			lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME) > 0) {
206 			unlink(path);
207 			SAFE_FREE(path);
208 		}
209 	}
210 
211 	idmap_close();
212 
213 	netlogon_creds_cli_close_global_db();
214 
215 #if 0
216 	if (interactive) {
217 		TALLOC_CTX *mem_ctx = talloc_init("end_description");
218 		char *description = talloc_describe_all(mem_ctx);
219 
220 		DEBUG(3, ("tallocs left:\n%s\n", description));
221 		talloc_destroy(mem_ctx);
222 	}
223 #endif
224 
225 	if (is_parent) {
226 		pidfile_unlink(lp_pid_directory(), "winbindd");
227 	}
228 
229 	exit(0);
230 }
231 
winbindd_sig_term_handler(struct tevent_context * ev,struct tevent_signal * se,int signum,int count,void * siginfo,void * private_data)232 static void winbindd_sig_term_handler(struct tevent_context *ev,
233 				      struct tevent_signal *se,
234 				      int signum,
235 				      int count,
236 				      void *siginfo,
237 				      void *private_data)
238 {
239 	bool *p = talloc_get_type_abort(private_data, bool);
240 	bool is_parent = *p;
241 
242 	TALLOC_FREE(p);
243 
244 	DEBUG(0,("Got sig[%d] terminate (is_parent=%d)\n",
245 		 signum, is_parent));
246 	terminate(is_parent);
247 }
248 
249 /*
250   handle stdin becoming readable when we are in --foreground mode
251  */
winbindd_stdin_handler(struct tevent_context * ev,struct tevent_fd * fde,uint16_t flags,void * private_data)252 static void winbindd_stdin_handler(struct tevent_context *ev,
253 			       struct tevent_fd *fde,
254 			       uint16_t flags,
255 			       void *private_data)
256 {
257 	char c;
258 	if (read(0, &c, 1) != 1) {
259 		bool *is_parent = talloc_get_type_abort(private_data, bool);
260 
261 		/* we have reached EOF on stdin, which means the
262 		   parent has exited. Shutdown the server */
263 		DEBUG(0,("EOF on stdin (is_parent=%d)\n",
264 			 (int)*is_parent));
265 		terminate(*is_parent);
266 	}
267 }
268 
winbindd_setup_sig_term_handler(bool parent)269 bool winbindd_setup_sig_term_handler(bool parent)
270 {
271 	struct tevent_signal *se;
272 	bool *is_parent;
273 
274 	is_parent = talloc(global_event_context(), bool);
275 	if (!is_parent) {
276 		return false;
277 	}
278 
279 	*is_parent = parent;
280 
281 	se = tevent_add_signal(global_event_context(),
282 			       is_parent,
283 			       SIGTERM, 0,
284 			       winbindd_sig_term_handler,
285 			       is_parent);
286 	if (!se) {
287 		DEBUG(0,("failed to setup SIGTERM handler"));
288 		talloc_free(is_parent);
289 		return false;
290 	}
291 
292 	se = tevent_add_signal(global_event_context(),
293 			       is_parent,
294 			       SIGINT, 0,
295 			       winbindd_sig_term_handler,
296 			       is_parent);
297 	if (!se) {
298 		DEBUG(0,("failed to setup SIGINT handler"));
299 		talloc_free(is_parent);
300 		return false;
301 	}
302 
303 	se = tevent_add_signal(global_event_context(),
304 			       is_parent,
305 			       SIGQUIT, 0,
306 			       winbindd_sig_term_handler,
307 			       is_parent);
308 	if (!se) {
309 		DEBUG(0,("failed to setup SIGINT handler"));
310 		talloc_free(is_parent);
311 		return false;
312 	}
313 
314 	return true;
315 }
316 
winbindd_setup_stdin_handler(bool parent,bool foreground)317 bool winbindd_setup_stdin_handler(bool parent, bool foreground)
318 {
319 	bool *is_parent;
320 
321 	if (foreground) {
322 		struct stat st;
323 
324 		is_parent = talloc(global_event_context(), bool);
325 		if (!is_parent) {
326 			return false;
327 		}
328 
329 		*is_parent = parent;
330 
331 		/* if we are running in the foreground then look for
332 		   EOF on stdin, and exit if it happens. This allows
333 		   us to die if the parent process dies
334 		   Only do this on a pipe or socket, no other device.
335 		*/
336 		if (fstat(0, &st) != 0) {
337 			return false;
338 		}
339 		if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
340 			tevent_add_fd(global_event_context(),
341 					is_parent,
342 					0,
343 					TEVENT_FD_READ,
344 					winbindd_stdin_handler,
345 					is_parent);
346 		}
347 	}
348 
349 	return true;
350 }
351 
winbindd_sig_hup_handler(struct tevent_context * ev,struct tevent_signal * se,int signum,int count,void * siginfo,void * private_data)352 static void winbindd_sig_hup_handler(struct tevent_context *ev,
353 				     struct tevent_signal *se,
354 				     int signum,
355 				     int count,
356 				     void *siginfo,
357 				     void *private_data)
358 {
359 	const char *file = (const char *)private_data;
360 
361 	DEBUG(1,("Reloading services after SIGHUP\n"));
362 	flush_caches_noinit();
363 	winbindd_reload_services_file(file);
364 }
365 
winbindd_setup_sig_hup_handler(const char * lfile)366 bool winbindd_setup_sig_hup_handler(const char *lfile)
367 {
368 	struct tevent_signal *se;
369 	char *file = NULL;
370 
371 	if (lfile) {
372 		file = talloc_strdup(global_event_context(),
373 				     lfile);
374 		if (!file) {
375 			return false;
376 		}
377 	}
378 
379 	se = tevent_add_signal(global_event_context(),
380 			       global_event_context(),
381 			       SIGHUP, 0,
382 			       winbindd_sig_hup_handler,
383 			       file);
384 	if (!se) {
385 		return false;
386 	}
387 
388 	return true;
389 }
390 
winbindd_sig_chld_handler(struct tevent_context * ev,struct tevent_signal * se,int signum,int count,void * siginfo,void * private_data)391 static void winbindd_sig_chld_handler(struct tevent_context *ev,
392 				      struct tevent_signal *se,
393 				      int signum,
394 				      int count,
395 				      void *siginfo,
396 				      void *private_data)
397 {
398 	pid_t pid;
399 
400 	while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) {
401 		winbind_child_died(pid);
402 	}
403 }
404 
winbindd_setup_sig_chld_handler(void)405 static bool winbindd_setup_sig_chld_handler(void)
406 {
407 	struct tevent_signal *se;
408 
409 	se = tevent_add_signal(global_event_context(),
410 			       global_event_context(),
411 			       SIGCHLD, 0,
412 			       winbindd_sig_chld_handler,
413 			       NULL);
414 	if (!se) {
415 		return false;
416 	}
417 
418 	return true;
419 }
420 
winbindd_sig_usr2_handler(struct tevent_context * ev,struct tevent_signal * se,int signum,int count,void * siginfo,void * private_data)421 static void winbindd_sig_usr2_handler(struct tevent_context *ev,
422 				      struct tevent_signal *se,
423 				      int signum,
424 				      int count,
425 				      void *siginfo,
426 				      void *private_data)
427 {
428 	winbindd_status();
429 }
430 
winbindd_setup_sig_usr2_handler(void)431 static bool winbindd_setup_sig_usr2_handler(void)
432 {
433 	struct tevent_signal *se;
434 
435 	se = tevent_add_signal(global_event_context(),
436 			       global_event_context(),
437 			       SIGUSR2, 0,
438 			       winbindd_sig_usr2_handler,
439 			       NULL);
440 	if (!se) {
441 		return false;
442 	}
443 
444 	return true;
445 }
446 
447 /* React on 'smbcontrol winbindd shutdown' in the same way as on SIGTERM*/
msg_shutdown(struct messaging_context * msg,void * private_data,uint32_t msg_type,struct server_id server_id,DATA_BLOB * data)448 static void msg_shutdown(struct messaging_context *msg,
449 			 void *private_data,
450 			 uint32_t msg_type,
451 			 struct server_id server_id,
452 			 DATA_BLOB *data)
453 {
454 	/* only the parent waits for this message */
455 	DEBUG(0,("Got shutdown message\n"));
456 	terminate(true);
457 }
458 
459 
winbind_msg_validate_cache(struct messaging_context * msg_ctx,void * private_data,uint32_t msg_type,struct server_id server_id,DATA_BLOB * data)460 static void winbind_msg_validate_cache(struct messaging_context *msg_ctx,
461 				       void *private_data,
462 				       uint32_t msg_type,
463 				       struct server_id server_id,
464 				       DATA_BLOB *data)
465 {
466 	uint8_t ret;
467 	pid_t child_pid;
468 	NTSTATUS status;
469 
470 	DEBUG(10, ("winbindd_msg_validate_cache: got validate-cache "
471 		   "message.\n"));
472 
473 	/*
474 	 * call the validation code from a child:
475 	 * so we don't block the main winbindd and the validation
476 	 * code can safely use fork/waitpid...
477 	 */
478 	child_pid = fork();
479 
480 	if (child_pid == -1) {
481 		DEBUG(1, ("winbind_msg_validate_cache: Could not fork: %s\n",
482 			  strerror(errno)));
483 		return;
484 	}
485 
486 	if (child_pid != 0) {
487 		/* parent */
488 		DEBUG(5, ("winbind_msg_validate_cache: child created with "
489 			  "pid %d.\n", (int)child_pid));
490 		return;
491 	}
492 
493 	/* child */
494 
495 	status = winbindd_reinit_after_fork(NULL, NULL);
496 	if (!NT_STATUS_IS_OK(status)) {
497 		DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
498 			  nt_errstr(status)));
499 		_exit(0);
500 	}
501 
502 	/* install default SIGCHLD handler: validation code uses fork/waitpid */
503 	CatchSignal(SIGCHLD, SIG_DFL);
504 
505 	setproctitle("validate cache child");
506 
507 	ret = (uint8_t)winbindd_validate_cache_nobackup();
508 	DEBUG(10, ("winbindd_msg_validata_cache: got return value %d\n", ret));
509 	messaging_send_buf(msg_ctx, server_id, MSG_WINBIND_VALIDATE_CACHE, &ret,
510 			   (size_t)1);
511 	_exit(0);
512 }
513 
514 static struct winbindd_bool_dispatch_table {
515 	enum winbindd_cmd cmd;
516 	bool (*fn)(struct winbindd_cli_state *state);
517 	const char *cmd_name;
518 } bool_dispatch_table[] = {
519 	{ WINBINDD_INTERFACE_VERSION,
520 	  winbindd_interface_version,
521 	  "INTERFACE_VERSION" },
522 	{ WINBINDD_INFO,
523 	  winbindd_info,
524 	  "INFO" },
525 	{ WINBINDD_PING,
526 	  winbindd_ping,
527 	  "PING" },
528 	{ WINBINDD_DOMAIN_NAME,
529 	  winbindd_domain_name,
530 	  "DOMAIN_NAME" },
531 	{ WINBINDD_NETBIOS_NAME,
532 	  winbindd_netbios_name,
533 	  "NETBIOS_NAME" },
534 	{ WINBINDD_DC_INFO,
535 	  winbindd_dc_info,
536 	  "DC_INFO" },
537 	{ WINBINDD_CCACHE_NTLMAUTH,
538 	  winbindd_ccache_ntlm_auth,
539 	  "NTLMAUTH" },
540 	{ WINBINDD_CCACHE_SAVE,
541 	  winbindd_ccache_save,
542 	  "CCACHE_SAVE" },
543 	{ WINBINDD_PRIV_PIPE_DIR,
544 	  winbindd_priv_pipe_dir,
545 	  "WINBINDD_PRIV_PIPE_DIR" },
546 	{ WINBINDD_LIST_TRUSTDOM,
547 	  winbindd_list_trusted_domains,
548 	  "LIST_TRUSTDOM" },
549 };
550 
551 struct winbindd_async_dispatch_table {
552 	enum winbindd_cmd cmd;
553 	const char *cmd_name;
554 	struct tevent_req *(*send_req)(TALLOC_CTX *mem_ctx,
555 				       struct tevent_context *ev,
556 				       struct winbindd_cli_state *cli,
557 				       struct winbindd_request *request);
558 	NTSTATUS (*recv_req)(struct tevent_req *req,
559 			     struct winbindd_response *presp);
560 };
561 
562 static struct winbindd_async_dispatch_table async_nonpriv_table[] = {
563 	{ WINBINDD_LOOKUPSID, "LOOKUPSID",
564 	  winbindd_lookupsid_send, winbindd_lookupsid_recv },
565 	{ WINBINDD_LOOKUPSIDS, "LOOKUPSIDS",
566 	  winbindd_lookupsids_send, winbindd_lookupsids_recv },
567 	{ WINBINDD_LOOKUPNAME, "LOOKUPNAME",
568 	  winbindd_lookupname_send, winbindd_lookupname_recv },
569 	{ WINBINDD_SIDS_TO_XIDS, "SIDS_TO_XIDS",
570 	  winbindd_sids_to_xids_send, winbindd_sids_to_xids_recv },
571 	{ WINBINDD_XIDS_TO_SIDS, "XIDS_TO_SIDS",
572 	  winbindd_xids_to_sids_send, winbindd_xids_to_sids_recv },
573 	{ WINBINDD_GETPWSID, "GETPWSID",
574 	  winbindd_getpwsid_send, winbindd_getpwsid_recv },
575 	{ WINBINDD_GETPWNAM, "GETPWNAM",
576 	  winbindd_getpwnam_send, winbindd_getpwnam_recv },
577 	{ WINBINDD_GETPWUID, "GETPWUID",
578 	  winbindd_getpwuid_send, winbindd_getpwuid_recv },
579 	{ WINBINDD_GETSIDALIASES, "GETSIDALIASES",
580 	  winbindd_getsidaliases_send, winbindd_getsidaliases_recv },
581 	{ WINBINDD_GETUSERDOMGROUPS, "GETUSERDOMGROUPS",
582 	  winbindd_getuserdomgroups_send, winbindd_getuserdomgroups_recv },
583 	{ WINBINDD_GETGROUPS, "GETGROUPS",
584 	  winbindd_getgroups_send, winbindd_getgroups_recv },
585 	{ WINBINDD_SHOW_SEQUENCE, "SHOW_SEQUENCE",
586 	  winbindd_show_sequence_send, winbindd_show_sequence_recv },
587 	{ WINBINDD_GETGRGID, "GETGRGID",
588 	  winbindd_getgrgid_send, winbindd_getgrgid_recv },
589 	{ WINBINDD_GETGRNAM, "GETGRNAM",
590 	  winbindd_getgrnam_send, winbindd_getgrnam_recv },
591 	{ WINBINDD_GETUSERSIDS, "GETUSERSIDS",
592 	  winbindd_getusersids_send, winbindd_getusersids_recv },
593 	{ WINBINDD_LOOKUPRIDS, "LOOKUPRIDS",
594 	  winbindd_lookuprids_send, winbindd_lookuprids_recv },
595 	{ WINBINDD_SETPWENT, "SETPWENT",
596 	  winbindd_setpwent_send, winbindd_setpwent_recv },
597 	{ WINBINDD_GETPWENT, "GETPWENT",
598 	  winbindd_getpwent_send, winbindd_getpwent_recv },
599 	{ WINBINDD_ENDPWENT, "ENDPWENT",
600 	  winbindd_endpwent_send, winbindd_endpwent_recv },
601 	{ WINBINDD_DSGETDCNAME, "DSGETDCNAME",
602 	  winbindd_dsgetdcname_send, winbindd_dsgetdcname_recv },
603 	{ WINBINDD_GETDCNAME, "GETDCNAME",
604 	  winbindd_getdcname_send, winbindd_getdcname_recv },
605 	{ WINBINDD_SETGRENT, "SETGRENT",
606 	  winbindd_setgrent_send, winbindd_setgrent_recv },
607 	{ WINBINDD_GETGRENT, "GETGRENT",
608 	  winbindd_getgrent_send, winbindd_getgrent_recv },
609 	{ WINBINDD_ENDGRENT, "ENDGRENT",
610 	  winbindd_endgrent_send, winbindd_endgrent_recv },
611 	{ WINBINDD_LIST_USERS, "LIST_USERS",
612 	  winbindd_list_users_send, winbindd_list_users_recv },
613 	{ WINBINDD_LIST_GROUPS, "LIST_GROUPS",
614 	  winbindd_list_groups_send, winbindd_list_groups_recv },
615 	{ WINBINDD_CHECK_MACHACC, "CHECK_MACHACC",
616 	  winbindd_check_machine_acct_send, winbindd_check_machine_acct_recv },
617 	{ WINBINDD_PING_DC, "PING_DC",
618 	  winbindd_ping_dc_send, winbindd_ping_dc_recv },
619 	{ WINBINDD_PAM_AUTH, "PAM_AUTH",
620 	  winbindd_pam_auth_send, winbindd_pam_auth_recv },
621 	{ WINBINDD_PAM_LOGOFF, "PAM_LOGOFF",
622 	  winbindd_pam_logoff_send, winbindd_pam_logoff_recv },
623 	{ WINBINDD_PAM_CHAUTHTOK, "PAM_CHAUTHTOK",
624 	  winbindd_pam_chauthtok_send, winbindd_pam_chauthtok_recv },
625 	{ WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, "PAM_CHNG_PSWD_AUTH_CRAP",
626 	  winbindd_pam_chng_pswd_auth_crap_send,
627 	  winbindd_pam_chng_pswd_auth_crap_recv },
628 	{ WINBINDD_WINS_BYIP, "WINS_BYIP",
629 	  winbindd_wins_byip_send, winbindd_wins_byip_recv },
630 	{ WINBINDD_WINS_BYNAME, "WINS_BYNAME",
631 	  winbindd_wins_byname_send, winbindd_wins_byname_recv },
632 	{ WINBINDD_DOMAIN_INFO, "DOMAIN_INFO",
633 	  winbindd_domain_info_send, winbindd_domain_info_recv },
634 
635 	{ 0, NULL, NULL, NULL }
636 };
637 
638 static struct winbindd_async_dispatch_table async_priv_table[] = {
639 	{ WINBINDD_ALLOCATE_UID, "ALLOCATE_UID",
640 	  winbindd_allocate_uid_send, winbindd_allocate_uid_recv },
641 	{ WINBINDD_ALLOCATE_GID, "ALLOCATE_GID",
642 	  winbindd_allocate_gid_send, winbindd_allocate_gid_recv },
643 	{ WINBINDD_CHANGE_MACHACC, "CHANGE_MACHACC",
644 	  winbindd_change_machine_acct_send, winbindd_change_machine_acct_recv },
645 	{ WINBINDD_PAM_AUTH_CRAP, "PAM_AUTH_CRAP",
646 	  winbindd_pam_auth_crap_send, winbindd_pam_auth_crap_recv },
647 
648 	{ 0, NULL, NULL, NULL }
649 };
650 
651 struct process_request_state {
652 	struct winbindd_cli_state *cli_state;
653 	struct tevent_context *ev;
654 };
655 
656 static void process_request_done(struct tevent_req *subreq);
657 static void process_request_written(struct tevent_req *subreq);
658 
process_request_send(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct winbindd_cli_state * cli_state)659 static struct tevent_req *process_request_send(
660 	TALLOC_CTX *mem_ctx,
661 	struct tevent_context *ev,
662 	struct winbindd_cli_state *cli_state)
663 {
664 	struct tevent_req *req, *subreq;
665 	struct process_request_state *state;
666 	struct winbindd_async_dispatch_table *atable;
667 	enum winbindd_cmd cmd = cli_state->request->cmd;
668 	size_t i;
669 	bool ok;
670 
671 	req = tevent_req_create(mem_ctx, &state,
672 				struct process_request_state);
673 	if (req == NULL) {
674 		return NULL;
675 	}
676 	state->cli_state = cli_state;
677 	state->ev = ev;
678 
679 	ok = tevent_req_set_profile(req);
680 	if (!ok) {
681 		return tevent_req_post(req, ev);
682 	}
683 
684 	SMB_ASSERT(cli_state->mem_ctx == NULL);
685 	cli_state->mem_ctx = talloc_named(cli_state, 0, "winbind request");
686 	if (tevent_req_nomem(cli_state->mem_ctx, req)) {
687 		return tevent_req_post(req, ev);
688 	}
689 
690 	cli_state->response = talloc_zero(
691 		cli_state->mem_ctx,
692 		struct winbindd_response);
693 	if (tevent_req_nomem(cli_state->response, req)) {
694 		return tevent_req_post(req, ev);
695 	}
696 	cli_state->response->result = WINBINDD_PENDING;
697 	cli_state->response->length = sizeof(struct winbindd_response);
698 
699 	/* Remember who asked us. */
700 	cli_state->pid = cli_state->request->pid;
701 	memcpy(cli_state->client_name,
702 	       cli_state->request->client_name,
703 	       sizeof(cli_state->client_name));
704 
705 	cli_state->cmd_name = "unknown request";
706 	cli_state->recv_fn = NULL;
707 
708 	/* client is newest */
709 	winbindd_promote_client(cli_state);
710 
711 	for (atable = async_nonpriv_table; atable->send_req; atable += 1) {
712 		if (cmd == atable->cmd) {
713 			break;
714 		}
715 	}
716 
717 	if ((atable->send_req == NULL) && cli_state->privileged) {
718 		for (atable = async_priv_table; atable->send_req;
719 		     atable += 1) {
720 			if (cmd == atable->cmd) {
721 				break;
722 			}
723 		}
724 	}
725 
726 	if (atable->send_req != NULL) {
727 		cli_state->cmd_name = atable->cmd_name;
728 		cli_state->recv_fn = atable->recv_req;
729 
730 		DBG_DEBUG("process_request: "
731 			  "Handling async request %s(%d):%s\n",
732 			  cli_state->client_name,
733 			  (int)cli_state->pid,
734 			  cli_state->cmd_name);
735 
736 		subreq = atable->send_req(
737 			state,
738 			state->ev,
739 			cli_state,
740 			cli_state->request);
741 		if (tevent_req_nomem(subreq, req)) {
742 			return tevent_req_post(req, ev);
743 		}
744 		tevent_req_set_callback(subreq, process_request_done, req);
745 		return req;
746 	}
747 
748 	for (i=0; i<ARRAY_SIZE(bool_dispatch_table); i++) {
749 		if (cmd == bool_dispatch_table[i].cmd) {
750 			break;
751 		}
752 	}
753 
754 	ok = false;
755 
756 	if (i < ARRAY_SIZE(bool_dispatch_table)) {
757 		cli_state->cmd_name = bool_dispatch_table[i].cmd_name;
758 
759 		DBG_DEBUG("process_request: request fn %s\n",
760 			  bool_dispatch_table[i].cmd_name);
761 		ok = bool_dispatch_table[i].fn(cli_state);
762 	}
763 
764 	cli_state->response->result = ok ? WINBINDD_OK : WINBINDD_ERROR;
765 
766 	TALLOC_FREE(cli_state->io_req);
767 	TALLOC_FREE(cli_state->request);
768 
769 	subreq = wb_resp_write_send(
770 		state,
771 		state->ev,
772 		cli_state->out_queue,
773 		cli_state->sock,
774 		cli_state->response);
775 	if (tevent_req_nomem(subreq, req)) {
776 		return tevent_req_post(req, ev);
777 	}
778 	tevent_req_set_callback(subreq, process_request_written, req);
779 
780 	cli_state->io_req = subreq;
781 
782 	return req;
783 }
784 
process_request_done(struct tevent_req * subreq)785 static void process_request_done(struct tevent_req *subreq)
786 {
787 	struct tevent_req *req = tevent_req_callback_data(
788 		subreq, struct tevent_req);
789 	struct process_request_state *state = tevent_req_data(
790 		req, struct process_request_state);
791 	struct winbindd_cli_state *cli_state = state->cli_state;
792 	NTSTATUS status;
793 	bool ok;
794 
795 	status = cli_state->recv_fn(subreq, cli_state->response);
796 	TALLOC_FREE(subreq);
797 
798 	DBG_DEBUG("[%s(%d):%s]: %s\n",
799 		  cli_state->client_name,
800 		  (int)cli_state->pid,
801 		  cli_state->cmd_name,
802 		  nt_errstr(status));
803 
804 	ok = NT_STATUS_IS_OK(status);
805 	cli_state->response->result = ok ? WINBINDD_OK : WINBINDD_ERROR;
806 
807 	TALLOC_FREE(cli_state->io_req);
808 	TALLOC_FREE(cli_state->request);
809 
810 	subreq = wb_resp_write_send(
811 		state,
812 		state->ev,
813 		cli_state->out_queue,
814 		cli_state->sock,
815 		cli_state->response);
816 	if (tevent_req_nomem(subreq, req)) {
817 		return;
818 	}
819 	tevent_req_set_callback(subreq, process_request_written, req);
820 
821 	cli_state->io_req = subreq;
822 }
823 
process_request_written(struct tevent_req * subreq)824 static void process_request_written(struct tevent_req *subreq)
825 {
826 	struct tevent_req *req = tevent_req_callback_data(
827 		subreq, struct tevent_req);
828 	struct process_request_state *state = tevent_req_data(
829 		req, struct process_request_state);
830 	struct winbindd_cli_state *cli_state = state->cli_state;
831 	ssize_t ret;
832 	int err;
833 
834 	cli_state->io_req = NULL;
835 
836 	ret = wb_resp_write_recv(subreq, &err);
837 	TALLOC_FREE(subreq);
838 	if (ret == -1) {
839 		tevent_req_nterror(req, map_nt_error_from_unix(err));
840 		return;
841 	}
842 
843 	DBG_DEBUG("[%s(%d):%s]: delivered response to client\n",
844 		  cli_state->client_name,
845 		  (int)cli_state->pid,
846 		  cli_state->cmd_name);
847 
848 	TALLOC_FREE(cli_state->mem_ctx);
849 	cli_state->response = NULL;
850 	cli_state->cmd_name = "no request";
851 	cli_state->recv_fn = NULL;
852 
853 	tevent_req_done(req);
854 }
855 
process_request_recv(struct tevent_req * req,TALLOC_CTX * mem_ctx,struct tevent_req_profile ** profile)856 static NTSTATUS process_request_recv(
857 	struct tevent_req *req,
858 	TALLOC_CTX *mem_ctx,
859 	struct tevent_req_profile **profile)
860 {
861 	NTSTATUS status;
862 
863 	if (tevent_req_is_nterror(req, &status)) {
864 		tevent_req_received(req);
865 		return status;
866 	}
867 
868 	*profile = tevent_req_move_profile(req, mem_ctx);
869 	tevent_req_received(req);
870 	return NT_STATUS_OK;
871 }
872 
873 /*
874  * This is the main event loop of winbind requests. It goes through a
875  * state-machine of 3 read/write requests, 4 if you have extra data to send.
876  *
877  * An idle winbind client has a read request of 4 bytes outstanding,
878  * finalizing function is request_len_recv, checking the length. request_recv
879  * then processes the packet. The processing function then at some point has
880  * to call request_finished which schedules sending the response.
881  */
882 
883 static void winbind_client_request_read(struct tevent_req *req);
884 static void winbind_client_activity(struct tevent_req *req);
885 static void winbind_client_processed(struct tevent_req *req);
886 
887 /* Process a new connection by adding it to the client connection list */
888 
new_connection(int listen_sock,bool privileged)889 static void new_connection(int listen_sock, bool privileged)
890 {
891 	struct sockaddr_un sunaddr;
892 	struct winbindd_cli_state *state;
893 	struct tevent_req *req;
894 	socklen_t len;
895 	int sock;
896 
897 	/* Accept connection */
898 
899 	len = sizeof(sunaddr);
900 
901 	sock = accept(listen_sock, (struct sockaddr *)(void *)&sunaddr, &len);
902 
903 	if (sock == -1) {
904 		if (errno != EINTR) {
905 			DEBUG(0, ("Failed to accept socket - %s\n",
906 				  strerror(errno)));
907 		}
908 		return;
909 	}
910 	smb_set_close_on_exec(sock);
911 
912 	DEBUG(6,("accepted socket %d\n", sock));
913 
914 	/* Create new connection structure */
915 
916 	if ((state = talloc_zero(NULL, struct winbindd_cli_state)) == NULL) {
917 		close(sock);
918 		return;
919 	}
920 
921 	state->sock = sock;
922 
923 	state->out_queue = tevent_queue_create(state, "winbind client reply");
924 	if (state->out_queue == NULL) {
925 		close(sock);
926 		TALLOC_FREE(state);
927 		return;
928 	}
929 
930 	state->privileged = privileged;
931 
932 	req = wb_req_read_send(state, global_event_context(), state->sock,
933 			       WINBINDD_MAX_EXTRA_DATA);
934 	if (req == NULL) {
935 		TALLOC_FREE(state);
936 		close(sock);
937 		return;
938 	}
939 	tevent_req_set_callback(req, winbind_client_request_read, state);
940 	state->io_req = req;
941 
942 	/* Add to connection list */
943 
944 	winbindd_add_client(state);
945 }
946 
winbind_client_request_read(struct tevent_req * req)947 static void winbind_client_request_read(struct tevent_req *req)
948 {
949 	struct winbindd_cli_state *state = tevent_req_callback_data(
950 		req, struct winbindd_cli_state);
951 	ssize_t ret;
952 	int err;
953 
954 	state->io_req = NULL;
955 
956 	ret = wb_req_read_recv(req, state, &state->request, &err);
957 	TALLOC_FREE(req);
958 	if (ret == -1) {
959 		if (err == EPIPE) {
960 			DEBUG(6, ("closing socket %d, client exited\n",
961 				  state->sock));
962 		} else {
963 			DEBUG(2, ("Could not read client request from fd %d: "
964 				  "%s\n", state->sock, strerror(err)));
965 		}
966 		close(state->sock);
967 		state->sock = -1;
968 		remove_client(state);
969 		return;
970 	}
971 
972 	req = wait_for_read_send(state, global_event_context(), state->sock,
973 				 true);
974 	if (req == NULL) {
975 		DEBUG(0, ("winbind_client_request_read[%d:%s]:"
976 			  " wait_for_read_send failed - removing client\n",
977 			  (int)state->pid, state->cmd_name));
978 		remove_client(state);
979 		return;
980 	}
981 	tevent_req_set_callback(req, winbind_client_activity, state);
982 	state->io_req = req;
983 
984 	req = process_request_send(state, global_event_context(), state);
985 	if (req == NULL) {
986 		DBG_ERR("process_request_send failed\n");
987 		remove_client(state);
988 		return;
989 	}
990 	tevent_req_set_callback(req, winbind_client_processed, state);
991 }
992 
winbind_client_activity(struct tevent_req * req)993 static void winbind_client_activity(struct tevent_req *req)
994 {
995 	struct winbindd_cli_state *state =
996 	    tevent_req_callback_data(req, struct winbindd_cli_state);
997 	int err;
998 	bool has_data;
999 
1000 	has_data = wait_for_read_recv(req, &err);
1001 
1002 	if (has_data) {
1003 		DEBUG(0, ("winbind_client_activity[%d:%s]:"
1004 			  "unexpected data from client - removing client\n",
1005 			  (int)state->pid, state->cmd_name));
1006 	} else {
1007 		if (err == EPIPE) {
1008 			DEBUG(6, ("winbind_client_activity[%d:%s]: "
1009 				  "client has closed connection - removing "
1010 				  "client\n",
1011 				  (int)state->pid, state->cmd_name));
1012 		} else {
1013 			DEBUG(2, ("winbind_client_activity[%d:%s]: "
1014 				  "client socket error (%s) - removing "
1015 				  "client\n",
1016 				  (int)state->pid, state->cmd_name,
1017 				  strerror(err)));
1018 		}
1019 	}
1020 
1021 	remove_client(state);
1022 }
1023 
winbind_client_processed(struct tevent_req * req)1024 static void winbind_client_processed(struct tevent_req *req)
1025 {
1026 	struct winbindd_cli_state *cli_state = tevent_req_callback_data(
1027 		req, struct winbindd_cli_state);
1028 	struct tevent_req_profile *profile = NULL;
1029 	struct timeval start, stop, diff;
1030 	int threshold;
1031 	NTSTATUS status;
1032 
1033 	status = process_request_recv(req, cli_state, &profile);
1034 	TALLOC_FREE(req);
1035 	if (!NT_STATUS_IS_OK(status)) {
1036 		DBG_DEBUG("process_request failed: %s\n", nt_errstr(status));
1037 		remove_client(cli_state);
1038 		return;
1039 	}
1040 
1041 	tevent_req_profile_get_start(profile, NULL, &start);
1042 	tevent_req_profile_get_stop(profile, NULL, &stop);
1043 	diff = tevent_timeval_until(&start, &stop);
1044 
1045 	threshold = lp_parm_int(-1, "winbind", "request profile threshold", 60);
1046 
1047 	if (diff.tv_sec >= threshold) {
1048 		int depth;
1049 		char *str;
1050 
1051 		depth = lp_parm_int(
1052 			-1,
1053 			"winbind",
1054 			"request profile depth",
1055 			INT_MAX);
1056 
1057 		DBG_ERR("request took %u.%.6u seconds\n",
1058 			(unsigned)diff.tv_sec, (unsigned)diff.tv_usec);
1059 
1060 		str = tevent_req_profile_string(
1061 			talloc_tos(), profile, 0, depth);
1062 		if (str != NULL) {
1063 			/* No "\n", already contained in "str" */
1064 			DEBUGADD(0, ("%s", str));
1065 		}
1066 		TALLOC_FREE(str);
1067 	}
1068 
1069 	TALLOC_FREE(profile);
1070 
1071 	req = wb_req_read_send(
1072 		cli_state,
1073 		global_event_context(),
1074 		cli_state->sock,
1075 		WINBINDD_MAX_EXTRA_DATA);
1076 	if (req == NULL) {
1077 		remove_client(cli_state);
1078 		return;
1079 	}
1080 	tevent_req_set_callback(req, winbind_client_request_read, cli_state);
1081 	cli_state->io_req = req;
1082 }
1083 
1084 /* Remove a client connection from client connection list */
1085 
remove_client(struct winbindd_cli_state * state)1086 static void remove_client(struct winbindd_cli_state *state)
1087 {
1088 	/* It's a dead client - hold a funeral */
1089 
1090 	if (state == NULL) {
1091 		return;
1092 	}
1093 
1094 	/*
1095 	 * We need to remove a pending wb_req_read_*
1096 	 * or wb_resp_write_* request before closing the
1097 	 * socket.
1098 	 *
1099 	 * This is important as they might have used tevent_add_fd() and we
1100 	 * use the epoll * backend on linux. So we must remove the tevent_fd
1101 	 * before closing the fd.
1102 	 *
1103 	 * Otherwise we might hit a race with close_conns_after_fork() (via
1104 	 * winbindd_reinit_after_fork()) where a file descriptor
1105 	 * is still open in a child, which means it's still active in
1106 	 * the parents epoll queue, but the related tevent_fd is already
1107 	 * already gone in the parent.
1108 	 *
1109 	 * See bug #11141.
1110 	 */
1111 	TALLOC_FREE(state->io_req);
1112 
1113 	if (state->sock != -1) {
1114 		char c = 0;
1115 		int nwritten;
1116 
1117 		/* tell client, we are closing ... */
1118 		nwritten = write(state->sock, &c, sizeof(c));
1119 		if (nwritten == -1) {
1120 			DEBUG(2, ("final write to client failed: %s\n",
1121 				strerror(errno)));
1122 		}
1123 
1124 		/* Close socket */
1125 
1126 		close(state->sock);
1127 		state->sock = -1;
1128 	}
1129 
1130 	TALLOC_FREE(state->mem_ctx);
1131 
1132 	/* Remove from list and free */
1133 
1134 	winbindd_remove_client(state);
1135 	TALLOC_FREE(state);
1136 }
1137 
1138 /* Is a client idle? */
1139 
client_is_idle(struct winbindd_cli_state * state)1140 static bool client_is_idle(struct winbindd_cli_state *state) {
1141   return (state->request == NULL &&
1142 	  state->response == NULL &&
1143 	  !state->pwent_state && !state->grent_state);
1144 }
1145 
1146 /* Shutdown client connection which has been idle for the longest time */
1147 
remove_idle_client(void)1148 static bool remove_idle_client(void)
1149 {
1150 	struct winbindd_cli_state *state, *remove_state = NULL;
1151 	int nidle = 0;
1152 
1153 	for (state = winbindd_client_list(); state; state = state->next) {
1154 		if (client_is_idle(state)) {
1155 			nidle++;
1156 			/* list is sorted by access time */
1157 			remove_state = state;
1158 		}
1159 	}
1160 
1161 	if (remove_state) {
1162 		DEBUG(5,("Found %d idle client connections, shutting down sock %d, pid %u\n",
1163 			nidle, remove_state->sock, (unsigned int)remove_state->pid));
1164 		remove_client(remove_state);
1165 		return True;
1166 	}
1167 
1168 	return False;
1169 }
1170 
1171 /*
1172  * Terminate all clients whose requests have taken longer than
1173  * "winbind request timeout" seconds to process, or have been
1174  * idle for more than "winbind request timeout" seconds.
1175  */
1176 
remove_timed_out_clients(void)1177 static void remove_timed_out_clients(void)
1178 {
1179 	struct winbindd_cli_state *state, *prev = NULL;
1180 	time_t curr_time = time(NULL);
1181 	int timeout_val = lp_winbind_request_timeout();
1182 
1183 	for (state = winbindd_client_list_tail(); state; state = prev) {
1184 		time_t expiry_time;
1185 
1186 		prev = winbindd_client_list_prev(state);
1187 		expiry_time = state->last_access + timeout_val;
1188 
1189 		if (curr_time <= expiry_time) {
1190 			/* list is sorted, previous clients in
1191 			   list are newer */
1192 			break;
1193 		}
1194 
1195 		if (client_is_idle(state)) {
1196 			DEBUG(5,("Idle client timed out, "
1197 				 "shutting down sock %d, pid %u\n",
1198 				 state->sock,
1199 				 (unsigned int)state->pid));
1200 		} else {
1201 			DEBUG(5,("Client request timed out, "
1202 				 "shutting down sock %d, pid %u\n",
1203 				 state->sock,
1204 				 (unsigned int)state->pid));
1205 		}
1206 
1207 		remove_client(state);
1208 	}
1209 }
1210 
winbindd_scrub_clients_handler(struct tevent_context * ev,struct tevent_timer * te,struct timeval current_time,void * private_data)1211 static void winbindd_scrub_clients_handler(struct tevent_context *ev,
1212 					   struct tevent_timer *te,
1213 					   struct timeval current_time,
1214 					   void *private_data)
1215 {
1216 	remove_timed_out_clients();
1217 	if (tevent_add_timer(ev, ev,
1218 			     timeval_current_ofs(SCRUB_CLIENTS_INTERVAL, 0),
1219 			     winbindd_scrub_clients_handler, NULL) == NULL) {
1220 		DEBUG(0, ("winbindd: failed to reschedule client scrubber\n"));
1221 		exit(1);
1222 	}
1223 }
1224 
1225 struct winbindd_listen_state {
1226 	bool privileged;
1227 	int fd;
1228 };
1229 
winbindd_listen_fde_handler(struct tevent_context * ev,struct tevent_fd * fde,uint16_t flags,void * private_data)1230 static void winbindd_listen_fde_handler(struct tevent_context *ev,
1231 					struct tevent_fd *fde,
1232 					uint16_t flags,
1233 					void *private_data)
1234 {
1235 	struct winbindd_listen_state *s = talloc_get_type_abort(private_data,
1236 					  struct winbindd_listen_state);
1237 
1238 	while (winbindd_num_clients() > lp_winbind_max_clients() - 1) {
1239 		DEBUG(5,("winbindd: Exceeding %d client "
1240 			 "connections, removing idle "
1241 			 "connection.\n", lp_winbind_max_clients()));
1242 		if (!remove_idle_client()) {
1243 			DEBUG(0,("winbindd: Exceeding %d "
1244 				 "client connections, no idle "
1245 				 "connection found\n",
1246 				 lp_winbind_max_clients()));
1247 			break;
1248 		}
1249 	}
1250 	remove_timed_out_clients();
1251 	new_connection(s->fd, s->privileged);
1252 }
1253 
1254 /*
1255  * Winbindd socket accessor functions
1256  */
1257 
get_winbind_priv_pipe_dir(void)1258 char *get_winbind_priv_pipe_dir(void)
1259 {
1260 	return state_path(talloc_tos(), WINBINDD_PRIV_SOCKET_SUBDIR);
1261 }
1262 
winbindd_setup_max_fds(void)1263 static void winbindd_setup_max_fds(void)
1264 {
1265 	int num_fds = MAX_OPEN_FUDGEFACTOR;
1266 	int actual_fds;
1267 
1268 	num_fds += lp_winbind_max_clients();
1269 	/* Add some more to account for 2 sockets open
1270 	   when the client transitions from unprivileged
1271 	   to privileged socket
1272 	*/
1273 	num_fds += lp_winbind_max_clients() / 10;
1274 
1275 	/* Add one socket per child process
1276 	   (yeah there are child processes other than the
1277 	   domain children but only domain children can vary
1278 	   with configuration
1279 	*/
1280 	num_fds += lp_winbind_max_domain_connections() *
1281 		   (lp_allow_trusted_domains() ? WINBIND_MAX_DOMAINS_HINT : 1);
1282 
1283 	actual_fds = set_maxfiles(num_fds);
1284 
1285 	if (actual_fds < num_fds) {
1286 		DEBUG(1, ("winbindd_setup_max_fds: Information only: "
1287 			  "requested %d open files, %d are available.\n",
1288 			  num_fds, actual_fds));
1289 	}
1290 }
1291 
winbindd_setup_listeners(void)1292 static bool winbindd_setup_listeners(void)
1293 {
1294 	struct winbindd_listen_state *pub_state = NULL;
1295 	struct winbindd_listen_state *priv_state = NULL;
1296 	struct tevent_fd *fde;
1297 	int rc;
1298 	char *socket_path;
1299 
1300 	pub_state = talloc(global_event_context(),
1301 			   struct winbindd_listen_state);
1302 	if (!pub_state) {
1303 		goto failed;
1304 	}
1305 
1306 	pub_state->privileged = false;
1307 	pub_state->fd = create_pipe_sock(
1308 		lp_winbindd_socket_directory(), WINBINDD_SOCKET_NAME, 0755);
1309 	if (pub_state->fd == -1) {
1310 		goto failed;
1311 	}
1312 	rc = listen(pub_state->fd, DEFAULT_LISTEN_BACKLOG);
1313 	if (rc < 0) {
1314 		goto failed;
1315 	}
1316 
1317 	fde = tevent_add_fd(global_event_context(), pub_state, pub_state->fd,
1318 			    TEVENT_FD_READ, winbindd_listen_fde_handler,
1319 			    pub_state);
1320 	if (fde == NULL) {
1321 		close(pub_state->fd);
1322 		goto failed;
1323 	}
1324 	tevent_fd_set_auto_close(fde);
1325 
1326 	priv_state = talloc(global_event_context(),
1327 			    struct winbindd_listen_state);
1328 	if (!priv_state) {
1329 		goto failed;
1330 	}
1331 
1332 	socket_path = get_winbind_priv_pipe_dir();
1333 	if (socket_path == NULL) {
1334 		goto failed;
1335 	}
1336 
1337 	priv_state->privileged = true;
1338 	priv_state->fd = create_pipe_sock(
1339 		socket_path, WINBINDD_SOCKET_NAME, 0750);
1340 	TALLOC_FREE(socket_path);
1341 	if (priv_state->fd == -1) {
1342 		goto failed;
1343 	}
1344 	rc = listen(priv_state->fd, DEFAULT_LISTEN_BACKLOG);
1345 	if (rc < 0) {
1346 		goto failed;
1347 	}
1348 
1349 	fde = tevent_add_fd(global_event_context(), priv_state,
1350 			    priv_state->fd, TEVENT_FD_READ,
1351 			    winbindd_listen_fde_handler, priv_state);
1352 	if (fde == NULL) {
1353 		close(priv_state->fd);
1354 		goto failed;
1355 	}
1356 	tevent_fd_set_auto_close(fde);
1357 
1358 	winbindd_scrub_clients_handler(global_event_context(), NULL,
1359 				       timeval_current(), NULL);
1360 	return true;
1361 failed:
1362 	TALLOC_FREE(pub_state);
1363 	TALLOC_FREE(priv_state);
1364 	return false;
1365 }
1366 
winbindd_use_idmap_cache(void)1367 bool winbindd_use_idmap_cache(void)
1368 {
1369 	return !opt_nocache;
1370 }
1371 
winbindd_use_cache(void)1372 bool winbindd_use_cache(void)
1373 {
1374 	return !opt_nocache;
1375 }
1376 
winbindd_register_handlers(struct messaging_context * msg_ctx,bool foreground)1377 static void winbindd_register_handlers(struct messaging_context *msg_ctx,
1378 				       bool foreground)
1379 {
1380 	bool scan_trusts = true;
1381 	NTSTATUS status;
1382 	/* Setup signal handlers */
1383 
1384 	if (!winbindd_setup_sig_term_handler(true))
1385 		exit(1);
1386 	if (!winbindd_setup_stdin_handler(true, foreground))
1387 		exit(1);
1388 	if (!winbindd_setup_sig_hup_handler(NULL))
1389 		exit(1);
1390 	if (!winbindd_setup_sig_chld_handler())
1391 		exit(1);
1392 	if (!winbindd_setup_sig_usr2_handler())
1393 		exit(1);
1394 
1395 	CatchSignal(SIGPIPE, SIG_IGN);                 /* Ignore sigpipe */
1396 
1397 	/*
1398 	 * Ensure all cache and idmap caches are consistent
1399 	 * and initialized before we startup.
1400 	 */
1401 	if (!winbindd_cache_validate_and_initialize()) {
1402 		exit(1);
1403 	}
1404 
1405 	/* React on 'smbcontrol winbindd reload-config' in the same way
1406 	   as to SIGHUP signal */
1407 	messaging_register(msg_ctx, NULL,
1408 			   MSG_SMB_CONF_UPDATED,
1409 			   winbindd_msg_reload_services_parent);
1410 	messaging_register(msg_ctx, NULL,
1411 			   MSG_SHUTDOWN, msg_shutdown);
1412 
1413 	/* Handle online/offline messages. */
1414 	messaging_register(msg_ctx, NULL,
1415 			   MSG_WINBIND_OFFLINE, winbind_msg_offline);
1416 	messaging_register(msg_ctx, NULL,
1417 			   MSG_WINBIND_ONLINE, winbind_msg_online);
1418 	messaging_register(msg_ctx, NULL,
1419 			   MSG_WINBIND_ONLINESTATUS, winbind_msg_onlinestatus);
1420 
1421 	/* Handle domain online/offline messages for domains */
1422 	messaging_register(global_messaging_context(), NULL,
1423 			   MSG_WINBIND_DOMAIN_OFFLINE, winbind_msg_domain_offline);
1424 	messaging_register(global_messaging_context(), NULL,
1425 			   MSG_WINBIND_DOMAIN_ONLINE, winbind_msg_domain_online);
1426 
1427 	messaging_register(msg_ctx, NULL,
1428 			   MSG_WINBIND_VALIDATE_CACHE,
1429 			   winbind_msg_validate_cache);
1430 
1431 	messaging_register(msg_ctx, NULL,
1432 			   MSG_WINBIND_DUMP_DOMAIN_LIST,
1433 			   winbind_msg_dump_domain_list);
1434 
1435 	messaging_register(msg_ctx, NULL,
1436 			   MSG_WINBIND_IP_DROPPED,
1437 			   winbind_msg_ip_dropped_parent);
1438 
1439 	/* Register handler for MSG_DEBUG. */
1440 	messaging_register(msg_ctx, NULL,
1441 			   MSG_DEBUG,
1442 			   winbind_msg_debug);
1443 
1444 	messaging_register(msg_ctx, NULL,
1445 			   MSG_WINBIND_DISCONNECT_DC,
1446 			   winbind_disconnect_dc_parent);
1447 
1448 	netsamlogon_cache_init(); /* Non-critical */
1449 
1450 	/* clear the cached list of trusted domains */
1451 
1452 	wcache_tdc_clear();
1453 
1454 	if (!init_domain_list()) {
1455 		DEBUG(0,("unable to initialize domain list\n"));
1456 		exit(1);
1457 	}
1458 
1459 	init_idmap_child();
1460 	init_locator_child();
1461 
1462 	smb_nscd_flush_user_cache();
1463 	smb_nscd_flush_group_cache();
1464 
1465 	if (!lp_winbind_scan_trusted_domains()) {
1466 		scan_trusts = false;
1467 	}
1468 
1469 	if (!lp_allow_trusted_domains()) {
1470 		scan_trusts = false;
1471 	}
1472 
1473 	if (IS_DC) {
1474 		scan_trusts = false;
1475 	}
1476 
1477 	if (scan_trusts) {
1478 		if (tevent_add_timer(global_event_context(), NULL, timeval_zero(),
1479 			      rescan_trusted_domains, NULL) == NULL) {
1480 			DEBUG(0, ("Could not trigger rescan_trusted_domains()\n"));
1481 			exit(1);
1482 		}
1483 	}
1484 
1485 	status = wb_irpc_register();
1486 
1487 	if (!NT_STATUS_IS_OK(status)) {
1488 		DEBUG(0, ("Could not register IRPC handlers\n"));
1489 		exit(1);
1490 	}
1491 }
1492 
1493 struct winbindd_addrchanged_state {
1494 	struct addrchange_context *ctx;
1495 	struct tevent_context *ev;
1496 	struct messaging_context *msg_ctx;
1497 };
1498 
1499 static void winbindd_addr_changed(struct tevent_req *req);
1500 
winbindd_init_addrchange(TALLOC_CTX * mem_ctx,struct tevent_context * ev,struct messaging_context * msg_ctx)1501 static void winbindd_init_addrchange(TALLOC_CTX *mem_ctx,
1502 				     struct tevent_context *ev,
1503 				     struct messaging_context *msg_ctx)
1504 {
1505 	struct winbindd_addrchanged_state *state;
1506 	struct tevent_req *req;
1507 	NTSTATUS status;
1508 
1509 	state = talloc(mem_ctx, struct winbindd_addrchanged_state);
1510 	if (state == NULL) {
1511 		DEBUG(10, ("talloc failed\n"));
1512 		return;
1513 	}
1514 	state->ev = ev;
1515 	state->msg_ctx = msg_ctx;
1516 
1517 	status = addrchange_context_create(state, &state->ctx);
1518 	if (!NT_STATUS_IS_OK(status)) {
1519 		DEBUG(10, ("addrchange_context_create failed: %s\n",
1520 			   nt_errstr(status)));
1521 		TALLOC_FREE(state);
1522 		return;
1523 	}
1524 	req = addrchange_send(state, ev, state->ctx);
1525 	if (req == NULL) {
1526 		DEBUG(0, ("addrchange_send failed\n"));
1527 		TALLOC_FREE(state);
1528 		return;
1529 	}
1530 	tevent_req_set_callback(req, winbindd_addr_changed, state);
1531 }
1532 
winbindd_addr_changed(struct tevent_req * req)1533 static void winbindd_addr_changed(struct tevent_req *req)
1534 {
1535 	struct winbindd_addrchanged_state *state = tevent_req_callback_data(
1536 		req, struct winbindd_addrchanged_state);
1537 	enum addrchange_type type;
1538 	struct sockaddr_storage addr;
1539 	NTSTATUS status;
1540 
1541 	status = addrchange_recv(req, &type, &addr);
1542 	TALLOC_FREE(req);
1543 	if (!NT_STATUS_IS_OK(status)) {
1544 		DEBUG(10, ("addrchange_recv failed: %s, stop listening\n",
1545 			   nt_errstr(status)));
1546 		TALLOC_FREE(state);
1547 		return;
1548 	}
1549 	if (type == ADDRCHANGE_DEL) {
1550 		char addrstr[INET6_ADDRSTRLEN];
1551 		DATA_BLOB blob;
1552 
1553 		print_sockaddr(addrstr, sizeof(addrstr), &addr);
1554 
1555 		DEBUG(3, ("winbindd: kernel (AF_NETLINK) dropped ip %s\n",
1556 			  addrstr));
1557 
1558 		blob = data_blob_const(addrstr, strlen(addrstr)+1);
1559 
1560 		status = messaging_send(state->msg_ctx,
1561 					messaging_server_id(state->msg_ctx),
1562 					MSG_WINBIND_IP_DROPPED, &blob);
1563 		if (!NT_STATUS_IS_OK(status)) {
1564 			DEBUG(10, ("messaging_send failed: %s - ignoring\n",
1565 				   nt_errstr(status)));
1566 		}
1567 	}
1568 	req = addrchange_send(state, state->ev, state->ctx);
1569 	if (req == NULL) {
1570 		DEBUG(0, ("addrchange_send failed\n"));
1571 		TALLOC_FREE(state);
1572 		return;
1573 	}
1574 	tevent_req_set_callback(req, winbindd_addr_changed, state);
1575 }
1576 
1577 /* Main function */
1578 
main(int argc,const char ** argv)1579 int main(int argc, const char **argv)
1580 {
1581 	static bool is_daemon = False;
1582 	static bool Fork = True;
1583 	static bool log_stdout = False;
1584 	static bool no_process_group = False;
1585 	enum {
1586 		OPT_DAEMON = 1000,
1587 		OPT_FORK,
1588 		OPT_NO_PROCESS_GROUP,
1589 		OPT_LOG_STDOUT
1590 	};
1591 	struct poptOption long_options[] = {
1592 		POPT_AUTOHELP
1593 		{
1594 			.longName   = "stdout",
1595 			.shortName  = 'S',
1596 			.argInfo    = POPT_ARG_NONE,
1597 			.arg        = NULL,
1598 			.val        = OPT_LOG_STDOUT,
1599 			.descrip    = "Log to stdout",
1600 		},
1601 		{
1602 			.longName   = "foreground",
1603 			.shortName  = 'F',
1604 			.argInfo    = POPT_ARG_NONE,
1605 			.arg        = NULL,
1606 			.val        = OPT_FORK,
1607 			.descrip    = "Daemon in foreground mode",
1608 		},
1609 		{
1610 			.longName   = "no-process-group",
1611 			.shortName  = 0,
1612 			.argInfo    = POPT_ARG_NONE,
1613 			.arg        = NULL,
1614 			.val        = OPT_NO_PROCESS_GROUP,
1615 			.descrip    = "Don't create a new process group",
1616 		},
1617 		{
1618 			.longName   = "daemon",
1619 			.shortName  = 'D',
1620 			.argInfo    = POPT_ARG_NONE,
1621 			.arg        = NULL,
1622 			.val        = OPT_DAEMON,
1623 			.descrip    = "Become a daemon (default)",
1624 		},
1625 		{
1626 			.longName   = "interactive",
1627 			.shortName  = 'i',
1628 			.argInfo    = POPT_ARG_NONE,
1629 			.arg        = NULL,
1630 			.val        = 'i',
1631 			.descrip    = "Interactive mode",
1632 		},
1633 		{
1634 			.longName   = "no-caching",
1635 			.shortName  = 'n',
1636 			.argInfo    = POPT_ARG_NONE,
1637 			.arg        = NULL,
1638 			.val        = 'n',
1639 			.descrip    = "Disable caching",
1640 		},
1641 		POPT_COMMON_SAMBA
1642 		POPT_TABLEEND
1643 	};
1644 	const struct loadparm_substitution *lp_sub =
1645 		loadparm_s3_global_substitution();
1646 	poptContext pc;
1647 	int opt;
1648 	TALLOC_CTX *frame;
1649 	NTSTATUS status;
1650 	bool ok;
1651 
1652 	setproctitle_init(argc, discard_const(argv), environ);
1653 
1654 	/*
1655 	 * Do this before any other talloc operation
1656 	 */
1657 	talloc_enable_null_tracking();
1658 	frame = talloc_stackframe();
1659 
1660 	/*
1661 	 * We want total control over the permissions on created files,
1662 	 * so set our umask to 0.
1663 	 */
1664 	umask(0);
1665 
1666 	setup_logging("winbindd", DEBUG_DEFAULT_STDOUT);
1667 
1668 	/* glibc (?) likes to print "User defined signal 1" and exit if a
1669 	   SIGUSR[12] is received before a handler is installed */
1670 
1671  	CatchSignal(SIGUSR1, SIG_IGN);
1672  	CatchSignal(SIGUSR2, SIG_IGN);
1673 
1674 	fault_setup();
1675 	dump_core_setup("winbindd", lp_logfile(talloc_tos(), lp_sub));
1676 
1677 	smb_init_locale();
1678 
1679 	/* Initialise for running in non-root mode */
1680 
1681 	sec_init();
1682 
1683 	set_remote_machine_name("winbindd", False);
1684 
1685 	/* Set environment variable so we don't recursively call ourselves.
1686 	   This may also be useful interactively. */
1687 
1688 	if ( !winbind_off() ) {
1689 		DEBUG(0,("Failed to disable recusive winbindd calls.  Exiting.\n"));
1690 		exit(1);
1691 	}
1692 
1693 	/* Initialise samba/rpc client stuff */
1694 
1695 	pc = poptGetContext("winbindd", argc, argv, long_options, 0);
1696 
1697 	while ((opt = poptGetNextOpt(pc)) != -1) {
1698 		switch (opt) {
1699 			/* Don't become a daemon */
1700 		case OPT_DAEMON:
1701 			is_daemon = True;
1702 			break;
1703 		case 'i':
1704 			interactive = True;
1705 			log_stdout = True;
1706 			Fork = False;
1707 			break;
1708                 case OPT_FORK:
1709 			Fork = false;
1710 			break;
1711 		case OPT_NO_PROCESS_GROUP:
1712 			no_process_group = true;
1713 			break;
1714 		case OPT_LOG_STDOUT:
1715 			log_stdout = true;
1716 			break;
1717 		case 'n':
1718 			opt_nocache = true;
1719 			break;
1720 		default:
1721 			d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
1722 				  poptBadOption(pc, 0), poptStrerror(opt));
1723 			poptPrintUsage(pc, stderr, 0);
1724 			exit(1);
1725 		}
1726 	}
1727 
1728 	/* We call dump_core_setup one more time because the command line can
1729 	 * set the log file or the log-basename and this will influence where
1730 	 * cores are stored. Without this call get_dyn_LOGFILEBASE will be
1731 	 * the default value derived from build's prefix. For EOM this value
1732 	 * is often not related to the path where winbindd is actually run
1733 	 * in production.
1734 	 */
1735 	dump_core_setup("winbindd", lp_logfile(talloc_tos(), lp_sub));
1736 	if (is_daemon && interactive) {
1737 		d_fprintf(stderr,"\nERROR: "
1738 			  "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
1739 		poptPrintUsage(pc, stderr, 0);
1740 		exit(1);
1741 	}
1742 
1743 	if (log_stdout && Fork) {
1744 		d_fprintf(stderr, "\nERROR: "
1745 			  "Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n\n");
1746 		poptPrintUsage(pc, stderr, 0);
1747 		exit(1);
1748 	}
1749 
1750 	poptFreeContext(pc);
1751 
1752 	if (!override_logfile) {
1753 		char *lfile = NULL;
1754 		if (asprintf(&lfile,"%s/log.winbindd",
1755 				get_dyn_LOGFILEBASE()) > 0) {
1756 			lp_set_logfile(lfile);
1757 			SAFE_FREE(lfile);
1758 		}
1759 	}
1760 
1761 	if (log_stdout) {
1762 		setup_logging("winbindd", DEBUG_STDOUT);
1763 	} else {
1764 		setup_logging("winbindd", DEBUG_FILE);
1765 	}
1766 	reopen_logs();
1767 
1768 	DEBUG(0,("winbindd version %s started.\n", samba_version_string()));
1769 	DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
1770 
1771 	if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
1772 		DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
1773 		exit(1);
1774 	}
1775 	/* After parsing the configuration file we setup the core path one more time
1776 	 * as the log file might have been set in the configuration and cores's
1777 	 * path is by default basename(lp_logfile()).
1778 	 */
1779 	dump_core_setup("winbindd", lp_logfile(talloc_tos(), lp_sub));
1780 
1781 	if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
1782 	    && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
1783 		DEBUG(0, ("server role = 'active directory domain controller' not compatible with running the winbindd binary. \n"));
1784 		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"));
1785 		exit(1);
1786 	}
1787 
1788 	if (!cluster_probe_ok()) {
1789 		exit(1);
1790 	}
1791 
1792 	/* Initialise messaging system */
1793 
1794 	if (global_messaging_context() == NULL) {
1795 		exit(1);
1796 	}
1797 
1798 	if (!winbindd_reload_services_file(NULL)) {
1799 		DEBUG(0, ("error opening config file\n"));
1800 		exit(1);
1801 	}
1802 
1803 	{
1804 		size_t i;
1805 		const char *idmap_backend;
1806 		const char *invalid_backends[] = {
1807 			"ad", "rfc2307", "rid",
1808 		};
1809 
1810 		idmap_backend = lp_idmap_default_backend();
1811 		for (i = 0; i < ARRAY_SIZE(invalid_backends); i++) {
1812 			ok = strequal(idmap_backend, invalid_backends[i]);
1813 			if (ok) {
1814 				DBG_ERR("FATAL: Invalid idmap backend %s "
1815 					"configured as the default backend!\n",
1816 					idmap_backend);
1817 				exit(1);
1818 			}
1819 		}
1820 	}
1821 
1822 	ok = directory_create_or_exist(lp_lock_directory(), 0755);
1823 	if (!ok) {
1824 		DEBUG(0, ("Failed to create directory %s for lock files - %s\n",
1825 			  lp_lock_directory(), strerror(errno)));
1826 		exit(1);
1827 	}
1828 
1829 	ok = directory_create_or_exist(lp_pid_directory(), 0755);
1830 	if (!ok) {
1831 		DEBUG(0, ("Failed to create directory %s for pid files - %s\n",
1832 			  lp_pid_directory(), strerror(errno)));
1833 		exit(1);
1834 	}
1835 
1836 	/* Setup names. */
1837 
1838 	if (!init_names())
1839 		exit(1);
1840 
1841   	load_interfaces();
1842 
1843 	if (!secrets_init()) {
1844 
1845 		DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n"));
1846 		return False;
1847 	}
1848 
1849 	status = rpccli_pre_open_netlogon_creds();
1850 	if (!NT_STATUS_IS_OK(status)) {
1851 		DEBUG(0, ("rpccli_pre_open_netlogon_creds() - %s\n",
1852 			  nt_errstr(status)));
1853 		exit(1);
1854 	}
1855 
1856 	/* Unblock all signals we are interested in as they may have been
1857 	   blocked by the parent process. */
1858 
1859 	BlockSignals(False, SIGINT);
1860 	BlockSignals(False, SIGQUIT);
1861 	BlockSignals(False, SIGTERM);
1862 	BlockSignals(False, SIGUSR1);
1863 	BlockSignals(False, SIGUSR2);
1864 	BlockSignals(False, SIGHUP);
1865 	BlockSignals(False, SIGCHLD);
1866 
1867 	if (!interactive)
1868 		become_daemon(Fork, no_process_group, log_stdout);
1869 
1870 	pidfile_create(lp_pid_directory(), "winbindd");
1871 
1872 #ifdef HAVE_SETPGID
1873 	/*
1874 	 * If we're interactive we want to set our own process group for
1875 	 * signal management.
1876 	 */
1877 	if (interactive && !no_process_group)
1878 		setpgid( (pid_t)0, (pid_t)0);
1879 #endif
1880 
1881 	TimeInit();
1882 
1883 	/* Don't use winbindd_reinit_after_fork here as
1884 	 * we're just starting up and haven't created any
1885 	 * winbindd-specific resources we must free yet. JRA.
1886 	 */
1887 
1888 	status = reinit_after_fork(global_messaging_context(),
1889 				   global_event_context(),
1890 				   false, NULL);
1891 	if (!NT_STATUS_IS_OK(status)) {
1892 		exit_daemon("Winbindd reinit_after_fork() failed", map_errno_from_nt_status(status));
1893 	}
1894 
1895 	ok = initialize_password_db(true, global_event_context());
1896 	if (!ok) {
1897 		exit_daemon("Failed to initialize passdb backend! "
1898 			    "Check the 'passdb backend' variable in your "
1899 			    "smb.conf file.", EINVAL);
1900 	}
1901 
1902 	/*
1903 	 * Do not initialize the parent-child-pipe before becoming
1904 	 * a daemon: this is used to detect a died parent in the child
1905 	 * process.
1906 	 */
1907 	status = init_before_fork();
1908 	if (!NT_STATUS_IS_OK(status)) {
1909 		exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1910 	}
1911 
1912 	winbindd_register_handlers(global_messaging_context(), !Fork);
1913 
1914 	if (!messaging_parent_dgm_cleanup_init(global_messaging_context())) {
1915 		exit(1);
1916 	}
1917 
1918 	status = init_system_session_info(NULL);
1919 	if (!NT_STATUS_IS_OK(status)) {
1920 		exit_daemon("Winbindd failed to setup system user info", map_errno_from_nt_status(status));
1921 	}
1922 
1923 	rpc_lsarpc_init(NULL);
1924 	rpc_samr_init(NULL);
1925 
1926 	winbindd_init_addrchange(NULL, global_event_context(),
1927 				 global_messaging_context());
1928 
1929 	/* setup listen sockets */
1930 
1931 	if (!winbindd_setup_listeners()) {
1932 		exit_daemon("Winbindd failed to setup listeners", EPIPE);
1933 	}
1934 
1935 	irpc_add_name(winbind_imessaging_context(), "winbind_server");
1936 
1937 	TALLOC_FREE(frame);
1938 
1939 	if (!interactive) {
1940 		daemon_ready("winbindd");
1941 	}
1942 
1943 	gpupdate_init();
1944 
1945 	/* Loop waiting for requests */
1946 	while (1) {
1947 		frame = talloc_stackframe();
1948 
1949 		if (tevent_loop_once(global_event_context()) == -1) {
1950 			DEBUG(1, ("tevent_loop_once() failed: %s\n",
1951 				  strerror(errno)));
1952 			return 1;
1953 		}
1954 
1955 		TALLOC_FREE(frame);
1956 	}
1957 
1958 	return 0;
1959 }
1960