2 Unix SMB/Netbios implementation.
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.
26 #include "rpc_parse.h"
28 extern int DEBUGLEVEL
;
32 struct msrpc_local
*cli
;
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
)
46 if (cli
->cli
->initialised
)
48 ncalrpc_l_shutdown(cli
->cli
);
56 /****************************************************************************
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
)
73 for (i
= 0; i
< num_clis
; i
++)
82 return (struct ncalrpc_use
*)add_item_to_array(len
,
88 /****************************************************************************
90 ****************************************************************************/
91 void init_ncalrpc_use(void)
97 /****************************************************************************
98 terminate client array
99 ****************************************************************************/
100 void free_ncalrpc_use(void)
102 free_cli_array(num_clis
, clis
);
106 /****************************************************************************
107 find client state. server name, user name, vuid name and password must all
109 ****************************************************************************/
110 static struct ncalrpc_use
*ncalrpc_l_find(const char *pipe_name
,
111 const vuser_key
* key
, BOOL reuse
)
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
)
136 cli_name
= c
->cli
->pipe_name
;
138 DEBUG(10, ("ncalrpc_l_find[%d]: %s [%d,%x]\n",
140 c
->cli
->nt
.key
.pid
, c
->cli
->nt
.key
.vuid
));
142 if (!strequal(cli_name
, pipe_name
))
150 if (key
->vuid
== c
->cli
->nt
.key
.vuid
&&
151 key
->pid
== c
->cli
->nt
.key
.pid
)
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
));
173 memset(cli
, 0, sizeof(*cli
));
175 cli
->cli
= ncalrpc_l_initialise(NULL
, key
);
177 if (cli
->cli
== NULL
)
185 /****************************************************************************
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
);
207 ("ncalrpc_l_use_add: num_users: %d\n", cli
->num_users
));
216 cli
= ncalrpc_use_get(pipe_name
, key
);
222 if (!ncalrpc_l_establish_connection(cli
->cli
, pipe_name
))
224 DEBUG(0, ("ncalrpc_l_use_add: connection failed\n"));
226 ncalrpc_use_free(cli
);
230 add_cli_to_array(&num_clis
, &clis
, cli
);
233 DEBUG(10, ("ncalrpc_l_use_add: num_users: %d\n", cli
->num_users
));
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
)
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
;
268 if (clis
[i
]->cli
== NULL
)
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
))
285 if (key
->pid
!= clis
[i
]->cli
->nt
.key
.pid
||
286 key
->vuid
!= clis
[i
]->cli
->nt
.key
.vuid
)
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
]);
300 if (connection_closed
!= NULL
)
302 *connection_closed
= True
;
311 /****************************************************************************
312 enumerate client states
313 ****************************************************************************/
314 void ncalrpc_l_use_enum(uint32
* num_cons
, struct use_info
***use
)
321 for (i
= 0; i
< num_clis
; i
++)
323 struct use_info item
;
330 item
.connected
= clis
[i
]->cli
!= NULL
? True
: False
;
334 item
.srv_name
= clis
[i
]->cli
->pipe_name
;
335 item
.user_name
= NULL
;
336 item
.key
= clis
[i
]->cli
->nt
.key
;
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)
351 struct timeval timeout
;
356 int maxfd
= fileno(stdin
);
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
;
365 maxfd
= MAX(fd
, maxfd
);
371 sys_select(maxfd
+ 1, &fds
, &timeout
);
373 if (FD_ISSET(fileno(stdin
), &fds
))
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);