/***************************************************** setup basic info in a stat structure *******************************************************/ void smbw_setup_stat(struct stat *st, char *fname, size_t size, int mode) { st->st_mode = 0; if (IS_DOS_DIR(mode)) { st->st_mode = SMBW_DIR_MODE; } else { st->st_mode = SMBW_FILE_MODE; } if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR; if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP; if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH; if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; st->st_size = size; st->st_blksize = 512; st->st_blocks = (size+511)/512; st->st_uid = getuid(); st->st_gid = getgid(); if (IS_DOS_DIR(mode)) { st->st_nlink = 2; } else { st->st_nlink = 1; } if (st->st_ino == 0) { st->st_ino = smbw_inode(fname); } }
static int setup_stat(SMBCCTX *context, struct stat *st, char *fname, SMB_OFF_T size, int mode) { TALLOC_CTX *frame = talloc_stackframe(); st->st_mode = 0; if (IS_DOS_DIR(mode)) { st->st_mode = SMBC_DIR_MODE; } else { st->st_mode = SMBC_FILE_MODE; } if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR; if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP; if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH; if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; st->st_size = size; #ifdef HAVE_STAT_ST_BLKSIZE st->st_blksize = 512; #endif #ifdef HAVE_STAT_ST_BLOCKS st->st_blocks = (size+511)/512; #endif #ifdef HAVE_STRUCT_STAT_ST_RDEV st->st_rdev = 0; #endif st->st_uid = getuid(); st->st_gid = getgid(); if (IS_DOS_DIR(mode)) { st->st_nlink = 2; } else { st->st_nlink = 1; } if (st->st_ino == 0) { st->st_ino = generate_inode(context, fname); } TALLOC_FREE(frame); return True; /* FIXME: Is this needed ? */ }
mode_t unix_mode(connection_struct *conn, int dosmode, const struct smb_filename *smb_fname, const char *inherit_from_dir) { mode_t result = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH); mode_t dir_mode = 0; /* Mode of the inherit_from directory if * inheriting. */ if (!lp_store_dos_attributes(SNUM(conn)) && IS_DOS_READONLY(dosmode)) { result &= ~(S_IWUSR | S_IWGRP | S_IWOTH); } if ((inherit_from_dir != NULL) && lp_inherit_permissions(SNUM(conn))) { struct smb_filename *smb_fname_parent; DEBUG(2, ("unix_mode(%s) inheriting from %s\n", smb_fname_str_dbg(smb_fname), inherit_from_dir)); smb_fname_parent = synthetic_smb_fname( talloc_tos(), inherit_from_dir, NULL, NULL); if (smb_fname_parent == NULL) { DEBUG(1,("unix_mode(%s) failed, [dir %s]: No memory\n", smb_fname_str_dbg(smb_fname), inherit_from_dir)); return(0); } if (SMB_VFS_STAT(conn, smb_fname_parent) != 0) { DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n", smb_fname_str_dbg(smb_fname), inherit_from_dir, strerror(errno))); TALLOC_FREE(smb_fname_parent); return(0); /* *** shouldn't happen! *** */ } /* Save for later - but explicitly remove setuid bit for safety. */ dir_mode = smb_fname_parent->st.st_ex_mode & ~S_ISUID; DEBUG(2,("unix_mode(%s) inherit mode %o\n", smb_fname_str_dbg(smb_fname), (int)dir_mode)); /* Clear "result" */ result = 0; TALLOC_FREE(smb_fname_parent); } 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_directory_mask(SNUM(conn)); /* Add in force bits */ result |= lp_force_directory_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)); } } DEBUG(3,("unix_mode(%s) returning 0%o\n", smb_fname_str_dbg(smb_fname), (int)result)); return(result); }
/**************************************************************************** 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); }