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.
27 #include "rpc_parse.h"
28 #include "rpc_client.h"
31 extern int DEBUGLEVEL
;
32 extern pstring global_myname
;
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
;
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
,
68 const struct ntuser_creds
*ntc
,
69 const char *pipe_name
,
73 cli
->smb
= cli_net_use_add(srv_name
, ntc
,
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
);
85 fstrcpy(cli
->pipe_name
, pipe_name
);
91 /****************************************************************************
92 terminate client connection
93 ****************************************************************************/
94 static void ncacn_np_use_free(struct ncacn_np_use
*cli
)
98 if (cli
->cli
->initialised
)
100 ncacn_np_shutdown(cli
->cli
);
102 ZERO_STRUCTP(cli
->cli
);
109 /****************************************************************************
110 add a client state to the array
111 ****************************************************************************/
112 static struct ncacn_np_use
*add_ncacn_np_to_array(uint32
* len
,
115 struct ncacn_np_use
*cli
)
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 */
133 return (struct ncacn_np_use
*)add_item_to_array(len
,
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
)
149 DEBUG(10, ("ncacn_np_net_use_del: %s. force close: %s ",
150 pipe_name
, BOOLSTR(force_close
)));
153 DEBUG(10, ("[%d,%x]", key
->pid
, key
->vuid
));
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
];
179 if (c
== NULL
|| c
->cli
== NULL
|| c
->cli
->smb
== NULL
)
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
))
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
))
208 if (key
->pid
!= k
.pid
|| key
->vuid
!= k
.vuid
)
212 /* decrement number of users */
214 DEBUG(10, ("idx: %i num_users now: %d\n",
216 if (force_close
|| c
->num_users
== 0)
218 ncacn_np_use_free(c
);
220 if (connection_closed
!= NULL
)
222 *connection_closed
= True
;
231 /****************************************************************************
232 find client state. server name, user name, domain name and password must all
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
)
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
));
261 DEBUG(10,("ncacn_np_find: %s (no creds)\n", srv_name
));
266 DEBUG(10, ("[%d,%x]", key
->pid
, key
->vuid
));
270 for (i
= 0; i
< num_msrpcs
; i
++)
272 char *ncacn_np_srv_name
= NULL
;
273 struct ncacn_np_use
*c
= msrpcs
[i
];
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
)
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
))
309 if (!strequal(ncacn_np_srv_name
, sv_name
))
313 if (key
!= NULL
&& (k
.pid
!= key
->pid
|| k
.vuid
!= key
->vuid
))
317 if (usr_creds
== NULL
)
329 (usr_creds
->user_name
, c
->cli
->smb
->user_name
))
334 && !pwd_compare(&usr_creds
->pwd
, &c
->cli
->smb
->pwd
))
336 DEBUG(100, ("password doesn't match\n"));
339 if (usr_creds
->domain
[0] == 0)
343 if (strequal(usr_creds
->domain
, c
->cli
->smb
->domain
))
353 /****************************************************************************
354 initialise a msrpcent structure
355 ****************************************************************************/
356 struct ncacn_np
*ncacn_np_initialise(struct ncacn_np
*msrpc
,
357 const vuser_key
* key
)
361 msrpc
= (struct ncacn_np
*)malloc(sizeof(*msrpc
));
367 if (msrpc
->initialised
)
369 ncacn_np_shutdown(msrpc
);
375 msrpc
->initialised
= 1;
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
));
394 memset(cli
, 0, sizeof(*cli
));
396 cli
->cli
= ncacn_np_initialise(NULL
, key
);
398 if (cli
->cli
== NULL
)
406 /****************************************************************************
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
);
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"));
440 ncacn_np_use_free(cli
);
446 cli
->cli
->smb
->key
= *key
;
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
);