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