diff --git a/src/fdcache.cpp b/src/fdcache.cpp index 4b0eab1..884b052 100644 --- a/src/fdcache.cpp +++ b/src/fdcache.cpp @@ -66,7 +66,11 @@ bool CacheFileStat::MakeCacheFileStatPath(const char* path, string& sfile_path, top_path += ".stat"; if(is_create_dir){ - mkdirp(top_path + mydirname(path), 0777); + int result; + if(0 != (result = mkdirp(top_path + mydirname(path), 0777))){ + DPRNINFO("failed to create dir(%s) by errno(%d).", path, result); + return false; + } } if(!path || '\0' == path[0]){ sfile_path = top_path; @@ -76,6 +80,20 @@ bool CacheFileStat::MakeCacheFileStatPath(const char* path, string& sfile_path, return true; } +bool CacheFileStat::CheckCacheFileStatTopDir(void) +{ + if(!FdManager::IsCacheDir()){ + return true; + } + // make stat dir top path( "//..stat" ) + string top_path = FdManager::GetCacheDir(); + top_path += "/."; + top_path += bucket; + top_path += ".stat"; + + return check_exist_dir_permission(top_path.c_str()); +} + bool CacheFileStat::DeleteCacheFileStat(const char* path) { if(!path || '\0' == path[0]){ @@ -1095,7 +1113,11 @@ bool FdManager::MakeCachePath(const char* path, string& cache_path, bool is_crea } string resolved_path(FdManager::cache_dir + "/" + bucket); if(is_create_dir){ - mkdirp(resolved_path + mydirname(path), 0777); + int result; + if(0 != (result = mkdirp(resolved_path + mydirname(path), 0777))){ + DPRNINFO("failed to create dir(%s) by errno(%d).", path, result); + return false; + } } if(!path || '\0' == path[0]){ cache_path = resolved_path; @@ -1105,6 +1127,16 @@ bool FdManager::MakeCachePath(const char* path, string& cache_path, bool is_crea return true; } +bool FdManager::CheckCacheTopDir(void) +{ + if(0 == FdManager::cache_dir.size()){ + return true; + } + string toppath(FdManager::cache_dir + "/" + bucket); + + return check_exist_dir_permission(toppath.c_str()); +} + bool FdManager::MakeRandomTempPath(const char* path, string& tmppath) { char szBuff[64]; diff --git a/src/fdcache.h b/src/fdcache.h index ac234be..b62a16f 100644 --- a/src/fdcache.h +++ b/src/fdcache.h @@ -34,6 +34,7 @@ class CacheFileStat public: static bool DeleteCacheFileStat(const char* path); + static bool CheckCacheFileStatTopDir(void); explicit CacheFileStat(const char* tpath = NULL); ~CacheFileStat(); @@ -166,6 +167,7 @@ class FdManager static size_t SetPageSize(size_t size); static size_t GetPageSize(void) { return FdManager::page_size; } static bool MakeCachePath(const char* path, std::string& cache_path, bool is_create_dir = true); + static bool CheckCacheTopDir(void); static bool MakeRandomTempPath(const char* path, std::string& tmppath); FdEntity* GetFdEntity(const char* path, int existfd = -1); diff --git a/src/s3fs.cpp b/src/s3fs.cpp index e503a51..8b0693a 100644 --- a/src/s3fs.cpp +++ b/src/s3fs.cpp @@ -4622,6 +4622,13 @@ int main(int argc, char* argv[]) // like checking for appropriate lengths and characters } + // check cache dir permission + if(!FdManager::CheckCacheTopDir() || !CacheFileStat::CheckCacheFileStatTopDir()){ + fprintf(stderr, "%s: could not allow cache directory permission, check permission of cache directories.\n", + program_name.c_str()); + exit(EXIT_FAILURE); + } + // There's room for more command line error checking // Check to see if the bucket name contains periods and https (SSL) is diff --git a/src/s3fs_util.cpp b/src/s3fs_util.cpp index 3cb7dab..44171d8 100644 --- a/src/s3fs_util.cpp +++ b/src/s3fs_util.cpp @@ -546,15 +546,72 @@ string mybasename(string path) // mkdir --parents int mkdirp(const string& path, mode_t mode) { - string base; - string component; + string base; + string component; stringstream ss(path); - int result = 0; while (getline(ss, component, '/')) { base += "/" + component; - result = mkdir(base.c_str(), mode); + + struct stat st; + if(0 == stat(base.c_str(), &st)){ + if(!S_ISDIR(st.st_mode)){ + return EPERM; + } + }else{ + int result; + if(0 != (result = mkdir(base.c_str(), mode))){ + return errno; + } + } } - return result; + return 0; +} + +bool check_exist_dir_permission(const char* dirpath) +{ + if(!dirpath || '\0' == dirpath[0]){ + return false; + } + + // exists + struct stat st; + if(0 != stat(dirpath, &st)){ + if(ENOENT == errno){ + // dir does not exitst + return true; + } + if(EACCES == errno){ + // could not access directory + return false; + } + // somthing error occured + return false; + } + + // check type + if(!S_ISDIR(st.st_mode)){ + // path is not directory + return false; + } + + // check permission + uid_t myuid = geteuid(); + if(myuid == st.st_uid){ + if(S_IRWXU != (st.st_mode & S_IRWXU)){ + return false; + } + }else{ + if(1 == is_uid_inculde_group(myuid, st.st_gid)){ + if(S_IRWXG != (st.st_mode & S_IRWXG)){ + return false; + } + }else{ + if(S_IRWXO != (st.st_mode & S_IRWXO)){ + return false; + } + } + } + return true; } bool delete_files_in_dir(const char* dir, bool is_remove_own) diff --git a/src/s3fs_util.h b/src/s3fs_util.h index 5898ced..d4d8ac5 100644 --- a/src/s3fs_util.h +++ b/src/s3fs_util.h @@ -109,6 +109,7 @@ int is_uid_inculde_group(uid_t uid, gid_t gid); std::string mydirname(std::string path); std::string mybasename(std::string path); int mkdirp(const std::string& path, mode_t mode); +bool check_exist_dir_permission(const char* dirpath); bool delete_files_in_dir(const char* dir, bool is_remove_own); time_t get_mtime(const char *s);