2
Unix SMB/CIFS implementation.
4
Winbind background daemon
6
Copyright (C) Andrew Tridgell 2002
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
the idea of the optional dual daemon mode is ot prevent slow domain
25
responses from clagging up the rest of the system. When in dual
26
daemon mode winbindd always responds to requests from cache if the
27
request is in cache, and if the cached answer is stale then it asks
28
the "dual daemon" to update the cache for that request
36
#define DBGC_CLASS DBGC_WINBIND
38
extern BOOL opt_dual_daemon;
39
BOOL background_process = False;
40
int dual_daemon_pipe = -1;
43
/* a list of requests ready to be sent to the dual daemon */
45
struct dual_list *next;
51
static struct dual_list *dual_list;
52
static struct dual_list *dual_list_end;
55
setup a select() including the dual daemon pipe
57
int dual_select_setup(fd_set *fds, int maxfd)
59
if (dual_daemon_pipe == -1 ||
64
FD_SET(dual_daemon_pipe, fds);
65
if (dual_daemon_pipe > maxfd) {
66
maxfd = dual_daemon_pipe;
73
a hook called from the main winbindd select() loop to handle writes
74
to the dual daemon pipe
76
void dual_select(fd_set *fds)
80
if (dual_daemon_pipe == -1 ||
82
!FD_ISSET(dual_daemon_pipe, fds)) {
86
n = sys_write(dual_daemon_pipe,
87
&dual_list->data[dual_list->offset],
88
dual_list->length - dual_list->offset);
91
/* the pipe is dead! fall back to normal operation */
92
dual_daemon_pipe = -1;
96
dual_list->offset += n;
98
if (dual_list->offset == dual_list->length) {
99
struct dual_list *next;
100
next = dual_list->next;
101
free(dual_list->data);
105
dual_list_end = NULL;
111
send a request to the background daemon
112
this is called for stale cached entries
114
void dual_send_request(struct winbindd_cli_state *state)
116
struct dual_list *list;
118
if (!background_process) return;
120
list = malloc(sizeof(*list));
124
list->data = memdup(&state->request, sizeof(state->request));
125
list->length = sizeof(state->request);
128
if (!dual_list_end) {
130
dual_list_end = list;
132
dual_list_end->next = list;
133
dual_list_end = list;
136
background_process = False;
143
void do_dual_daemon(void)
146
struct winbindd_cli_state state;
148
if (pipe(fdpair) != 0) {
153
state.pid = getpid();
155
dual_daemon_pipe = fdpair[1];
156
state.sock = fdpair[0];
164
/* tdb needs special fork handling */
165
if (tdb_reopen_all() == -1) {
166
DEBUG(0,("tdb_reopen_all failed.\n"));
170
dual_daemon_pipe = -1;
171
opt_dual_daemon = False;
174
/* free up any talloc memory */
176
main_loop_talloc_free();
178
/* fetch a request from the main daemon */
179
winbind_client_read(&state);
181
if (state.finished) {
182
/* we lost contact with our parent */
186
/* process full rquests */
187
if (state.read_buf_len == sizeof(state.request)) {
188
DEBUG(4,("dual daemon request %d\n", (int)state.request.cmd));
190
/* special handling for the stateful requests */
191
switch (state.request.cmd) {
192
case WINBINDD_GETPWENT:
193
winbindd_setpwent(&state);
196
case WINBINDD_GETGRENT:
197
case WINBINDD_GETGRLST:
198
winbindd_setgrent(&state);
204
winbind_process_packet(&state);
205
SAFE_FREE(state.response.extra_data);
207
free_getent_state(state.getpwent_state);
208
free_getent_state(state.getgrent_state);
209
state.getpwent_state = NULL;
210
state.getgrent_state = NULL;