-N option still prompted for password in smbclient -L usage
[samba.git] / source3 / client / clientutil.c
index d05be8ae9b8fbb85038c80295bac529099397d4c..8d5e11e4d8c2ce955dbbed15296fd19af7f5d510 100644 (file)
@@ -2,7 +2,7 @@
    Unix SMB/Netbios implementation.
    Version 1.9.
    SMB client
-   Copyright (C) Andrew Tridgell 1994-1997
+   Copyright (C) Andrew Tridgell 1994-1998
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #define REGISTER 0
 #endif
 
+#define USENMB
+
 pstring service="";
 pstring desthost="";
 extern pstring myname;
 pstring password = "";
+pstring smb_login_passwd = "";
 pstring username="";
 pstring workgroup=WORKGROUP;
 BOOL got_pass = False;
+BOOL no_pass = False;
 BOOL connect_as_printer = False;
 BOOL connect_as_ipc = False;
 
@@ -92,7 +96,8 @@ void cli_setup_pkt(char *outbuf)
 /****************************************************************************
 call a remote api
 ****************************************************************************/
-BOOL cli_call_api(char *pipe_name, int prcnt,int drcnt, int srcnt,
+BOOL cli_call_api(char *pipe_name, int pipe_name_len,
+                       int prcnt,int drcnt, int srcnt,
                     int mprcnt,int mdrcnt,
                     int *rprcnt,int *rdrcnt,
                     char *param,char *data, uint16 *setup,
@@ -104,7 +109,9 @@ BOOL cli_call_api(char *pipe_name, int prcnt,int drcnt, int srcnt,
   if (!inbuf) inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
   if (!outbuf) outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
 
-  cli_send_trans_request(outbuf,SMBtrans,pipe_name, 0,0,
+  if (pipe_name_len == 0) pipe_name_len = strlen(pipe_name);
+
+  cli_send_trans_request(outbuf,SMBtrans,pipe_name, pipe_name_len, 0,0,
                     data, param, setup,
                     drcnt, prcnt, srcnt,
                     mdrcnt, mprcnt, 0);
@@ -128,7 +135,7 @@ BOOL cli_receive_trans_response(char *inbuf,int trans,
 
   *data_len = *param_len = 0;
 
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
   show_msg(inbuf);
 
   /* sanity check */
@@ -171,7 +178,7 @@ BOOL cli_receive_trans_response(char *inbuf,int trans,
       if (total_data <= *data_len && total_param <= *param_len)
        break;
 
-      receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+      client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
       show_msg(inbuf);
 
       /* sanity check */
@@ -194,7 +201,7 @@ BOOL cli_receive_trans_response(char *inbuf,int trans,
   send a SMB trans or trans2 request
   ****************************************************************************/
 BOOL cli_send_trans_request(char *outbuf,int trans,
-                              char *name,int fid,int flags,
+                              char *name,int namelen, int fid,int flags,
                               char *data,char *param,uint16 *setup,
                               int ldata,int lparam,int lsetup,
                               int mdata,int mparam,int msetup)
@@ -215,7 +222,7 @@ BOOL cli_send_trans_request(char *outbuf,int trans,
   SSVAL(outbuf,smb_tid,cnum);
   cli_setup_pkt(outbuf);
 
-  outparam = smb_buf(outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3);
+  outparam = smb_buf(outbuf)+(trans==SMBtrans ? namelen+1 : 3);
   outdata = outparam+this_lparam;
 
   /* primary request */
@@ -235,7 +242,7 @@ BOOL cli_send_trans_request(char *outbuf,int trans,
     SSVAL(outbuf,smb_setup+i*SIZEOFWORD,setup[i]);
   p = smb_buf(outbuf);
   if (trans==SMBtrans)
-    strcpy(p,name);                    /* name[] */
+    memcpy(p,name, namelen+1);                 /* name[] */
   else
     {
       *p++ = 0;                                /* put in a null smb_name */
@@ -254,7 +261,7 @@ BOOL cli_send_trans_request(char *outbuf,int trans,
   if (this_ldata < ldata || this_lparam < lparam)
     {
       /* receive interim response */
-      if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
+      if (!client_receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
        {
          DEBUG(0,("%s request failed (%s)\n",
                   trans==SMBtrans?"SMBtrans":"SMBtrans2", smb_errstr(inbuf)));
@@ -336,7 +343,7 @@ BOOL cli_send_session_request(char *inbuf,char *outbuf)
   send_smb(Client,outbuf);
   DEBUG(5,("Sent session request\n"));
 
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
 
   if (CVAL(inbuf,0) == 0x84) /* C. Hoch  9/14/95 Start */
     {
@@ -422,22 +429,22 @@ static struct {
 
 
 /****************************************************************************
-send a login command
+send a login command.  
 ****************************************************************************/
-BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
+BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup, struct connection_options *options)
 {
   BOOL was_null = (!inbuf && !outbuf);
-  int sesskey=0;
   time_t servertime = 0;
   extern int serverzone;
-  int sec_mode=0;
-  int crypt_len;
-  int max_vcs=0;
+  int crypt_len=0;
   char *pass = NULL;  
   pstring dev;
   char *p;
   int numprots;
   int tries=0;
+  struct connection_options opt;
+
+  bzero(&opt, sizeof(opt));
 
   if (was_null)
     {
@@ -496,7 +503,7 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
   CVAL(smb_buf(outbuf),0) = 2;
 
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
 
   show_msg(inbuf);
 
@@ -512,32 +519,35 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
       return(False);
     }
 
-  Protocol = prots[SVAL(inbuf,smb_vwv0)].prot;
+  opt.protocol = Protocol = prots[SVAL(inbuf,smb_vwv0)].prot;
 
 
-  if (Protocol < PROTOCOL_NT1) {    
-    sec_mode = SVAL(inbuf,smb_vwv1);
-    max_xmit = SVAL(inbuf,smb_vwv2);
-    sesskey = IVAL(inbuf,smb_vwv6);
-    serverzone = SVALS(inbuf,smb_vwv10)*60;
+  if (Protocol < PROTOCOL_LANMAN1) {    
+         /* no extra params */
+  } else if (Protocol < PROTOCOL_NT1) {
+    opt.sec_mode = SVAL(inbuf,smb_vwv1);
+    opt.max_xmit = max_xmit = SVAL(inbuf,smb_vwv2);
+    opt.sesskey = IVAL(inbuf,smb_vwv6);
+    opt.serverzone = serverzone = SVALS(inbuf,smb_vwv10)*60;
     /* this time is converted to GMT by make_unix_date */
     servertime = make_unix_date(inbuf+smb_vwv8);
     if (Protocol >= PROTOCOL_COREPLUS) {
+      opt.rawmode = SVAL(inbuf,smb_vwv5);
       readbraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x1) != 0);
       writebraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x2) != 0);
     }
     crypt_len = smb_buflen(inbuf);
     memcpy(cryptkey,smb_buf(inbuf),8);
     DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv3)));
-    max_vcs = SVAL(inbuf,smb_vwv4); 
-    DEBUG(3,("max vcs %d\n",max_vcs)); 
+    opt.max_vcs = SVAL(inbuf,smb_vwv4); 
+    DEBUG(3,("max vcs %d\n",opt.max_vcs)); 
     DEBUG(3,("max blk %d\n",SVAL(inbuf,smb_vwv5)));
   } else {
     /* NT protocol */
-    sec_mode = CVAL(inbuf,smb_vwv1);
-    max_xmit = IVAL(inbuf,smb_vwv3+1);
-    sesskey = IVAL(inbuf,smb_vwv7+1);
-    serverzone = SVALS(inbuf,smb_vwv15+1)*60;
+    opt.sec_mode = CVAL(inbuf,smb_vwv1);
+    opt.max_xmit = max_xmit = IVAL(inbuf,smb_vwv3+1);
+    opt.sesskey = IVAL(inbuf,smb_vwv7+1);
+    opt.serverzone = SVALS(inbuf,smb_vwv15+1)*60;
     /* this time arrives in real GMT */
     servertime = interpret_long_date(inbuf+smb_vwv11+1);
     crypt_len = CVAL(inbuf,smb_vwv16+1);
@@ -545,8 +555,8 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
     if (IVAL(inbuf,smb_vwv9+1) & 1)
       readbraw_supported = writebraw_supported = True;      
     DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv1+1)));
-    max_vcs = SVAL(inbuf,smb_vwv2+1); 
-    DEBUG(3,("max vcs %d\n",max_vcs));
+    opt.max_vcs = SVAL(inbuf,smb_vwv2+1); 
+    DEBUG(3,("max vcs %d\n",opt.max_vcs));
     DEBUG(3,("max raw %d\n",IVAL(inbuf,smb_vwv5+1)));
     DEBUG(3,("capabilities 0x%x\n",IVAL(inbuf,smb_vwv9+1)));
   }
@@ -556,7 +566,7 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
   DEBUG(3,("Got %d byte crypt key\n",crypt_len));
   DEBUG(3,("Chose protocol [%s]\n",prots[SVAL(inbuf,smb_vwv0)].name));
 
-  doencrypt = ((sec_mode & 2) != 0);
+  doencrypt = ((opt.sec_mode & 2) != 0);
 
   if (servertime) {
     static BOOL done_time = False;
@@ -575,6 +585,8 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
   else
     pass = (char *)getpass("Password: ");
 
+  pstrcpy(smb_login_passwd, pass);
+
   /* use a blank username for the 2nd try with a blank password */
   if (tries++ && !*pass)
     *username = 0;
@@ -592,7 +604,7 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
       }
 
       /* if in share level security then don't send a password now */
-      if (!(sec_mode & 1)) {strcpy(pword, "");passlen=1;} 
+      if (!(opt.sec_mode & 1)) {strcpy(pword, "");passlen=1;} 
 
       /* send a session setup command */
       bzero(outbuf,smb_size);
@@ -605,8 +617,8 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
        CVAL(outbuf,smb_vwv0) = 0xFF;
        SSVAL(outbuf,smb_vwv2,max_xmit);
        SSVAL(outbuf,smb_vwv3,2);
-       SSVAL(outbuf,smb_vwv4,max_vcs-1);
-       SIVAL(outbuf,smb_vwv5,sesskey);
+       SSVAL(outbuf,smb_vwv4,opt.max_vcs-1);
+       SIVAL(outbuf,smb_vwv5,opt.sesskey);
        SSVAL(outbuf,smb_vwv7,passlen);
        p = smb_buf(outbuf);
        memcpy(p,pword,passlen);
@@ -623,7 +635,7 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
        SSVAL(outbuf,smb_vwv2,BUFFER_SIZE);
        SSVAL(outbuf,smb_vwv3,2);
        SSVAL(outbuf,smb_vwv4,getpid());
-       SIVAL(outbuf,smb_vwv5,sesskey);
+       SIVAL(outbuf,smb_vwv5,opt.sesskey);
        SSVAL(outbuf,smb_vwv7,passlen);
        SSVAL(outbuf,smb_vwv8,0);
        p = smb_buf(outbuf);
@@ -636,7 +648,7 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
       }
 
       send_smb(Client,outbuf);
-      receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+      client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
 
       show_msg(inbuf);
 
@@ -650,7 +662,8 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
            {
              got_pass = False;
              DEBUG(3,("resending login\n"));
-             goto get_pass;
+             if (! no_pass)
+                 goto get_pass;
            }
              
          DEBUG(0,("Session setup failed for username=%s myname=%s destname=%s   %s\n",
@@ -680,10 +693,10 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
       if (SVAL(inbuf,smb_uid) != uid)
        DEBUG(3,("Server gave us a UID of %d. We gave %d\n",
              SVAL(inbuf,smb_uid),uid));
-      uid = SVAL(inbuf,smb_uid);
+      opt.server_uid = uid = SVAL(inbuf,smb_uid);
     }
 
-  if (sec_mode & 1) {
+  if (opt.sec_mode & 1) {
          if (SVAL(inbuf, smb_vwv2) & 1)
                  DEBUG(1,("connected as guest "));
          DEBUG(1,("security=user\n"));
@@ -714,7 +727,7 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
     }
 
     /* if in user level security then don't send a password now */
-    if ((sec_mode & 1)) {
+    if ((opt.sec_mode & 1)) {
       strcpy(pword, ""); passlen=1; 
     }
 
@@ -751,7 +764,7 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
   }
 
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+  client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
 
   /* trying again with a blank password */
   if (CVAL(inbuf,smb_rcls) != 0 && 
@@ -790,6 +803,8 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
 
     cnum = SVAL(inbuf,smb_tid);
   }
+  opt.max_xmit = max_xmit;
+  opt.tid = cnum;
 
   DEBUG(3,("Connected with cnum=%d max_xmit=%d\n",cnum,max_xmit));
 
@@ -799,6 +814,11 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
       free(outbuf);
     }
 
+  if (options != NULL)
+    {
+      *options = opt;
+    }
+
   return True;
 }
 
@@ -819,7 +839,7 @@ void cli_send_logout(void )
   cli_setup_pkt(outbuf);
 
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,SHORT_TIMEOUT);
+  client_receive_smb(Client,inbuf,SHORT_TIMEOUT);
 
   if (CVAL(inbuf,smb_rcls) != 0)
     {
@@ -885,15 +905,18 @@ BOOL cli_open_sockets(int port )
       {
 #ifdef USENMB
        /* Try and resolve the name with the netbios server */
-       int             bcast;
+       int             bcast, count;
+       struct in_addr *ip_list;
 
        if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3,
                                    interpret_addr(lp_socket_address()))) != -1) {
          set_socket_options(bcast, "SO_BROADCAST");
 
-         if (name_query(bcast, host, name_type, True, True, *iface_bcast(dest_ip),
-                        &dest_ip,0)) {
-           failed = False;
+         if ((ip_list = name_query(bcast, host, name_type, True, True, *iface_bcast(dest_ip),
+                                   &count,0)) != NULL) {
+                 dest_ip = ip_list[0];
+                 free(ip_list);
+                 failed = False;
          }
          close (bcast);
        }
@@ -935,165 +958,11 @@ BOOL cli_reopen_connection(char *inbuf,char *outbuf)
   cli_setup_pkt(outbuf);
 
   send_smb(Client,outbuf);
-  receive_smb(Client,inbuf,SHORT_TIMEOUT);
+  client_receive_smb(Client,inbuf,SHORT_TIMEOUT);
 
   close_sockets();
   if (!cli_open_sockets(0)) return(False);
 
-  return(cli_send_login(inbuf,outbuf,True,True));
+  return(cli_send_login(inbuf,outbuf,True,True,NULL));
 }
 
-/* error code stuff - put together by Merik Karman
-   merik@blackadder.dsh.oz.au */
-
-typedef struct
-{
-  char *name;
-  int code;
-  char *message;
-} err_code_struct;
-
-/* Dos Error Messages */
-err_code_struct dos_msgs[] = {
-  {"ERRbadfunc",1,"Invalid function."},
-  {"ERRbadfile",2,"File not found."},
-  {"ERRbadpath",3,"Directory invalid."},
-  {"ERRnofids",4,"No file descriptors available"},
-  {"ERRnoaccess",5,"Access denied."},
-  {"ERRbadfid",6,"Invalid file handle."},
-  {"ERRbadmcb",7,"Memory control blocks destroyed."},
-  {"ERRnomem",8,"Insufficient server memory to perform the requested function."},
-  {"ERRbadmem",9,"Invalid memory block address."},
-  {"ERRbadenv",10,"Invalid environment."},
-  {"ERRbadformat",11,"Invalid format."},
-  {"ERRbadaccess",12,"Invalid open mode."},
-  {"ERRbaddata",13,"Invalid data."},
-  {"ERR",14,"reserved."},
-  {"ERRbaddrive",15,"Invalid drive specified."},
-  {"ERRremcd",16,"A Delete Directory request attempted  to  remove  the  server's  current directory."},
-  {"ERRdiffdevice",17,"Not same device."},
-  {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."},
-  {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing  FIDs  on the file."},
-  {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an  invalid mode,  or an Unlock requested attempted to remove a lock held by another process."},
-  {"ERRnosuchshare", 67, "You specified an invalid share name"},
-  {"ERRfilexists",80,"The file named in a Create Directory, Make  New  File  or  Link  request already exists."},
-  {"ERRbadpipe",230,"Pipe invalid."},
-  {"ERRpipebusy",231,"All instances of the requested pipe are busy."},
-  {"ERRpipeclosing",232,"Pipe close in progress."},
-  {"ERRnotconnected",233,"No process on other end of pipe."},
-  {"ERRmoredata",234,"There is more data to be returned."},
-  {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"},
-  {NULL,-1,NULL}};
-
-/* Server Error Messages */
-err_code_struct server_msgs[] = {
-  {"ERRerror",1,"Non-specific error code."},
-  {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."},
-  {"ERRbadtype",3,"reserved."},
-  {"ERRaccess",4,"The requester does not have  the  necessary  access  rights  within  the specified  context for the requested function. The context is defined by the TID or the UID."},
-  {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."},
-  {"ERRinvnetname",6,"Invalid network name in tree connect."},
-  {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or  non-printer request made to printer connection."},
-  {"ERRqfull",49,"Print queue full (files) -- returned by open print file."},
-  {"ERRqtoobig",50,"Print queue full -- no space."},
-  {"ERRqeof",51,"EOF on print queue dump."},
-  {"ERRinvpfid",52,"Invalid print file FID."},
-  {"ERRsmbcmd",64,"The server did not recognize the command received."},
-  {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."},
-  {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid  combination of values."},
-  {"ERRreserved",68,"reserved."},
-  {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination.  The server cannot set the requested attribute."},
-  {"ERRreserved",70,"reserved."},
-  {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."},
-  {"ERRpaused",81,"Server is paused."},
-  {"ERRmsgoff",82,"Not receiving messages."},
-  {"ERRnoroom",83,"No room to buffer message."},
-  {"ERRrmuns",87,"Too many remote user names."},
-  {"ERRtimeout",88,"Operation timed out."},
-  {"ERRnoresource",89,"No resources currently available for request."},
-  {"ERRtoomanyuids",90,"Too many UIDs active on this session."},
-  {"ERRbaduid",91,"The UID is not known as a valid ID on this session."},
-  {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."},
-  {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."},
-  {"ERRcontmpx",252,"Continue in MPX mode."},
-  {"ERRreserved",253,"reserved."},
-  {"ERRreserved",254,"reserved."},
-  {"ERRnosupport",0xFFFF,"Function not supported."},
-  {NULL,-1,NULL}};
-
-/* Hard Error Messages */
-err_code_struct hard_msgs[] = {
-  {"ERRnowrite",19,"Attempt to write on write-protected diskette."},
-  {"ERRbadunit",20,"Unknown unit."},
-  {"ERRnotready",21,"Drive not ready."},
-  {"ERRbadcmd",22,"Unknown command."},
-  {"ERRdata",23,"Data error (CRC)."},
-  {"ERRbadreq",24,"Bad request structure length."},
-  {"ERRseek",25 ,"Seek error."},
-  {"ERRbadmedia",26,"Unknown media type."},
-  {"ERRbadsector",27,"Sector not found."},
-  {"ERRnopaper",28,"Printer out of paper."},
-  {"ERRwrite",29,"Write fault."},
-  {"ERRread",30,"Read fault."},
-  {"ERRgeneral",31,"General failure."},
-  {"ERRbadshare",32,"An open conflicts with an existing open."},
-  {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."},
-  {"ERRwrongdisk",34,"The wrong disk was found in a drive."},
-  {"ERRFCBUnavail",35,"No FCBs are available to process request."},
-  {"ERRsharebufexc",36,"A sharing buffer has been exceeded."},
-  {NULL,-1,NULL}};
-
-
-struct
-{
-  int code;
-  char *class;
-  err_code_struct *err_msgs;
-} err_classes[] = { 
-  {0,"SUCCESS",NULL},
-  {0x01,"ERRDOS",dos_msgs},
-  {0x02,"ERRSRV",server_msgs},
-  {0x03,"ERRHRD",hard_msgs},
-  {0x04,"ERRXOS",NULL},
-  {0xE1,"ERRRMX1",NULL},
-  {0xE2,"ERRRMX2",NULL},
-  {0xE3,"ERRRMX3",NULL},
-  {0xFF,"ERRCMD",NULL},
-  {-1,NULL,NULL}};
-
-
-/****************************************************************************
-return a SMB error string from a SMB buffer
-****************************************************************************/
-char *smb_errstr(char *inbuf)
-{
-  static pstring ret;
-  int class = CVAL(inbuf,smb_rcls);
-  int num = SVAL(inbuf,smb_err);
-  int i,j;
-
-  for (i=0;err_classes[i].class;i++)
-    if (err_classes[i].code == class)
-      {
-       if (err_classes[i].err_msgs)
-         {
-           err_code_struct *err = err_classes[i].err_msgs;
-           for (j=0;err[j].name;j++)
-             if (num == err[j].code)
-               {
-                 if (DEBUGLEVEL > 0)
-                   sprintf(ret,"%s - %s (%s)",err_classes[i].class,
-                           err[j].name,err[j].message);
-                 else
-                   sprintf(ret,"%s - %s",err_classes[i].class,err[j].name);
-                 return ret;
-               }
-         }
-
-       sprintf(ret,"%s - %d",err_classes[i].class,num);
-       return ret;
-      }
-  
-  sprintf(ret,"Error: Unknown error (%d,%d)",class,num);
-  return(ret);
-}