Exemple #1
0
/*
 * fchmod stub, ignore S_ISUID and/or S_ISGID on EPERM,
 * mandated for conformance.
 *
 * This is for UNIX03 only.
 */
int
fchmod(int fd, mode_t mode)
{
	int res = __fchmod(fd, mode);

	if (res >= 0 || errno != EPERM || (mode & (S_ISUID | S_ISGID)) == 0)
		return res;
	if (mode & S_ISGID) {
		res = __fchmod(fd, mode ^ S_ISGID);
		if (res >= 0 || errno != EPERM)
			return res;
	}
	if (mode & S_ISUID) {
		res = __fchmod(fd, mode ^ S_ISUID);
		if (res >= 0 || errno != EPERM)
			return res;
	}
	if ((mode & (S_ISUID | S_ISGID)) == (S_ISUID | S_ISGID))
		res = __fchmod(fd, mode ^ (S_ISUID | S_ISGID));
	return res;
}
Exemple #2
0
/* Provide operations to control over shared memory segments.  */
int
__shmctl (int id, int cmd, struct shmid_ds *buf)
{
  error_t err = 0;
  int fd;
  int res;
  char filename[sizeof (SHM_DIR) - 1 + SHM_NAMEMAX];
  struct stat statbuf;

  sprintf (filename, SHM_DIR SHM_NAMEPRI, id);
  /* SysV requires read access for IPC_STAT.  */
  fd = __open (filename, O_NORW);
  if (fd < 0)
    {
      if (errno == ENOENT)
	errno = EINVAL;
      return -1;
    }

  res = __fstat (fd, &statbuf);
  if (res < 0)
    {
      err = errno;
      __close (fd);
      errno = err;
      return -1;
    }
  
  switch (cmd)
    {
    case IPC_STAT:

      buf->shm_perm.__key = id;
      buf->shm_perm.uid = statbuf.st_uid;
      buf->shm_perm.gid = statbuf.st_gid;

      /* We do not support the creator.  */
      buf->shm_perm.cuid = statbuf.st_uid;
      buf->shm_perm.cgid = statbuf.st_gid;

      /* We just want the protection bits.  */
      buf->shm_perm.mode = statbuf.st_mode & 0777;
      /* Hopeless.  We do not support a sequence number.  */
      buf->shm_perm.__seq = statbuf.st_ino;
      buf->shm_segsz = statbuf.st_size;

      /* Hopeless.  We do not support any of these.  */
      buf->shm_atime = statbuf.st_atime;
      buf->shm_dtime = statbuf.st_mtime;
      /* Well, this comes at least close.  */
      buf->shm_ctime = statbuf.st_ctime;

      /* We do not support the PID.  */
      buf->shm_cpid = 0;
      buf->shm_lpid = 0;

      if (statbuf.st_mode & S_IMMAP0)
        buf->shm_nattch = 0;
      else
        /* 42 is the answer.  Of course this is bogus, but for most
	   applications, this should be fine.  */
        buf->shm_nattch = 42;

      break;

    case IPC_SET:
      if (statbuf.st_uid != buf->shm_perm.uid
	  || statbuf.st_gid != buf->shm_perm.gid)
	{
	  res = __fchown (fd,
			  (statbuf.st_uid != buf->shm_perm.uid)
			  ? buf->shm_perm.uid : -1,
			  (statbuf.st_gid != buf->shm_perm.gid)
			  ? buf->shm_perm.gid : -1);
	  if (res < 0)
	    err = errno;
	}

      if (!err && statbuf.st_mode & 0777 != buf->shm_perm.mode & 0777)
	{
	  res = __fchmod (fd, (statbuf.st_mode & ~0777)
			  | (buf->shm_perm.mode & 0777));
	  if (res < 0)
	    err = errno;
	}
      break;

    case IPC_RMID:
      res = __unlink (filename);
      /* FIXME: Check error (mapping ENOENT to EINVAL).  */
      break;

    default:
      err = EINVAL;
    }

  __close (fd);
  errno = err;
  return err ? -1 : 0;
}
Exemple #3
0
int
fchmod(int filedes, mode_t mode)
{
	_gfs_hook_debug_v(fputs("Hooking fchmod\n", stderr));
	return (__fchmod(filedes, mode));
}