diff options
| -rw-r--r-- | source3/smbd/trans2.c | 324 | 
1 files changed, 145 insertions, 179 deletions
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 714d42ce2a..22a7378ed9 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -199,8 +199,6 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,    int16 open_ofun = SVAL(params,12);    int32 open_size = IVAL(params,14);    char *pname = ¶ms[28]; -  int16 namelen = strlen(pname)+1; -    pstring fname;    mode_t unixmode;    SMB_OFF_T size=0; @@ -211,7 +209,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,    BOOL bad_path = False;    files_struct *fsp; -  StrnCpy(fname,pname,namelen); +  srvstr_pull(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE);    DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n",  	   fname,open_mode, open_attr, open_ofun, open_size)); @@ -709,11 +707,6 @@ static int call_trans2findfirst(connection_struct *conn,    srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE); -  DEBUG(0,("path=%s params=%p inbuf=%p params[0]=%c params[1]=%d params[2]=%c params[3]=%d\n", -	   directory, -	   params, inbuf, -	   params[12], params[13], params[14], params[15])); -    RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf);    unix_convert(directory,conn,0,&bad_path,&sbuf); @@ -1146,7 +1139,7 @@ static int call_trans2qfsinfo(connection_struct *conn,    char *pdata = *ppdata;    char *params = *pparams;    uint16 info_level = SVAL(params,0); -  int data_len; +  int data_len, len;    SMB_STRUCT_STAT st;    char *vname = volume_label(SNUM(conn));    int snum = SNUM(conn); @@ -1184,72 +1177,49 @@ static int call_trans2qfsinfo(connection_struct *conn,        break;      }      case 2: -    {  -      /* Return volume name */ -      int volname_len = MIN(strlen(vname),11); -      data_len = l2_vol_szVolLabel + volname_len + 1; -      /*  -       * Add volume serial number - hash of a combination of -       * the called hostname and the service name. -       */ -      SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) ); -      SCVAL(pdata,l2_vol_cch,volname_len); -      StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len); -      DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n", -	       (unsigned)st.st_ctime, volname_len, -	       pdata+l2_vol_szVolLabel)); -      break; -    } +	    /* Return volume name */ +	    /*  +	     * Add volume serial number - hash of a combination of +	     * the called hostname and the service name. +	     */ +	    SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) ); +	    len = srvstr_push(outbuf, pdata+l2_vol_szVolLabel, vname, -1,  +			      STR_TERMINATE|STR_CONVERT); +	    SCVAL(pdata,l2_vol_cch,len); +	    data_len = l2_vol_szVolLabel + len; +	    DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n", +		     (unsigned)st.st_ctime, len, vname)); +	    break; +      case SMB_QUERY_FS_ATTRIBUTE_INFO: -    { -      int fstype_len; -      SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH| -			FILE_DEVICE_IS_MOUNTED| -            (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */ -#if 0 /* Old code. JRA. */ -      SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */ -#endif /* Old code. */ - -      SIVAL(pdata,4,128); /* Max filename component length */ -      fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring), False); -      SIVAL(pdata,8,fstype_len); -      data_len = 12 + fstype_len; -      SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS); -      break; -    } +	    SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH| +		  FILE_DEVICE_IS_MOUNTED| +		  (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */ +	    SIVAL(pdata,4,128); /* Max filename component length */ +	    len = srvstr_push(outbuf, pdata+12, fstype, -1, STR_TERMINATE|STR_CONVERT); +	    SIVAL(pdata,8,len); +	    data_len = 12 + len; +	    break; +      case SMB_QUERY_FS_LABEL_INFO: -      data_len = 4 + strlen(vname); -      SIVAL(pdata,0,strlen(vname)); -      pstrcpy(pdata+4,vname);       -      break; +	    len = srvstr_push(outbuf, pdata+4, vname, -1, STR_TERMINATE|STR_CONVERT); +	    data_len = 4 + len; +	    SIVAL(pdata,0,len); +	    break;      case SMB_QUERY_FS_VOLUME_INFO:       - -      /*  -       * Add volume serial number - hash of a combination of -       * the called hostname and the service name. -       */ -      SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^  -	    (str_checksum(local_machine)<<16)); - -      /* NT4 always serves this up as unicode but expects it to be -       * delivered as ascii! (tridge && JRA) -       */ -      if ((get_remote_arch() != RA_WIN2K) && (global_client_caps & CAP_NT_SMBS)) { -	      data_len = 18 + strlen(vname); -	      SIVAL(pdata,12,strlen(vname)); -	      pstrcpy(pdata+18,vname);       -      } else { -          int vnamelen; - -          vnamelen = dos_PutUniCode(pdata+18, vname, sizeof(pstring), False); -	      data_len = 18 + vnamelen; -	      SIVAL(pdata,12,vnamelen); -	      SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS); -      } - -      DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",  -	       (int)strlen(vname),vname)); -      break; +	    /*  +	     * Add volume serial number - hash of a combination of +	     * the called hostname and the service name. +	     */ +	    SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^  +		  (str_checksum(local_machine)<<16)); + +	    len = srvstr_push(outbuf, pdata+18, vname, -1, STR_TERMINATE|STR_CONVERT); +	    SIVAL(pdata,12,len); +	    data_len = 18+len; +	    DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",  +		     (int)strlen(vname),vname)); +	    break;      case SMB_QUERY_FS_SIZE_INFO:      {        SMB_BIG_UINT dfree,dsize,bsize; @@ -1277,8 +1247,8 @@ static int call_trans2qfsinfo(connection_struct *conn,  		    break;  	    }  	    /* drop through */ -    default: -      return(ERROR(ERRDOS,ERRunknownlevel)); +  default: +	  return(ERROR(ERRDOS,ERRunknownlevel));    } @@ -1331,80 +1301,79 @@ static int call_trans2qfilepathinfo(connection_struct *conn,    SMB_OFF_T size=0;    unsigned int data_size;    SMB_STRUCT_STAT sbuf; -  pstring fname1; -  char *fname; +  pstring fname; +  char *base_name;    char *p; -  int l;    SMB_OFF_T pos = 0;    BOOL bad_path = False;    BOOL delete_pending = False; +  int len;    if (tran_call == TRANSACT2_QFILEINFO) { -    files_struct *fsp = file_fsp(params,0); -    info_level = SVAL(params,2); - -    DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level)); - -    if(fsp && (fsp->is_directory || fsp->stat_open)) { -      /* -       * This is actually a QFILEINFO on a directory -       * handle (returned from an NT SMB). NT5.0 seems -       * to do this call. JRA. -       */ -      fname = fsp->fsp_name; -      unix_convert(fname,conn,0,&bad_path,&sbuf); -      if (!check_name(fname,conn) ||  -          (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) { -        DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno))); -        if((errno == ENOENT) && bad_path) -        { -          unix_ERR_class = ERRDOS; -          unix_ERR_code = ERRbadpath; -        } -        return(UNIXERROR(ERRDOS,ERRbadpath)); -      } - -      delete_pending = fsp->directory_delete_on_close; - -    } else { -      /* -       * Original code - this is an open file. -       */ -      CHECK_FSP(fsp,conn); -      CHECK_ERROR(fsp); - -      fname = fsp->fsp_name; -      if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) { -        DEBUG(3,("fstat of fnum %d failed (%s)\n",fsp->fnum, strerror(errno))); -        return(UNIXERROR(ERRDOS,ERRbadfid)); -      } -      if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1) -        return(UNIXERROR(ERRDOS,ERRnoaccess)); - -      delete_pending = fsp->delete_on_close; -    } +	  files_struct *fsp = file_fsp(params,0); +	  info_level = SVAL(params,2); + +	  DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n",  +		   info_level)); + +	  if(fsp && (fsp->is_directory || fsp->stat_open)) { +		  /* +		   * This is actually a QFILEINFO on a directory +		   * handle (returned from an NT SMB). NT5.0 seems +		   * to do this call. JRA. +		   */ +		  pstrcpy(fname, fsp->fsp_name); +		  unix_convert(fname,conn,0,&bad_path,&sbuf); +		  if (!check_name(fname,conn) ||  +		      (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) { +			  DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno))); +			  if((errno == ENOENT) && bad_path) { +				  unix_ERR_class = ERRDOS; +				  unix_ERR_code = ERRbadpath; +			  } +			  return(UNIXERROR(ERRDOS,ERRbadpath)); +		  } +		   +		  delete_pending = fsp->directory_delete_on_close; +	  } else { +		  /* +		   * Original code - this is an open file. +		   */ +		  CHECK_FSP(fsp,conn); +		  CHECK_ERROR(fsp); + +		  pstrcpy(fname, fsp->fsp_name); +		  if (vfs_fstat(fsp,fsp->fd,&sbuf) != 0) { +			  DEBUG(3,("fstat of fnum %d failed (%s)\n", +				   fsp->fnum, strerror(errno))); +			  return(UNIXERROR(ERRDOS,ERRbadfid)); +		  } +		  if((pos = fsp->conn->vfs_ops.lseek(fsp,fsp->fd,0,SEEK_CUR)) == -1) +			  return(UNIXERROR(ERRDOS,ERRnoaccess)); + +		  delete_pending = fsp->delete_on_close; +	  }    } else { -    /* qpathinfo */ -    info_level = SVAL(params,0); +	  /* qpathinfo */ +	  info_level = SVAL(params,0); -    DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level)); +	  DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n",  +		   info_level)); -    fname = &fname1[0]; -    pstrcpy(fname,¶ms[6]); +	  srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE); -    RESOLVE_DFSPATH(fname, conn, inbuf, outbuf); +	  RESOLVE_DFSPATH(fname, conn, inbuf, outbuf); -    unix_convert(fname,conn,0,&bad_path,&sbuf); -    if (!check_name(fname,conn) ||  -        (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) { -      DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno))); -      if((errno == ENOENT) && bad_path) -      { -        unix_ERR_class = ERRDOS; -        unix_ERR_code = ERRbadpath; -      } -      return(UNIXERROR(ERRDOS,ERRbadpath)); -    } +	  unix_convert(fname,conn,0,&bad_path,&sbuf); +	  if (!check_name(fname,conn) ||  +	      (!VALID_STAT(sbuf) && vfs_stat(conn,fname,&sbuf))) { +		  DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno))); +		  if((errno == ENOENT) && bad_path) { +			  unix_ERR_class = ERRDOS; +			  unix_ERR_code = ERRbadpath; +		  } +		  return(UNIXERROR(ERRDOS,ERRbadpath)); +	  }    } @@ -1412,21 +1381,19 @@ static int call_trans2qfilepathinfo(connection_struct *conn,  	   fname,info_level,tran_call,total_data));    p = strrchr(fname,'/');  -  if (!p)  -    p = fname; -  else -    p++; -  l = strlen(p);   +  if (!p) { +	  base_name = fname; +  } else { +	  base_name = p+1; +  } +    mode = dos_mode(conn,fname,&sbuf);    size = sbuf.st_size;    if (mode & aDIR) size = 0; -  /* from now on we only want the part after the / */ -  fname = p; -      params = Realloc(*pparams,2); -  if ( params == NULL ) { -    return(ERROR(ERRDOS,ERRnomem)); +  if (params == NULL) { +	  return(ERROR(ERRDOS,ERRnomem));    }    *pparams	= params;    memset((char *)params,'\0',2); @@ -1435,7 +1402,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,    if ( pdata == NULL ) {      return(ERROR(ERRDOS,ERRnomem));    } -  *ppdata	= pdata; +  *ppdata = pdata;    if (total_data > 0 && IVAL(pdata,0) == total_data) {      /* uggh, EAs for OS2 */ @@ -1514,43 +1481,42 @@ static int call_trans2qfilepathinfo(connection_struct *conn,      case SMB_QUERY_FILE_ALT_NAME_INFO:        {          pstring short_name; -        pstrcpy(short_name,p); + +        pstrcpy(short_name,base_name);          /* Mangle if not already 8.3 */          if(!is_8_3(short_name, True))          {            if(!name_map_mangle(short_name,True,True,SNUM(conn)))              *short_name = '\0';          } -        strupper(short_name); -        l = dos_PutUniCode(pdata + 4, short_name, sizeof(pstring), False); -        data_size = 4 + l; -        SIVAL(pdata,0,l); +	len = srvstr_push(outbuf, pdata+4, short_name, -1,  +			  STR_TERMINATE|STR_CONVERT|STR_UPPER); +        data_size = 4 + len; +        SIVAL(pdata,0,len);        }        break;      case SMB_QUERY_FILE_NAME_INFO: -      /* -       * The first part of this code is essential -       * to get security descriptors to work on mapped -       * drives. Don't ask how I discovered this unless -       * you like hearing about me suffering.... :-). JRA. -       */ -      if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) { -        l = l*2; -        SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS); -        dos_PutUniCode(pdata + 4, "\\",sizeof(pstring), False); -      } else { -        pstrcpy(pdata+4,fname); -      } -      data_size = 4 + l; -      SIVAL(pdata,0,l); -      break; +	    /* +	     * The first part of this code is essential +	     * to get security descriptors to work on mapped +	     * drives. Don't ask how I discovered this unless +	     * you like hearing about me suffering.... :-). JRA. +	     */ +	    if(strequal(".", fname)) { +		    len = srvstr_push(outbuf, pdata+4, "\\", -1, STR_TERMINATE|STR_CONVERT); +	    } else { +		    len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE|STR_CONVERT); +	    } +	    data_size = 4 + len; +	    SIVAL(pdata,0,len); +	    break;      case SMB_QUERY_FILE_ALLOCATION_INFO:      case SMB_QUERY_FILE_END_OF_FILEINFO: -      data_size = 8; -      SOFF_T(pdata,0,size); -      break; +	    data_size = 8; +	    SOFF_T(pdata,0,size); +	    break;      case SMB_QUERY_FILE_ALL_INFO:        put_long_date(pdata,get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)))); @@ -1578,9 +1544,9 @@ static int call_trans2qfilepathinfo(connection_struct *conn,        SIVAL(pdata,0,mode); /* is this the right sort of mode info? */        pdata += 4;        pdata += 4; /* alignment */ -      SIVAL(pdata,0,l); -      pstrcpy(pdata+4,fname); -      pdata += 4 + l; +      len = srvstr_push(outbuf, pdata+4, fname, -1, STR_TERMINATE|STR_CONVERT); +      SIVAL(pdata,0,len); +      pdata += 4 + len;        data_size = PTR_DIFF(pdata,(*ppdata));        break; @@ -1588,12 +1554,12 @@ static int call_trans2qfilepathinfo(connection_struct *conn,        /* NT4 server just returns "invalid query" to this - if we try to answer   	 it then NTws gets a BSOD! (tridge) */      case SMB_QUERY_FILE_STREAM_INFO: -      data_size = 24 + l;        SIVAL(pdata,0,pos);        SIVAL(pdata,4,size);        SIVAL(pdata,12,size); -      SIVAL(pdata,20,l);	 -      pstrcpy(pdata+24,fname); +      len = srvstr_push(outbuf, pdata+24, fname, -1, STR_TERMINATE|STR_CONVERT); +      SIVAL(pdata,20,len); +      data_size = 24 + len;        break;  #endif @@ -1601,7 +1567,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,        return(ERROR(ERRDOS,ERRunknownlevel));      } -  send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size); +  send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size);    return(-1);  }  | 
