2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-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.
24 #include "rpc_parse.h"
25 #include "rpc_client.h"
27 extern int DEBUGLEVEL
;
29 /****************************************************************************
30 decrypt data on an rpc pipe
31 ****************************************************************************/
32 static BOOL
decode_netsec_pdu(struct cli_connection
*con
,
33 prs_struct
*rdata
, int len
, int auth_len
)
35 RPC_AUTH_NETSEC_CHK chk
;
36 RPC_HDR_AUTH auth_info
;
37 int data_len
= len
- 0x18 - auth_len
- 8;
38 char *reply_data
= prs_data(rdata
, 0x18);
41 netsec_auth_struct
*a
;
42 a
= (netsec_auth_struct
*)cli_conn_get_auth_info(con
);
49 DEBUG(5,("decode_netsec_pdu: len: %d auth_len: %d\n",
52 if (reply_data
== NULL
) return False
;
54 if (auth_len
!= 0x20 )
59 /*** skip the data, record the offset so we can restore it again */
60 old_offset
= rdata
->offset
;
62 rdata
->offset
= data_len
+ 0x18;
63 smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, rdata
, 0);
64 if (!rpc_hdr_netsec_auth_chk(&(auth_info
)))
69 smb_io_rpc_auth_netsec_chk("auth_sign", &chk
, rdata
, 0);
71 if (!netsec_decode(a
, &chk
, reply_data
, data_len
))
78 /* restore the [data, now decoded] offset */
79 rdata
->offset
= old_offset
;
84 /****************************************************************************
85 send a request on an rpc pipe.
86 ****************************************************************************/
87 static BOOL
create_netsec_pdu(struct cli_connection
*con
,
89 prs_struct
*data
, int data_start
, int *data_end
,
100 char *d
= prs_data(data
, data_start
);
101 struct ntdom_info
*nt
= cli_conn_get_ntinfo(con
);
102 netsec_auth_struct
*a
= NULL
;
104 RPC_HDR_AUTH auth_info
;
105 RPC_AUTH_NETSEC_CHK verf
;
107 static const uchar netsec_sig
[8] = NETSEC_SIGNATURE
;
109 a
= (netsec_auth_struct
*)cli_conn_get_auth_info(con
);
118 data_len
= data
->offset
- data_start
;
122 (*flags
) |= RPC_FLG_FIRST
;
125 if (data_len
> nt
->max_recv_frag
)
127 data_len
= nt
->max_recv_frag
- auth_len
- 8 - 0x18;
131 (*flags
) |= RPC_FLG_LAST
;
134 (*data_end
) += data_len
;
136 /* happen to know that NETSEC authentication verifier is 16 bytes */
137 frag_len
= data_len
+ auth_len
+ 8 + 0x18;
139 prs_init(&data_t
, 0 , 4, False
);
140 prs_init(&hdr
, frag_len
, 4, False
);
141 prs_init(&hdr_auth
, 0 , 4, False
);
142 prs_init(&auth_verf
, auth_len
, 4, False
);
144 prs_append_data(&data_t
, d
, data_len
);
145 data_t
.end
= data_t
.data_size
;
146 data_t
.offset
= data_t
.data_size
;
148 create_rpc_request(&hdr
, nt
->key
.vuid
, op_num
, (*flags
),
151 DEBUG(5,("create_netsec_reply: data %d auth %d\n",
152 data_len
, auth_len
));
154 make_rpc_hdr_auth(&auth_info
, 0x44, 0x06, 0x0, 1);
155 smb_io_rpc_hdr_auth("hdr_auth", &auth_info
, &hdr_auth
, 0);
157 memset(sign
, 0, sizeof(sign
));
160 make_rpc_auth_netsec_chk(&verf
, netsec_sig
, NULL
, sign
, NULL
);
162 ret
= netsec_encode(a
, &verf
, prs_data(&data_t
, 0),
163 prs_buf_len(&data_t
));
167 smb_io_rpc_auth_netsec_chk("auth_sign", &verf
, &auth_verf
, 0);
172 prs_link(NULL
, &hdr
, &data_t
);
173 prs_link(&hdr
, &data_t
, &hdr_auth
);
174 prs_link(&data_t
, &hdr_auth
, &auth_verf
);
175 prs_link(&hdr_auth
, &auth_verf
, NULL
);
177 prs_init(dataa
, 0, 4, False
);
178 ret
= prs_copy(dataa
, &hdr
);
181 prs_free_data(&hdr_auth
);
182 prs_free_data(&data_t
);
183 prs_free_data(&auth_verf
);
184 prs_free_data(&hdr
);
189 /*******************************************************************
190 creates a DCE/RPC bind request
192 - initialises the parse structure.
193 - dynamically allocates the header data structure
194 - caller is expected to free the header data structure once used.
196 ********************************************************************/
197 static BOOL
create_netsec_bind_req(struct cli_connection
*con
,
200 RPC_IFACE
*abstract
, RPC_IFACE
*transfer
)
204 prs_struct rhdr_auth
;
209 RPC_HDR_AUTH hdr_auth
;
210 RPC_AUTH_VERIFIER auth_verifier
;
211 RPC_AUTH_NETSEC_NEG netsec_neg
;
213 struct ntdom_info
*nt
= cli_conn_get_ntinfo(con
);
214 netsec_auth_struct
*a
;
215 struct netsec_creds
*usr
;
216 usr
= (struct netsec_creds
*)cli_conn_get_auth_creds(con
);
218 prs_init(&rhdr
, 0x0, 4, False
);
219 prs_init(&rhdr_rb
, 0x0, 4, False
);
220 prs_init(&rhdr_auth
, 0x0, 4, False
);
221 prs_init(&auth_req
, 0x0, 4, False
);
223 /* create the bind request RPC_HDR_RB */
224 make_rpc_hdr_rb(&hdr_rb
, 0x1630, 0x1630, nt
->key
.pid
,
225 0x1, nt
->key
.vuid
, 0x1, abstract
, transfer
);
227 /* stream the bind request data */
228 smb_io_rpc_hdr_rb("", &hdr_rb
, &rhdr_rb
, 0);
230 make_rpc_hdr_auth(&hdr_auth
, 0x44, 0x06, 0x00, 1);
231 smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth
, &rhdr_auth
, 0);
233 make_rpc_auth_verifier(&auth_verifier
, "", 0x3);
235 smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier
, &auth_req
, 0);
237 make_rpc_auth_netsec_neg(&netsec_neg
, usr
->domain
, usr
->myname
);
239 smb_io_rpc_auth_netsec_neg("netsec_neg", &netsec_neg
, &auth_req
, 0);
241 /* create the request RPC_HDR */
242 make_rpc_hdr(&hdr
, RPC_BIND
, 0x0, rpc_call_id
,
243 auth_req
.offset
+ rhdr_auth
.offset
+
244 rhdr_rb
.offset
+ 0x10,
247 smb_io_rpc_hdr("hdr" , &hdr
, &rhdr
, 0);
249 if (rhdr
.data
== NULL
|| rhdr_rb
.data
== NULL
) return False
;
252 /*** link rpc header, bind ack and auth responses ***/
255 prs_link(NULL
, &rhdr
, &rhdr_rb
);
256 prs_link(&rhdr
, &rhdr_rb
, &rhdr_auth
);
257 prs_link(&rhdr_rb
, &rhdr_auth
, &auth_req
);
258 prs_link(&rhdr_auth
, &auth_req
, NULL
);
260 prs_init(data
, prs_buf_len(&rhdr
), 4, False
);
261 prs_buf_copy(data
->data
, &rhdr
, 0, prs_buf_len(&rhdr
));
263 prs_free_data(&rhdr
);
264 prs_free_data(&rhdr_rb
);
265 prs_free_data(&rhdr_auth
);
266 prs_free_data(&auth_req
);
268 a
= malloc(sizeof(struct netsec_auth_struct
));
274 memcpy(a
->sess_key
, usr
->sess_key
, sizeof(a
->sess_key
));
276 if (!cli_conn_set_auth_info(con
, (void*)a
))
284 static BOOL
decode_netsec_bind_resp(struct cli_connection
*con
,
287 BOOL valid_ack
= True
;
288 netsec_auth_struct
*a
;
289 a
= (netsec_auth_struct
*)cli_conn_get_auth_info(con
);
298 RPC_HDR_AUTH rhdr_auth
;
299 smb_io_rpc_hdr_auth("", &rhdr_auth
, rdata
, 0);
300 if (rdata
->offset
== 0 ||
301 !rpc_hdr_netsec_auth_chk(&rhdr_auth
))
308 RPC_AUTH_VERIFIER rhdr_verf
;
309 smb_io_rpc_auth_verifier("", &rhdr_verf
, rdata
, 0);
310 if (rdata
->offset
== 0 ||
311 !rpc_auth_verifier_chk(&rhdr_verf
, "\001", 0))
318 RPC_AUTH_NETSEC_RESP rresp
;
319 smb_io_rpc_auth_netsec_resp("", &rresp
, rdata
, 0);
320 if (rdata
->offset
== 0) valid_ack
= False
;
325 cli_auth_fns cli_netsec_fns
=
327 create_netsec_bind_req
,
328 decode_netsec_bind_resp
,