preparing for release of alpha-2.6
[Samba/gbeck.git] / source / rpc_client / ncacn_np_use.c
blobc3ed51fc036532b7a9fad9f3e2147c78a5f59450
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.
23 #define NO_SYSLOG
25 #include "includes.h"
26 #include "rpc_parse.h"
27 #include "rpc_client.h"
28 #include "trans2.h"
30 extern int DEBUGLEVEL;
31 extern pstring global_myname;
33 struct ncacn_np_use
35 struct ncacn_np *cli;
36 uint32 num_users;
39 static struct ncacn_np_use **msrpcs = NULL;
40 static uint32 num_msrpcs = 0;
42 /****************************************************************************
43 terminate client connection
44 ****************************************************************************/
45 static void ncacn_np_shutdown(struct ncacn_np *cli)
47 if (cli != NULL)
49 if (cli->smb != NULL)
51 if (cli->smb->initialised)
53 cli_nt_session_close(cli->smb, cli->fnum);
55 cli_net_use_del(cli->smb->desthost,
56 &cli->smb->usr, False, False);
61 static BOOL ncacn_np_establish_connection(struct ncacn_np *cli,
62 const char *srv_name,
63 const struct ntuser_creds *ntc,
64 const char *pipe_name,
65 BOOL reuse)
67 BOOL new_smb_conn;
68 cli->smb = cli_net_use_add(srv_name, ntc,
69 True, &new_smb_conn);
70 if (cli->smb == NULL)
72 return False;
74 if (!cli_nt_session_open(cli->smb, pipe_name, &cli->fnum))
76 cli_net_use_del(srv_name, ntc, False, NULL);
77 return False;
79 fstrcpy(cli->pipe_name, pipe_name);
80 dump_data_pw("sess key:", cli->smb->nt.usr_sess_key, 16);
81 return True;
84 #if 0
86 /* Useful for debugging rpc caching */
88 static void dump_msrpcs(void)
90 int i;
92 for (i = 0; i < num_msrpcs; i++) {
93 if (msrpcs[i]) {
94 DEBUG(3, ("[%d]: %s %s num_users=%d np_use=0x%08x "
95 " np=0x%08x smb=0x%08x\n",
96 i, msrpcs[i]->cli->smb->desthost,
97 msrpcs[i]->cli->pipe_name,
98 msrpcs[i]->num_users,
99 msrpcs[i],
100 msrpcs[i]->cli,
101 msrpcs[i]->cli->smb));
102 } else {
103 DEBUG(3, ("[%d]: NULL\n", i));
108 #endif
110 /****************************************************************************
111 terminate client connection
112 ****************************************************************************/
113 static void ncacn_np_use_free(struct ncacn_np_use *cli)
115 if (cli->cli != NULL)
117 int i;
119 /* Check that another connection doesn't have this same smb
120 open. */
122 for (i = 0; i < num_msrpcs; i++)
124 if (msrpcs[i] && msrpcs[i] != cli &&
125 msrpcs[i]->cli &&
126 msrpcs[i]->cli->smb == cli->cli->smb) {
127 goto no_shutdown;
131 if (cli->cli->initialised)
133 ncacn_np_shutdown(cli->cli);
135 no_shutdown:
137 ZERO_STRUCTP(cli->cli);
138 free(cli->cli);
141 ZERO_STRUCTP(cli);
142 free(cli);
145 /****************************************************************************
146 free a client array
147 ****************************************************************************/
148 static void free_ncacn_np_array(uint32 num_entries,
149 struct ncacn_np_use **entries)
151 void (*fn) (void *) = (void (*)(void *))&ncacn_np_use_free;
152 free_void_array(num_entries, (void **)entries, *fn);
155 /****************************************************************************
156 add a client state to the array
157 ****************************************************************************/
158 static struct ncacn_np_use *add_ncacn_np_to_array(uint32 * len,
159 struct ncacn_np_use
160 ***array,
161 struct ncacn_np_use *cli)
163 int i;
164 for (i = 0; i < num_msrpcs; i++)
166 if (msrpcs[i] == NULL)
168 msrpcs[i] = cli;
169 return cli;
173 return (struct ncacn_np_use *)add_item_to_array(len,
174 (void ***)array,
175 (void *)cli);
179 /****************************************************************************
180 initiate client array
181 ****************************************************************************/
182 void init_ncacn_np_use(void)
184 msrpcs = NULL;
185 num_msrpcs = 0;
188 /****************************************************************************
189 terminate client array
190 ****************************************************************************/
191 void free_ncacn_np_use(void)
193 free_ncacn_np_array(num_msrpcs, msrpcs);
194 init_ncacn_np_use();
197 /****************************************************************************
198 find client state. server name, user name, domain name and password must all
199 match.
200 ****************************************************************************/
201 static struct ncacn_np_use *ncacn_np_find(const char *srv_name,
202 const char *pipe_name,
203 const vuser_key * key,
204 const struct ntuser_creds
205 *usr_creds, BOOL reuse)
207 int i;
208 const char *sv_name = srv_name;
210 if (strnequal("\\PIPE\\", pipe_name, 6))
212 pipe_name = &pipe_name[6];
215 if (strnequal("\\\\", sv_name, 2))
217 sv_name = &sv_name[2];
220 if (usr_creds != NULL)
222 DEBUG(10, ("ncacn_np_find: %s %s %s",
223 srv_name, usr_creds->user_name, usr_creds->domain));
225 else
227 DEBUG(10,("ncacn_np_find: %s (no creds)\n", srv_name));
230 if (key != NULL)
232 DEBUG(10, ("[%d,%x]", key->pid, key->vuid));
234 DEBUG(10, ("\n"));
236 for (i = 0; i < num_msrpcs; i++)
238 char *ncacn_np_srv_name = NULL;
239 struct ncacn_np_use *c = msrpcs[i];
240 vuser_key k;
242 char *ncacn_np_name = NULL;
244 if (c == NULL || c->cli == NULL || c->cli->smb == NULL ||
245 c->cli->smb->fd == -1 ||
246 !c->cli->initialised)
248 continue;
251 ncacn_np_name = c->cli->pipe_name;
252 ncacn_np_srv_name = c->cli->smb->desthost;
254 k = c->cli->smb->nt.key;
256 DEBUG(10, ("ncacn_np_find[%d]: %s %s %s %s [%d,%x]\n",
257 i, ncacn_np_name, ncacn_np_srv_name,
258 c->cli->smb->usr.user_name,
259 c->cli->smb->usr.domain, k.pid, k.vuid));
261 if (strnequal("\\\\", ncacn_np_srv_name, 2))
263 ncacn_np_srv_name = &ncacn_np_srv_name[2];
266 if (strnequal("\\PIPE\\", ncacn_np_name, 6))
268 ncacn_np_name = &ncacn_np_name[6];
271 if (!strequal(ncacn_np_name, pipe_name))
273 continue;
275 if (!strequal(ncacn_np_srv_name, sv_name))
277 continue;
279 if (key != NULL && (k.pid != key->pid || k.vuid != key->vuid))
281 continue;
283 if (usr_creds == NULL)
285 if (reuse)
287 return c;
289 else
291 continue;
294 if (!strequal
295 (usr_creds->user_name, c->cli->smb->usr.user_name))
297 continue;
299 if (!reuse
300 && !pwd_compare(&usr_creds->pwd, &c->cli->smb->usr.pwd))
302 DEBUG(100, ("password doesn't match\n"));
303 continue;
305 if (usr_creds->domain[0] == 0)
307 return c;
309 if (strequal(usr_creds->domain, c->cli->smb->usr.domain))
311 return c;
315 return NULL;
318 /****************************************************************************
319 initialise a msrpcent structure
320 ****************************************************************************/
321 struct ncacn_np *ncacn_np_initialise(struct ncacn_np *msrpc,
322 const vuser_key * key)
324 if (!msrpc)
326 msrpc = (struct ncacn_np *)malloc(sizeof(*msrpc));
327 if (!msrpc)
328 return NULL;
329 ZERO_STRUCTP(msrpc);
332 if (msrpc->initialised)
334 ncacn_np_shutdown(msrpc);
337 ZERO_STRUCTP(msrpc);
339 msrpc->fnum = -1;
340 msrpc->initialised = 1;
342 return msrpc;
345 /****************************************************************************
346 create a new client state from user credentials
347 ****************************************************************************/
348 static struct ncacn_np_use *ncacn_np_use_get(const char *pipe_name,
349 const vuser_key * key)
351 struct ncacn_np_use *cli =
352 (struct ncacn_np_use *)malloc(sizeof(*cli));
354 if (cli == NULL)
356 return NULL;
359 memset(cli, 0, sizeof(*cli));
361 cli->cli = ncacn_np_initialise(NULL, key);
363 if (cli->cli == NULL)
365 return NULL;
368 return cli;
371 /****************************************************************************
372 init client state
373 ****************************************************************************/
374 struct ncacn_np *ncacn_np_use_add(const char *pipe_name,
375 const vuser_key * key,
376 const char *srv_name,
377 const struct ntuser_creds *ntc,
378 BOOL reuse, BOOL *is_new_connection)
380 struct ncacn_np_use *cli;
381 DEBUG(10, ("ncacn_np_use_add: %s, %s\n", srv_name, pipe_name));
383 (*is_new_connection) = False;
384 cli = ncacn_np_find(srv_name, pipe_name, key, ntc, reuse);
386 if (cli != NULL)
388 cli->num_users++;
389 return cli->cli;
393 * allocate
396 (*is_new_connection) = True;
398 cli = ncacn_np_use_get(pipe_name, key);
400 if (!ncacn_np_establish_connection
401 (cli->cli, srv_name, ntc, pipe_name, True))
403 DEBUG(0, ("ncacn_np_use_add: connection failed\n"));
404 ncacn_np_use_free(cli);
405 return NULL;
408 if (key != NULL)
410 cli->cli->smb->nt.key = *key;
412 else
414 cli->cli->smb->nt.key.pid = sys_getpid();
415 cli->cli->smb->nt.key.vuid = UID_FIELD_INVALID;
416 #if 0
417 NET_USER_INFO_3 usr;
418 uid_t uid = getuid();
419 gid_t gid = getgid();
420 char *name = uidtoname(uid);
422 ZERO_STRUCT(usr);
424 cli->cli->smb->nt.key.pid = sys_getpid();
425 cli->cli->smb->nt.key.vuid =
426 register_vuid(cli->cli->smb->nt.key.pid, uid, gid,
427 name, name, False, &usr);
428 #endif
431 add_ncacn_np_to_array(&num_msrpcs, &msrpcs, cli);
432 cli->num_users++;
433 return cli->cli;
436 /****************************************************************************
437 delete a client state
438 ****************************************************************************/
439 BOOL ncacn_np_use_del(const char *srv_name, const char *pipe_name,
440 const vuser_key * key,
441 BOOL force_close, BOOL *connection_closed)
443 int i;
444 DEBUG(10, ("ncacn_np_net_use_del: %s, %s. force close: %s ",
445 srv_name, pipe_name, BOOLSTR(force_close)));
446 if (key != NULL)
448 DEBUG(3, ("[%d,%x]", key->pid, key->vuid));
450 DEBUG(10, ("\n"));
452 if (connection_closed != NULL)
454 *connection_closed = False;
457 if (strnequal("\\PIPE\\", pipe_name, 6))
459 pipe_name = &pipe_name[6];
462 if (strnequal("\\\\", srv_name, 2))
464 srv_name = &srv_name[2];
467 for (i = 0; i < num_msrpcs; i++)
469 char *ncacn_np_name = NULL;
470 char *ncacn_np_srv_name = NULL;
471 struct ncacn_np_use *c = msrpcs[i];
472 vuser_key k;
474 if (c == NULL || c->cli == NULL || c->cli->smb == NULL)
475 continue;
477 ncacn_np_name = c->cli->pipe_name;
478 ncacn_np_srv_name = c->cli->smb->desthost;
480 k = c->cli->smb->nt.key;
482 DEBUG(10, ("use_del[%d]: %s %s %s %s [%d,%x]\n",
483 i, ncacn_np_name, ncacn_np_srv_name,
484 c->cli->smb->usr.user_name,
485 c->cli->smb->usr.domain, k.pid, k.vuid));
487 if (strnequal("\\PIPE\\", ncacn_np_name, 6))
489 ncacn_np_name = &ncacn_np_name[6];
491 if (!strequal(ncacn_np_name, pipe_name))
493 continue;
495 if (strnequal("\\\\", ncacn_np_srv_name, 2))
497 ncacn_np_srv_name = &ncacn_np_srv_name[2];
499 if (!strequal(ncacn_np_srv_name, srv_name))
501 continue;
503 if (key->pid != k.pid || key->vuid != k.vuid)
505 continue;
507 /* decrement number of users */
508 c->num_users--;
509 DEBUG(3, ("idx: %i num_users now: %d\n",
510 i, c->num_users));
511 if (force_close || c->num_users == 0)
513 ncacn_np_use_free(c);
514 msrpcs[i] = NULL;
515 if (connection_closed != NULL)
517 *connection_closed = True;
520 return True;
523 return False;
526 /****************************************************************************
527 enumerate client states
528 ****************************************************************************/
529 void ncacn_np_use_enum(uint32 * num_cons, struct use_info ***use)
531 int i;
532 *num_cons = 0;
533 *use = NULL;
534 for (i = 0; i < num_msrpcs; i++)
536 struct use_info item;
537 ZERO_STRUCT(item);
538 if (msrpcs[i] == NULL)
539 continue;
540 item.connected = msrpcs[i]->cli != NULL ? True : False;
541 if (item.connected)
543 item.srv_name = msrpcs[i]->cli->pipe_name;
544 item.key = msrpcs[i]->cli->smb->nt.key;
547 add_use_info_to_array(num_cons, use, &item);