Exemplo n.º 1
0
/*===========================================================================*
 *				do_unlink				     *
 *===========================================================================*/
int do_unlink()
{
/* Perform the unlink(name) or rmdir(name) system call. The code for these two
 * is almost the same.  They differ only in some condition testing.  Unlink()
 * may be used by the superuser to do dangerous things; rmdir() may not.
 */
  register struct fproc *rfp;
  struct vnode *vldirp, *vp;
  int r;
  
  /* Get the last directory in the path. */
  if (fetch_name(user_fullpath, PATH_MAX, m_in.name) < 0) return(err_code);
  if ((vldirp = last_dir()) == NIL_VNODE) return(err_code);

  /* Make sure that the object is a directory */
  if((vldirp->v_mode & I_TYPE) != I_DIRECTORY) {
	  put_vnode(vldirp);
	  return(-ENOTDIR);
  }

  /* The caller must have both search and execute permission */
  if ((r = forbidden(vldirp, X_BIT | W_BIT)) != 0) {
	put_vnode(vldirp);
	return(r);
  }
  
  /* Also, if the sticky bit is set, only the owner of the file or a privileged
     user is allowed to unlink */
  if ((vldirp->v_mode & S_ISVTX) == S_ISVTX) {
	/* Look up inode of file to unlink to retrieve owner */
	vp = advance(vldirp, PATH_RET_SYMLINK);
	if (vp != NIL_VNODE) {
		if(vp->v_uid != fp->fp_effuid && fp->fp_effuid != SU_UID) 
			r = -EPERM;
  put_vnode(vp);
	} else
		r = err_code;
	if (r != 0) {
		put_vnode(vldirp);
		return(r);
	}
  }

  if(call_nr == __NR_unlink) 
	  r = req_unlink(vldirp->v_fs_e, vldirp->v_inode_nr, user_fullpath);
  else 
	  r = req_rmdir(vldirp->v_fs_e, vldirp->v_inode_nr, user_fullpath);
  
  put_vnode(vldirp);
  return(r);
}
Exemplo n.º 2
0
/*===========================================================================*
 *				do_unlink				     *
 *===========================================================================*/
int do_unlink()
{
/* Perform the unlink(name) or rmdir(name) system call. The code for these two
 * is almost the same.  They differ only in some condition testing.  Unlink()
 * may be used by the superuser to do dangerous things; rmdir() may not.
 * The syscall might provide 'name' embedded in the message.
 */
  struct vnode *dirp, *dirp_l, *vp;
  struct vmnt *vmp, *vmp2;
  int r;
  char fullpath[PATH_MAX];
  struct lookup resolve, stickycheck;
  vir_bytes vname;
  size_t vname_length;

  vname = (vir_bytes) job_m_in.name;
  vname_length = job_m_in.name_length;
  if (copy_name(vname_length, fullpath) != OK) {
	/* Direct copy failed, try fetching from user space */
	if (fetch_name(vname, vname_length, fullpath) != OK)
		/* CSC2025 Mod Start */
		logfserr_nopath(FSOP_UNLNK, err_code);
		/* CSC2025 Mod End */
		return(err_code);
  }

  lookup_init(&resolve, fullpath, PATH_RET_SYMLINK, &vmp, &dirp_l);
  resolve.l_vmnt_lock = VMNT_WRITE;
  resolve.l_vnode_lock = VNODE_WRITE;

  /* Get the last directory in the path. */
  if ((dirp = last_dir(&resolve, fp)) == NULL){
	  /* CSC2025 Mod Start */
	  logfserr_nopath(FSOP_UNLNK, err_code);
	  /* CSC2025 Mod End */
	  return(err_code)
  };

  /* Make sure that the object is a directory */
  if (!S_ISDIR(dirp->v_mode)) {
	unlock_vnode(dirp);
	unlock_vmnt(vmp);
	put_vnode(dirp);
	/* CSC2025 Mod Start */
	logfserr_nopath(FSOP_UNLNK, ENOTDIR);
	/* CSC2025 Mod End */
	return(ENOTDIR);
  }

  /* The caller must have both search and execute permission */
  if ((r = forbidden(fp, dirp, X_BIT | W_BIT)) != OK) {
	unlock_vnode(dirp);
	unlock_vmnt(vmp);
	put_vnode(dirp);
	/* CSC2025 Mod Start */
	logfserr(FSOP_UNLNK, r, fullpath);
	/* CSC2025 Mod End */
	return(r);
  }

  /* Also, if the sticky bit is set, only the owner of the file or a privileged
     user is allowed to unlink */
  if ((dirp->v_mode & S_ISVTX) == S_ISVTX) {
	/* Look up inode of file to unlink to retrieve owner */
	lookup_init(&stickycheck, resolve.l_path, PATH_RET_SYMLINK, &vmp2, &vp);
	stickycheck.l_vmnt_lock = VMNT_READ;
	stickycheck.l_vnode_lock = VNODE_READ;
	vp = advance(dirp, &stickycheck, fp);
	assert(vmp2 == NULL);
	if (vp != NULL) {
		if (vp->v_uid != fp->fp_effuid && fp->fp_effuid != SU_UID)
			r = EPERM;
		unlock_vnode(vp);
		put_vnode(vp);
	} else
		r = err_code;
	if (r != OK) {
		unlock_vnode(dirp);
		unlock_vmnt(vmp);
		put_vnode(dirp);
		/* CSC2025 Mod Start */
		logfserr(FSOP_UNLNK, r, fullpath);
		/* CSC2025 Mod End */
		return(r);
	}
  }

  upgrade_vmnt_lock(vmp);

  if (job_call_nr == UNLINK)
	  r = req_unlink(dirp->v_fs_e, dirp->v_inode_nr, fullpath);
  else
	  r = req_rmdir(dirp->v_fs_e, dirp->v_inode_nr, fullpath);
  unlock_vnode(dirp);
  unlock_vmnt(vmp);
  put_vnode(dirp);
  /* CSC2025 Mod Start */
  if(r == OK){
	  logfsop(FSOP_UNLNK, r, fullpath, scratch(fp).file.fd_nr, vp->v_mode, vp->v_uid, vp->v_gid, vp->v_size};
  } else {