preparing for release of alpha-2.6
[Samba/gbeck.git] / source / rpc_client / ncalrpc_l_use.c
blob64e4b90ed7fc3dbb4d86c35967b22b214ba9a10c
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 SMB client generic functions
5 Copyright (C) Andrew Tridgell 1994-1999
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1999
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.
23 #define NO_SYSLOG
25 #include "includes.h"
26 #include "rpc_parse.h"
28 extern int DEBUGLEVEL;
30 struct ncalrpc_use
32 struct msrpc_local *cli;
33 uint32 num_users;
36 static struct ncalrpc_use **clis = NULL;
37 static uint32 num_clis = 0;
39 /****************************************************************************
40 terminate client connection
41 ****************************************************************************/
42 static void ncalrpc_use_free(struct ncalrpc_use *cli)
44 if (cli->cli != NULL)
46 if (cli->cli->initialised)
48 ncalrpc_l_shutdown(cli->cli);
50 free(cli->cli);
53 free(cli);
56 /****************************************************************************
57 free a client array
58 ****************************************************************************/
59 static void free_cli_array(uint32 num_entries, struct ncalrpc_use **entries)
61 void (*fn) (void *) = (void (*)(void *))&ncalrpc_use_free;
62 free_void_array(num_entries, (void **)entries, *fn);
65 /****************************************************************************
66 add a client state to the array
67 ****************************************************************************/
68 static struct ncalrpc_use *add_cli_to_array(uint32 * len,
69 struct ncalrpc_use ***array,
70 struct ncalrpc_use *cli)
72 int i;
73 for (i = 0; i < num_clis; i++)
75 if (clis[i] == NULL)
77 clis[i] = cli;
78 return cli;
82 return (struct ncalrpc_use *)add_item_to_array(len,
83 (void ***)array,
84 (void *)cli);
88 /****************************************************************************
89 initiate client array
90 ****************************************************************************/
91 void init_ncalrpc_use(void)
93 clis = NULL;
94 num_clis = 0;
97 /****************************************************************************
98 terminate client array
99 ****************************************************************************/
100 void free_ncalrpc_use(void)
102 free_cli_array(num_clis, clis);
103 init_ncalrpc_use();
106 /****************************************************************************
107 find client state. server name, user name, vuid name and password must all
108 match.
109 ****************************************************************************/
110 static struct ncalrpc_use *ncalrpc_l_find(const char *pipe_name,
111 const vuser_key * key, BOOL reuse)
113 int i;
114 vuser_key null_usr;
116 if (key == NULL)
118 key = &null_usr;
119 null_usr.pid = sys_getpid();
120 null_usr.vuid = UID_FIELD_INVALID;
123 DEBUG(10, ("ncalrpc_l_find: %s [%d,%x]\n",
124 pipe_name, key->pid, key->vuid));
126 for (i = 0; i < num_clis; i++)
128 char *cli_name = NULL;
129 struct ncalrpc_use *c = clis[i];
131 if (c == NULL || !c->cli->initialised)
133 continue;
136 cli_name = c->cli->pipe_name;
138 DEBUG(10, ("ncalrpc_l_find[%d]: %s [%d,%x]\n",
139 i, cli_name,
140 c->cli->nt.key.pid, c->cli->nt.key.vuid));
142 if (!strequal(cli_name, pipe_name))
144 continue;
146 if (reuse)
148 return c;
150 if (key->vuid == c->cli->nt.key.vuid &&
151 key->pid == c->cli->nt.key.pid)
153 return c;
157 return NULL;
160 /****************************************************************************
161 create a new client state from user credentials
162 ****************************************************************************/
163 static struct ncalrpc_use *ncalrpc_use_get(const char *pipe_name,
164 const vuser_key * key)
166 struct ncalrpc_use *cli = (struct ncalrpc_use *)malloc(sizeof(*cli));
168 if (cli == NULL)
170 return NULL;
173 memset(cli, 0, sizeof(*cli));
175 cli->cli = ncalrpc_l_initialise(NULL, key);
177 if (cli->cli == NULL)
179 return NULL;
182 return cli;
185 /****************************************************************************
186 init client state
187 ****************************************************************************/
188 struct msrpc_local *ncalrpc_l_use_add(const char *pipe_name,
189 const vuser_key * key,
190 BOOL reuse, BOOL *is_new)
192 struct ncalrpc_use *cli;
194 DEBUG(10, ("ncalrpc_l_use_add\n"));
196 if (strnequal("\\PIPE\\", pipe_name, 6))
198 pipe_name = &pipe_name[6];
201 cli = ncalrpc_l_find(pipe_name, key, reuse);
203 if (cli != NULL)
205 cli->num_users++;
206 DEBUG(10,
207 ("ncalrpc_l_use_add: num_users: %d\n", cli->num_users));
208 (*is_new) = False;
209 return cli->cli;
213 * allocate
216 cli = ncalrpc_use_get(pipe_name, key);
219 * connect
222 if (!ncalrpc_l_establish_connection(cli->cli, pipe_name))
224 DEBUG(0, ("ncalrpc_l_use_add: connection failed\n"));
225 cli->cli = NULL;
226 ncalrpc_use_free(cli);
227 return NULL;
230 add_cli_to_array(&num_clis, &clis, cli);
231 cli->num_users++;
233 DEBUG(10, ("ncalrpc_l_use_add: num_users: %d\n", cli->num_users));
235 (*is_new) = True;
237 return cli->cli;
240 /****************************************************************************
241 delete a client state
242 ****************************************************************************/
243 BOOL ncalrpc_l_use_del(const char *pipe_name,
244 const vuser_key * key,
245 BOOL force_close, BOOL *connection_closed)
247 int i;
249 if (strnequal("\\PIPE\\", pipe_name, 6))
251 pipe_name = &pipe_name[6];
254 DEBUG(10, ("ncalrpc_l_use_del: %s. [%d,%x] force close: %s\n",
255 pipe_name, key->pid, key->vuid, BOOLSTR(force_close)));
257 if (connection_closed != NULL)
259 *connection_closed = False;
262 for (i = 0; i < num_clis; i++)
264 char *ncalrpc_name = NULL;
266 if (clis[i] == NULL)
267 continue;
268 if (clis[i]->cli == NULL)
269 continue;
271 ncalrpc_name = clis[i]->cli->pipe_name;
273 if (strnequal("\\PIPE\\", pipe_name, 6))
275 ncalrpc_name = &ncalrpc_name[6];
278 DEBUG(10, ("connection: %s [%d,%x]", ncalrpc_name,
279 clis[i]->cli->nt.key.pid,
280 clis[i]->cli->nt.key.vuid));
282 if (!strequal(ncalrpc_name, pipe_name))
283 continue;
285 if (key->pid != clis[i]->cli->nt.key.pid ||
286 key->vuid != clis[i]->cli->nt.key.vuid)
288 continue;
290 /* decrement number of users */
291 clis[i]->num_users--;
293 DEBUG(10, ("idx: %i num_users now: %d\n",
294 i, clis[i]->num_users));
296 if (force_close || clis[i]->num_users == 0)
298 ncalrpc_use_free(clis[i]);
299 clis[i] = NULL;
300 if (connection_closed != NULL)
302 *connection_closed = True;
305 return True;
308 return False;
311 /****************************************************************************
312 enumerate client states
313 ****************************************************************************/
314 void ncalrpc_l_use_enum(uint32 * num_cons, struct use_info ***use)
316 int i;
318 *num_cons = 0;
319 *use = NULL;
321 for (i = 0; i < num_clis; i++)
323 struct use_info item;
325 ZERO_STRUCT(item);
327 if (clis[i] == NULL)
328 continue;
330 item.connected = clis[i]->cli != NULL ? True : False;
332 if (item.connected)
334 item.srv_name = clis[i]->cli->pipe_name;
335 item.user_name = NULL;
336 item.key = clis[i]->cli->nt.key;
337 item.domain = NULL;
340 add_use_info_to_array(num_cons, use, &item);
345 /****************************************************************************
346 wait for keyboard activity, swallowing network packets on all client states.
347 ****************************************************************************/
348 void ncalrpc_use_wait_keyboard(void)
350 fd_set fds;
351 struct timeval timeout;
353 while (1)
355 int i;
356 int maxfd = fileno(stdin);
357 FD_ZERO(&fds);
358 FD_SET(fileno(stdin), &fds);
359 for (i = 0; i < num_clis; i++)
361 if (clis[i] != NULL && clis[i]->cli != NULL)
363 int fd = clis[i]->cli->fd;
364 FD_SET(fd, &fds);
365 maxfd = MAX(fd, maxfd);
369 timeout.tv_sec = 20;
370 timeout.tv_usec = 0;
371 sys_select(maxfd + 1, &fds, &timeout);
373 if (FD_ISSET(fileno(stdin), &fds))
374 return;
376 /* We deliberately use receive_smb instead of
377 client_receive_smb as we want to receive
378 session keepalives and then drop them here.
380 for (i = 0; i < num_clis; i++)
382 int fd = clis[i]->cli->fd;
383 if (FD_ISSET(fd, &fds))
384 receive_smb(fd, clis[i]->cli->inbuf, 0);