1 
2 /*
3  *  Unix SMB/Netbios implementation.
4  *  Version 1.9.
5  *  RPC Pipe client / server routines
6  *  Copyright (C) Andrew Tridgell              1992-1997,
7  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
8  *  Copyright (C) Paul Ashton                       1997.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24 
25 
26 #ifdef SYSLOG
27 #undef SYSLOG
28 #endif
29 
30 #include "../includes.h"
31 
32 extern int DEBUGLEVEL;
33 extern pstring username;
34 extern pstring workgroup;
35 
36 #define CLIENT_TIMEOUT (30*1000)
37 
38 #ifdef NTDOMAIN
39 
40 /****************************************************************************
41 do a LSA Request Challenge
42 ****************************************************************************/
do_lsa_req_chal(uint16 fnum,uint32 call_id,char * desthost,char * myhostname,DOM_CHAL * clnt_chal,DOM_CHAL * srv_chal)43 BOOL do_lsa_req_chal(uint16 fnum, uint32 call_id,
44 		char *desthost, char *myhostname,
45         DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal)
46 {
47 	char *rparam = NULL;
48 	char *rdata = NULL;
49 	char *p;
50 	int rdrcnt,rprcnt;
51 	pstring data; /* only 1024 bytes */
52 	uint16 setup[2]; /* only need 2 uint16 setup parameters */
53 	LSA_Q_REQ_CHAL q_c;
54     BOOL valid_chal = False;
55 
56 	if (srv_chal == NULL || clnt_chal == NULL) return False;
57 
58 	/* create and send a MSRPC command with api LSA_REQCHAL */
59 
60 	DEBUG(4,("LSA Request Challenge from %s to %s: %s\n",
61 	          desthost, myhostname, credstr(clnt_chal->data)));
62 
63 	/* store the parameters */
64 	make_q_req_chal(&q_c, desthost, myhostname, clnt_chal);
65 
66 
67 	/* turn parameters into data stream */
68 	p = lsa_io_q_req_chal(False, &q_c, data + 0x18, data, 4, 0);
69 
70 	/* create the request RPC_HDR_RR _after_ the main data: length is now known */
71 	create_rpc_request(call_id, LSA_REQCHAL, data, PTR_DIFF(p, data));
72 
73 	/* create setup parameters. */
74 	setup[0] = 0x0026; /* 0x26 indicates "transact named pipe" */
75 	setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
76 
77 	/* send the data on \PIPE\ */
78 	if (cli_call_api("\\PIPE\\", 0,
79 	            0, PTR_DIFF(p, data), 2,
80 	            1024, BUFFER_SIZE,
81 				&rprcnt,&rdrcnt,
82 				NULL, data, setup,
83 				&rparam,&rdata))
84 	{
85 		LSA_R_REQ_CHAL r_c;
86 		RPC_HDR_RR hdr;
87 		int hdr_len;
88 		int pkt_len;
89 
90 		DEBUG(5, ("cli_call_api: return OK\n"));
91 
92 		p = rdata;
93 
94 		if (p) p = smb_io_rpc_hdr_rr   (True, &hdr, p, rdata, 4, 0);
95 		if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
96 
97 		hdr_len = PTR_DIFF(p, rdata);
98 
99 		if (p && hdr_len != hdr.hdr.frag_len - hdr.alloc_hint)
100 		{
101 			/* header length not same as calculated header length */
102 			DEBUG(2,("do_lsa_req_chal: hdr_len %x != frag_len-alloc_hint %x\n",
103 			          hdr_len, hdr.hdr.frag_len - hdr.alloc_hint));
104 			p = NULL;
105 		}
106 
107 		if (p) p = lsa_io_r_req_chal(True, &r_c, p, rdata, 4, 0);
108 
109 		pkt_len = PTR_DIFF(p, rdata);
110 
111 		if (p && pkt_len != hdr.hdr.frag_len)
112 		{
113 			/* packet data size not same as reported fragment length */
114 			DEBUG(2,("do_lsa_req_chal: pkt_len %x != frag_len \n",
115 			                           pkt_len, hdr.hdr.frag_len));
116 			p = NULL;
117 		}
118 
119 		if (p && r_c.status != 0)
120 		{
121 			/* report error code */
122 			DEBUG(0,("LSA_REQ_CHAL: nt_status error %lx\n", r_c.status));
123 			p = NULL;
124 		}
125 
126 		if (p)
127 		{
128 			/* ok, at last: we're happy. return the challenge */
129 			memcpy(srv_chal, r_c.srv_chal.data, sizeof(srv_chal->data));
130 			valid_chal = True;
131 		}
132 	}
133 
134 	if (rparam) free(rparam);
135 	if (rdata) free(rdata);
136 
137 	return valid_chal;
138 }
139 
140 /****************************************************************************
141 do a LSA Authenticate 2
142 ****************************************************************************/
do_lsa_auth2(uint16 fnum,uint32 call_id,char * logon_srv,char * acct_name,uint16 sec_chan,char * comp_name,DOM_CHAL * clnt_chal,uint32 neg_flags,DOM_CHAL * srv_chal)143 BOOL do_lsa_auth2(uint16 fnum, uint32 call_id,
144 		char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
145         DOM_CHAL *clnt_chal, uint32 neg_flags, DOM_CHAL *srv_chal)
146 {
147 	char *rparam = NULL;
148 	char *rdata = NULL;
149 	char *p;
150 	int rdrcnt,rprcnt;
151 	pstring data; /* only 1024 bytes */
152 	uint16 setup[2]; /* only need 2 uint16 setup parameters */
153 	LSA_Q_AUTH_2 q_a;
154     BOOL valid_chal = False;
155 
156 	if (srv_chal == NULL || clnt_chal == NULL) return False;
157 
158 	/* create and send a MSRPC command with api LSA_AUTH2 */
159 
160 	DEBUG(4,("LSA Authenticate 2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %lx\n",
161 	          logon_srv, acct_name, sec_chan, comp_name,
162 	          credstr(clnt_chal->data), neg_flags));
163 
164 	/* store the parameters */
165 	make_q_auth_2(&q_a, logon_srv, acct_name, sec_chan, comp_name,
166 	             clnt_chal, neg_flags);
167 
168 	/* turn parameters into data stream */
169 	p = lsa_io_q_auth_2(False, &q_a, data + 0x18, data, 4, 0);
170 
171 	/* create the request RPC_HDR_RR _after_ the main data: length is now known */
172 	create_rpc_request(call_id, LSA_AUTH2, data, PTR_DIFF(p, data));
173 
174 	/* create setup parameters. */
175 	setup[0] = 0x0026; /* 0x26 indicates "transact named pipe" */
176 	setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
177 
178 	/* send the data on \PIPE\ */
179 	if (cli_call_api("\\PIPE\\", 0,
180 	            0, PTR_DIFF(p, data), 2,
181 	            1024, BUFFER_SIZE,
182 				&rprcnt,&rdrcnt,
183 				NULL, data, setup,
184 				&rparam,&rdata))
185 	{
186 		LSA_R_AUTH_2 r_a;
187 		RPC_HDR_RR hdr;
188 		int hdr_len;
189 		int pkt_len;
190 
191 		DEBUG(5, ("cli_call_api: return OK\n"));
192 
193 		p = rdata;
194 
195 		if (p) p = smb_io_rpc_hdr_rr   (True, &hdr, p, rdata, 4, 0);
196 		if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
197 
198 		hdr_len = PTR_DIFF(p, rdata);
199 
200 		if (p && hdr_len != hdr.hdr.frag_len - hdr.alloc_hint)
201 		{
202 			/* header length not same as calculated header length */
203 			DEBUG(2,("do_lsa_auth2: hdr_len %x != frag_len-alloc_hint %x\n",
204 			          hdr_len, hdr.hdr.frag_len - hdr.alloc_hint));
205 			p = NULL;
206 		}
207 
208 		if (p) p = lsa_io_r_auth_2(True, &r_a, p, rdata, 4, 0);
209 
210 		pkt_len = PTR_DIFF(p, rdata);
211 
212 		if (p && pkt_len != hdr.hdr.frag_len)
213 		{
214 			/* packet data size not same as reported fragment length */
215 			DEBUG(2,("do_lsa_auth2: pkt_len %x != frag_len \n",
216 			                           pkt_len, hdr.hdr.frag_len));
217 			p = NULL;
218 		}
219 
220 		if (p && r_a.status != 0)
221 		{
222 			/* report error code */
223 			DEBUG(0,("LSA_AUTH2: nt_status error %lx\n", r_a.status));
224 			p = NULL;
225 		}
226 
227 		if (p && r_a.srv_flgs.neg_flags != q_a.clnt_flgs.neg_flags)
228 		{
229 			/* report different neg_flags */
230 			DEBUG(0,("LSA_AUTH2: error neg_flags (q,r) differ - (%lx,%lx)\n",
231 					q_a.clnt_flgs.neg_flags, r_a.srv_flgs.neg_flags));
232 			p = NULL;
233 		}
234 
235 		if (p)
236 		{
237 			/* ok, at last: we're happy. return the challenge */
238 			memcpy(srv_chal, r_a.srv_chal.data, sizeof(srv_chal->data));
239 			valid_chal = True;
240 		}
241 	}
242 
243 	if (rparam) free(rparam);
244 	if (rdata) free(rdata);
245 
246 	return valid_chal;
247 }
248 
249 /***************************************************************************
250 do a LSA Server Password Set
251 ****************************************************************************/
do_lsa_srv_pwset(uint16 fnum,uint32 call_id,uchar sess_key[8],char * logon_srv,char * mach_acct,uint16 sec_chan_type,char * comp_name,DOM_CRED * clnt_cred,DOM_CRED * srv_cred,char nt_owf_new_mach_pwd[16])252 BOOL do_lsa_srv_pwset(uint16 fnum, uint32 call_id,
253 		uchar sess_key[8],
254 		char *logon_srv, char *mach_acct, uint16 sec_chan_type, char *comp_name,
255         DOM_CRED *clnt_cred, DOM_CRED *srv_cred,
256 		char nt_owf_new_mach_pwd[16])
257 {
258 	char *rparam = NULL;
259 	char *rdata = NULL;
260 	char *p;
261 	int rdrcnt,rprcnt;
262 	pstring data; /* only 1024 bytes */
263 	uint16 setup[2]; /* only need 2 uint16 setup parameters */
264 	LSA_Q_SRV_PWSET q_s;
265     BOOL valid_cred = False;
266 
267 	if (srv_cred == NULL || clnt_cred == NULL) return False;
268 
269 	/* create and send a MSRPC command with api LSA_SRV_PWSET */
270 
271 	DEBUG(4,("LSA Server Password Set: srv:%s acct:%s sc: %d mc: %s clnt %s %lx\n",
272 		 logon_srv, mach_acct, sec_chan_type, comp_name,
273 		 credstr(clnt_cred->challenge.data), clnt_cred->timestamp.time));
274 
275 	/* store the parameters */
276 	make_q_srv_pwset(&q_s,
277                  sess_key,
278 	             logon_srv, mach_acct, sec_chan_type, comp_name,
279 	             clnt_cred,
280 	             nt_owf_new_mach_pwd);
281 
282 	/* turn parameters into data stream */
283 	p = lsa_io_q_srv_pwset(False, &q_s, data + 0x18, data, 4, 0);
284 
285 	/* create the request RPC_HDR_RR _after_ the main data: length is now known */
286 	create_rpc_request(call_id, LSA_SAMLOGON, data, PTR_DIFF(p, data));
287 
288 	/* create setup parameters. */
289 	setup[0] = 0x0026; /* 0x26 indicates "transact named pipe" */
290 	setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
291 
292 	/* send the data on \PIPE\ */
293 	if (cli_call_api("\\PIPE\\", 0,
294 	            0, PTR_DIFF(p, data), 2,
295 	            1024, BUFFER_SIZE,
296 				&rprcnt,&rdrcnt,
297 				NULL, data, setup,
298 				&rparam,&rdata))
299 	{
300 #if 0
301 		LSA_R_SAM_LOGON r_s;
302 		RPC_HDR_RR hdr;
303 		int hdr_len;
304 		int pkt_len;
305 
306 		r_s.user = user_info;
307 
308 		DEBUG(5, ("cli_call_api: return OK\n"));
309 
310 		p = rdata;
311 
312 		if (p) p = smb_io_rpc_hdr_rr   (True, &hdr, p, rdata, 4, 0);
313 		if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
314 
315 		hdr_len = PTR_DIFF(p, rdata);
316 
317 		if (p && hdr_len != hdr.hdr.frag_len - hdr.alloc_hint)
318 		{
319 			/* header length not same as calculated header length */
320 			DEBUG(2,("do_lsa_sam_logon: hdr_len %x != frag_len-alloc_hint %x\n",
321 			          hdr_len, hdr.hdr.frag_len - hdr.alloc_hint));
322 			p = NULL;
323 		}
324 
325 		if (p) p = lsa_io_r_sam_logon(True, &r_s, p, rdata, 4, 0);
326 
327 		pkt_len = PTR_DIFF(p, rdata);
328 
329 		if (p && pkt_len != hdr.hdr.frag_len)
330 		{
331 			/* packet data size not same as reported fragment length */
332 			DEBUG(2,("do_lsa_sam_logon: pkt_len %x != frag_len \n",
333 			                           pkt_len, hdr.hdr.frag_len));
334 			p = NULL;
335 		}
336 
337 		if (p && r_s.status != 0)
338 		{
339 			/* report error code */
340 			DEBUG(0,("LSA_SAMLOGON: nt_status error %lx\n", r_s.status));
341 			p = NULL;
342 		}
343 
344 		if (p && r_s.switch_value != 3)
345 		{
346 			/* report different switch_value */
347 			DEBUG(0,("LSA_SAMLOGON: switch_value of 3 expected %x\n",
348 					r_s.switch_value));
349 			p = NULL;
350 		}
351 
352 		if (p)
353 		{
354 			if (clnt_deal_with_creds(sess_key, sto_clnt_cred, &(r_s.srv_creds)))
355 			{
356 				DEBUG(5, ("do_lsa_sam_logon: server credential check OK\n"));
357 				/* ok, at last: we're happy. return the challenge */
358 				memcpy(srv_cred, &(r_s.srv_creds), sizeof(r_s.srv_creds));
359 				valid_cred = True;
360 			}
361 			else
362 			{
363 				DEBUG(5, ("do_lsa_sam_logon: server credential check failed\n"));
364 			}
365 		}
366 #endif
367 	}
368 
369 	if (rparam) free(rparam);
370 	if (rdata) free(rdata);
371 
372 	return valid_cred;
373 }
374 
375 /***************************************************************************
376 do a LSA SAM Logon
377 ****************************************************************************/
do_lsa_sam_logon(uint16 fnum,uint32 call_id,uchar sess_key[8],DOM_CRED * sto_clnt_cred,char * logon_srv,char * comp_name,DOM_CRED * clnt_cred,DOM_CRED * rtn_cred,uint16 logon_level,uint16 switch_value,DOM_ID_INFO_1 * id1,LSA_USER_INFO * user_info,DOM_CRED * srv_cred)378 BOOL do_lsa_sam_logon(uint16 fnum, uint32 call_id,
379 		uchar sess_key[8], DOM_CRED *sto_clnt_cred,
380 		char *logon_srv, char *comp_name,
381         DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
382 		uint16 logon_level, uint16 switch_value, DOM_ID_INFO_1 *id1,
383 		LSA_USER_INFO *user_info,
384 		DOM_CRED *srv_cred)
385 {
386 	char *rparam = NULL;
387 	char *rdata = NULL;
388 	char *p;
389 	int rdrcnt,rprcnt;
390 	pstring data; /* only 1024 bytes */
391 	uint16 setup[2]; /* only need 2 uint16 setup parameters */
392 	LSA_Q_SAM_LOGON q_s;
393     BOOL valid_cred = False;
394 
395 	if (srv_cred == NULL || clnt_cred == NULL || rtn_cred == NULL || user_info == NULL) return False;
396 
397 	/* create and send a MSRPC command with api LSA_SAMLOGON */
398 
399 	DEBUG(4,("LSA SAM Logon: srv:%s mc:%s clnt %s %lx rtn: %s %lx ll: %d\n",
400 		 logon_srv, comp_name,
401 		 credstr(clnt_cred->challenge.data), clnt_cred->timestamp.time,
402 		 credstr(rtn_cred->challenge.data), rtn_cred ->timestamp.time,
403 		 logon_level));
404 
405 	/* store the parameters */
406 	make_sam_info(&(q_s.sam_id), logon_srv, comp_name,
407 	             clnt_cred, rtn_cred, logon_level, switch_value, id1);
408 
409 	/* turn parameters into data stream */
410 	p = lsa_io_q_sam_logon(False, &q_s, data + 0x18, data, 4, 0);
411 
412 	/* create the request RPC_HDR_RR _after_ the main data: length is now known */
413 	create_rpc_request(call_id, LSA_SAMLOGON, data, PTR_DIFF(p, data));
414 
415 	/* create setup parameters. */
416 	setup[0] = 0x0026; /* 0x26 indicates "transact named pipe" */
417 	setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
418 
419 	/* send the data on \PIPE\ */
420 	if (cli_call_api("\\PIPE\\", 0,
421 	            0, PTR_DIFF(p, data), 2,
422 	            1024, BUFFER_SIZE,
423 				&rprcnt,&rdrcnt,
424 				NULL, data, setup,
425 				&rparam,&rdata))
426 	{
427 		LSA_R_SAM_LOGON r_s;
428 		RPC_HDR_RR hdr;
429 		int hdr_len;
430 		int pkt_len;
431 
432 		r_s.user = user_info;
433 
434 		DEBUG(5, ("cli_call_api: return OK\n"));
435 
436 		p = rdata;
437 
438 		if (p) p = smb_io_rpc_hdr_rr   (True, &hdr, p, rdata, 4, 0);
439 		if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
440 
441 		hdr_len = PTR_DIFF(p, rdata);
442 
443 		if (p && hdr_len != hdr.hdr.frag_len - hdr.alloc_hint)
444 		{
445 			/* header length not same as calculated header length */
446 			DEBUG(2,("do_lsa_sam_logon: hdr_len %x != frag_len-alloc_hint %x\n",
447 			          hdr_len, hdr.hdr.frag_len - hdr.alloc_hint));
448 			p = NULL;
449 		}
450 
451 		if (p) p = lsa_io_r_sam_logon(True, &r_s, p, rdata, 4, 0);
452 
453 		pkt_len = PTR_DIFF(p, rdata);
454 
455 		if (p && pkt_len != hdr.hdr.frag_len)
456 		{
457 			/* packet data size not same as reported fragment length */
458 			DEBUG(2,("do_lsa_sam_logon: pkt_len %x != frag_len \n",
459 			                           pkt_len, hdr.hdr.frag_len));
460 			p = NULL;
461 		}
462 
463 		if (p && r_s.status != 0)
464 		{
465 			/* report error code */
466 			DEBUG(0,("LSA_SAMLOGON: nt_status error %lx\n", r_s.status));
467 			p = NULL;
468 		}
469 
470 		if (p && r_s.switch_value != 3)
471 		{
472 			/* report different switch_value */
473 			DEBUG(0,("LSA_SAMLOGON: switch_value of 3 expected %x\n",
474 					r_s.switch_value));
475 			p = NULL;
476 		}
477 
478 		if (p)
479 		{
480 			if (clnt_deal_with_creds(sess_key, sto_clnt_cred, &(r_s.srv_creds)))
481 			{
482 				DEBUG(5, ("do_lsa_sam_logon: server credential check OK\n"));
483 				/* ok, at last: we're happy. return the challenge */
484 				memcpy(srv_cred, &(r_s.srv_creds), sizeof(r_s.srv_creds));
485 				valid_cred = True;
486 			}
487 			else
488 			{
489 				DEBUG(5, ("do_lsa_sam_logon: server credential check failed\n"));
490 			}
491 		}
492 	}
493 
494 	if (rparam) free(rparam);
495 	if (rdata) free(rdata);
496 
497 	return valid_cred;
498 }
499 
500 /***************************************************************************
501 do a LSA SAM Logoff
502 ****************************************************************************/
do_lsa_sam_logoff(uint16 fnum,uint32 call_id,uchar sess_key[8],DOM_CRED * sto_clnt_cred,char * logon_srv,char * comp_name,DOM_CRED * clnt_cred,DOM_CRED * rtn_cred,uint16 logon_level,uint16 switch_value,DOM_ID_INFO_1 * id1,DOM_CRED * srv_cred)503 BOOL do_lsa_sam_logoff(uint16 fnum, uint32 call_id,
504 		uchar sess_key[8], DOM_CRED *sto_clnt_cred,
505 		char *logon_srv, char *comp_name,
506         DOM_CRED *clnt_cred, DOM_CRED *rtn_cred,
507 		uint16 logon_level, uint16 switch_value, DOM_ID_INFO_1 *id1,
508 		DOM_CRED *srv_cred)
509 {
510 	char *rparam = NULL;
511 	char *rdata = NULL;
512 	char *p;
513 	int rdrcnt,rprcnt;
514 	pstring data; /* only 1024 bytes */
515 	uint16 setup[2]; /* only need 2 uint16 setup parameters */
516 	LSA_Q_SAM_LOGOFF q_s;
517     BOOL valid_cred = False;
518 
519 	if (srv_cred == NULL || clnt_cred == NULL || rtn_cred == NULL) return False;
520 
521 	/* create and send a MSRPC command with api LSA_SAMLOGON */
522 
523 	DEBUG(4,("LSA SAM Logoff: srv:%s mc:%s clnt %s %lx rtn: %s %lx ll: %d\n",
524 		 logon_srv, comp_name,
525 		 credstr(clnt_cred->challenge.data), clnt_cred->timestamp.time,
526 		 credstr(rtn_cred->challenge.data), rtn_cred ->timestamp.time,
527 		 logon_level));
528 
529 	/* store the parameters */
530 	make_sam_info(&(q_s.sam_id), logon_srv, comp_name,
531 	             clnt_cred, rtn_cred, logon_level, switch_value, id1);
532 
533 	/* turn parameters into data stream */
534 	p = lsa_io_q_sam_logoff(False, &q_s, data + 0x18, data, 4, 0);
535 
536 	/* create the request RPC_HDR_RR _after_ the main data: length is now known */
537 	create_rpc_request(call_id, LSA_SAMLOGOFF, data, PTR_DIFF(p, data));
538 
539 	/* create setup parameters. */
540 	setup[0] = 0x0026; /* 0x26 indicates "transact named pipe" */
541 	setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
542 
543 	/* send the data on \PIPE\ */
544 	if (cli_call_api("\\PIPE\\", 0,
545 	            0, PTR_DIFF(p, data), 2,
546 	            1024, BUFFER_SIZE,
547 				&rprcnt,&rdrcnt,
548 				NULL, data, setup,
549 				&rparam,&rdata))
550 	{
551 		LSA_R_SAM_LOGOFF r_s;
552 		RPC_HDR_RR hdr;
553 		int hdr_len;
554 		int pkt_len;
555 
556 		DEBUG(5, ("cli_call_api: return OK\n"));
557 
558 		p = rdata;
559 
560 		if (p) p = smb_io_rpc_hdr_rr   (True, &hdr, p, rdata, 4, 0);
561 		if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
562 
563 		hdr_len = PTR_DIFF(p, rdata);
564 
565 		if (p && hdr_len != hdr.hdr.frag_len - hdr.alloc_hint)
566 		{
567 			/* header length not same as calculated header length */
568 			DEBUG(2,("do_lsa_sam_logoff: hdr_len %x != frag_len-alloc_hint %x\n",
569 			          hdr_len, hdr.hdr.frag_len - hdr.alloc_hint));
570 			p = NULL;
571 		}
572 
573 		if (p) p = lsa_io_r_sam_logoff(True, &r_s, p, rdata, 4, 0);
574 
575 		pkt_len = PTR_DIFF(p, rdata);
576 
577 		if (p && pkt_len != hdr.hdr.frag_len)
578 		{
579 			/* packet data size not same as reported fragment length */
580 			DEBUG(2,("do_lsa_sam_logoff: pkt_len %x != frag_len \n",
581 			                           pkt_len, hdr.hdr.frag_len));
582 			p = NULL;
583 		}
584 
585 		if (p && r_s.status != 0)
586 		{
587 			/* report error code */
588 			DEBUG(0,("LSA_SAMLOGOFF: nt_status error %lx\n", r_s.status));
589 			p = NULL;
590 		}
591 
592 		if (p)
593 		{
594 			if (clnt_deal_with_creds(sess_key, sto_clnt_cred, &(r_s.srv_creds)))
595 			{
596 				DEBUG(5, ("do_lsa_sam_logoff: server credential check OK\n"));
597 				/* ok, at last: we're happy. return the challenge */
598 				memcpy(srv_cred, &(r_s.srv_creds), sizeof(r_s.srv_creds));
599 				valid_cred = True;
600 			}
601 			else
602 			{
603 				DEBUG(5, ("do_lsa_sam_logoff: server credential check failed\n"));
604 			}
605 		}
606 	}
607 
608 	if (rparam) free(rparam);
609 	if (rdata) free(rdata);
610 
611 	return valid_cred;
612 }
613 
614 #endif /* NTDOMAIN */
615