home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Networking / SambaManager / samba-1.9.17p4 / source / clientgen.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-30  |  18.4 KB  |  676 lines

  1. /* 
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.9.
  4.    SMB client generic functions
  5.    Copyright (C) Andrew Tridgell 1994-1997
  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.  
  29. extern int DEBUGLEVEL;
  30.  
  31. /****************************************************************************
  32. setup basics in a outgoing packet
  33. ****************************************************************************/
  34. static void cli_setup_pkt(struct cli_state *cli)
  35. {
  36.     SSVAL(cli->outbuf,smb_pid,cli->pid);
  37.     SSVAL(cli->outbuf,smb_uid,cli->uid);
  38.     SSVAL(cli->outbuf,smb_mid,cli->mid);
  39.     if (cli->protocol > PROTOCOL_CORE) {
  40.         SCVAL(cli->outbuf,smb_flg,0x8);
  41.         SSVAL(cli->outbuf,smb_flg2,0x1);
  42.     }
  43. }
  44.  
  45.  
  46. /****************************************************************************
  47.   send a SMB trans or trans2 request
  48.   ****************************************************************************/
  49. static BOOL cli_send_trans(struct cli_state *cli,
  50.                int trans, char *name, int fid, int flags,
  51.                char *data,char *param,uint16 *setup, int ldata,int lparam,
  52.                int lsetup,int mdata,int mparam,int msetup)
  53. {
  54.     int i;
  55.     int this_ldata,this_lparam;
  56.     int tot_data=0,tot_param=0;
  57.     char *outdata,*outparam;
  58.     char *p;
  59.  
  60.     this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */
  61.     this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*SIZEOFWORD+this_lparam));
  62.  
  63.     bzero(cli->outbuf,smb_size);
  64.     set_message(cli->outbuf,14+lsetup,0,True);
  65.     CVAL(cli->outbuf,smb_com) = trans;
  66.     SSVAL(cli->outbuf,smb_tid, cli->cnum);
  67.     cli_setup_pkt(cli);
  68.  
  69.     outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3);
  70.     outdata = outparam+this_lparam;
  71.  
  72.     /* primary request */
  73.     SSVAL(cli->outbuf,smb_tpscnt,lparam);    /* tpscnt */
  74.     SSVAL(cli->outbuf,smb_tdscnt,ldata);    /* tdscnt */
  75.     SSVAL(cli->outbuf,smb_mprcnt,mparam);    /* mprcnt */
  76.     SSVAL(cli->outbuf,smb_mdrcnt,mdata);    /* mdrcnt */
  77.     SCVAL(cli->outbuf,smb_msrcnt,msetup);    /* msrcnt */
  78.     SSVAL(cli->outbuf,smb_flags,flags);    /* flags */
  79.     SIVAL(cli->outbuf,smb_timeout,0);        /* timeout */
  80.     SSVAL(cli->outbuf,smb_pscnt,this_lparam);    /* pscnt */
  81.     SSVAL(cli->outbuf,smb_psoff,smb_offset(outparam,cli->outbuf)); /* psoff */
  82.     SSVAL(cli->outbuf,smb_dscnt,this_ldata);    /* dscnt */
  83.     SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */
  84.     SCVAL(cli->outbuf,smb_suwcnt,lsetup);    /* suwcnt */
  85.     for (i=0;i<lsetup;i++)        /* setup[] */
  86.         SSVAL(cli->outbuf,smb_setup+i*SIZEOFWORD,setup[i]);
  87.     p = smb_buf(cli->outbuf);
  88.     if (trans==SMBtrans) {
  89.         strcpy(p,name);            /* name[] */
  90.     } else {
  91.         *p++ = 0;  /* put in a null smb_name */
  92.         *p++ = 'D'; *p++ = ' ';    /* observed in OS/2 */
  93.     }
  94.     if (this_lparam)            /* param[] */
  95.         memcpy(outparam,param,this_lparam);
  96.     if (this_ldata)            /* data[] */
  97.         memcpy(outdata,data,this_ldata);
  98.     set_message(cli->outbuf,14+lsetup,        /* wcnt, bcc */
  99.             PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False);
  100.  
  101.     show_msg(cli->outbuf);
  102.     send_smb(cli->fd,cli->outbuf);
  103.  
  104.     if (this_ldata < ldata || this_lparam < lparam) {
  105.         /* receive interim response */
  106.         if (!receive_smb(cli->fd,cli->inbuf,cli->timeout) || 
  107.             CVAL(cli->inbuf,smb_rcls) != 0) {
  108.             return(False);
  109.         }      
  110.  
  111.         tot_data = this_ldata;
  112.         tot_param = this_lparam;
  113.         
  114.         while (tot_data < ldata || tot_param < lparam)  {
  115.             this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */
  116.             this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam));
  117.  
  118.             set_message(cli->outbuf,trans==SMBtrans?8:9,0,True);
  119.             CVAL(cli->outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2;
  120.             
  121.             outparam = smb_buf(cli->outbuf);
  122.             outdata = outparam+this_lparam;
  123.             
  124.             /* secondary request */
  125.             SSVAL(cli->outbuf,smb_tpscnt,lparam);    /* tpscnt */
  126.             SSVAL(cli->outbuf,smb_tdscnt,ldata);    /* tdscnt */
  127.             SSVAL(cli->outbuf,smb_spscnt,this_lparam);    /* pscnt */
  128.             SSVAL(cli->outbuf,smb_spsoff,smb_offset(outparam,cli->outbuf)); /* psoff */
  129.             SSVAL(cli->outbuf,smb_spsdisp,tot_param);    /* psdisp */
  130.             SSVAL(cli->outbuf,smb_sdscnt,this_ldata);    /* dscnt */
  131.             SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */
  132.             SSVAL(cli->outbuf,smb_sdsdisp,tot_data);    /* dsdisp */
  133.             if (trans==SMBtrans2)
  134.                 SSVAL(cli->outbuf,smb_sfid,fid);        /* fid */
  135.             if (this_lparam)            /* param[] */
  136.                 memcpy(outparam,param,this_lparam);
  137.             if (this_ldata)            /* data[] */
  138.                 memcpy(outdata,data,this_ldata);
  139.             set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */
  140.                     PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False);
  141.             
  142.             show_msg(cli->outbuf);
  143.             send_smb(cli->fd,cli->outbuf);
  144.             
  145.             tot_data += this_ldata;
  146.             tot_param += this_lparam;
  147.         }
  148.     }
  149.  
  150.     return(True);
  151. }
  152.  
  153.  
  154. /****************************************************************************
  155.   receive a SMB trans or trans2 response allocating the necessary memory
  156.   ****************************************************************************/
  157. static BOOL cli_receive_trans(struct cli_state *cli,
  158.                   int trans,int *data_len,
  159.                   int *param_len, char **data,char **param)
  160. {
  161.     int total_data=0;
  162.     int total_param=0;
  163.     int this_data,this_param;
  164.     
  165.     *data_len = *param_len = 0;
  166.     
  167.     if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
  168.         return False;
  169.  
  170.     show_msg(cli->inbuf);
  171.     
  172.     /* sanity check */
  173.     if (CVAL(cli->inbuf,smb_com) != trans) {
  174.         DEBUG(0,("Expected %s response, got command 0x%02x\n",
  175.              trans==SMBtrans?"SMBtrans":"SMBtrans2", 
  176.              CVAL(cli->inbuf,smb_com)));
  177.         return(False);
  178.     }
  179.     if (CVAL(cli->inbuf,smb_rcls) != 0)
  180.         return(False);
  181.  
  182.     /* parse out the lengths */
  183.     total_data = SVAL(cli->inbuf,smb_tdrcnt);
  184.     total_param = SVAL(cli->inbuf,smb_tprcnt);
  185.  
  186.     /* allocate it */
  187.     *data = Realloc(*data,total_data);
  188.     *param = Realloc(*param,total_param);
  189.  
  190.     while (1)  {
  191.         this_data = SVAL(cli->inbuf,smb_drcnt);
  192.         this_param = SVAL(cli->inbuf,smb_prcnt);
  193.  
  194.         if (this_data + *data_len > total_data ||
  195.             this_param + *param_len > total_param) {
  196.             DEBUG(1,("Data overflow in cli_receive_trans\n"));
  197.             return False;
  198.         }
  199.  
  200.         if (this_data)
  201.             memcpy(*data + SVAL(cli->inbuf,smb_drdisp),
  202.                    smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_droff),
  203.                    this_data);
  204.         if (this_param)
  205.             memcpy(*param + SVAL(cli->inbuf,smb_prdisp),
  206.                    smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_proff),
  207.                    this_param);
  208.         *data_len += this_data;
  209.         *param_len += this_param;
  210.  
  211.         /* parse out the total lengths again - they can shrink! */
  212.         total_data = SVAL(cli->inbuf,smb_tdrcnt);
  213.         total_param = SVAL(cli->inbuf,smb_tprcnt);
  214.         
  215.         if (total_data <= *data_len && total_param <= *param_len)
  216.             break;
  217.         
  218.         if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
  219.             return False;
  220.  
  221.         show_msg(cli->inbuf);
  222.         
  223.         /* sanity check */
  224.         if (CVAL(cli->inbuf,smb_com) != trans) {
  225.             DEBUG(0,("Expected %s response, got command 0x%02x\n",
  226.                  trans==SMBtrans?"SMBtrans":"SMBtrans2", 
  227.                  CVAL(cli->inbuf,smb_com)));
  228.             return(False);
  229.         }
  230.         if (CVAL(cli->inbuf,smb_rcls) != 0)
  231.             return(False);
  232.     }
  233.     
  234.     return(True);
  235. }
  236.  
  237.  
  238. /****************************************************************************
  239. call a remote api
  240. ****************************************************************************/
  241. static BOOL cli_api(struct cli_state *cli,
  242.             int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt,
  243.             int *rdrcnt, char *param,char *data, 
  244.             char **rparam, char **rdata)
  245. {
  246.   cli_send_trans(cli,SMBtrans,"\\PIPE\\LANMAN",0,0,
  247.          data,param,NULL,
  248.          drcnt,prcnt,0,
  249.          mdrcnt,mprcnt,0);
  250.  
  251.   return (cli_receive_trans(cli,SMBtrans,
  252.                      rdrcnt,rprcnt,
  253.                      rdata,rparam));
  254. }
  255.  
  256.  
  257. /****************************************************************************
  258. perform a NetWkstaUserLogon
  259. ****************************************************************************/
  260. BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation)
  261. {
  262.     char *rparam = NULL;
  263.     char *rdata = NULL;
  264.     char *p;
  265.     int rdrcnt,rprcnt;
  266.     pstring param;
  267.  
  268.     memset(param, 0, sizeof(param));
  269.     
  270.     /* send a SMBtrans command with api NetWkstaUserLogon */
  271.     p = param;
  272.     SSVAL(p,0,132); /* api number */
  273.     p += 2;
  274.     strcpy(p,"OOWb54WrLh");
  275.     p = skip_string(p,1);
  276.     strcpy(p,"WB21BWDWWDDDDDDDzzzD");
  277.     p = skip_string(p,1);
  278.     SSVAL(p,0,1);
  279.     p += 2;
  280.     strcpy(p,user);
  281.     strupper(p);
  282.     p += 21; p++; p += 15; p++; 
  283.     strcpy(p, workstation); 
  284.     strupper(p);
  285.     p += 16;
  286.     SSVAL(p, 0, BUFFER_SIZE);
  287.     p += 2;
  288.     SSVAL(p, 0, BUFFER_SIZE);
  289.     p += 2;
  290.     
  291.     cli->error = -1;
  292.     
  293.     if (cli_api(cli, PTR_DIFF(p,param),0,
  294.             1024,BUFFER_SIZE,
  295.             &rprcnt,&rdrcnt,
  296.             param,NULL,
  297.             &rparam,&rdata)) {
  298.         cli->error = SVAL(rparam,0);
  299.         p = rdata;
  300.         
  301.         if (cli->error == 0) {
  302.             DEBUG(4,("NetWkstaUserLogon success\n"));
  303.             cli->privilages = SVAL(p, 24);
  304.             fstrcpy(cli->eff_name,p+2);
  305.         } else {
  306.             DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->error));
  307.         }
  308.     }
  309.     
  310.     if (rparam) free(rparam);
  311.     if (rdata) free(rdata);
  312.     return cli->error == 0;
  313. }
  314.  
  315.  
  316.  
  317. static  struct {
  318.     int prot;
  319.     char *name;
  320.   }
  321. prots[] = 
  322.     {
  323.       {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
  324.       {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
  325.       {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
  326.       {PROTOCOL_LANMAN1,"LANMAN1.0"},
  327.       {PROTOCOL_LANMAN2,"LM1.2X002"},
  328.       {PROTOCOL_LANMAN2,"Samba"},
  329.       {PROTOCOL_NT1,"NT LM 0.12"},
  330.       {PROTOCOL_NT1,"NT LANMAN 1.0"},
  331.       {-1,NULL}
  332.     };
  333.  
  334.  
  335. /****************************************************************************
  336. send a session setup
  337. ****************************************************************************/
  338. BOOL cli_session_setup(struct cli_state *cli, 
  339.                char *user, 
  340.                char *pass, int passlen,
  341.                char *ntpass, int ntpasslen,
  342.                char *workgroup)
  343. {
  344.     char *p;
  345.     fstring pword;
  346.  
  347.     if (cli->protocol < PROTOCOL_LANMAN1)
  348.         return False;
  349.  
  350.     if (passlen > sizeof(pword)-1) {
  351.         return False;
  352.     }
  353.  
  354.     if ((cli->sec_mode & 2) && *pass && passlen != 24) {
  355. #ifdef SMB_PASSWD
  356.         passlen = 24;
  357.         SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword);
  358. #endif
  359.     } else {
  360.         memcpy(pword, pass, passlen);
  361.     }
  362.  
  363.     /* if in share level security then don't send a password now */
  364.     if (!(cli->sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} 
  365.  
  366.     /* send a session setup command */
  367.     bzero(cli->outbuf,smb_size);
  368.  
  369.     if (cli->protocol < PROTOCOL_NT1) {
  370.         set_message(cli->outbuf,10,1 + strlen(user) + passlen,True);
  371.         CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
  372.         cli_setup_pkt(cli);
  373.  
  374.         CVAL(cli->outbuf,smb_vwv0) = 0xFF;
  375.         SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit);
  376.         SSVAL(cli->outbuf,smb_vwv3,2);
  377.         SSVAL(cli->outbuf,smb_vwv4,1);
  378.         SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
  379.         SSVAL(cli->outbuf,smb_vwv7,passlen);
  380.         p = smb_buf(cli->outbuf);
  381.         memcpy(p,pword,passlen);
  382.         p += passlen;
  383.         strcpy(p,user);
  384.         strupper(p);
  385.     } else {
  386.         set_message(cli->outbuf,13,0,True);
  387.         CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
  388.         cli_setup_pkt(cli);
  389.         
  390.         CVAL(cli->outbuf,smb_vwv0) = 0xFF;
  391.         SSVAL(cli->outbuf,smb_vwv2,BUFFER_SIZE);
  392.         SSVAL(cli->outbuf,smb_vwv3,2);
  393.         SSVAL(cli->outbuf,smb_vwv4,cli->pid);
  394.         SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
  395.         SSVAL(cli->outbuf,smb_vwv7,passlen);
  396.         SSVAL(cli->outbuf,smb_vwv8,ntpasslen);
  397.         p = smb_buf(cli->outbuf);
  398.         memcpy(p,pword,passlen); 
  399.         p += SVAL(cli->outbuf,smb_vwv7);
  400.         memcpy(p,ntpass,ntpasslen); 
  401.         p += SVAL(cli->outbuf,smb_vwv8);
  402.         strcpy(p,user);
  403.         strupper(p);
  404.         p = skip_string(p,1);
  405.         strcpy(p,workgroup);
  406.         strupper(p);
  407.         p = skip_string(p,1);
  408.         strcpy(p,"Unix");p = skip_string(p,1);
  409.         strcpy(p,"Samba");p = skip_string(p,1);
  410.         set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False);
  411.     }
  412.  
  413.       send_smb(cli->fd,cli->outbuf);
  414.       if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
  415.           return False;
  416.  
  417.       show_msg(cli->inbuf);
  418.  
  419.       if (CVAL(cli->inbuf,smb_rcls) != 0) {
  420.           return False;
  421.       }
  422.  
  423.       /* use the returned uid from now on */
  424.       cli->uid = SVAL(cli->inbuf,smb_uid);
  425.  
  426.       return True;
  427. }
  428.  
  429.  
  430. /****************************************************************************
  431. send a tconX
  432. ****************************************************************************/
  433. BOOL cli_send_tconX(struct cli_state *cli, 
  434.             char *share, char *dev, char *pword, int passlen)
  435. {
  436.     char *p;
  437.     bzero(cli->outbuf,smb_size);
  438.     bzero(cli->inbuf,smb_size);
  439.  
  440.     set_message(cli->outbuf,4,
  441.             2 + strlen(share) + passlen + strlen(dev),True);
  442.     CVAL(cli->outbuf,smb_com) = SMBtconX;
  443.     cli_setup_pkt(cli);
  444.  
  445.     SSVAL(cli->outbuf,smb_vwv0,0xFF);
  446.     SSVAL(cli->outbuf,smb_vwv3,passlen);
  447.  
  448.     p = smb_buf(cli->outbuf);
  449.     memcpy(p,pword,passlen);
  450.     p += passlen;
  451.     strcpy(p,share);
  452.     p = skip_string(p,1);
  453.     strcpy(p,dev);
  454.  
  455.     SCVAL(cli->inbuf,smb_rcls, 1);
  456.  
  457.     send_smb(cli->fd,cli->outbuf);
  458.     if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
  459.         return False;
  460.  
  461.     if (CVAL(cli->inbuf,smb_rcls) != 0) {
  462.         return False;
  463.     }
  464.  
  465.     cli->cnum = SVAL(cli->inbuf,smb_tid);
  466.     return True;
  467. }
  468.  
  469.  
  470. /****************************************************************************
  471. send a tree disconnect
  472. ****************************************************************************/
  473. BOOL cli_tdis(struct cli_state *cli)
  474. {
  475.     bzero(cli->outbuf,smb_size);
  476.     set_message(cli->outbuf,0,0,True);
  477.     CVAL(cli->outbuf,smb_com) = SMBtdis;
  478.     SSVAL(cli->outbuf,smb_tid,cli->cnum);
  479.     cli_setup_pkt(cli);
  480.     
  481.     send_smb(cli->fd,cli->outbuf);
  482.     if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
  483.         return False;
  484.     
  485.     return CVAL(cli->inbuf,smb_rcls) == 0;
  486. }
  487.  
  488.  
  489. /****************************************************************************
  490. send a negprot command
  491. ****************************************************************************/
  492. BOOL cli_negprot(struct cli_state *cli)
  493. {
  494.     char *p;
  495.     int numprots;
  496.     int plength;
  497.  
  498.     bzero(cli->outbuf,smb_size);
  499.  
  500.     /* setup the protocol strings */
  501.     for (plength=0,numprots=0;
  502.          prots[numprots].name && prots[numprots].prot<=cli->protocol;
  503.          numprots++)
  504.         plength += strlen(prots[numprots].name)+2;
  505.     
  506.     set_message(cli->outbuf,0,plength,True);
  507.  
  508.     p = smb_buf(cli->outbuf);
  509.     for (numprots=0;
  510.          prots[numprots].name && prots[numprots].prot<=cli->protocol;
  511.          numprots++) {
  512.         *p++ = 2;
  513.         strcpy(p,prots[numprots].name);
  514.         p += strlen(p) + 1;
  515.     }
  516.  
  517.     CVAL(cli->outbuf,smb_com) = SMBnegprot;
  518.     cli_setup_pkt(cli);
  519.  
  520.     CVAL(smb_buf(cli->outbuf),0) = 2;
  521.  
  522.     send_smb(cli->fd,cli->outbuf);
  523.     if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
  524.         return False;
  525.  
  526.     show_msg(cli->inbuf);
  527.  
  528.     if (CVAL(cli->inbuf,smb_rcls) != 0 || 
  529.         ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) {
  530.         return(False);
  531.     }
  532.  
  533.     cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;
  534.  
  535.  
  536.     if (cli->protocol < PROTOCOL_NT1) {    
  537.         cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
  538.         cli->max_xmit = SVAL(cli->inbuf,smb_vwv2);
  539.         cli->sesskey = IVAL(cli->inbuf,smb_vwv6);
  540.         cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60;
  541.         /* this time is converted to GMT by make_unix_date */
  542.         cli->servertime = make_unix_date(cli->inbuf+smb_vwv8);
  543.         if (cli->protocol >= PROTOCOL_COREPLUS) {
  544.             cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0);
  545.             cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0);
  546.         }
  547.         memcpy(cli->cryptkey,smb_buf(cli->inbuf),8);
  548.     } else {
  549.         /* NT protocol */
  550.         cli->sec_mode = CVAL(cli->inbuf,smb_vwv1);
  551.         cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1);
  552.         cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1);
  553.         cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60;
  554.         /* this time arrives in real GMT */
  555.         cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1);
  556.         memcpy(cli->cryptkey,smb_buf(cli->inbuf),8);
  557.         if (IVAL(cli->inbuf,smb_vwv9+1) & 1)
  558.             cli->readbraw_supported = 
  559.                 cli->writebraw_supported = True;      
  560.     }
  561.  
  562.     return True;
  563. }
  564.  
  565.  
  566. /****************************************************************************
  567.   send a session request
  568. ****************************************************************************/
  569. BOOL cli_session_request(struct cli_state *cli, char *host, int name_type,
  570.              char *myname)
  571. {
  572.     fstring dest;
  573.     char *p;
  574.     int len = 4;
  575.     /* send a session request (RFC 1002) */
  576.  
  577.     fstrcpy(dest,host);
  578.   
  579.     p = strchr(dest,'.');
  580.     if (p) *p = 0;
  581.  
  582.     fstrcpy(cli->desthost, dest);
  583.  
  584.     /* put in the destination name */
  585.     p = cli->outbuf+len;
  586.     name_mangle(dest,p,name_type);
  587.     len += name_len(p);
  588.  
  589.     /* and my name */
  590.     p = cli->outbuf+len;
  591.     name_mangle(myname,p,0);
  592.     len += name_len(p);
  593.  
  594.     /* setup the packet length */
  595.     _smb_setlen(cli->outbuf,len);
  596.     CVAL(cli->outbuf,0) = 0x81;
  597.  
  598.     send_smb(cli->fd,cli->outbuf);
  599.     DEBUG(5,("Sent session request\n"));
  600.  
  601.     if (!receive_smb(cli->fd,cli->inbuf,cli->timeout))
  602.         return False;
  603.  
  604.     if (CVAL(cli->inbuf,0) != 0x82) {
  605.         cli->error = CVAL(cli->inbuf,0);
  606.         return False;
  607.     }
  608.     return(True);
  609. }
  610.  
  611.  
  612. /****************************************************************************
  613. open the client sockets
  614. ****************************************************************************/
  615. BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip)
  616. {
  617.     struct in_addr dest_ip;
  618.  
  619.     fstrcpy(cli->desthost, host);
  620.     
  621.     if (!ip) {
  622.         struct hostent *hp;
  623.  
  624.         if ((hp = Get_Hostbyname(cli->desthost)) == 0) {
  625.             return False;
  626.         }
  627.  
  628.         putip((char *)&dest_ip,(char *)hp->h_addr);
  629.     } else {
  630.         dest_ip = *ip;
  631.     }
  632.  
  633.  
  634.     cli->fd = open_socket_out(SOCK_STREAM, &dest_ip, 139, cli->timeout);
  635.     if (cli->fd == -1)
  636.         return False;
  637.  
  638.     return True;
  639. }
  640.  
  641.  
  642. /****************************************************************************
  643. initialise a client structure
  644. ****************************************************************************/
  645. BOOL cli_initialise(struct cli_state *cli)
  646. {
  647.     if (cli->initialised) cli_shutdown(cli);
  648.  
  649.     memset(cli, 0, sizeof(*cli));
  650.     cli->fd = -1;
  651.     cli->cnum = -1;
  652.     cli->pid = getpid();
  653.     cli->mid = 1;
  654.     cli->uid = getuid();
  655.     cli->protocol = PROTOCOL_NT1;
  656.     cli->timeout = 20000;
  657.     cli->bufsize = 0x10000;
  658.     cli->max_xmit = cli->bufsize - 4;
  659.     cli->outbuf = (char *)malloc(cli->bufsize);
  660.     cli->inbuf = (char *)malloc(cli->bufsize);
  661.     if (!cli->outbuf || !cli->inbuf) return False;
  662.     cli->initialised = 1;
  663.     return True;
  664. }
  665.  
  666. /****************************************************************************
  667. shutdown a client structure
  668. ****************************************************************************/
  669. void cli_shutdown(struct cli_state *cli)
  670. {
  671.     if (cli->outbuf) free(cli->outbuf);
  672.     if (cli->inbuf) free(cli->inbuf);
  673.     if (cli->fd != -1) close(cli->fd);
  674.     memset(cli, 0, sizeof(*cli));
  675. }
  676.