2 Unix SMB/Netbios implementation.
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.
26 #include "rpc_parse.h"
27 #include "rpc_client.h"
30 extern int DEBUGLEVEL
;
31 extern pstring global_myname
;
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
)
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
,
63 const struct ntuser_creds
*ntc
,
64 const char *pipe_name
,
68 cli
->smb
= cli_net_use_add(srv_name
, ntc
,
74 if (!cli_nt_session_open(cli
->smb
, pipe_name
, &cli
->fnum
))
76 cli_net_use_del(srv_name
, ntc
, False
, NULL
);
79 fstrcpy(cli
->pipe_name
, pipe_name
);
80 dump_data_pw("sess key:", cli
->smb
->nt
.usr_sess_key
, 16);
86 /* Useful for debugging rpc caching */
88 static void dump_msrpcs(void)
92 for (i
= 0; i
< num_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
,
101 msrpcs
[i
]->cli
->smb
));
103 DEBUG(3, ("[%d]: NULL\n", i
));
110 /****************************************************************************
111 terminate client connection
112 ****************************************************************************/
113 static void ncacn_np_use_free(struct ncacn_np_use
*cli
)
115 if (cli
->cli
!= NULL
)
119 /* Check that another connection doesn't have this same smb
122 for (i
= 0; i
< num_msrpcs
; i
++)
124 if (msrpcs
[i
] && msrpcs
[i
] != cli
&&
126 msrpcs
[i
]->cli
->smb
== cli
->cli
->smb
) {
131 if (cli
->cli
->initialised
)
133 ncacn_np_shutdown(cli
->cli
);
137 ZERO_STRUCTP(cli
->cli
);
145 /****************************************************************************
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
,
161 struct ncacn_np_use
*cli
)
164 for (i
= 0; i
< num_msrpcs
; i
++)
166 if (msrpcs
[i
] == NULL
)
173 return (struct ncacn_np_use
*)add_item_to_array(len
,
179 /****************************************************************************
180 initiate client array
181 ****************************************************************************/
182 void init_ncacn_np_use(void)
188 /****************************************************************************
189 terminate client array
190 ****************************************************************************/
191 void free_ncacn_np_use(void)
193 free_ncacn_np_array(num_msrpcs
, msrpcs
);
197 /****************************************************************************
198 find client state. server name, user name, domain name and password must all
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
)
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
));
227 DEBUG(10,("ncacn_np_find: %s (no creds)\n", srv_name
));
232 DEBUG(10, ("[%d,%x]", key
->pid
, key
->vuid
));
236 for (i
= 0; i
< num_msrpcs
; i
++)
238 char *ncacn_np_srv_name
= NULL
;
239 struct ncacn_np_use
*c
= msrpcs
[i
];
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
)
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
))
275 if (!strequal(ncacn_np_srv_name
, sv_name
))
279 if (key
!= NULL
&& (k
.pid
!= key
->pid
|| k
.vuid
!= key
->vuid
))
283 if (usr_creds
== NULL
)
295 (usr_creds
->user_name
, c
->cli
->smb
->usr
.user_name
))
300 && !pwd_compare(&usr_creds
->pwd
, &c
->cli
->smb
->usr
.pwd
))
302 DEBUG(100, ("password doesn't match\n"));
305 if (usr_creds
->domain
[0] == 0)
309 if (strequal(usr_creds
->domain
, c
->cli
->smb
->usr
.domain
))
318 /****************************************************************************
319 initialise a msrpcent structure
320 ****************************************************************************/
321 struct ncacn_np
*ncacn_np_initialise(struct ncacn_np
*msrpc
,
322 const vuser_key
* key
)
326 msrpc
= (struct ncacn_np
*)malloc(sizeof(*msrpc
));
332 if (msrpc
->initialised
)
334 ncacn_np_shutdown(msrpc
);
340 msrpc
->initialised
= 1;
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
));
359 memset(cli
, 0, sizeof(*cli
));
361 cli
->cli
= ncacn_np_initialise(NULL
, key
);
363 if (cli
->cli
== NULL
)
371 /****************************************************************************
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
);
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
);
410 cli
->cli
->smb
->nt
.key
= *key
;
414 cli
->cli
->smb
->nt
.key
.pid
= sys_getpid();
415 cli
->cli
->smb
->nt
.key
.vuid
= UID_FIELD_INVALID
;
418 uid_t uid
= getuid();
419 gid_t gid
= getgid();
420 char *name
= uidtoname(uid
);
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
);
431 add_ncacn_np_to_array(&num_msrpcs
, &msrpcs
, 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
)
444 DEBUG(10, ("ncacn_np_net_use_del: %s, %s. force close: %s ",
445 srv_name
, pipe_name
, BOOLSTR(force_close
)));
448 DEBUG(3, ("[%d,%x]", key
->pid
, key
->vuid
));
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
];
474 if (c
== NULL
|| c
->cli
== NULL
|| c
->cli
->smb
== NULL
)
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
))
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
))
503 if (key
->pid
!= k
.pid
|| key
->vuid
!= k
.vuid
)
507 /* decrement number of users */
509 DEBUG(3, ("idx: %i num_users now: %d\n",
511 if (force_close
|| c
->num_users
== 0)
513 ncacn_np_use_free(c
);
515 if (connection_closed
!= NULL
)
517 *connection_closed
= True
;
526 /****************************************************************************
527 enumerate client states
528 ****************************************************************************/
529 void ncacn_np_use_enum(uint32
* num_cons
, struct use_info
***use
)
534 for (i
= 0; i
< num_msrpcs
; i
++)
536 struct use_info item
;
538 if (msrpcs
[i
] == NULL
)
540 item
.connected
= msrpcs
[i
]->cli
!= NULL
? True
: False
;
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
);