3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-2000,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 extern int DEBUGLEVEL
;
30 /*******************************************************************
31 checks an RPC_HDR_AUTH structure.
32 ********************************************************************/
33 BOOL
rpc_hdr_ntlmssp_auth_chk(RPC_HDR_AUTH
*rai
)
35 return (rai
->auth_type
== 0x0a && rai
->auth_level
== 0x06);
38 /*******************************************************************
39 creates an RPC_AUTH_NTLMSSP_NEG structure.
40 ********************************************************************/
41 BOOL
make_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG
*neg
,
43 fstring myname
, fstring domain
)
45 int len_myname
= strlen(myname
);
46 int len_domain
= strlen(domain
);
48 if (neg
== NULL
) return False
;
50 neg
->neg_flgs
= neg_flgs
; /* 0x00b2b3 */
52 make_str_hdr(&neg
->hdr_domain
, len_domain
, len_domain
, 0x20 + len_myname
);
53 make_str_hdr(&neg
->hdr_myname
, len_myname
, len_myname
, 0x20);
55 fstrcpy(neg
->myname
, myname
);
56 fstrcpy(neg
->domain
, domain
);
61 /*******************************************************************
62 reads or writes an RPC_AUTH_NTLMSSP_NEG structure.
64 *** lkclXXXX HACK ALERT! ***
66 ********************************************************************/
67 BOOL
smb_io_rpc_auth_ntlmssp_neg(char *desc
, RPC_AUTH_NTLMSSP_NEG
*neg
, prs_struct
*ps
, int depth
)
69 int start_offset
= ps
->offset
;
70 if (neg
== NULL
) return False
;
72 prs_debug(ps
, depth
, desc
, "smb_io_rpc_auth_ntlmssp_neg");
75 prs_uint32("neg_flgs ", ps
, depth
, &(neg
->neg_flgs
));
85 smb_io_strhdr("hdr_domain", &(neg
->hdr_domain
), ps
, depth
);
86 smb_io_strhdr("hdr_myname", &(neg
->hdr_myname
), ps
, depth
);
88 old_offset
= ps
->offset
;
90 ps
->offset
= neg
->hdr_myname
.buffer
+ start_offset
- 12;
91 prs_uint8s(True
, "myname", ps
, depth
, (uint8
*)neg
->myname
, MIN(neg
->hdr_myname
.str_str_len
, sizeof(neg
->myname
)));
92 old_offset
+= neg
->hdr_myname
.str_str_len
;
94 ps
->offset
= neg
->hdr_domain
.buffer
+ start_offset
- 12;
95 prs_uint8s(True
, "domain", ps
, depth
, (uint8
*)neg
->domain
, MIN(neg
->hdr_domain
.str_str_len
, sizeof(neg
->domain
)));
96 old_offset
+= neg
->hdr_domain
.str_str_len
;
98 ps
->offset
= old_offset
;
103 smb_io_strhdr("hdr_domain", &(neg
->hdr_domain
), ps
, depth
);
104 smb_io_strhdr("hdr_myname", &(neg
->hdr_myname
), ps
, depth
);
106 prs_uint8s(True
, "myname", ps
, depth
, (uint8
*)neg
->myname
, MIN(neg
->hdr_myname
.str_str_len
, sizeof(neg
->myname
)));
107 prs_uint8s(True
, "domain", ps
, depth
, (uint8
*)neg
->domain
, MIN(neg
->hdr_domain
.str_str_len
, sizeof(neg
->domain
)));
113 /*******************************************************************
114 creates an RPC_AUTH_NTLMSSP_CHAL structure.
115 ********************************************************************/
116 BOOL
make_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL
*chl
,
120 if (chl
== NULL
) return False
;
122 chl
->unknown_1
= 0x0;
123 chl
->unknown_2
= 0x00000028;
124 chl
->neg_flags
= neg_flags
; /* 0x0082b1 */
126 memcpy(chl
->challenge
, challenge
, sizeof(chl
->challenge
));
127 bzero (chl
->reserved
, sizeof(chl
->reserved
));
132 /*******************************************************************
133 reads or writes an RPC_AUTH_NTLMSSP_CHAL structure.
134 ********************************************************************/
135 BOOL
smb_io_rpc_auth_ntlmssp_chal(char *desc
, RPC_AUTH_NTLMSSP_CHAL
*chl
, prs_struct
*ps
, int depth
)
137 if (chl
== NULL
) return False
;
139 prs_debug(ps
, depth
, desc
, "smb_io_rpc_auth_ntlmssp_chal");
142 prs_uint32("unknown_1", ps
, depth
, &(chl
->unknown_1
)); /* 0x0000 0000 */
143 prs_uint32("unknown_2", ps
, depth
, &(chl
->unknown_2
)); /* 0x0000 b2b3 */
144 prs_uint32("neg_flags", ps
, depth
, &(chl
->neg_flags
)); /* 0x0000 82b1 */
146 prs_uint8s (False
, "challenge", ps
, depth
, chl
->challenge
, sizeof(chl
->challenge
));
147 prs_uint8s (False
, "reserved ", ps
, depth
, chl
->reserved
, sizeof(chl
->reserved
));
152 /*******************************************************************
153 creates an RPC_AUTH_NTLMSSP_RESP structure.
155 *** lkclXXXX FUDGE! HAVE TO MANUALLY SPECIFY OFFSET HERE (0x1c bytes) ***
156 *** lkclXXXX the actual offset is at the start of the auth verifier ***
158 ********************************************************************/
159 BOOL
make_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP
*rsp
,
161 uchar
*nt_resp
, size_t nt_len
,
162 char *domain
, char *user
, char *wks
,
166 int dom_len
= strlen(domain
);
167 int wks_len
= strlen(wks
);
168 int usr_len
= strlen(user
);
169 int lm_len
= nt_len
!= 0 ? (lm_resp
!= NULL
? 24 : 0) : 1;
171 DEBUG(5,("make_rpc_auth_ntlmssp_resp\n"));
173 if (rsp
== NULL
) return False
;
175 #ifdef DEBUG_PASSWORD
176 DEBUG(100,("lm_resp\n"));
179 dump_data(100, lm_resp
, lm_len
);
181 DEBUG(100,("nt_resp\n"));
184 dump_data(100, nt_resp
, nt_len
);
188 DEBUG(6,("dom: %s user: %s wks: %s neg_flgs: 0x%x\n",
189 domain
, user
, wks
, neg_flags
));
193 if (IS_BITS_SET_ALL(neg_flags
, NTLMSSP_NEGOTIATE_UNICODE
))
200 make_str_hdr(&rsp
->hdr_domain
, dom_len
, dom_len
, offset
);
203 make_str_hdr(&rsp
->hdr_usr
, usr_len
, usr_len
, offset
);
206 make_str_hdr(&rsp
->hdr_wks
, wks_len
, wks_len
, offset
);
209 make_str_hdr(&rsp
->hdr_lm_resp
, lm_len
, lm_len
, offset
);
212 make_str_hdr(&rsp
->hdr_nt_resp
, nt_len
, nt_len
, offset
);
215 make_str_hdr(&rsp
->hdr_sess_key
, 0, 0, offset
);
217 rsp
->neg_flags
= neg_flags
;
219 if (lm_resp
!= NULL
&& lm_len
!= 1)
221 memcpy(rsp
->lm_resp
, lm_resp
, lm_len
);
229 memcpy(rsp
->nt_resp
, nt_resp
, nt_len
);
236 if (IS_BITS_SET_ALL(neg_flags
, NTLMSSP_NEGOTIATE_UNICODE
))
238 ascii_to_unibuf(rsp
->domain
, domain
, sizeof(rsp
->domain
)-2);
239 ascii_to_unibuf(rsp
->user
, user
, sizeof(rsp
->user
)-2);
240 ascii_to_unibuf(rsp
->wks
, wks
, sizeof(rsp
->wks
)-2);
244 fstrcpy(rsp
->domain
, domain
);
245 fstrcpy(rsp
->user
, user
);
246 fstrcpy(rsp
->wks
, wks
);
248 rsp
->sess_key
[0] = 0;
253 /*******************************************************************
254 reads or writes an RPC_AUTH_NTLMSSP_RESP structure.
256 *** lkclXXXX FUDGE! HAVE TO MANUALLY SPECIFY OFFSET HERE (0x1c bytes) ***
257 *** lkclXXXX the actual offset is at the start of the auth verifier ***
259 ********************************************************************/
260 BOOL
smb_io_rpc_auth_ntlmssp_resp(char *desc
, RPC_AUTH_NTLMSSP_RESP
*rsp
, prs_struct
*ps
, int depth
)
262 if (rsp
== NULL
) return False
;
264 prs_debug(ps
, depth
, desc
, "smb_io_rpc_auth_ntlmssp_resp");
275 smb_io_strhdr("hdr_lm_resp ", &rsp
->hdr_lm_resp
, ps
, depth
);
276 smb_io_strhdr("hdr_nt_resp ", &rsp
->hdr_nt_resp
, ps
, depth
);
277 smb_io_strhdr("hdr_domain ", &rsp
->hdr_domain
, ps
, depth
);
278 smb_io_strhdr("hdr_user ", &rsp
->hdr_usr
, ps
, depth
);
279 smb_io_strhdr("hdr_wks ", &rsp
->hdr_wks
, ps
, depth
);
280 smb_io_strhdr("hdr_sess_key", &rsp
->hdr_sess_key
, ps
, depth
);
282 prs_uint32("neg_flags", ps
, depth
, &(rsp
->neg_flags
)); /* 0x0000 82b1 */
284 old_offset
= ps
->offset
;
286 ps
->offset
= rsp
->hdr_domain
.buffer
+ 0xc;
287 prs_uint8s(True
, "domain ", ps
, depth
, (uint8
*)rsp
->domain
, MIN(rsp
->hdr_domain
.str_str_len
, sizeof(rsp
->domain
)));
288 old_offset
+= rsp
->hdr_domain
.str_str_len
;
290 ps
->offset
= rsp
->hdr_usr
.buffer
+ 0xc;
291 prs_uint8s(True
, "user ", ps
, depth
, (uint8
*)rsp
->user
, MIN(rsp
->hdr_usr
.str_str_len
, sizeof(rsp
->user
)));
292 old_offset
+= rsp
->hdr_usr
.str_str_len
;
294 ps
->offset
= rsp
->hdr_wks
.buffer
+ 0xc;
295 prs_uint8s(True
, "wks ", ps
, depth
, (uint8
*)rsp
->wks
, MIN(rsp
->hdr_wks
.str_str_len
, sizeof(rsp
->wks
)));
296 old_offset
+= rsp
->hdr_wks
.str_str_len
;
298 ps
->offset
= rsp
->hdr_lm_resp
.buffer
+ 0xc;
299 prs_uint8s(False
, "lm_resp ", ps
, depth
, (uint8
*)rsp
->lm_resp
, MIN(rsp
->hdr_lm_resp
.str_str_len
, sizeof(rsp
->lm_resp
)));
300 old_offset
+= rsp
->hdr_lm_resp
.str_str_len
;
302 ps
->offset
= rsp
->hdr_nt_resp
.buffer
+ 0xc;
303 prs_uint8s(False
, "nt_resp ", ps
, depth
, (uint8
*)rsp
->nt_resp
, MIN(rsp
->hdr_nt_resp
.str_str_len
, sizeof(rsp
->nt_resp
)));
304 old_offset
+= rsp
->hdr_nt_resp
.str_str_len
;
306 if (rsp
->hdr_sess_key
.str_str_len
!= 0)
308 ps
->offset
= rsp
->hdr_sess_key
.buffer
+ 0x10;
309 old_offset
+= rsp
->hdr_sess_key
.str_str_len
;
310 prs_uint8s(False
, "sess_key", ps
, depth
, (uint8
*)rsp
->sess_key
, MIN(rsp
->hdr_sess_key
.str_str_len
, sizeof(rsp
->sess_key
)));
313 ps
->offset
= old_offset
;
318 smb_io_strhdr("hdr_lm_resp ", &rsp
->hdr_lm_resp
, ps
, depth
);
319 smb_io_strhdr("hdr_nt_resp ", &rsp
->hdr_nt_resp
, ps
, depth
);
320 smb_io_strhdr("hdr_domain ", &rsp
->hdr_domain
, ps
, depth
);
321 smb_io_strhdr("hdr_user ", &rsp
->hdr_usr
, ps
, depth
);
322 smb_io_strhdr("hdr_wks ", &rsp
->hdr_wks
, ps
, depth
);
323 smb_io_strhdr("hdr_sess_key", &rsp
->hdr_sess_key
, ps
, depth
);
325 prs_uint32("neg_flags", ps
, depth
, &(rsp
->neg_flags
)); /* 0x0000 82b1 */
327 prs_uint8s(True
, "domain ", ps
, depth
, (uint8
*)rsp
->domain
, MIN(rsp
->hdr_domain
.str_str_len
, sizeof(rsp
->domain
)));
328 prs_uint8s(True
, "user ", ps
, depth
, (uint8
*)rsp
->user
, MIN(rsp
->hdr_usr
.str_str_len
, sizeof(rsp
->user
)));
329 prs_uint8s(True
, "wks ", ps
, depth
, (uint8
*)rsp
->wks
, MIN(rsp
->hdr_wks
.str_str_len
, sizeof(rsp
->wks
)));
330 prs_uint8s(False
, "lm_resp ", ps
, depth
, (uint8
*)rsp
->lm_resp
, MIN(rsp
->hdr_lm_resp
.str_str_len
, sizeof(rsp
->lm_resp
)));
331 prs_uint8s(False
, "nt_resp ", ps
, depth
, (uint8
*)rsp
->nt_resp
, MIN(rsp
->hdr_nt_resp
.str_str_len
, sizeof(rsp
->nt_resp
)));
332 prs_uint8s(False
, "sess_key", ps
, depth
, (uint8
*)rsp
->sess_key
, MIN(rsp
->hdr_sess_key
.str_str_len
, sizeof(rsp
->sess_key
)));
338 /*******************************************************************
339 checks an RPC_AUTH_NTLMSSP_CHK structure.
340 ********************************************************************/
341 BOOL
rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK
*chk
, uint32 crc32
, uint32 seq_num
)
348 if (chk
->crc32
!= crc32
||
349 chk
->ver
!= NTLMSSP_SIGN_VERSION
||
350 chk
->seq_num
!= seq_num
)
352 DEBUG(5,("verify failed - crc %x ver %x seq %d\n",
353 crc32
, NTLMSSP_SIGN_VERSION
, seq_num
));
354 DEBUG(5,("verify expect - crc %x ver %x seq %d\n",
355 chk
->crc32
, chk
->ver
, chk
->seq_num
));
361 /*******************************************************************
362 creates an RPC_AUTH_NTLMSSP_CHK structure.
363 ********************************************************************/
364 BOOL
make_rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK
*chk
,
365 uint32 ver
, uint32 crc32
, uint32 seq_num
)
367 if (chk
== NULL
) return False
;
372 chk
->seq_num
= seq_num
;
377 /*******************************************************************
378 reads or writes an RPC_AUTH_NTLMSSP_CHK structure.
379 ********************************************************************/
380 BOOL
smb_io_rpc_auth_ntlmssp_chk(char *desc
, RPC_AUTH_NTLMSSP_CHK
*chk
, prs_struct
*ps
, int depth
)
382 if (chk
== NULL
) return False
;
384 prs_debug(ps
, depth
, desc
, "smb_io_rpc_auth_ntlmssp_chk");
387 prs_uint32("ver ", ps
, depth
, &(chk
->ver
));
388 prs_uint32("reserved", ps
, depth
, &(chk
->reserved
));
389 prs_uint32("crc32 ", ps
, depth
, &(chk
->crc32
));
390 prs_uint32("seq_num ", ps
, depth
, &(chk
->seq_num
));