Beispiel #1
0
/*******************************************************************
chmod a file - but preserve some bits
********************************************************************/
int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *st)
{
  SMB_STRUCT_STAT st1;
  int mask=0;
  mode_t tmp;
  mode_t unixmode;

  if (!st) {
    st = &st1;
    if (dos_stat(fname,st)) return(-1);
  }

  if (S_ISDIR(st->st_mode)) dosmode |= aDIR;

  if (dos_mode(conn,fname,st) == dosmode) return(0);

  unixmode = unix_mode(conn,dosmode,fname);

  /* preserve the s bits */
  mask |= (S_ISUID | S_ISGID);

  /* preserve the t bit */
#ifdef S_ISVTX
  mask |= S_ISVTX;
#endif

  /* possibly preserve the x bits */
  if (!MAP_ARCHIVE(conn)) mask |= S_IXUSR;
  if (!MAP_SYSTEM(conn)) mask |= S_IXGRP;
  if (!MAP_HIDDEN(conn)) mask |= S_IXOTH;

  unixmode |= (st->st_mode & mask);

  /* if we previously had any r bits set then leave them alone */
  if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
    unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
    unixmode |= tmp;
  }

  /* if we previously had any w bits set then leave them alone 
   whilst adding in the new w bits, if the new mode is not rdonly */
  if (!IS_DOS_READONLY(dosmode)) {
    unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
  }

  return(dos_chmod(fname,unixmode));
}
Beispiel #2
0
/*******************************************************************
Wrapper around dos_utime that possibly allows DOS semantics rather
than POSIX.
*******************************************************************/
int file_utime(connection_struct *conn, char *fname, struct utimbuf *times)
{
  extern struct current_user current_user;
  SMB_STRUCT_STAT sb;
  int ret = -1;

  errno = 0;

  if(dos_utime(fname, times) == 0)
    return 0;

  if((errno != EPERM) && (errno != EACCES))
    return -1;

  if(!lp_dos_filetimes(SNUM(conn)))
    return -1;

  /* We have permission (given by the Samba admin) to
     break POSIX semantics and allow a user to change
     the time on a file they don't own but can write to
     (as DOS does).
   */

  if(dos_stat(fname,&sb) != 0)
    return -1;

  /* Check if we have write access. */
  if (CAN_WRITE(conn)) {
	  if (((sb.st_mode & S_IWOTH) ||
	       conn->admin_user ||
	       ((sb.st_mode & S_IWUSR) && current_user.uid==sb.st_uid) ||
	       ((sb.st_mode & S_IWGRP) &&
		in_group(sb.st_gid,current_user.gid,
			 current_user.ngroups,current_user.groups)))) {
		  /* We are allowed to become root and change the filetime. */
		  become_root(False);
		  ret = dos_utime(fname, times);
		  unbecome_root(False);
	  }
  }

  return ret;
}
Beispiel #3
0
char *dos_GetWd(char *path)
{
  pstring s;
  static BOOL getwd_cache_init = False;
  SMB_STRUCT_STAT st, st2;
  int i;

  *s = 0;

  if (!use_getwd_cache)
    return(dos_getwd(path));

  /* init the cache */
  if (!getwd_cache_init)
  {
    getwd_cache_init = True;
    for (i=0;i<MAX_GETWDCACHE;i++)
    {
      string_set(&ino_list[i].dos_path,"");
      ino_list[i].valid = False;
    }
  }

  /*  Get the inode of the current directory, if this doesn't work we're
      in trouble :-) */

  if (sys_stat(".",&st) == -1)
  {
    DEBUG(0,("Very strange, couldn't stat \".\" path=%s\n", path));
    return(dos_getwd(path));
  }


  for (i=0; i<MAX_GETWDCACHE; i++)
    if (ino_list[i].valid)
    {

      /*  If we have found an entry with a matching inode and dev number
          then find the inode number for the directory in the cached string.
          If this agrees with that returned by the stat for the current
          directory then all is o.k. (but make sure it is a directory all
          the same...) */

      if (st.st_ino == ino_list[i].inode &&
          st.st_dev == ino_list[i].dev)
      {
        if (dos_stat(ino_list[i].dos_path,&st2) == 0)
        {
          if (st.st_ino == st2.st_ino &&
              st.st_dev == st2.st_dev &&
              (st2.st_mode & S_IFMT) == S_IFDIR)
          {
            pstrcpy (path, ino_list[i].dos_path);

            /* promote it for future use */
            array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
            return (path);
          }
          else
          {
            /*  If the inode is different then something's changed,
                scrub the entry and start from scratch. */
            ino_list[i].valid = False;
          }
        }
      }
    }


  /*  We don't have the information to hand so rely on traditional methods.
      The very slow getcwd, which spawns a process on some systems, or the
      not quite so bad getwd. */

  if (!dos_getwd(s))
  {
    DEBUG(0,("dos_GetWd: dos_getwd call failed, errno %s\n",strerror(errno)));
    return (NULL);
  }

  pstrcpy(path,s);

  DEBUG(5,("dos_GetWd %s, inode %.0f, dev %.0f\n",s,(double)st.st_ino,(double)st.st_dev));

  /* add it to the cache */
  i = MAX_GETWDCACHE - 1;
  string_set(&ino_list[i].dos_path,s);
  ino_list[i].dev = st.st_dev;
  ino_list[i].inode = st.st_ino;
  ino_list[i].valid = True;

  /* put it at the top of the list */
  array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);

  return (path);
}
Beispiel #4
0
/****************************************************************************
  change a dos mode to a unix mode
    base permission for files:
         if inheriting
           apply read/write bits from parent directory.
         else   
           everybody gets read bit set
         dos readonly is represented in unix by removing everyone's write bit
         dos archive is represented in unix by the user's execute bit
         dos system is represented in unix by the group's execute bit
         dos hidden is represented in unix by the other's execute bit
         if !inheriting {
           Then apply create mask,
           then add force bits.
         }
    base permission for directories:
         dos directory is represented in unix by unix's dir bit and the exec bit
         if !inheriting {
           Then apply create mask,
           then add force bits.
         }
****************************************************************************/
mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname)
{
  mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
  mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */

  if ( !IS_DOS_READONLY(dosmode) )
    result |= (S_IWUSR | S_IWGRP | S_IWOTH);

  if (fname && lp_inherit_perms(SNUM(conn))) {
    char *dname;
    SMB_STRUCT_STAT sbuf;

    dname = parent_dirname(fname);
    DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname));
    if (dos_stat(dname,&sbuf) != 0) {
      DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno)));
      return(0);      /* *** shouldn't happen! *** */
    }

    /* Save for later - but explicitly remove setuid bit for safety. */
    dir_mode = sbuf.st_mode & ~S_ISUID;
    DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode));
    /* Clear "result" */
    result = 0;
  } 

  if (IS_DOS_DIR(dosmode)) {
    /* We never make directories read only for the owner as under DOS a user
       can always create a file in a read-only directory. */
    result |= (S_IFDIR | S_IWUSR);

    if (dir_mode) {
      /* Inherit mode of parent directory. */
      result |= dir_mode;
    } else {
      /* Provisionally add all 'x' bits */
      result |= (S_IXUSR | S_IXGRP | S_IXOTH);                 

      /* Apply directory mask */
      result &= lp_dir_mask(SNUM(conn));
      /* Add in force bits */
      result |= lp_force_dir_mode(SNUM(conn));
    }
  } else { 
    if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode))
      result |= S_IXUSR;

    if (lp_map_system(SNUM(conn)) && IS_DOS_SYSTEM(dosmode))
      result |= S_IXGRP;
 
    if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
      result |= S_IXOTH;  

    if (dir_mode) {
      /* Inherit 666 component of parent directory mode */
      result |= dir_mode
        &  (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
    } else {
      /* Apply mode mask */
      result &= lp_create_mask(SNUM(conn));
      /* Add in force bits */
      result |= lp_force_create_mode(SNUM(conn));
    }
  }
  return(result);
}
Beispiel #5
0
/*
 ****************************************************************
 *	Remove um arquivo					*
 ****************************************************************
 */
