Example #1
0
  def chown(self, path, newuid, newgid):
    '''
    Change the owner and/or group of a file.

    Returns:
      True on successful change, otherwise errno code is returned.
    '''

    self._debug('opcode: chown | path: %s | uid: %d | gid: %d' %
               (path, newuid, newgid))

    context = self.GetContext()
    file_stat = tsumufs.getManager(path).statFile(path)

    if context['uid'] != 0:
      if newuid != -1 and context['uid'] != newuid:
        raise OSError(errno.EPERM, os.strerror(errno.EPERM))

      if (file_stat.st_uid != context['uid']) and (newgid != -1):
        if newgid not in tsumufs.getGidsForUid(context['uid']):
          raise OSError(errno.EPERM, os.strerror(errno.EPERM))

    try:
      if tsumufs.getManager(path).chown(path, newuid, newgid):
        tsumufs.syncLog.addMetadataChange(path, uid=True, gid=True)

      return 0
    except OSError, e:
      self._debug('chown: Caught OSError: errno %d: %s'
                  % (e.errno, e.strerror))
      return -e.errno
Example #2
0
  def access(self, uid, fusepath, mode):
    '''
    Test for access to a path.

    Returns:
      True upon successful check, otherwise False. Don't alter _recurse. That's
      used internally.

    Raises:
      OSError upon access problems.
    '''

    self.lockFile(fusepath)

    try:
      opcodes = self._genCacheOpcodes(fusepath)
      self._validateCache(fusepath, opcodes)
      realpath = self._generatePath(fusepath, opcodes)

      if 'use-nfs' in opcodes:
        logger.debug('Using nfs for access')
        return os.access(realpath, mode)

      # TODO(cleanup): make the above chunk of code into a decorator for crying
      # out loud. We do this in every public method and it adds confusion. =o(

      # Root owns everything
      if uid == 0:
        logger.debug('Root -- returning 0')
        return 0

      # Recursively go down the path from longest to shortest, checking access
      # perms on each directory as we go down.
      if fusepath != '/':
        self.access(uid,
                    os.path.dirname(fusepath),
                    os.X_OK)

      file_stat = self.statFile(fusepath)

      mode_string = ''
      if mode & os.R_OK:
        mode_string += 'R_OK|'
      if mode & os.W_OK:
        mode_string += 'W_OK|'
      if mode & os.X_OK:
        mode_string += 'X_OK|'
      if mode == os.F_OK:
        mode_string = 'F_OK|'
      mode_string = mode_string[:-1]

      logger.debug('access(%s, %s) -> (uid, gid, mode) = (%d, %d, %o)' %
                  (repr(fusepath), mode_string,
                   file_stat.st_uid, file_stat.st_gid, file_stat.st_mode))

      # Catch the case where the user only wants to check if the file exists.
      if mode == os.F_OK:
        logger.debug('User just wanted to verify %s existed -- returning 0.' %
                    fusepath)
        return 0

      # Check user bits first
      if uid == file_stat.st_uid:
        if ((file_stat.st_mode & stat.S_IRWXU) >> 6) & mode:
          logger.debug('Allowing for user bits.')
          return 0

      # Then group bits
      if file_stat.st_gid in tsumufs.getGidsForUid(uid):
        if ((file_stat.st_mode & stat.S_IRWXG) >> 3) & mode:
          logger.debug('Allowing for group bits.')
          return 0

      # Finally assume other bits
      if (file_stat.st_mode & stat.S_IRWXO) & mode:
        logger.debug('Allowing for other bits.')
        return 0

      logger.debug('No access allowed.')
      raise OSError(errno.EACCES, os.strerror(errno.EACCES))

    finally:
      self.unlockFile(fusepath)