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"
29 static struct cli_connection
**con_list
= NULL
;
30 static uint32 num_cons
= 0;
32 struct user_creds
*usr_creds
= NULL
;
33 vuser_key
*user_key
= NULL
;
35 extern int DEBUGLEVEL
;
36 extern pstring global_myname
;
38 * needed for the struct cli_connection
39 * none of these functions are implemented in HEAD currently
40 * rpc_client/cli_connect.c for details
42 * the 'typedef struct _cli_auth_fns cli_auth_fns;' is in
45 struct _cli_auth_fns
{
47 /* these three will do for now. they *should* match with server-side */
48 BOOL (*create_bind_req
) (struct cli_connection
*, prs_struct
*,
49 uint32
, RPC_IFACE
*, RPC_IFACE
*);
50 BOOL (*decode_bind_resp
) (struct cli_connection
*, prs_struct
*);
51 BOOL (*create_bind_cont
) (struct cli_connection
*, prs_struct
*, uint32
);
53 /* creates an authenticated PDU */
54 BOOL (*cli_create_pdu
) (struct cli_connection
*, uint8
, prs_struct
*,
55 int, int *, prs_struct
*, uint8
*);
57 /* decodes an authenticated PDU */
58 BOOL (*cli_decode_pdu
) (struct cli_connection
*, prs_struct
*, int, int);
62 cli_auth_fns cli_noauth_fns
=
74 void init_connections(void)
82 static void free_con_array(uint32 num_entries
,
83 struct cli_connection
**entries
)
85 void (*fn
) (void *) = (void (*)(void *))&cli_connection_free
;
86 free_void_array(num_entries
, (void **)entries
, *fn
);
90 static struct cli_connection
*add_con_to_array(uint32
* len
,
91 struct cli_connection
***array
,
92 struct cli_connection
*con
)
94 return (struct cli_connection
*)add_item_to_array(len
,
100 void free_connections(void)
102 DEBUG(3, ("free_connections: closing all MSRPC connections\n"));
103 free_con_array(num_cons
, con_list
);
109 static struct cli_connection
*cli_con_get(const char *srv_name
,
112 void *auth_creds
, BOOL reuse
)
114 struct cli_connection
*con
= NULL
;
115 BOOL is_new_connection
= False
;
117 struct ntuser_creds
*ntc
= NULL
;
118 struct ncacn_np
*pNcacn
;
121 * initialization stuff
123 con
= (struct cli_connection
*)malloc(sizeof(*con
));
128 memset(con
, 0, sizeof(*con
));
130 copy_user_creds(&con
->usr_creds
, NULL
);
131 con
->usr_creds
.reuse
= reuse
;
133 if (srv_name
!= NULL
)
135 con
->srv_name
= strdup(srv_name
);
137 if (pipe_name
!= NULL
)
139 con
->pipe_name
= strdup(pipe_name
);
141 if (usr_creds
!= NULL
)
143 ntc
= &usr_creds
->ntc
;
146 /* fix me XXXX **WHAT** a hack. The cli_state* is malloc'd
147 deep within the call stack, so we can grab that pointer.
148 ncacn_np* is stored in an array which is currently handled
149 by underlying systems. --jerry */
150 pNcacn
= ncacn_np_use_add(pipe_name
, user_key
, srv_name
,
156 con
->pCli_state
= pNcacn
->smb
;
158 if (con
->pCli_state
== NULL
)
161 con
->pCli_state
->key
.pid
= 0;
162 con
->pCli_state
->key
.vuid
= UID_FIELD_INVALID
;
163 create_ntc_from_cli_state ( &usr
, con
->pCli_state
);
164 copy_nt_creds(&con
->usr_creds
.ntc
, &usr
);
166 if (is_new_connection
)
168 con
->auth_info
= NULL
;
169 con
->auth_creds
= auth_creds
;
177 con
->auth
= &cli_noauth_fns
;
180 if (!rpc_pipe_bind(con
->pCli_state
, pipe_name
, global_myname
))
182 DEBUG(0, ("rpc_pipe_bind failed\n"));
183 cli_connection_free(con
);
189 con
->auth_info
= cli_conn_get_auth_creds(con
);
190 con
->auth
= cli_conn_get_authfns(con
);
191 if (con
->auth_info
!= NULL
)
193 DEBUG(1,("cli_con_get: TODO: auth reuse\n"));
194 cli_connection_free(con
);
199 con
->auth
= &cli_noauth_fns
;
203 add_con_to_array(&num_cons
, &con_list
, con
);
208 /****************************************************************************
209 terminate client connection
210 ****************************************************************************/
211 void cli_connection_free(struct cli_connection
*con
)
214 struct cli_state
*oldcli
= NULL
;
217 DEBUG(10, ("cli_connection_free: %d\n", __LINE__
));
219 if (con
->pCli_state
!= NULL
)
221 DEBUG(10, ("msrpc smb connection\n"));
222 ncacn_np_use_del(con
->srv_name
, con
->pipe_name
,
223 &con
->pCli_state
->key
, False
, &closed
);
224 oldcli
= con
->pCli_state
;
225 con
->pCli_state
= NULL
;
228 DEBUG(10, ("cli_connection_free: closed: %s\n", BOOLSTR(closed
)));
232 for (i
= 0; i
< num_cons
; i
++)
234 struct cli_connection
*c
= con_list
[i
];
235 if (c
!= NULL
&& con
!= c
&& c
->pCli_state
== oldcli
)
237 /* WHOOPS! fnum already open: too bad!!!
238 get rid of all other connections that
239 were using that connection
241 c
->pCli_state
= NULL
;
246 /* don't free the cli_state since it is being handled
247 by the *clis list in rpc_client/cli_use.c.
248 This code needs to be fixed badly. It is **way**
249 to complicated. --jerry */
250 /* if (oldcli != NULL)
255 if (con
->srv_name
!= NULL
)
258 con
->srv_name
= NULL
;
260 if (con
->pipe_name
!= NULL
)
262 free(con
->pipe_name
);
263 con
->pipe_name
= NULL
;
266 if (con
->auth_info
!= NULL
)
268 free(con
->auth_info
);
269 con
->auth_info
= NULL
;
272 memset(&con
->usr_creds
, 0, sizeof(con
->usr_creds
));
274 for (i
= 0; i
< num_cons
; i
++)
276 if (con
== con_list
[i
])
285 void cli_connection_unlink(struct cli_connection
*con
)
289 cli_connection_free(con
);
294 /****************************************************************************
296 ****************************************************************************/
297 BOOL
cli_connection_init(const char *srv_name
, char *pipe_name
,
298 struct cli_connection
**con
)
300 return cli_connection_init_auth(srv_name
, pipe_name
, con
, NULL
, NULL
);
303 /****************************************************************************
305 ****************************************************************************/
306 BOOL
cli_connection_init_auth(const char *srv_name
, char *pipe_name
,
307 struct cli_connection
**con
,
308 cli_auth_fns
* auth
, void *auth_creds
)
316 DEBUG(10, ("cli_connection_init_auth: %s %s\n",
317 srv_name
!= NULL
? srv_name
: "<null>", pipe_name
));
319 *con
= cli_con_get(srv_name
, pipe_name
, auth
, auth_creds
, reuse
);
321 return (*con
) != NULL
;
324 /****************************************************************************
325 get auth functions associated with an msrpc session.
326 ****************************************************************************/
327 struct _cli_auth_fns
*cli_conn_get_authfns(struct cli_connection
*con
)
329 return con
!= NULL
? con
->auth
: NULL
;
333 /****************************************************************************
334 get auth info associated with an msrpc session.
335 ****************************************************************************/
336 void *cli_conn_get_auth_creds(struct cli_connection
*con
)
338 return con
!= NULL
? con
->auth_creds
: NULL
;
342 /****************************************************************************
343 send a request on an rpc pipe.
344 ****************************************************************************/
345 BOOL
rpc_hnd_pipe_req(const POLICY_HND
* hnd
, uint8 op_num
,
346 prs_struct
* data
, prs_struct
* rdata
)
348 struct cli_connection
*con
= NULL
;
350 /* we need this to locate the cli_connection associated
351 with the POLICY_HND */
352 if ((con
=RpcHndList_get_connection(hnd
)) == NULL
)
355 if (!rpc_con_ok(con
)) return False
;
357 return rpc_con_pipe_req(con
, op_num
, data
, rdata
);
360 /****************************************************************************
361 send a request on an rpc pipe.
362 ****************************************************************************/
363 BOOL
rpc_con_pipe_req(struct cli_connection
*con
, uint8 op_num
,
364 prs_struct
* data
, prs_struct
* rdata
)
367 DEBUG(10, ("rpc_con_pipe_req: op_num %d offset %d used: %d\n",
368 op_num
, data
->data_offset
, data
->buffer_size
));
369 prs_dump("in_rpcclient", (int)op_num
, data
);
371 /* Why does this use prs->data_offset? --jerry */
372 /* prs_realloc_data(data, data->data_offset); */
374 ret
= rpc_api_pipe_req(con
->pCli_state
, op_num
, data
, rdata
);
375 prs_dump("out_rpcclient", (int)op_num
, rdata
);
379 /****************************************************************************
380 this allows us to detect dead servers. The cli->fd is set to -1 when
382 *****************************************************************************/
383 BOOL
rpc_con_ok(struct cli_connection
*con
)
388 if (!con
->pCli_state
)
390 if (con
->pCli_state
->fd
== -1)