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 / clientutil.c < prev    next >
C/C++ Source or Header  |  1998-05-12  |  25KB  |  939 lines

  1. /* 
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.9.
  4.    SMB client
  5.    Copyright (C) Andrew Tridgell 1994-1998
  6.    
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    This program is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.    
  17.    You should have received a copy of the GNU General Public License
  18.    along with this program; if not, write to the Free Software
  19.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. #ifdef SYSLOG
  23. #undef SYSLOG
  24. #endif
  25.  
  26. #include "includes.h"
  27.  
  28. #ifndef REGISTER
  29. #define REGISTER 0
  30. #endif
  31.  
  32. pstring service="";
  33. pstring desthost="";
  34. extern pstring myname;
  35. pstring password = "";
  36. pstring smb_login_passwd = "";
  37. pstring username="";
  38. pstring workgroup=WORKGROUP;
  39. BOOL got_pass = False;
  40. BOOL no_pass = False;
  41. BOOL connect_as_printer = False;
  42. BOOL connect_as_ipc = False;
  43.  
  44. char cryptkey[8];
  45. BOOL doencrypt=False;
  46.  
  47. extern pstring user_socket_options;
  48.  
  49. /* 30 second timeout on most commands */
  50. #define CLIENT_TIMEOUT (30*1000)
  51. #define SHORT_TIMEOUT (5*1000)
  52.  
  53. int name_type = 0x20;
  54.  
  55. int max_protocol = PROTOCOL_NT1;
  56.  
  57. BOOL readbraw_supported = False;
  58. BOOL writebraw_supported = False;
  59.  
  60. extern int DEBUGLEVEL;
  61.  
  62. int cnum = 0;
  63. int pid = 0;
  64. int gid = 0;
  65. int uid = 0;
  66. int mid = 0;
  67.  
  68. int max_xmit = BUFFER_SIZE;
  69.  
  70. BOOL have_ip = False;
  71.  
  72. extern struct in_addr dest_ip;
  73.  
  74. extern int Protocol;
  75.  
  76. extern int Client;
  77.  
  78.  
  79. /****************************************************************************
  80. setup basics in a outgoing packet
  81. ****************************************************************************/
  82. void cli_setup_pkt(char *outbuf)
  83. {
  84.   SSVAL(outbuf,smb_pid,pid);
  85.   SSVAL(outbuf,smb_uid,uid);
  86.   SSVAL(outbuf,smb_mid,mid);
  87.   if (Protocol > PROTOCOL_COREPLUS)
  88.     {
  89.       SCVAL(outbuf,smb_flg,0x8);
  90.       SSVAL(outbuf,smb_flg2,0x1);
  91.     }
  92. }
  93.  
  94. /****************************************************************************
  95. call a remote api
  96. ****************************************************************************/
  97. BOOL cli_call_api(char *pipe_name, int pipe_name_len,
  98.             int prcnt,int drcnt, int srcnt,
  99.              int mprcnt,int mdrcnt,
  100.              int *rprcnt,int *rdrcnt,
  101.              char *param,char *data, uint16 *setup,
  102.              char **rparam,char **rdata)
  103. {
  104.   static char *inbuf=NULL;
  105.   static char *outbuf=NULL;
  106.  
  107.   if (!inbuf) inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
  108.   if (!outbuf) outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
  109.  
  110.   if (pipe_name_len == 0) pipe_name_len = strlen(pipe_name);
  111.  
  112.   cli_send_trans_request(outbuf,SMBtrans,pipe_name, pipe_name_len, 0,0,
  113.              data, param, setup,
  114.              drcnt, prcnt, srcnt,
  115.              mdrcnt, mprcnt, 0);
  116.  
  117.   return (cli_receive_trans_response(inbuf,SMBtrans,
  118.                                  rdrcnt,rprcnt,
  119.                                  rdata,rparam));
  120. }
  121.  
  122.  
  123. /****************************************************************************
  124.   receive a SMB trans or trans2 response allocating the necessary memory
  125.   ****************************************************************************/
  126. BOOL cli_receive_trans_response(char *inbuf,int trans,
  127.                                    int *data_len,int *param_len,
  128.                    char **data,char **param)
  129. {
  130.   int total_data=0;
  131.   int total_param=0;
  132.   int this_data,this_param;
  133.  
  134.   *data_len = *param_len = 0;
  135.  
  136.   client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  137.   show_msg(inbuf);
  138.  
  139.   /* sanity check */
  140.   if (CVAL(inbuf,smb_com) != trans)
  141.     {
  142.       DEBUG(0,("Expected %s response, got command 0x%02x\n",
  143.            trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
  144.       return(False);
  145.     }
  146.   if (CVAL(inbuf,smb_rcls) != 0)
  147.     return(False);
  148.  
  149.   /* parse out the lengths */
  150.   total_data = SVAL(inbuf,smb_tdrcnt);
  151.   total_param = SVAL(inbuf,smb_tprcnt);
  152.  
  153.   /* allocate it */
  154.   *data = Realloc(*data,total_data);
  155.   *param = Realloc(*param,total_param);
  156.  
  157.   while (1)
  158.     {
  159.       this_data = SVAL(inbuf,smb_drcnt);
  160.       this_param = SVAL(inbuf,smb_prcnt);
  161.       if (this_data)
  162.     memcpy(*data + SVAL(inbuf,smb_drdisp),
  163.            smb_base(inbuf) + SVAL(inbuf,smb_droff),
  164.            this_data);
  165.       if (this_param)
  166.     memcpy(*param + SVAL(inbuf,smb_prdisp),
  167.            smb_base(inbuf) + SVAL(inbuf,smb_proff),
  168.            this_param);
  169.       *data_len += this_data;
  170.       *param_len += this_param;
  171.  
  172.       /* parse out the total lengths again - they can shrink! */
  173.       total_data = SVAL(inbuf,smb_tdrcnt);
  174.       total_param = SVAL(inbuf,smb_tprcnt);
  175.  
  176.       if (total_data <= *data_len && total_param <= *param_len)
  177.     break;
  178.  
  179.       client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  180.       show_msg(inbuf);
  181.  
  182.       /* sanity check */
  183.       if (CVAL(inbuf,smb_com) != trans)
  184.     {
  185.       DEBUG(0,("Expected %s response, got command 0x%02x\n",
  186.            trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
  187.       return(False);
  188.     }
  189.       if (CVAL(inbuf,smb_rcls) != 0)
  190.       return(False);
  191.     }
  192.   
  193.   return(True);
  194. }
  195.  
  196.  
  197.  
  198. /****************************************************************************
  199.   send a SMB trans or trans2 request
  200.   ****************************************************************************/
  201. BOOL cli_send_trans_request(char *outbuf,int trans,
  202.                    char *name,int namelen, int fid,int flags,
  203.                    char *data,char *param,uint16 *setup,
  204.                    int ldata,int lparam,int lsetup,
  205.                    int mdata,int mparam,int msetup)
  206. {
  207.   int i;
  208.   int this_ldata,this_lparam;
  209.   int tot_data=0,tot_param=0;
  210.   char *outdata,*outparam;
  211.   pstring inbuf;
  212.   char *p;
  213.  
  214.   this_lparam = MIN(lparam,max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */
  215.   this_ldata = MIN(ldata,max_xmit - (500+lsetup*SIZEOFWORD+this_lparam));
  216.  
  217.   bzero(outbuf,smb_size);
  218.   set_message(outbuf,14+lsetup,0,True);
  219.   CVAL(outbuf,smb_com) = trans;
  220.   SSVAL(outbuf,smb_tid,cnum);
  221.   cli_setup_pkt(outbuf);
  222.  
  223.   outparam = smb_buf(outbuf)+(trans==SMBtrans ? namelen+1 : 3);
  224.   outdata = outparam+this_lparam;
  225.  
  226.   /* primary request */
  227.   SSVAL(outbuf,smb_tpscnt,lparam);    /* tpscnt */
  228.   SSVAL(outbuf,smb_tdscnt,ldata);    /* tdscnt */
  229.   SSVAL(outbuf,smb_mprcnt,mparam);    /* mprcnt */
  230.   SSVAL(outbuf,smb_mdrcnt,mdata);    /* mdrcnt */
  231.   SCVAL(outbuf,smb_msrcnt,msetup);    /* msrcnt */
  232.   SSVAL(outbuf,smb_flags,flags);    /* flags */
  233.   SIVAL(outbuf,smb_timeout,0);        /* timeout */
  234.   SSVAL(outbuf,smb_pscnt,this_lparam);    /* pscnt */
  235.   SSVAL(outbuf,smb_psoff,smb_offset(outparam,outbuf)); /* psoff */
  236.   SSVAL(outbuf,smb_dscnt,this_ldata);    /* dscnt */
  237.   SSVAL(outbuf,smb_dsoff,smb_offset(outdata,outbuf)); /* dsoff */
  238.   SCVAL(outbuf,smb_suwcnt,lsetup);    /* suwcnt */
  239.   for (i=0;i<lsetup;i++)        /* setup[] */
  240.     SSVAL(outbuf,smb_setup+i*SIZEOFWORD,setup[i]);
  241.   p = smb_buf(outbuf);
  242.   if (trans==SMBtrans)
  243.     memcpy(p,name, namelen+1);            /* name[] */
  244.   else
  245.     {
  246.       *p++ = 0;                /* put in a null smb_name */
  247.       *p++ = 'D'; *p++ = ' ';        /* this was added because OS/2 does it */
  248.     }
  249.   if (this_lparam)            /* param[] */
  250.     memcpy(outparam,param,this_lparam);
  251.   if (this_ldata)            /* data[] */
  252.     memcpy(outdata,data,this_ldata);
  253.   set_message(outbuf,14+lsetup,        /* wcnt, bcc */
  254.           PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
  255.  
  256.   show_msg(outbuf);
  257.   send_smb(Client,outbuf);
  258.  
  259.   if (this_ldata < ldata || this_lparam < lparam)
  260.     {
  261.       /* receive interim response */
  262.       if (!client_receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
  263.     {
  264.       DEBUG(0,("%s request failed (%s)\n",
  265.                trans==SMBtrans?"SMBtrans":"SMBtrans2", smb_errstr(inbuf)));
  266.       return(False);
  267.     }      
  268.  
  269.       tot_data = this_ldata;
  270.       tot_param = this_lparam;
  271.  
  272.       while (tot_data < ldata || tot_param < lparam)
  273.     {
  274.       this_lparam = MIN(lparam-tot_param,max_xmit - 500); /* hack */
  275.       this_ldata = MIN(ldata-tot_data,max_xmit - (500+this_lparam));
  276.  
  277.       set_message(outbuf,trans==SMBtrans?8:9,0,True);
  278.       CVAL(outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2;
  279.  
  280.       outparam = smb_buf(outbuf);
  281.       outdata = outparam+this_lparam;
  282.  
  283.       /* secondary request */
  284.       SSVAL(outbuf,smb_tpscnt,lparam);    /* tpscnt */
  285.       SSVAL(outbuf,smb_tdscnt,ldata);    /* tdscnt */
  286.       SSVAL(outbuf,smb_spscnt,this_lparam);    /* pscnt */
  287.       SSVAL(outbuf,smb_spsoff,smb_offset(outparam,outbuf)); /* psoff */
  288.       SSVAL(outbuf,smb_spsdisp,tot_param);    /* psdisp */
  289.       SSVAL(outbuf,smb_sdscnt,this_ldata);    /* dscnt */
  290.       SSVAL(outbuf,smb_sdsoff,smb_offset(outdata,outbuf)); /* dsoff */
  291.       SSVAL(outbuf,smb_sdsdisp,tot_data);    /* dsdisp */
  292.       if (trans==SMBtrans2)
  293.         SSVAL(outbuf,smb_sfid,fid);        /* fid */
  294.       if (this_lparam)            /* param[] */
  295.         memcpy(outparam,param,this_lparam);
  296.       if (this_ldata)            /* data[] */
  297.         memcpy(outdata,data,this_ldata);
  298.       set_message(outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */
  299.               PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
  300.  
  301.       show_msg(outbuf);
  302.       send_smb(Client,outbuf);
  303.  
  304.       tot_data += this_ldata;
  305.       tot_param += this_lparam;
  306.     }
  307.     }
  308.  
  309.     return(True);
  310. }
  311.  
  312.  
  313. /****************************************************************************
  314. send a session request
  315. ****************************************************************************/
  316. BOOL cli_send_session_request(char *inbuf,char *outbuf)
  317. {
  318.   fstring dest;
  319.   char *p;
  320.   int len = 4;
  321.   /* send a session request (RFC 8002) */
  322.  
  323.   fstrcpy(dest,desthost);
  324.   p = strchr(dest,'.');
  325.   if (p) *p = 0;
  326.  
  327.   /* put in the destination name */
  328.   p = outbuf+len;
  329.   name_mangle(dest,p,name_type); /* 0x20 is the SMB server NetBIOS type. */
  330.   len += name_len(p);
  331.  
  332.   /* and my name */
  333.   p = outbuf+len;
  334.   name_mangle(myname,p,0);
  335.   len += name_len(p);
  336.  
  337.   /* setup the packet length */
  338.   _smb_setlen(outbuf,len);
  339.   CVAL(outbuf,0) = 0x81;
  340.  
  341.   send_smb(Client,outbuf);
  342.   DEBUG(5,("Sent session request\n"));
  343.  
  344.   client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  345.  
  346.   if (CVAL(inbuf,0) == 0x84) /* C. Hoch  9/14/95 Start */
  347.     {
  348.       /* For information, here is the response structure.
  349.        * We do the byte-twiddling to for portability.
  350.        struct RetargetResponse{
  351.        unsigned char type;
  352.        unsigned char flags;
  353.        int16 length;
  354.        int32 ip_addr;
  355.        int16 port;
  356.        };
  357.        */
  358.       extern int Client;
  359.       int port = (CVAL(inbuf,8)<<8)+CVAL(inbuf,9);
  360.       /* SESSION RETARGET */
  361.       putip((char *)&dest_ip,inbuf+4);
  362.  
  363.       close_sockets();
  364.       Client = open_socket_out(SOCK_STREAM, &dest_ip, port, LONG_CONNECT_TIMEOUT);
  365.       if (Client == -1)
  366.         return False;
  367.  
  368.       DEBUG(3,("Retargeted\n"));
  369.  
  370.       set_socket_options(Client,user_socket_options);
  371.  
  372.       /* Try again */
  373.       return cli_send_session_request(inbuf,outbuf);
  374.     } /* C. Hoch 9/14/95 End */
  375.  
  376.  
  377.   if (CVAL(inbuf,0) != 0x82)
  378.     {
  379.       int ecode = CVAL(inbuf,4);
  380.       DEBUG(0,("Session request failed (%d,%d) with myname=%s destname=%s\n",
  381.            CVAL(inbuf,0),ecode,myname,desthost));
  382.       switch (ecode)
  383.     {
  384.     case 0x80: 
  385.       DEBUG(0,("Not listening on called name\n")); 
  386.       DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
  387.       DEBUG(0,("You may find the -I option useful for this\n"));
  388.       break;
  389.     case 0x81: 
  390.       DEBUG(0,("Not listening for calling name\n")); 
  391.       DEBUG(0,("Try to connect as another name (instead of %s)\n",myname));
  392.       DEBUG(0,("You may find the -n option useful for this\n"));
  393.       break;
  394.     case 0x82: 
  395.       DEBUG(0,("Called name not present\n")); 
  396.       DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
  397.       DEBUG(0,("You may find the -I option useful for this\n"));
  398.       break;
  399.     case 0x83: 
  400.       DEBUG(0,("Called name present, but insufficient resources\n")); 
  401.       DEBUG(0,("Perhaps you should try again later?\n")); 
  402.       break;
  403.     default:
  404.       DEBUG(0,("Unspecified error 0x%X\n",ecode)); 
  405.       DEBUG(0,("Your server software is being unfriendly\n"));
  406.       break;      
  407.     }
  408.       return(False);
  409.     }
  410.   return(True);
  411. }
  412.  
  413. static struct {
  414.   int prot;
  415.   char *name;
  416. } prots[] = {
  417.   {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
  418.   {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
  419.   {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
  420.   {PROTOCOL_LANMAN1,"LANMAN1.0"},
  421.   {PROTOCOL_LANMAN2,"LM1.2X002"},
  422.   {PROTOCOL_LANMAN2,"Samba"},
  423.   {PROTOCOL_NT1,"NT LM 0.12"},
  424.   {PROTOCOL_NT1,"NT LANMAN 1.0"},
  425.   {-1,NULL}
  426. };
  427.  
  428.  
  429. /****************************************************************************
  430. send a login command.  
  431. ****************************************************************************/
  432. BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup, struct connection_options *options)
  433. {
  434.   BOOL was_null = (!inbuf && !outbuf);
  435.   time_t servertime = 0;
  436.   extern int serverzone;
  437.   int crypt_len=0;
  438.   char *pass = NULL;  
  439.   pstring dev;
  440.   char *p;
  441.   int numprots;
  442.   int tries=0;
  443.   struct connection_options opt;
  444.  
  445.   bzero(&opt, sizeof(opt));
  446.  
  447.   if (was_null)
  448.     {
  449.       inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
  450.       outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
  451.     }
  452.  
  453. #if AJT
  454.   if (strstr(service,"IPC$")) connect_as_ipc = True;
  455. #endif
  456.  
  457.   pstrcpy(dev,"A:");
  458.   if (connect_as_printer)
  459.     pstrcpy(dev,"LPT1:");
  460.   if (connect_as_ipc)
  461.     pstrcpy(dev,"IPC");
  462.  
  463.  
  464.   if (start_session && !cli_send_session_request(inbuf,outbuf))
  465.     {
  466.       if (was_null)
  467.     {
  468.       free(inbuf);
  469.       free(outbuf);
  470.     }      
  471.       return(False);
  472.     }
  473.  
  474.   bzero(outbuf,smb_size);
  475.  
  476.   /* setup the protocol strings */
  477.   {
  478.     int plength;
  479.  
  480.     for (plength=0,numprots=0;
  481.      prots[numprots].name && prots[numprots].prot<=max_protocol;
  482.      numprots++)
  483.       plength += strlen(prots[numprots].name)+2;
  484.     
  485.     set_message(outbuf,0,plength,True);
  486.  
  487.     p = smb_buf(outbuf);
  488.     for (numprots=0;
  489.      prots[numprots].name && prots[numprots].prot<=max_protocol;
  490.      numprots++)
  491.       {
  492.     *p++ = 2;
  493.     pstrcpy(p,prots[numprots].name);
  494.     p += strlen(p) + 1;
  495.       }
  496.   }
  497.  
  498.   CVAL(outbuf,smb_com) = SMBnegprot;
  499.   cli_setup_pkt(outbuf);
  500.  
  501.   CVAL(smb_buf(outbuf),0) = 2;
  502.  
  503.   send_smb(Client,outbuf);
  504.   client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  505.  
  506.   show_msg(inbuf);
  507.  
  508.   if (CVAL(inbuf,smb_rcls) != 0 || ((int)SVAL(inbuf,smb_vwv0) >= numprots))
  509.     {
  510.       DEBUG(0,("SMBnegprot failed. myname=%s destname=%s - %s \n",
  511.         myname,desthost,smb_errstr(inbuf)));
  512.       if (was_null)
  513.     {
  514.       free(inbuf);
  515.       free(outbuf);
  516.     }
  517.       return(False);
  518.     }
  519.  
  520.   opt.protocol = Protocol = prots[SVAL(inbuf,smb_vwv0)].prot;
  521.  
  522.  
  523.   if (Protocol < PROTOCOL_LANMAN1) {    
  524.       /* no extra params */
  525.   } else if (Protocol < PROTOCOL_NT1) {
  526.     opt.sec_mode = SVAL(inbuf,smb_vwv1);
  527.     opt.max_xmit = max_xmit = SVAL(inbuf,smb_vwv2);
  528.     opt.sesskey = IVAL(inbuf,smb_vwv6);
  529.     opt.serverzone = serverzone = SVALS(inbuf,smb_vwv10)*60;
  530.     /* this time is converted to GMT by make_unix_date */
  531.     servertime = make_unix_date(inbuf+smb_vwv8);
  532.     if (Protocol >= PROTOCOL_COREPLUS) {
  533.       opt.rawmode = SVAL(inbuf,smb_vwv5);
  534.       readbraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x1) != 0);
  535.       writebraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x2) != 0);
  536.     }
  537.     crypt_len = smb_buflen(inbuf);
  538.     memcpy(cryptkey,smb_buf(inbuf),8);
  539.     DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv3)));
  540.     opt.max_vcs = SVAL(inbuf,smb_vwv4); 
  541.     DEBUG(3,("max vcs %d\n",opt.max_vcs)); 
  542.     DEBUG(3,("max blk %d\n",SVAL(inbuf,smb_vwv5)));
  543.   } else {
  544.     /* NT protocol */
  545.     opt.sec_mode = CVAL(inbuf,smb_vwv1);
  546.     opt.max_xmit = max_xmit = IVAL(inbuf,smb_vwv3+1);
  547.     opt.sesskey = IVAL(inbuf,smb_vwv7+1);
  548.     opt.serverzone = SVALS(inbuf,smb_vwv15+1)*60;
  549.     /* this time arrives in real GMT */
  550.     servertime = interpret_long_date(inbuf+smb_vwv11+1);
  551.     crypt_len = CVAL(inbuf,smb_vwv16+1);
  552.     memcpy(cryptkey,smb_buf(inbuf),8);
  553.     if (IVAL(inbuf,smb_vwv9+1) & 1)
  554.       readbraw_supported = writebraw_supported = True;      
  555.     DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv1+1)));
  556.     opt.max_vcs = SVAL(inbuf,smb_vwv2+1); 
  557.     DEBUG(3,("max vcs %d\n",opt.max_vcs));
  558.     DEBUG(3,("max raw %d\n",IVAL(inbuf,smb_vwv5+1)));
  559.     DEBUG(3,("capabilities 0x%x\n",IVAL(inbuf,smb_vwv9+1)));
  560.   }
  561.  
  562.   DEBUG(3,("Sec mode %d\n",SVAL(inbuf,smb_vwv1)));
  563.   DEBUG(3,("max xmt %d\n",max_xmit));
  564.   DEBUG(3,("Got %d byte crypt key\n",crypt_len));
  565.   DEBUG(3,("Chose protocol [%s]\n",prots[SVAL(inbuf,smb_vwv0)].name));
  566.  
  567.   doencrypt = ((opt.sec_mode & 2) != 0);
  568.  
  569.   if (servertime) {
  570.     static BOOL done_time = False;
  571.     if (!done_time) {
  572.       DEBUG(1,("Server time is %sTimezone is UTC%+02.1f\n",
  573.            asctime(LocalTime(&servertime)),
  574.            -(double)(serverzone/3600.0)));
  575.       done_time = True;
  576.     }
  577.   }
  578.  
  579.  get_pass:
  580.  
  581.   if (got_pass)
  582.     pass = password;
  583.   else
  584.     pass = (char *)getpass("Password: ");
  585.  
  586.   pstrcpy(smb_login_passwd, pass);
  587.  
  588.   /* use a blank username for the 2nd try with a blank password */
  589.   if (tries++ && !*pass)
  590.     *username = 0;
  591.  
  592.   if (Protocol >= PROTOCOL_LANMAN1 && use_setup)
  593.     {
  594.       fstring pword;
  595.       int passlen = strlen(pass)+1;
  596.       fstrcpy(pword,pass);      
  597.  
  598.       if (doencrypt && *pass) {
  599.     DEBUG(3,("Using encrypted passwords\n"));
  600.     passlen = 24;
  601.     SMBencrypt((uchar *)pass,(uchar *)cryptkey,(uchar *)pword);
  602.       }
  603.  
  604.       /* if in share level security then don't send a password now */
  605.       if (!(opt.sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} 
  606.  
  607.       /* send a session setup command */
  608.       bzero(outbuf,smb_size);
  609.  
  610.       if (Protocol < PROTOCOL_NT1) {
  611.     set_message(outbuf,10,1 + strlen(username) + passlen,True);
  612.     CVAL(outbuf,smb_com) = SMBsesssetupX;
  613.     cli_setup_pkt(outbuf);
  614.  
  615.     CVAL(outbuf,smb_vwv0) = 0xFF;
  616.     SSVAL(outbuf,smb_vwv2,max_xmit);
  617.     SSVAL(outbuf,smb_vwv3,2);
  618.     SSVAL(outbuf,smb_vwv4,opt.max_vcs-1);
  619.     SIVAL(outbuf,smb_vwv5,opt.sesskey);
  620.     SSVAL(outbuf,smb_vwv7,passlen);
  621.     p = smb_buf(outbuf);
  622.     memcpy(p,pword,passlen);
  623.     p += passlen;
  624.     pstrcpy(p,username);
  625.       } else {
  626.     if (!doencrypt) passlen--;
  627.     /* for Win95 */
  628.     set_message(outbuf,13,0,True);
  629.     CVAL(outbuf,smb_com) = SMBsesssetupX;
  630.     cli_setup_pkt(outbuf);
  631.  
  632.     CVAL(outbuf,smb_vwv0) = 0xFF;
  633.     SSVAL(outbuf,smb_vwv2,BUFFER_SIZE);
  634.     SSVAL(outbuf,smb_vwv3,2);
  635.     SSVAL(outbuf,smb_vwv4,getpid());
  636.     SIVAL(outbuf,smb_vwv5,opt.sesskey);
  637.     SSVAL(outbuf,smb_vwv7,passlen);
  638.     SSVAL(outbuf,smb_vwv8,0);
  639.     p = smb_buf(outbuf);
  640.     memcpy(p,pword,passlen); p += SVAL(outbuf,smb_vwv7);
  641.     pstrcpy(p,username);p = skip_string(p,1);
  642.     pstrcpy(p,workgroup);p = skip_string(p,1);
  643.     pstrcpy(p,"Unix");p = skip_string(p,1);
  644.     pstrcpy(p,"Samba");p = skip_string(p,1);
  645.     set_message(outbuf,13,PTR_DIFF(p,smb_buf(outbuf)),False);
  646.       }
  647.  
  648.       send_smb(Client,outbuf);
  649.       client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  650.  
  651.       show_msg(inbuf);
  652.  
  653.       if (CVAL(inbuf,smb_rcls) != 0)
  654.     {
  655.       if (! *pass &&
  656.           ((CVAL(inbuf,smb_rcls) == ERRDOS && 
  657.         SVAL(inbuf,smb_err) == ERRnoaccess) ||
  658.            (CVAL(inbuf,smb_rcls) == ERRSRV && 
  659.         SVAL(inbuf,smb_err) == ERRbadpw)))
  660.         {
  661.           got_pass = False;
  662.           DEBUG(3,("resending login\n"));
  663.           if (! no_pass)
  664.               goto get_pass;
  665.         }
  666.           
  667.       DEBUG(0,("Session setup failed for username=%s myname=%s destname=%s   %s\n",
  668.         username,myname,desthost,smb_errstr(inbuf)));
  669.       DEBUG(0,("You might find the -U, -W or -n options useful\n"));
  670.       DEBUG(0,("Sometimes you have to use `-n USERNAME' (particularly with OS/2)\n"));
  671.       DEBUG(0,("Some servers also insist on uppercase-only passwords\n"));
  672.       if (was_null)
  673.         {
  674.           free(inbuf);
  675.           free(outbuf);
  676.         }
  677.       return(False);
  678.     }
  679.  
  680.       if (Protocol >= PROTOCOL_NT1) {
  681.     char *domain,*os,*lanman;
  682.     p = smb_buf(inbuf);
  683.     os = p;
  684.     lanman = skip_string(os,1);
  685.     domain = skip_string(lanman,1);
  686.     if (*domain || *os || *lanman)
  687.       DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",domain,os,lanman));
  688.       }
  689.  
  690.       /* use the returned uid from now on */
  691.       if (SVAL(inbuf,smb_uid) != uid)
  692.     DEBUG(3,("Server gave us a UID of %d. We gave %d\n",
  693.           SVAL(inbuf,smb_uid),uid));
  694.       opt.server_uid = uid = SVAL(inbuf,smb_uid);
  695.     }
  696.  
  697.   if (opt.sec_mode & 1) {
  698.       if (SVAL(inbuf, smb_vwv2) & 1)
  699.           DEBUG(1,("connected as guest "));
  700.       DEBUG(1,("security=user\n"));
  701.   } else {
  702.       DEBUG(1,("security=share\n"));
  703.   }
  704.  
  705.   /* now we've got a connection - send a tcon message */
  706.   bzero(outbuf,smb_size);
  707.  
  708.   if (strncmp(service,"\\\\",2) != 0)
  709.     {
  710.       DEBUG(0,("\nWarning: Your service name doesn't start with \\\\. This is probably incorrect.\n"));
  711.       DEBUG(0,("Perhaps try replacing each \\ with \\\\ on the command line?\n\n"));
  712.     }
  713.  
  714.  
  715.  again2:
  716.  
  717.   {
  718.     int passlen = strlen(pass)+1;
  719.     fstring pword;
  720.     fstrcpy(pword,pass);
  721.  
  722.     if (doencrypt && *pass) {
  723.       passlen=24;
  724.       SMBencrypt((uchar *)pass,(uchar *)cryptkey,(uchar *)pword);      
  725.     }
  726.  
  727.     /* if in user level security then don't send a password now */
  728.     if ((opt.sec_mode & 1)) {
  729.       fstrcpy(pword, ""); passlen=1; 
  730.     }
  731.  
  732.     if (Protocol <= PROTOCOL_COREPLUS) {
  733.       set_message(outbuf,0,6 + strlen(service) + passlen + strlen(dev),True);
  734.       CVAL(outbuf,smb_com) = SMBtcon;
  735.       cli_setup_pkt(outbuf);
  736.  
  737.       p = smb_buf(outbuf);
  738.       *p++ = 0x04;
  739.       pstrcpy(p, service);
  740.       p = skip_string(p,1);
  741.       *p++ = 0x04;
  742.       memcpy(p,pword,passlen);
  743.       p += passlen;
  744.       *p++ = 0x04;
  745.       pstrcpy(p, dev);
  746.     }
  747.     else {
  748.       set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True);
  749.       CVAL(outbuf,smb_com) = SMBtconX;
  750.       cli_setup_pkt(outbuf);
  751.   
  752.       SSVAL(outbuf,smb_vwv0,0xFF);
  753.       SSVAL(outbuf,smb_vwv3,passlen);
  754.   
  755.       p = smb_buf(outbuf);
  756.       memcpy(p,pword,passlen);
  757.       p += passlen;
  758.       pstrcpy(p,service);
  759.       p = skip_string(p,1);
  760.       pstrcpy(p,dev);
  761.     }
  762.   }
  763.  
  764.   send_smb(Client,outbuf);
  765.   client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
  766.  
  767.   /* trying again with a blank password */
  768.   if (CVAL(inbuf,smb_rcls) != 0 && 
  769.       (int)strlen(pass) > 0 && 
  770.       !doencrypt &&
  771.       Protocol >= PROTOCOL_LANMAN1)
  772.     {
  773.       DEBUG(2,("first SMBtconX failed, trying again. %s\n",smb_errstr(inbuf)));
  774.       pstrcpy(pass,"");
  775.       goto again2;
  776.     }  
  777.  
  778.   if (CVAL(inbuf,smb_rcls) != 0)
  779.     {
  780.       DEBUG(0,("SMBtconX failed. %s\n",smb_errstr(inbuf)));
  781.       DEBUG(0,("Perhaps you are using the wrong sharename, username or password?\n"));
  782.       DEBUG(0,("Some servers insist that these be in uppercase\n"));
  783.       if (was_null)
  784.     {
  785.       free(inbuf);
  786.       free(outbuf);
  787.     }
  788.       return(False);
  789.     }
  790.   
  791.  
  792.   if (Protocol <= PROTOCOL_COREPLUS) {
  793.     max_xmit = SVAL(inbuf,smb_vwv0);
  794.  
  795.     cnum = SVAL(inbuf,smb_vwv1);
  796.   }
  797.   else {
  798.     max_xmit = MIN(max_xmit,BUFFER_SIZE-4);
  799.     if (max_xmit <= 0)
  800.       max_xmit = BUFFER_SIZE - 4;
  801.  
  802.     cnum = SVAL(inbuf,smb_tid);
  803.   }
  804.   opt.max_xmit = max_xmit;
  805.   opt.tid = cnum;
  806.  
  807.   DEBUG(3,("Connected with cnum=%d max_xmit=%d\n",cnum,max_xmit));
  808.  
  809.   if (was_null)
  810.     {
  811.       free(inbuf);
  812.       free(outbuf);
  813.     }
  814.  
  815.   if (options != NULL)
  816.     {
  817.       *options = opt;
  818.     }
  819.  
  820.   return True;
  821. }
  822.  
  823.  
  824. /****************************************************************************
  825. send a logout command
  826. ****************************************************************************/
  827. void cli_send_logout(char *dum_in, char *dum_out)
  828. {
  829.   pstring inbuf,outbuf;
  830.  
  831.   DEBUG(5,("cli_send_logout\n"));
  832.  
  833.   bzero(outbuf,smb_size);
  834.   set_message(outbuf,0,0,True);
  835.   CVAL(outbuf,smb_com) = SMBtdis;
  836.   SSVAL(outbuf,smb_tid,cnum);
  837.   cli_setup_pkt(outbuf);
  838.  
  839.   send_smb(Client,outbuf);
  840.   client_receive_smb(Client,inbuf,SHORT_TIMEOUT);
  841.  
  842.   if (CVAL(inbuf,smb_rcls) != 0)
  843.     {
  844.       DEBUG(0,("SMBtdis failed %s\n",smb_errstr(inbuf)));
  845.     }
  846.  
  847.   
  848. #ifdef STATS
  849.   stats_report();
  850. #endif
  851.   exit(0);
  852. }
  853.  
  854.  
  855. /****************************************************************************
  856. open the client sockets
  857. ****************************************************************************/
  858. BOOL cli_open_sockets(int port )
  859. {
  860.   static int last_port;
  861.   char *host;
  862.   pstring service2;
  863.   extern int Client;
  864.  
  865.   if (port == 0) port=last_port;
  866.   last_port=port;
  867.  
  868.   strupper(service);
  869.  
  870.   if (*desthost)
  871.     {
  872.       host = desthost;
  873.     }
  874.   else
  875.     {
  876.       pstrcpy(service2,service);
  877.       host = strtok(service2,"\\/");
  878.       if (!host) {
  879.     DEBUG(0,("Badly formed host name\n"));
  880.     return(False);
  881.       }
  882.       pstrcpy(desthost,host);
  883.     }
  884.  
  885.   if (!(*myname)) {
  886.       get_myname(myname,NULL);
  887.   }
  888.   strupper(myname);
  889.  
  890.   DEBUG(3,("Opening sockets\n"));
  891.  
  892.   if (!have_ip)
  893.     {
  894.       if(!resolve_name( host, &dest_ip))
  895.       {
  896.       DEBUG(0,("cli_open_sockets: Unknown host %s.\n",host));
  897.       return False;
  898.       }
  899.     }
  900.  
  901.   Client = open_socket_out(SOCK_STREAM, &dest_ip, port, LONG_CONNECT_TIMEOUT);
  902.   if (Client == -1)
  903.     return False;
  904.  
  905.   DEBUG(3,("Connected\n"));
  906.   
  907.   set_socket_options(Client,user_socket_options);  
  908.   
  909.   return True;
  910. }
  911.  
  912. /****************************************************************************
  913. close and open the connection again
  914. ****************************************************************************/
  915. BOOL cli_reopen_connection(char *inbuf,char *outbuf)
  916. {
  917.   static int open_count=0;
  918.  
  919.   open_count++;
  920.  
  921.   if (open_count>5) return(False);
  922.  
  923.   DEBUG(1,("Trying to re-open connection\n"));
  924.  
  925.   set_message(outbuf,0,0,True);
  926.   SCVAL(outbuf,smb_com,SMBtdis);
  927.   SSVAL(outbuf,smb_tid,cnum);
  928.   cli_setup_pkt(outbuf);
  929.  
  930.   send_smb(Client,outbuf);
  931.   client_receive_smb(Client,inbuf,SHORT_TIMEOUT);
  932.  
  933.   close_sockets();
  934.   if (!cli_open_sockets(0)) return(False);
  935.  
  936.   return(cli_send_login(inbuf,outbuf,True,True,NULL));
  937. }
  938.  
  939.