deal with allocation size of 0 in prs_unistr when UNMARSHALLING
[Samba.git] / source / rpc_client / ncacn_np_use.c
blob8e5c7240461fc07b99ded79c3f3b12bceda15a14
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 SMB client generic functions
5 Copyright (C) Andrew Tridgell 1994-2000
6 Copyright (C) Luke Kenneth Casson Leighton 1996-2000
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 #define NO_SYSLOG
26 #include "includes.h"
27 #include "rpc_parse.h"
28 #include "rpc_client.h"
29 #include "trans2.h"
31 extern int DEBUGLEVEL;
32 extern pstring global_myname;
34 struct ncacn_np_use
36 struct ncacn_np *cli;
37 uint32 num_users;
40 static struct ncacn_np_use **msrpcs = NULL;
41 static uint32 num_msrpcs = 0;
43 /****************************************************************************
44 terminate client connection
45 ****************************************************************************/
46 static void ncacn_np_shutdown(struct ncacn_np *cli)
48 struct ntuser_creds usr;
49 BOOL closed;
51 if (cli != NULL)
53 if (cli->smb != NULL)
55 if (cli->smb->initialised)
57 /* cli_nt_session_close(cli->smb, cli->fnum); JERRY */
58 cli_nt_session_close(cli->smb);
60 create_ntc_from_cli_state(&usr, cli->smb);
61 cli_net_use_del(cli->smb->desthost, &usr, False, &closed);
66 static BOOL ncacn_np_establish_connection(struct ncacn_np *cli,
67 const char *srv_name,
68 const struct ntuser_creds *ntc,
69 const char *pipe_name,
70 BOOL reuse)
72 BOOL new_smb_conn;
73 cli->smb = cli_net_use_add(srv_name, ntc,
74 True, &new_smb_conn);
75 if (cli->smb == NULL)
77 return False;
79 /* if (!cli_nt_session_open(cli->smb, pipe_name, &cli->fnum)) by JERRY */
80 if (!cli_nt_session_open(cli->smb, pipe_name))
82 cli_net_use_del(srv_name, ntc, False, NULL);
83 return False;
85 fstrcpy(cli->pipe_name, pipe_name);
86 return True;
91 /****************************************************************************
92 terminate client connection
93 ****************************************************************************/
94 static void ncacn_np_use_free(struct ncacn_np_use *cli)
96 if (cli->cli != NULL)
98 if (cli->cli->initialised)
100 ncacn_np_shutdown(cli->cli);
102 ZERO_STRUCTP(cli->cli);
103 free(cli->cli);
105 ZERO_STRUCTP(cli);
106 free(cli);
109 /****************************************************************************
110 add a client state to the array
111 ****************************************************************************/
112 static struct ncacn_np_use *add_ncacn_np_to_array(uint32 * len,
113 struct ncacn_np_use
114 ***array,
115 struct ncacn_np_use *cli)
118 int i;
120 /* traverse the list and try to find a previously
121 allocate spot that is not being used */
122 for (i = 0; i < num_msrpcs; i++)
124 if (msrpcs[i] == NULL)
126 /* found and empty spot to
127 store the cli pointer */
128 msrpcs[i] = cli;
129 return cli;
133 return (struct ncacn_np_use *)add_item_to_array(len,
134 (void ***)array,
135 (void *)cli);
141 /****************************************************************************
142 delete a client state
143 ****************************************************************************/
144 BOOL ncacn_np_use_del(const char *srv_name, const char *pipe_name,
145 const vuser_key * key,
146 BOOL force_close, BOOL *connection_closed)
148 int i;
149 DEBUG(10, ("ncacn_np_net_use_del: %s. force close: %s ",
150 pipe_name, BOOLSTR(force_close)));
151 if (key != NULL)
153 DEBUG(10, ("[%d,%x]", key->pid, key->vuid));
155 DEBUG(10, ("\n"));
157 if (connection_closed != NULL)
159 *connection_closed = False;
162 if (strnequal("\\PIPE\\", pipe_name, 6))
164 pipe_name = &pipe_name[6];
167 if (strnequal("\\\\", srv_name, 2))
169 srv_name = &srv_name[2];
172 for (i = 0; i < num_msrpcs; i++)
174 char *ncacn_np_name = NULL;
175 char *ncacn_np_srv_name = NULL;
176 struct ncacn_np_use *c = msrpcs[i];
177 vuser_key k;
179 if (c == NULL || c->cli == NULL || c->cli->smb == NULL)
180 continue;
182 ncacn_np_name = c->cli->pipe_name;
183 ncacn_np_srv_name = c->cli->smb->desthost;
185 k = c->cli->smb->key;
187 DEBUG(10, ("use_del[%d]: %s %s %s %s [%d,%x]\n",
188 i, ncacn_np_name, ncacn_np_srv_name,
189 c->cli->smb->user_name,
190 c->cli->smb->domain, k.pid, k.vuid));
192 if (strnequal("\\PIPE\\", ncacn_np_name, 6))
194 ncacn_np_name = &ncacn_np_name[6];
196 if (!strequal(ncacn_np_name, pipe_name))
198 continue;
200 if (strnequal("\\\\", ncacn_np_srv_name, 2))
202 ncacn_np_srv_name = &ncacn_np_srv_name[2];
204 if (!strequal(ncacn_np_srv_name, srv_name))
206 continue;
208 if (key->pid != k.pid || key->vuid != k.vuid)
210 continue;
212 /* decrement number of users */
213 c->num_users--;
214 DEBUG(10, ("idx: %i num_users now: %d\n",
215 i, c->num_users));
216 if (force_close || c->num_users == 0)
218 ncacn_np_use_free(c);
219 msrpcs[i] = NULL;
220 if (connection_closed != NULL)
222 *connection_closed = True;
225 return True;
228 return False;
231 /****************************************************************************
232 find client state. server name, user name, domain name and password must all
233 match.
234 ****************************************************************************/
235 static struct ncacn_np_use *ncacn_np_find(const char *srv_name,
236 const char *pipe_name,
237 const vuser_key * key,
238 const struct ntuser_creds
239 *usr_creds, BOOL reuse)
241 int i;
242 const char *sv_name = srv_name;
244 if (strnequal("\\PIPE\\", pipe_name, 6))
246 pipe_name = &pipe_name[6];
249 if (strnequal("\\\\", sv_name, 2))
251 sv_name = &sv_name[2];
254 if (usr_creds != NULL)
256 DEBUG(10, ("ncacn_np_find: %s %s %s",
257 srv_name, usr_creds->user_name, usr_creds->domain));
259 else
261 DEBUG(10,("ncacn_np_find: %s (no creds)\n", srv_name));
264 if (key != NULL)
266 DEBUG(10, ("[%d,%x]", key->pid, key->vuid));
268 DEBUG(10, ("\n"));
270 for (i = 0; i < num_msrpcs; i++)
272 char *ncacn_np_srv_name = NULL;
273 struct ncacn_np_use *c = msrpcs[i];
274 vuser_key k;
276 char *ncacn_np_name = NULL;
278 if (c == NULL || c->cli == NULL || c->cli->smb == NULL ||
279 c->cli->smb->fd == -1 ||
280 !c->cli->initialised)
282 continue;
285 ncacn_np_name = c->cli->pipe_name;
286 ncacn_np_srv_name = c->cli->smb->desthost;
288 k = c->cli->smb->key;
290 DEBUG(10, ("ncacn_np_find[%d]: %s %s %s %s [%d,%x]\n",
291 i, ncacn_np_name, ncacn_np_srv_name,
292 c->cli->smb->user_name,
293 c->cli->smb->domain, k.pid, k.vuid));
295 if (strnequal("\\\\", ncacn_np_srv_name, 2))
297 ncacn_np_srv_name = &ncacn_np_srv_name[2];
300 if (strnequal("\\PIPE\\", ncacn_np_name, 6))
302 ncacn_np_name = &ncacn_np_name[6];
305 if (!strequal(ncacn_np_name, pipe_name))
307 continue;
309 if (!strequal(ncacn_np_srv_name, sv_name))
311 continue;
313 if (key != NULL && (k.pid != key->pid || k.vuid != key->vuid))
315 continue;
317 if (usr_creds == NULL)
319 if (reuse)
321 return c;
323 else
325 continue;
328 if (!strequal
329 (usr_creds->user_name, c->cli->smb->user_name))
331 continue;
333 if (!reuse
334 && !pwd_compare(&usr_creds->pwd, &c->cli->smb->pwd))
336 DEBUG(100, ("password doesn't match\n"));
337 continue;
339 if (usr_creds->domain[0] == 0)
341 return c;
343 if (strequal(usr_creds->domain, c->cli->smb->domain))
345 return c;
349 return NULL;
353 /****************************************************************************
354 initialise a msrpcent structure
355 ****************************************************************************/
356 struct ncacn_np *ncacn_np_initialise(struct ncacn_np *msrpc,
357 const vuser_key * key)
359 if (!msrpc)
361 msrpc = (struct ncacn_np *)malloc(sizeof(*msrpc));
362 if (!msrpc)
363 return NULL;
364 ZERO_STRUCTP(msrpc);
367 if (msrpc->initialised)
369 ncacn_np_shutdown(msrpc);
372 ZERO_STRUCTP(msrpc);
374 msrpc->fnum = -1;
375 msrpc->initialised = 1;
377 return msrpc;
380 /****************************************************************************
381 create a new client state from user credentials
382 ****************************************************************************/
383 static struct ncacn_np_use *ncacn_np_use_get(const char *pipe_name,
384 const vuser_key * key)
386 struct ncacn_np_use *cli =
387 (struct ncacn_np_use *)malloc(sizeof(*cli));
389 if (cli == NULL)
391 return NULL;
394 memset(cli, 0, sizeof(*cli));
396 cli->cli = ncacn_np_initialise(NULL, key);
398 if (cli->cli == NULL)
400 return NULL;
403 return cli;
406 /****************************************************************************
407 init client state
408 ****************************************************************************/
409 struct ncacn_np *ncacn_np_use_add(const char *pipe_name,
410 const vuser_key * key,
411 const char *srv_name,
412 const struct ntuser_creds *ntc,
413 BOOL reuse, BOOL *is_new_connection)
415 struct ncacn_np_use *cli;
416 DEBUG(10, ("ncacn_np_use_add: %s\n", pipe_name));
418 (*is_new_connection) = False;
419 cli = ncacn_np_find(srv_name, pipe_name, key, ntc, reuse);
421 if (cli != NULL)
423 cli->num_users++;
424 return cli->cli;
428 * allocate
431 (*is_new_connection) = True;
433 cli = ncacn_np_use_get(pipe_name, key);
435 if (!ncacn_np_establish_connection
436 (cli->cli, srv_name, ntc, pipe_name, True))
438 DEBUG(0, ("ncacn_np_use_add: connection failed\n"));
439 cli->cli = NULL;
440 ncacn_np_use_free(cli);
441 return NULL;
444 if (key != NULL)
446 cli->cli->smb->key = *key;
448 else
450 cli->cli->smb->key.pid = sys_getpid();
451 cli->cli->smb->key.vuid = UID_FIELD_INVALID;
454 add_ncacn_np_to_array(&num_msrpcs, &msrpcs, cli);
455 cli->num_users++;
456 return cli->cli;