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 static struct cli_connection
**con_list
= NULL
;
31 static uint32 num_cons
= 0;
33 struct user_creds
*usr_creds
= NULL
;
34 vuser_key
*user_key
= NULL
;
36 extern int DEBUGLEVEL
;
37 extern pstring global_myname
;
39 * needed for the struct cli_connection
40 * none of these functions are implemented in HEAD currently
41 * rpc_client/cli_connect.c for details
43 * the 'typedef struct _cli_auth_fns cli_auth_fns;' is in
46 struct _cli_auth_fns
{
48 /* these three will do for now. they *should* match with server-side */
49 BOOL (*create_bind_req
) (struct cli_connection
*, prs_struct
*,
50 uint32
, RPC_IFACE
*, RPC_IFACE
*);
51 BOOL (*decode_bind_resp
) (struct cli_connection
*, prs_struct
*);
52 BOOL (*create_bind_cont
) (struct cli_connection
*, prs_struct
*, uint32
);
54 /* creates an authenticated PDU */
55 BOOL (*cli_create_pdu
) (struct cli_connection
*, uint8
, prs_struct
*,
56 int, int *, prs_struct
*, uint8
*);
58 /* decodes an authenticated PDU */
59 BOOL (*cli_decode_pdu
) (struct cli_connection
*, prs_struct
*, int, int);
63 cli_auth_fns cli_noauth_fns
=
75 void init_connections(void)
83 static void free_con_array(uint32 num_entries
,
84 struct cli_connection
**entries
)
86 void (*fn
) (void *) = (void (*)(void *))&cli_connection_free
;
87 free_void_array(num_entries
, (void **)entries
, *fn
);
91 static struct cli_connection
*add_con_to_array(uint32
* len
,
92 struct cli_connection
***array
,
93 struct cli_connection
*con
)
95 return (struct cli_connection
*)add_item_to_array(len
,
101 void free_connections(void)
103 DEBUG(3, ("free_connections: closing all MSRPC connections\n"));
104 free_con_array(num_cons
, con_list
);
110 static struct cli_connection
*cli_con_get(const char *srv_name
,
113 void *auth_creds
, BOOL reuse
)
115 struct cli_connection
*con
= NULL
;
116 BOOL is_new_connection
= False
;
118 struct ntuser_creds
*ntc
= NULL
;
119 struct ncacn_np
*pNcacn
;
122 * initialization stuff
124 con
= (struct cli_connection
*)malloc(sizeof(*con
));
129 memset(con
, 0, sizeof(*con
));
131 copy_user_creds(&con
->usr_creds
, NULL
);
132 con
->usr_creds
.reuse
= reuse
;
134 if (srv_name
!= NULL
)
136 con
->srv_name
= strdup(srv_name
);
138 if (pipe_name
!= NULL
)
140 con
->pipe_name
= strdup(pipe_name
);
142 if (usr_creds
!= NULL
)
144 ntc
= &usr_creds
->ntc
;
147 /* fix me XXXX **WHAT** a hack. The cli_state* is malloc'd
148 deep within the call stack, so we can grab that pointer.
149 ncacn_np* is stored in an array which is currently handled
150 by underlying systems. --jerry */
151 pNcacn
= ncacn_np_use_add(pipe_name
, user_key
, srv_name
,
157 con
->pCli_state
= pNcacn
->smb
;
159 if (con
->pCli_state
== NULL
)
162 con
->pCli_state
->key
.pid
= 0;
163 con
->pCli_state
->key
.vuid
= UID_FIELD_INVALID
;
164 create_ntc_from_cli_state ( &usr
, con
->pCli_state
);
165 copy_nt_creds(&con
->usr_creds
.ntc
, &usr
);
167 if (is_new_connection
)
169 con
->auth_info
= NULL
;
170 con
->auth_creds
= auth_creds
;
178 con
->auth
= &cli_noauth_fns
;
181 if (!rpc_pipe_bind(con
->pCli_state
, pipe_name
, global_myname
))
183 DEBUG(0, ("rpc_pipe_bind failed\n"));
184 cli_connection_free(con
);
190 con
->auth_info
= cli_conn_get_auth_creds(con
);
191 con
->auth
= cli_conn_get_authfns(con
);
192 if (con
->auth_info
!= NULL
)
194 DEBUG(1,("cli_con_get: TODO: auth reuse\n"));
195 cli_connection_free(con
);
200 con
->auth
= &cli_noauth_fns
;
204 add_con_to_array(&num_cons
, &con_list
, con
);
209 /****************************************************************************
210 terminate client connection
211 ****************************************************************************/
212 void cli_connection_free(struct cli_connection
*con
)
215 struct cli_state
*oldcli
= NULL
;
218 DEBUG(10, ("cli_connection_free: %d\n", __LINE__
));
220 if (con
->pCli_state
!= NULL
)
222 DEBUG(10, ("msrpc smb connection\n"));
223 ncacn_np_use_del(con
->srv_name
, con
->pipe_name
,
224 &con
->pCli_state
->key
, False
, &closed
);
225 oldcli
= con
->pCli_state
;
226 con
->pCli_state
= NULL
;
229 DEBUG(10, ("cli_connection_free: closed: %s\n", BOOLSTR(closed
)));
233 for (i
= 0; i
< num_cons
; i
++)
235 struct cli_connection
*c
= con_list
[i
];
236 if (c
!= NULL
&& con
!= c
&& c
->pCli_state
== oldcli
)
238 /* WHOOPS! fnum already open: too bad!!!
239 get rid of all other connections that
240 were using that connection
242 c
->pCli_state
= NULL
;
247 /* don't free the cli_state since it is being handled
248 by the *clis list in rpc_client/cli_use.c.
249 This code needs to be fixed badly. It is **way**
250 to complicated. --jerry */
251 /* if (oldcli != NULL)
256 if (con
->srv_name
!= NULL
)
259 con
->srv_name
= NULL
;
261 if (con
->pipe_name
!= NULL
)
263 free(con
->pipe_name
);
264 con
->pipe_name
= NULL
;
267 if (con
->auth_info
!= NULL
)
269 free(con
->auth_info
);
270 con
->auth_info
= NULL
;
273 memset(&con
->usr_creds
, 0, sizeof(con
->usr_creds
));
275 for (i
= 0; i
< num_cons
; i
++)
277 if (con
== con_list
[i
])
286 void cli_connection_unlink(struct cli_connection
*con
)
290 cli_connection_free(con
);
295 /****************************************************************************
297 ****************************************************************************/
298 BOOL
cli_connection_init(const char *srv_name
, char *pipe_name
,
299 struct cli_connection
**con
)
301 return cli_connection_init_auth(srv_name
, pipe_name
, con
, NULL
, NULL
);
304 /****************************************************************************
306 ****************************************************************************/
307 BOOL
cli_connection_init_auth(const char *srv_name
, char *pipe_name
,
308 struct cli_connection
**con
,
309 cli_auth_fns
* auth
, void *auth_creds
)
317 DEBUG(10, ("cli_connection_init_auth: %s %s\n",
318 srv_name
!= NULL
? srv_name
: "<null>", pipe_name
));
320 *con
= cli_con_get(srv_name
, pipe_name
, auth
, auth_creds
, reuse
);
322 return (*con
) != NULL
;
325 /****************************************************************************
326 get auth functions associated with an msrpc session.
327 ****************************************************************************/
328 struct _cli_auth_fns
*cli_conn_get_authfns(struct cli_connection
*con
)
330 return con
!= NULL
? con
->auth
: NULL
;
334 /****************************************************************************
335 get auth info associated with an msrpc session.
336 ****************************************************************************/
337 void *cli_conn_get_auth_creds(struct cli_connection
*con
)
339 return con
!= NULL
? con
->auth_creds
: NULL
;
343 /****************************************************************************
344 send a request on an rpc pipe.
345 ****************************************************************************/
346 BOOL
rpc_hnd_pipe_req(const POLICY_HND
* hnd
, uint8 op_num
,
347 prs_struct
* data
, prs_struct
* rdata
)
349 struct cli_connection
*con
= NULL
;
351 /* we need this to locate the cli_connection associated
352 with the POLICY_HND */
353 if ((con
=RpcHndList_get_connection(hnd
)) == NULL
)
356 if (!rpc_con_ok(con
)) return False
;
358 return rpc_con_pipe_req(con
, op_num
, data
, rdata
);
361 /****************************************************************************
362 send a request on an rpc pipe.
363 ****************************************************************************/
364 BOOL
rpc_con_pipe_req(struct cli_connection
*con
, uint8 op_num
,
365 prs_struct
* data
, prs_struct
* rdata
)
368 DEBUG(10, ("rpc_con_pipe_req: op_num %d offset %d used: %d\n",
369 op_num
, data
->data_offset
, data
->buffer_size
));
370 prs_dump("in_rpcclient", (int)op_num
, data
);
372 /* Why does this use prs->data_offset? --jerry */
373 /* prs_realloc_data(data, data->data_offset); */
375 ret
= rpc_api_pipe_req(con
->pCli_state
, op_num
, data
, rdata
);
376 prs_dump("out_rpcclient", (int)op_num
, rdata
);
380 /****************************************************************************
381 this allows us to detect dead servers. The cli->fd is set to -1 when
383 *****************************************************************************/
384 BOOL
rpc_con_ok(struct cli_connection
*con
)
389 if (!con
->pCli_state
)
391 if (con
->pCli_state
->fd
== -1)