ipc.c: Changed reply_trans to use receive_next_smb() to cope
[tprouty/samba.git] / source / smbd / ipc.c
index b7939f2461c6daab94d05cb63660265240c0d72a..c862ff3b3895e842d0c039280961f04cf703ed9d 100644 (file)
@@ -62,6 +62,8 @@ extern fstring myworkgroup;
 #define QNLEN 12               /* queue name maximum length */
 
 extern int Client;
+extern int oplock_sock;
+extern int smb_read_error;
 
 static BOOL api_Unsupported(int cnum,uint16 vuid, char *param,char *data,
                            int mdrcnt,int mprcnt,
@@ -144,7 +146,12 @@ static void send_trans_reply(char *outbuf,char *data,char *param,uint16 *setup,
   this_lparam = MIN(lparam,max_send - (500+lsetup*SIZEOFWORD)); /* hack */
   this_ldata = MIN(ldata,max_send - (500+lsetup*SIZEOFWORD+this_lparam));
 
+#ifdef CONFUSE_NETMONITOR_MSRPC_DECODING
+  /* if you don't want Net Monitor to decode your packets, do this!!! */
+  align = ((this_lparam+1)%4);
+#else
   align = (this_lparam%4);
+#endif
 
   set_message(outbuf,10+lsetup,align+this_ldata+this_lparam,True);
   if (this_lparam)
@@ -2862,23 +2869,25 @@ static BOOL api_WPrintPortEnum(int cnum,uint16 vuid, char *param,char *data,
 struct
 {
   char * name;
-  char * pipename;
+  char * pipe_clnt_name;
+#ifdef NTDOMAIN
+  char * pipe_srv_name;
+#endif
   int subcommand;
   BOOL (*fn) ();
 } api_fd_commands [] =
   {
 #ifdef NTDOMAIN
-    { "SetNmdPpHndState",      "lsarpc",       1,      api_LsarpcSNPHS },
-    { "SetNmdPpHndState",      "srvsvc",       1,      api_LsarpcSNPHS },
-    { "SetNmdPpHndState",      "NETLOGON",     1,      api_LsarpcSNPHS },
-    { "TransactNmPipe",        "lsarpc",       0x26,   api_ntLsarpcTNP },
-    { "TransactNmPipe",        "srvsvc",       0x26,   api_srvsvcTNP },
-    { "TransactNmPipe",        "NETLOGON",     0x26,   api_netlogrpcTNP },
+    { "TransactNmPipe",     "lsarpc",  "lsass",        0x26,   api_ntLsarpcTNP },
+    { "TransactNmPipe",     "samr",    "lsass",        0x26,   api_samrTNP },
+    { "TransactNmPipe",     "srvsvc",  "lsass",        0x26,   api_srvsvcTNP },
+    { "TransactNmPipe",     "wkssvc",  "ntsvcs",       0x26,   api_wkssvcTNP },
+    { "TransactNmPipe",     "NETLOGON",        "NETLOGON",     0x26,   api_netlogrpcTNP },
+    { NULL,                        NULL,       NULL,   -1,     (BOOL (*)())api_Unsupported }
 #else
-    { "SetNmdPpHndState",      "lsarpc",       1,      api_LsarpcSNPHS },
     { "TransactNmPipe"  ,      "lsarpc",       0x26,   api_LsarpcTNP },
-#endif
     { NULL,            NULL,           -1,     (BOOL (*)())api_Unsupported }
+#endif
   };
 
 /****************************************************************************
@@ -2895,11 +2904,12 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
 
   BOOL reply    = False;
   BOOL bind_req = False;
+  BOOL set_nphs = False;
 
   int i;
   int fd;
   int subcommand;
-  pstring pipe_name;
+  char *pipe_name;
   
   DEBUG(5,("api_fd_reply\n"));
   /* First find out the name of this file. */
@@ -2912,14 +2922,11 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
   /* Get the file handle and hence the file name. */
   fd = setup[1];
   subcommand = setup[0];
-  if (fd >= 0 && fd < MAX_OPEN_FILES)
-  {
-    pstrcpy(pipe_name, Files[fd].name);
-  }
-  else
+  pipe_name = get_rpc_pipe_hnd_name(fd);
+
+  if (pipe_name == NULL)
   {
-    pipe_name[0] = 0;
-    DEBUG(1,("api_fd_reply: INVALID FILE HANDLE: %x\n", fd));
+    DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", fd));
   }
 
   DEBUG(3,("Got API command %d on pipe %s (fd %x)",
@@ -2929,7 +2936,7 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
   
   for (i = 0; api_fd_commands[i].name; i++)
   {
-    if (strequal(api_fd_commands[i].pipename, pipe_name) &&
+    if (strequal(api_fd_commands[i].pipe_clnt_name, pipe_name) &&
            api_fd_commands[i].subcommand == subcommand &&
            api_fd_commands[i].fn)
     {
@@ -2942,23 +2949,35 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
   rparam = (char *)malloc(1024); if (rparam) bzero(rparam,1024);
   
 #ifdef NTDOMAIN
-  if (api_fd_commands[i].subcommand != -1)
+  /* RPC Pipe command 0x26. */
+  if (data != NULL && api_fd_commands[i].subcommand == 0x26)
   {
     RPC_HDR hdr;
+
+    /* process the rpc header */
     char *q = smb_io_rpc_hdr(True, &hdr, data, data, 4, 0);
     
+       /* bind request received */
     if ((bind_req = ((q != NULL) && (hdr.pkt_type == RPC_BIND))))
     {
       RPC_HDR_RB hdr_rb;
 
+      /* decode the bind request */
       char *p = smb_io_rpc_hdr_rb(True, &hdr_rb, q, data, 4, 0);
 
       if ((bind_req = (p != NULL)))
       {
         RPC_HDR_BA hdr_ba;
+        fstring ack_pipe_name;
+
+        /* name has to be \PIPE\xxxxx */
+        strcpy(ack_pipe_name, "\\PIPE\\");
+        strcat(ack_pipe_name, api_fd_commands[i].pipe_srv_name);
+
+        /* make a bind acknowledgement */
         make_rpc_hdr_ba(&hdr_ba,
                hdr_rb.bba.max_tsize, hdr_rb.bba.max_rsize, hdr_rb.bba.assoc_gid,
-               api_fd_commands[i].pipename,
+               ack_pipe_name,
                0x1, 0x0, 0x0,
                &(hdr_rb.transfer));
 
@@ -2966,7 +2985,7 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
 
                rdata_len = PTR_DIFF(p, rdata);
 
-        make_rpc_hdr(&hdr, RPC_BINDACK, hdr.call_id, rdata_len);
+        make_rpc_hdr(&hdr, RPC_BINDACK, 0x0, hdr.call_id, rdata_len);
 
         p = smb_io_rpc_hdr(False, &hdr, rdata, rdata, 4, 0);
         
@@ -2976,7 +2995,14 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
   }
 #endif
 
-  if (!bind_req)
+  /* Set Named Pipe Handle state */
+  if (subcommand == 0x1)
+  {
+    set_nphs = True;
+    reply = api_LsarpcSNPHS(fd, cnum, params);
+  }
+
+  if (!bind_req && !set_nphs)
   {
     DEBUG(10,("calling api_fd_command\n"));
 
@@ -2991,19 +3017,18 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
                           &rdata,&rparam,&rdata_len,&rparam_len);
   }
   
-  
   /* if we get False back then it's actually unsupported */
   if (!reply)
+  {
     api_Unsupported(cnum,vuid,params,data,mdrcnt,mprcnt,
                    &rdata,&rparam,&rdata_len,&rparam_len);
+  }
   
   /* now send the reply */
   send_trans_reply(outbuf,rdata,rparam,NULL,rdata_len,rparam_len,0);
   
-  if (rdata)
-    free(rdata);
-  if (rparam)
-    free(rparam);
+  if (rdata ) free(rdata );
+  if (rparam) free(rparam);
   
   return(-1);
 }
@@ -3180,7 +3205,7 @@ static int named_pipe(int cnum,uint16 vuid, char *outbuf,char *name,
 /****************************************************************************
   reply to a SMBtrans
   ****************************************************************************/
-int reply_trans(char *inbuf,char *outbuf)
+int reply_trans(char *inbuf,char *outbuf, int size, int bufsize)
 {
   fstring name;
 
@@ -3243,12 +3268,18 @@ int reply_trans(char *inbuf,char *outbuf)
   /* receive the rest of the trans packet */
   while (pscnt < tpscnt || dscnt < tdscnt)
     {
+      BOOL ret;
       int pcnt,poff,dcnt,doff,pdisp,ddisp;
       
-      if (!receive_smb(Client,inbuf, SMB_SECONDARY_WAIT) ||
-         CVAL(inbuf, smb_com) != SMBtrans)
+      ret = receive_next_smb(Client,oplock_sock,inbuf,bufsize,SMB_SECONDARY_WAIT);
+
+      if ((ret && (CVAL(inbuf, smb_com) != SMBtrans)) || !ret)
        {
-         DEBUG(2,("Invalid secondary trans2 packet\n"));
+          if(ret)
+            DEBUG(0,("reply_trans: Invalid secondary trans packet\n"));
+          else
+            DEBUG(0,("reply_trans: %s in getting secondary trans response.\n",
+              (smb_read_error == READ_ERROR) ? "error" : "timeout" ));
          if (params) free(params);
          if (data) free(data);
          if (setup) free(setup);