in src/s3fs.cpp [505:579]
static int check_object_access(const char* path, int mask, struct stat* pstbuf)
{
int result;
struct stat st;
struct stat* pst = (pstbuf ? pstbuf : &st);
struct fuse_context* pcxt;
S3FS_PRN_DBG("[path=%s]", path);
if(NULL == (pcxt = fuse_get_context())){
return -EIO;
}
S3FS_PRN_DBG("[pid=%u,uid=%u,gid=%u]", (unsigned int)(pcxt->pid), (unsigned int)(pcxt->uid), (unsigned int)(pcxt->gid));
if(0 != (result = get_object_attribute(path, pst))){
// If there is not the target file(object), result is -ENOENT.
return result;
}
if(0 == pcxt->uid){
// root is allowed all accessing.
return 0;
}
if(is_s3fs_uid && s3fs_uid == pcxt->uid){
// "uid" user is allowed all accessing.
return 0;
}
if(F_OK == mask){
// if there is a file, always return allowed.
return 0;
}
// for "uid", "gid" option
uid_t obj_uid = (is_s3fs_uid ? s3fs_uid : pst->st_uid);
gid_t obj_gid = (is_s3fs_gid ? s3fs_gid : pst->st_gid);
// compare file mode and uid/gid + mask.
mode_t mode;
mode_t base_mask = S_IRWXO;
if(is_s3fs_umask){
// If umask is set, all object attributes set ~umask.
mode = ((S_IRWXU | S_IRWXG | S_IRWXO) & ~s3fs_umask);
}else{
mode = pst->st_mode;
}
if(pcxt->uid == obj_uid){
base_mask |= S_IRWXU;
}
if(pcxt->gid == obj_gid){
base_mask |= S_IRWXG;
}
if(1 == is_uid_include_group(pcxt->uid, obj_gid)){
base_mask |= S_IRWXG;
}
mode &= base_mask;
if(X_OK == (mask & X_OK)){
if(0 == (mode & (S_IXUSR | S_IXGRP | S_IXOTH))){
return -EACCES;
}
}
if(W_OK == (mask & W_OK)){
if(0 == (mode & (S_IWUSR | S_IWGRP | S_IWOTH))){
return -EACCES;
}
}
if(R_OK == (mask & R_OK)){
if(0 == (mode & (S_IRUSR | S_IRGRP | S_IROTH))){
return -EACCES;
}
}
if(0 == mode){
return -EACCES;
}
return 0;
}