home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / samba-1.9.18p7.tar.gz / samba-1.9.18p7.tar / samba-1.9.18p7 / source / rpc_pipes / ntclientnet.c < prev    next >
C/C++ Source or Header  |  1997-11-09  |  18KB  |  615 lines

  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. ****************************************************************************/
  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. ****************************************************************************/
  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. ****************************************************************************/
  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. ****************************************************************************/
  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. ****************************************************************************/
  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.