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.
28 extern int DEBUGLEVEL;
30 extern pstring global_myname;
34 struct cli_state *cli;
38 static struct cli_use **clis = NULL;
41 /****************************************************************************
42 terminate client connection
43 ****************************************************************************/
44 static void cli_use_free(struct cli_use *cli)
48 if (cli->cli->initialised)
50 cli_ulogoff(cli->cli);
51 cli_shutdown(cli->cli);
59 /****************************************************************************
61 ****************************************************************************/
62 static void free_cli_array(uint32 num_entries, struct cli_use **entries)
64 void(*fn)(void*) = (void(*)(void*))&cli_use_free;
65 free_void_array(num_entries, (void**)entries, *fn);
68 /****************************************************************************
69 add a client state to the array
70 ****************************************************************************/
71 static struct cli_use* add_cli_to_array(uint32 *len,
72 struct cli_use ***array,
76 for (i = 0; i < num_clis; i++)
85 return (struct cli_use*)add_item_to_array(len,
86 (void***)array, (void*)cli);
90 /****************************************************************************
92 ****************************************************************************/
93 void init_cli_use(void)
99 /****************************************************************************
100 terminate client array
101 ****************************************************************************/
102 void free_cli_use(void)
104 free_cli_array(num_clis, clis);
108 /****************************************************************************
109 find client state. server name, user name, domain name and password must all
111 ****************************************************************************/
112 static struct cli_use *cli_find(const char* srv_name,
113 const struct user_credentials *usr_creds)
116 const char *sv_name = srv_name;
117 if (strnequal("\\\\", sv_name, 2))
119 sv_name = &sv_name[2];
122 DEBUG(10,("cli_find: %s %s %s\n",
124 usr_creds->user_name,
127 for (i = 0; i < num_clis; i++)
129 char *cli_name = NULL;
130 struct cli_use *c = clis[i];
132 if (c == NULL) continue;
134 cli_name = c->cli->desthost;
136 DEBUG(10,("cli_find[%d]: %s %s %s\n",
138 c->cli->usr.user_name,
139 c->cli->usr.domain));
141 if (strnequal("\\\\", cli_name, 2))
143 cli_name = &cli_name[2];
146 if (!strequal(cli_name, sv_name))
150 if (!strequal(usr_creds->user_name, c->cli->usr.user_name))
154 if (!pwd_compare(&usr_creds->pwd, &c->cli->usr.pwd))
158 if (usr_creds->domain[0] == 0)
162 if (strequal(usr_creds->domain, c->cli->usr.domain))
171 /****************************************************************************
172 create a new client state from user credentials
173 ****************************************************************************/
174 static struct cli_use *cli_use_get(const char* srv_name,
175 const struct user_credentials *usr_creds)
177 struct cli_use *cli = (struct cli_use*)malloc(sizeof(*cli));
184 memset(cli, 0, sizeof(*cli));
186 cli->cli = cli_initialise(NULL);
188 if (cli->cli == NULL)
193 cli_init_creds(cli->cli, usr_creds);
198 /****************************************************************************
200 ****************************************************************************/
201 struct cli_state *cli_net_use_addlist(char* servers,
202 const struct user_credentials *usr_creds)
204 struct cli_use *cli = cli_find(servers, usr_creds);
216 cli = cli_use_get(servers, usr_creds);
223 if (!cli_connect_serverlist(cli->cli, servers))
225 DEBUG(0,("cli_net_use_addlist: connection failed\n"));
230 cli->cli->ntlmssp_cli_flgs = 0x0;
232 add_cli_to_array(&num_clis, &clis, cli);
238 /****************************************************************************
240 ****************************************************************************/
241 struct cli_state *cli_net_use_add(const char* srv_name,
242 const struct user_credentials *usr_creds)
244 struct nmb_name calling;
245 struct nmb_name called;
246 struct in_addr *dest_ip = NULL;
250 struct cli_use *cli = cli_find(srv_name, usr_creds);
262 cli = cli_use_get(srv_name, usr_creds);
264 if (resolve_srv_name(srv_name, dest_host, &ip))
274 make_nmb_name(&called , dns_to_netbios_name(dest_host ), 32, scope);
275 make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0, scope);
281 if (!cli_establish_connection(cli->cli,
287 DEBUG(0,("cli_net_use_add: connection failed\n"));
292 cli->cli->ntlmssp_cli_flgs = 0x0;
294 add_cli_to_array(&num_clis, &clis, cli);
300 /****************************************************************************
301 delete a client state
302 ****************************************************************************/
303 BOOL cli_net_use_del(const char* srv_name,
304 const struct user_credentials *usr_creds,
306 BOOL *connection_closed)
309 const char *sv_name = srv_name;
311 DEBUG(10,("cli_net_use_del: %s. force close: %s\n",
312 srv_name, BOOLSTR(force_close)));
314 if (strnequal("\\\\", sv_name, 2))
316 sv_name = &sv_name[2];
319 *connection_closed = False;
321 for (i = 0; i < num_clis; i++)
323 char *cli_name = NULL;
325 if (clis[i] == NULL) continue;
326 if (clis[i]->cli == NULL) continue;
328 cli_name = clis[i]->cli->desthost;
329 if (strnequal("\\\\", cli_name, 2))
331 cli_name = &cli_name[2];
334 if (!strequal(cli_name, sv_name)) continue;
336 if (strequal(usr_creds->user_name,
337 clis[i]->cli->usr.user_name) &&
338 strequal(usr_creds->domain,
339 clis[i]->cli->usr.domain))
341 /* decrement number of users */
342 clis[i]->num_users--;
344 DEBUG(10,("idx: %i num_users now: %d\n",
345 i, clis[i]->num_users));
347 if (force_close || clis[i]->num_users == 0)
349 cli_use_free(clis[i]);
351 *connection_closed = True;
360 /****************************************************************************
361 enumerate client states
362 ****************************************************************************/
363 void cli_net_use_enum(uint32 *num_cons, struct use_info ***use)
370 for (i = 0; i < num_clis; i++)
372 struct use_info item;
376 if (clis[i] == NULL) continue;
378 item.connected = clis[i]->cli != NULL ? True : False;
382 item.srv_name = clis[i]->cli->desthost;
383 item.user_name = clis[i]->cli->usr.user_name;
384 item.domain = clis[i]->cli->usr.domain;
387 add_use_to_array(num_cons, use, &item);
392 /****************************************************************************
393 wait for keyboard activity, swallowing network packets on all client states.
394 ****************************************************************************/
395 void cli_use_wait_keyboard(void)
398 struct timeval timeout;
403 int maxfd = fileno(stdin);
405 FD_SET(fileno(stdin),&fds);
406 for (i = 0; i < num_clis; i++)
408 if (clis[i] != NULL && clis[i]->cli != NULL)
410 int fd = clis[i]->cli->fd;
412 maxfd = MAX(fd, maxfd);
418 sys_select(maxfd+1,NULL, &fds,&timeout);
420 if (FD_ISSET(fileno(stdin),&fds))
423 /* We deliberately use receive_smb instead of
424 client_receive_smb as we want to receive
425 session keepalives and then drop them here.
427 for (i = 0; i < num_clis; i++)
429 int fd = clis[i]->cli->fd;
430 if (FD_ISSET(fd,&fds))
431 receive_smb(fd,clis[i]->cli->inbuf,0);