void
simple_rm (const char *path)
{
	DOSSTAT		z;

	/*
	 *	Obtém o estado do arquivo
	 */
	if (dos_stat (path, &z) < 0)
	{
		printf
		(	"%s: Não consegui obter o estado de \"%s\" (%s)\n",
			cmd_nm, path, strerror (errno)
		);
		return;
	}

#undef	DEBUG
#ifdef	DEBUG
	printf
	(	"simple_rm: entries = %d, clusno = %d\n",
		z.z_lfn_entries, z.z_lfn_clusno
	);

	printf
	(	"simple_rm: blkno = %d, end_blkno = %d, offset = %d\n",
		z.z_lfn_blkno, z.z_lfn_end_blkno, z.z_lfn_offset
	);
#endif	DEBUG

	/*
	 *	Se necessário, pede confirmação do usuario
	 */
	if   (cmd_iflag)
	{
		fprintf
		(	stderr,
			"(%c, %d) %s? (n): ",
			file_type_edit (z.z_mode), GET_LONG (z.z_size), path
		);

		if (askyesno () <= 0)
			return;
	}
	elif (cmd_vflag)
	{
		printf ("%s:\n", path);
	}

	/*
	 *	Verifica se é um arquivo regular
	 */
	if (Z_ISDIR (z.z_mode))
	{
		printf
		(	"%s: O arquivo \"%s\" é um diretório\n",
			cmd_nm, path
		);
		return;
	}

	/*
	 *	Verifica se tem o bit "r" ligado
	 */
	if (z.z_mode & Z_RO)
	{
		fprintf
		(	stderr,
			"%s: O arquivo \"%s\" só permite leituras - "
			"remove? (n): ",
			cmd_nm, path
		);

		if (askyesno () <= 0)
			return;
	}

	/*
	 *	Remove o arquivo
	 */
	if (dos_unlink (&z, 1 /* trunca */) < 0)
		return;

	/*
	 *	Verifica se alterou o nome do volume principal
	 */
	if (Z_ISVOL (z.z_mode))
	{
		vol_nm[0] = '\0';

		dir_walk (vol_search, uni.u_root_cluster);
	}

}	/* end simple_rm */