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.
27 #include "rpc_client.h"
29 extern int DEBUGLEVEL
;
31 extern pstring global_myname
;
35 struct cli_state
*cli
;
39 static struct cli_use
**clis
= NULL
;
40 static uint32 num_clis
= 0;
42 /****************************************************************************
43 terminate client connection
44 ****************************************************************************/
45 static void cli_use_free(struct cli_use
*cli
)
49 if (cli
->cli
->initialised
)
51 /* only call logoff() if we have a valid socket */
52 if (cli
->cli
->fd
!= -1)
53 cli_ulogoff(cli
->cli
);
54 cli_shutdown(cli
->cli
);
62 /****************************************************************************
64 ****************************************************************************/
65 static void free_cli_array(uint32 num_entries
, struct cli_use
**entries
)
67 void (*fn
) (void *) = (void (*)(void *))&cli_use_free
;
68 free_void_array(num_entries
, (void **)entries
, *fn
);
71 /****************************************************************************
72 add a client state to the array
73 ****************************************************************************/
74 static struct cli_use
*add_cli_to_array(uint32
*len
,
75 struct cli_use
***array
,
79 for (i
= 0; i
< num_clis
; i
++)
88 return (struct cli_use
*)add_item_to_array(len
,
94 /****************************************************************************
96 ****************************************************************************/
97 void init_cli_use(void)
103 /****************************************************************************
104 terminate client array
105 ****************************************************************************/
106 void free_cli_use(void)
108 free_cli_array(num_clis
, clis
);
112 /****************************************************************************
113 find client state. server name, user name, domain name and password must all
115 ****************************************************************************/
116 static struct cli_use
*cli_find(const char *srv_name
,
117 const struct ntuser_creds
*usr_creds
,
121 const char *sv_name
= srv_name
;
122 struct ntuser_creds null_usr
;
124 if (usr_creds
== NULL
)
126 copy_nt_creds(&null_usr
, usr_creds
);
127 usr_creds
= &null_usr
;
130 if (strnequal("\\\\", sv_name
, 2))
132 sv_name
= &sv_name
[2];
135 DEBUG(10, ("cli_find: %s %s %s reuse: %s\n",
136 srv_name
, usr_creds
->user_name
, usr_creds
->domain
,
140 for (i
= 0; i
< num_clis
; i
++)
142 char *cli_name
= NULL
;
143 struct cli_use
*c
= clis
[i
];
145 if (c
== NULL
|| !c
->cli
->initialised
|| c
->cli
->fd
== -1)
150 cli_name
= c
->cli
->desthost
;
152 DEBUG(10, ("cli_find[%d]: %s %s %s\n",
154 c
->cli
->usr
.user_name
, c
->cli
->usr
.domain
));
156 if (strnequal("\\\\", cli_name
, 2))
158 cli_name
= &cli_name
[2];
161 if (!strequal(cli_name
, sv_name
))
165 if (strequal(usr_creds
->user_name
, "") &&
166 strequal(usr_creds
->domain
, "") &&
167 pwd_is_nullpwd(&usr_creds
->pwd
))
171 if (!strequal(usr_creds
->user_name
, c
->cli
->usr
.user_name
))
175 if (!reuse
&& !pwd_compare(&usr_creds
->pwd
, &c
->cli
->usr
.pwd
))
177 DEBUG(100, ("password doesn't match\n"));
180 if (usr_creds
->domain
[0] == 0)
184 if (strequal(usr_creds
->domain
, c
->cli
->usr
.domain
))
193 /****************************************************************************
194 create a new client state from user credentials
195 ****************************************************************************/
196 static struct cli_use
*cli_use_get(const char *srv_name
,
197 const struct ntuser_creds
*usr_creds
)
199 struct cli_use
*cli
= (struct cli_use
*)malloc(sizeof(*cli
));
206 memset(cli
, 0, sizeof(*cli
));
208 cli
->cli
= cli_initialise(NULL
);
210 if (cli
->cli
== NULL
)
215 cli_init_creds(cli
->cli
, usr_creds
);
220 /****************************************************************************
222 ****************************************************************************/
223 struct cli_state
*cli_net_use_add(const char *srv_name
,
224 const struct ntuser_creds
*usr_creds
,
225 BOOL reuse
, BOOL
*is_new
)
227 struct nmb_name calling
;
228 struct nmb_name called
;
229 struct in_addr
*dest_ip
= NULL
;
234 DEBUG(10, ("cli_net_use_add\n"));
236 cli
= cli_find(srv_name
, usr_creds
, reuse
);
242 ("cli_net_use_add: num_users: %d\n", cli
->num_users
));
247 /* reuse an existing connection requested, and one was not found */
248 if (usr_creds
!= NULL
&& reuse
)
257 cli
= cli_use_get(srv_name
, usr_creds
);
259 if (resolve_srv_name(srv_name
, dest_host
, &ip
))
269 make_nmb_name(&called
, dns_to_netbios_name(dest_host
), 0x20);
270 make_nmb_name(&calling
, dns_to_netbios_name(global_myname
), 0);
276 if (!cli_establish_connection(cli
->cli
,
279 "IPC$", "IPC", False
, True
))
281 DEBUG(0, ("cli_net_use_add: connection failed\n"));
286 add_cli_to_array(&num_clis
, &clis
, cli
);
289 DEBUG(10, ("cli_net_use_add: num_users: %d\n", cli
->num_users
));
296 /****************************************************************************
297 delete a client state
298 ****************************************************************************/
299 BOOL
cli_net_use_del(const char *srv_name
,
300 const struct ntuser_creds
*usr_creds
,
301 BOOL force_close
, BOOL
*connection_closed
)
304 const char *sv_name
= srv_name
;
306 DEBUG(10, ("cli_net_use_del: %s. %s. %s. force close: %s\n",
308 usr_creds
? usr_creds
->user_name
: "",
309 usr_creds
? usr_creds
->domain
: "", BOOLSTR(force_close
)));
311 if (strnequal("\\\\", sv_name
, 2))
313 sv_name
= &sv_name
[2];
316 if (connection_closed
!= NULL
)
318 *connection_closed
= False
;
321 for (i
= 0; i
< num_clis
; i
++)
323 char *cli_name
= NULL
;
327 if (clis
[i
]->cli
== NULL
)
330 cli_name
= clis
[i
]->cli
->desthost
;
332 DEBUG(10, ("connection: %s %s %s\n", cli_name
,
333 clis
[i
]->cli
->usr
.user_name
,
334 clis
[i
]->cli
->usr
.domain
));
336 if (strnequal("\\\\", cli_name
, 2))
338 cli_name
= &cli_name
[2];
341 if (!strequal(cli_name
, sv_name
))
344 if (strequal(usr_creds
? usr_creds
->user_name
: "",
345 clis
[i
]->cli
->usr
.user_name
) &&
346 strequal(usr_creds
? usr_creds
->domain
: "",
347 clis
[i
]->cli
->usr
.domain
))
349 /* decrement number of users */
350 clis
[i
]->num_users
--;
352 DEBUG(10, ("idx: %i num_users now: %d\n",
353 i
, clis
[i
]->num_users
));
355 if (force_close
|| clis
[i
]->num_users
== 0)
357 cli_use_free(clis
[i
]);
359 if (connection_closed
!= NULL
)
361 *connection_closed
= True
;
371 /****************************************************************************
372 enumerate client states
373 ****************************************************************************/
374 void cli_net_use_enum(uint32
*num_cons
, struct use_info
***use
)
381 for (i
= 0; i
< num_clis
; i
++)
383 struct use_info item
;
390 item
.connected
= clis
[i
]->cli
!= NULL
? True
: False
;
394 item
.srv_name
= clis
[i
]->cli
->desthost
;
395 item
.user_name
= clis
[i
]->cli
->usr
.user_name
;
396 item
.key
= clis
[i
]->cli
->nt
.key
;
397 item
.domain
= clis
[i
]->cli
->usr
.domain
;
400 add_use_info_to_array(num_cons
, use
, &item
);
405 /****************************************************************************
406 wait for keyboard activity, swallowing network packets on all client states.
407 ****************************************************************************/
408 void cli_use_wait_keyboard(void)
411 struct timeval timeout
;
416 int maxfd
= fileno(stdin
);
418 FD_SET(fileno(stdin
), &fds
);
419 for (i
= 0; i
< num_clis
; i
++)
421 if (clis
[i
] != NULL
&& clis
[i
]->cli
!= NULL
)
423 int fd
= clis
[i
]->cli
->fd
;
425 maxfd
= MAX(fd
, maxfd
);
431 sys_select(maxfd
+ 1, &fds
, &timeout
);
433 if (FD_ISSET(fileno(stdin
), &fds
))
436 /* We deliberately use receive_smb instead of
437 client_receive_smb as we want to receive
438 session keepalives and then drop them here.
440 for (i
= 0; i
< num_clis
; i
++)
443 if (clis
[i
] == NULL
|| clis
[i
]->cli
== NULL
)
445 fd
= clis
[i
]->cli
->fd
;
446 if (FD_ISSET(fd
, &fds
))
447 receive_smb(fd
, clis
[i
]->cli
->inbuf
, 0);