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 / ntclientpipe.c < prev    next >
C/C++ Source or Header  |  1998-05-12  |  9KB  |  335 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.   open an rpc pipe (\NETLOGON or \srvsvc for example)
  42.   ****************************************************************************/
  43. uint16 rpc_pipe_open(char *inbuf, char *outbuf, char *rname, int Client, int cnum)
  44. {
  45.     int fnum;
  46.     char *p;
  47.  
  48.     DEBUG(5,("open_rpc_pipe: %s\n", rname));
  49.  
  50.     bzero(outbuf,smb_size);
  51.     set_message(outbuf,15,1 + strlen(rname),True);
  52.  
  53.     CVAL(outbuf,smb_com) = SMBopenX;
  54.     SSVAL(outbuf,smb_tid, cnum);
  55.     cli_setup_pkt(outbuf);
  56.  
  57.     SSVAL(outbuf,smb_vwv0,0xFF);
  58.     SSVAL(outbuf,smb_vwv2,1);
  59.     SSVAL(outbuf,smb_vwv3,(DENY_NONE<<4));
  60.     SSVAL(outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
  61.     SSVAL(outbuf,smb_vwv5,aSYSTEM | aHIDDEN);
  62.     SSVAL(outbuf,smb_vwv8,1);
  63.  
  64.     p = smb_buf(outbuf);
  65.     pstrcpy(p,rname);
  66.     p = skip_string(p,1);
  67.  
  68.     send_smb(Client,outbuf);
  69.     receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  70.  
  71.     if (CVAL(inbuf,smb_rcls) != 0)
  72.     {
  73.         if (CVAL(inbuf,smb_rcls) == ERRSRV &&
  74.             SVAL(inbuf,smb_err) == ERRnoresource &&
  75.             cli_reopen_connection(inbuf,outbuf))
  76.         {
  77.             return rpc_pipe_open(inbuf, outbuf, rname, Client, cnum);
  78.         }
  79.         DEBUG(0,("opening remote pipe %s - error %s\n", rname, smb_errstr(inbuf)));
  80.  
  81.         return 0xffff;
  82.     }
  83.  
  84.     fnum = SVAL(inbuf, smb_vwv2);
  85.  
  86.     DEBUG(5,("opening pipe: fnum %d\n", fnum));
  87.  
  88.     return fnum;
  89. }
  90.  
  91. struct
  92. {
  93.     char *client;
  94.     char *server;
  95. } pipe_names [] =
  96. {
  97.     { PIPE_LSARPC  , PIPE_LSASS },
  98.     { PIPE_NETLOGON, PIPE_NETLOGON },
  99.     { PIPE_SRVSVC  , PIPE_SRVSVC   },
  100.     { NULL         , NULL          }
  101. };
  102.  
  103. /****************************************************************************
  104. do an rpc bind
  105. ****************************************************************************/
  106. BOOL rpc_pipe_set_hnd_state(char *pipe_name, uint16 fnum, uint16 device_state)
  107. {
  108.     char *rparam = NULL;
  109.     char *rdata = NULL;
  110.     int rdrcnt,rprcnt;
  111.     char pipe_str[11]; /* only 2 bytes */
  112.     char param [2]; /* only 2 bytes */
  113.     uint16 setup[2]; /* only need 2 uint16 setup parameters */
  114.     BOOL state_set = False;
  115.     int pipe_name_len = 0;
  116.  
  117.     if (pipe_name == NULL) return False;
  118.  
  119.     DEBUG(5,("Bind RPC Pipe[%x]: %s - device state:%x\n",
  120.               fnum, pipe_name, device_state));
  121.  
  122.     /* create data parameters: device state */
  123.     SSVAL(param, 0, device_state);
  124.  
  125.     /* create setup parameters. */
  126.     setup[0] = 0x0001; /* 0x01 indicates "set named pipe handle state" */
  127.     setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
  128.  
  129.     safe_strcpy(pipe_str, "\\PIPE\\", sizeof(pipe_str)-1);
  130.  
  131.     pipe_str[8] = 0;
  132.     pipe_str[9] = 0;
  133.     pipe_str[10] = 0;
  134.  
  135.     pipe_name_len = strlen(pipe_str);
  136.  
  137.     if (strcmp(pipe_name, PIPE_NETLOGON) == 0)
  138.     {
  139.         /* create param parameters.  no idea what these are */
  140.         /* lkclXXXX speculating on these two values... */
  141.         pipe_str[pipe_name_len+1] = 0x72;
  142.         pipe_str[pipe_name_len+2] = 0x70;
  143.         pipe_name_len += 2;
  144.     }
  145.     if (strcmp(pipe_name, PIPE_LSARPC) == 0)
  146.     {
  147.         /* create param parameters.  no idea what these are */
  148.         pipe_str[pipe_name_len+1] = 0x72;
  149.         pipe_str[pipe_name_len+2] = 0x70;
  150.         pipe_name_len += 2;
  151.     }
  152.     else if (strcmp(pipe_name, PIPE_SRVSVC) == 0)
  153.     {
  154.         /* create param parameters.  no idea what these are */
  155.         pipe_str[pipe_name_len+1] = 0x73;
  156.         pipe_str[pipe_name_len+2] = 0x76;
  157.         pipe_name_len += 2;
  158.     }
  159.  
  160.     /* send the data on \PIPE\ */
  161.     if (cli_call_api(pipe_str, pipe_name_len, 2, 0, 2,
  162.                 1024, BUFFER_SIZE,
  163.                 &rprcnt, &rdrcnt,
  164.                 param, 0, setup,
  165.                 &rparam, &rdata))
  166.     {
  167.         DEBUG(5, ("cli_call_api: return OK\n"));
  168.         state_set = True;
  169.     }
  170.  
  171.     if (rparam) free(rparam);
  172.     if (rdata ) free(rdata);
  173.  
  174.     return state_set;
  175. }
  176. /****************************************************************************
  177. do an rpc bind
  178. ****************************************************************************/
  179. BOOL rpc_pipe_bind(char *pipe_name, uint16 fnum, uint32 call_id,
  180.                 RPC_IFACE *abstract, RPC_IFACE *transfer)
  181. {
  182.     char *rparam = NULL;
  183.     char *rdata = NULL;
  184.     char *p;
  185.     int rdrcnt,rprcnt;
  186.     int data_len;
  187.     pstring data; /* only 1024 bytes */
  188.     uint16 setup[2]; /* only need 2 uint16 setup parameters */
  189.  
  190.     RPC_HDR    hdr;
  191.  
  192.     RPC_HDR_RB hdr_rb;
  193.  
  194.     BOOL valid_ack = False;
  195.  
  196.     if (pipe_name == NULL || abstract == NULL || transfer == NULL) return False;
  197.  
  198.     DEBUG(5,("Bind RPC Pipe[%x]: %s\n", fnum, pipe_name));
  199.  
  200.     /* create the request RPC_HDR_RB */
  201.     make_rpc_hdr_rb(&hdr_rb, 
  202.                     0x1630, 0x1630, 0x0,
  203.                     0x1, 0x1, 0x1,
  204.                     abstract, transfer);
  205.  
  206.     /* stream the bind request data */
  207.     p = smb_io_rpc_hdr_rb(False, &hdr_rb, data + 0x10, data, 4, 0);
  208.  
  209.     data_len = PTR_DIFF(p, data);
  210.  
  211.     /* create the request RPC_HDR */
  212.     make_rpc_hdr(&hdr, RPC_BIND, 0x0, call_id, PTR_DIFF(p, data + 0x10));
  213.  
  214.     /* stream the header into data */
  215.     p = smb_io_rpc_hdr(False, &hdr, data, data, 4, 0);
  216.  
  217.     /* create setup parameters. */
  218.     setup[0] = 0x0026; /* 0x26 indicates "transact named pipe" */
  219.     setup[1] = fnum; /* file handle, from the SMBcreateX pipe, earlier */
  220.  
  221.     /* send the data on \PIPE\ */
  222.     if (cli_call_api("\\PIPE\\", 0, 0, data_len, 2, 1024,
  223.                 BUFFER_SIZE,
  224.                 &rprcnt, &rdrcnt,
  225.                 NULL, data, setup,
  226.                 &rparam, &rdata))
  227.     {
  228.         RPC_HDR_BA hdr_ba;
  229.         int hdr_len;
  230.         int pkt_len;
  231.         int i = 0;
  232.  
  233.         DEBUG(5, ("cli_call_api: return OK\n"));
  234.  
  235.         p = rdata;
  236.  
  237.         if (p) p = smb_io_rpc_hdr(True, &hdr, p, rdata, 4, 0);
  238.         if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */
  239.  
  240.         hdr_len = PTR_DIFF(p, rdata);
  241.  
  242.         if (p) p = smb_io_rpc_hdr_ba(True, &hdr_ba, p, rdata, 4, 0);
  243.  
  244.         pkt_len = PTR_DIFF(p, rdata);
  245. #if 0
  246.         if (p && hdr_len != hdr.hdr.frag_len - hdr.alloc_hint)
  247.         {
  248.             /* header length not same as calculated header length */
  249.             DEBUG(2,("bind_rpc_pipe: hdr_len %x != frag_len-alloc_hint %x\n",
  250.                       hdr_len, hdr.hdr.frag_len - hdr.alloc_hint));
  251.             p = NULL;
  252.         }
  253.  
  254.  
  255.         if (p && pkt_len != hdr.hdr.frag_len)
  256.         {
  257.             /* packet data size not same as reported fragment length */
  258.             DEBUG(2,("bind_rpc_pipe: pkt_len %x != frag_len \n",
  259.                                        pkt_len, hdr.hdr.frag_len));
  260.             p = NULL;
  261.         }
  262. #endif
  263.  
  264.         while (p && (pipe_names[i].server != NULL))
  265.         {
  266.             DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n",
  267.                       pipe_names[i].client, pipe_names[i].server));
  268.  
  269.             if ((strcmp(pipe_name      , pipe_names[i].client) == 0))
  270.             {
  271.                 if (strcmp(hdr_ba.addr.str, pipe_names[i].server) == 0)
  272.                 {
  273.                     DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n",
  274.                             pipe_names[i].server));
  275.                     break;
  276.                 }
  277.                 else
  278.                 {
  279.                     DEBUG(2,("bind_rpc_pipe: pipe_name %s != expected pipe %s\n",
  280.                             pipe_names[i].server, hdr_ba.addr.str));
  281.                     p = NULL;
  282.                 }
  283.             }
  284.             else
  285.             {
  286.                 i++;
  287.             }
  288.         }
  289.  
  290.         if (p && pipe_names[i].server == NULL)
  291.         {
  292.             DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba.addr.str));
  293.             p = NULL;
  294.         }
  295.  
  296.         if (p)
  297.         {
  298.             /* check the transfer syntax */
  299.             valid_ack = (hdr_ba.transfer.version == transfer->version) &&
  300.                     (memcmp(hdr_ba.transfer.data, transfer->data,
  301.                             sizeof(transfer->version)) ==0);
  302.             if (!valid_ack)
  303.             {
  304.                 DEBUG(2,("bind_rpc_pipe: transfer syntax differs\n"));
  305.                 p = NULL;
  306.             }
  307.         }
  308.         
  309.         if (p)
  310.         {
  311.             /* check the results */
  312.             valid_ack = (hdr_ba.res.num_results == 0x1) &&
  313.                         (hdr_ba.res.result == 0);
  314.             
  315.             if (!valid_ack)
  316.             {
  317.                 DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
  318.                           hdr_ba.res.num_results,
  319.                           hdr_ba.res.reason));
  320.                 p = NULL;
  321.             }
  322.             else
  323.             {
  324.                 DEBUG(5,("bind_rpc_pipe: accepted!\n"));
  325.             }
  326.         }
  327.     }
  328.  
  329.     if (rparam) free(rparam);
  330.     if (rdata) free(rdata);
  331.  
  332.     return valid_ack;
  333. }
  334. #endif /* NTDOMAIN */
  335.