Loading src/config.cpp +36 −1 Changes for src/config.cpp: 36 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -41,6 +41,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <sys/stat.h> #include <unistd.h> #if __has_include(<sys/uid_r.h>) #include <sys/uid_r.h> // systempp: UUID and GUID owners #define SHAREDD_UID_R 1 #endif #include <confplus/conf.h> #include <confplus/exception.h> Loading Loading @@ -331,6 +336,28 @@ std::string createShareDir(const Share &s, const std::string &lang) { uid_t uid = 0; gid_t gid = 0; mode_t mode = 01777; #ifdef SHAREDD_UID_R // the owner may be a UUID or GUID user or group uid_r_t ruid = uid_r_legacy(0), rgid = uid_r_legacy(0); if (s.readOnly) { mode = 0755; } else if (s.users.size() == 1 && s.users[0][0] != '@') { if (struct passwd_id_r *pw = getpwnam_id_r(s.users[0].c_str())) { ruid = pw->pw_uid; rgid = pw->pw_gid; mode = 0755; } endpwent_id_r(); } else if (s.users.size() == 1) { if (struct group_id_r *gr = getgrnam_id_r(s.users[0].c_str() + 1)) { rgid = gr->gr_gid; mode = 02775; } endgrent_id_r(); } uid = uid_r_to_legacy(&ruid); gid = uid_r_to_legacy(&rgid); #else if (s.readOnly) { mode = 0755; } else if (s.users.size() == 1 && s.users[0][0] != '@') { Loading @@ -349,6 +376,7 @@ std::string createShareDir(const Share &s, const std::string &lang) { } endgrent(); } #endif // parents first, root's for (size_t slash = s.path.find('/', 1); slash != std::string::npos; slash = s.path.find('/', slash + 1)) { std::string dir = s.path.substr(0, slash); Loading @@ -357,7 +385,14 @@ std::string createShareDir(const Share &s, const std::string &lang) { } if (mkdir(s.path.c_str(), 0700) != 0 && errno != EEXIST) return tr(lang, "creating %1 failed: %2", "%1 anlegen fehlgeschlagen: %2", {s.path, strerror(errno)}); if (chown(s.path.c_str(), uid, gid) != 0 || chmod(s.path.c_str(), mode) != 0) #ifdef SHAREDD_UID_R int owned = chown_r(s.path.c_str(), &ruid, &rgid); if (owned != 0 && errno == ENOSYS && uid_r_is_legacy(&ruid) && uid_r_is_legacy(&rgid)) owned = chown(s.path.c_str(), uid, gid); #else int owned = chown(s.path.c_str(), uid, gid); #endif if (owned != 0 || chmod(s.path.c_str(), mode) != 0) return tr(lang, "setting up %1 failed: %2", "%1 einrichten fehlgeschlagen: %2", {s.path, strerror(errno)}); char m[8]; snprintf(m, sizeof(m), "%04o", (unsigned)mode); Loading src/files.cpp +39 −5 Changes for src/files.cpp: 39 added lines, 5 removed lines. Original line number Diff line number Diff line Loading @@ -39,6 +39,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <sys/stat.h> #include <unistd.h> #if __has_include(<sys/uid_r.h>) #include <sys/uid_r.h> // systempp: UUID and GUID owners #define SHAREDD_UID_R 1 #endif namespace sharedd { namespace { Loading Loading @@ -119,6 +124,37 @@ std::string groupName(gid_t gid) { return gr ? gr->gr_name : std::to_string(gid); } // owner and group names of name in dir (st: its classic stat); a UUID or // GUID owner (st shows the overflow id for it) by its name or text form void ownerNames(int dir, const char *name, const struct stat &st, std::string &owner, std::string &group) { owner = userName(st.st_uid); group = groupName(st.st_gid); #ifdef SHAREDD_UID_R uid_r_t u, g; if (fstatat_id_r(dir, name, &u, &g, AT_SYMLINK_NOFOLLOW | (*name ? 0 : AT_EMPTY_PATH)) != 0) return; char buf[UID_R_STR_LEN]; if (!uid_r_is_legacy(&u)) { struct passwd_id_r *pw = getpwuid_id_r(&u); owner = pw ? pw->pw_name : uid_r_to_str(&u, buf); } if (!uid_r_is_legacy(&g)) { struct group_id_r *gr = getgrgid_id_r(&g); group = gr ? gr->gr_name : uid_r_to_str(&g, buf); } #endif } // gives fd the owner and group of the directory dir (st: its classic stat), // a UUID or GUID one too bool inheritOwner(int fd, int dir, const struct stat &st) { #ifdef SHAREDD_UID_R uid_r_t u, g; if (fstatat_id_r(dir, "", &u, &g, AT_EMPTY_PATH) == 0) return fchown_r(fd, &u, &g) == 0; if (errno != ENOSYS) return false; #endif return fchown(fd, st.st_uid, st.st_gid) == 0; } bool parseId(const std::string &v, bool group, unsigned &out) { if (!v.empty() && v.find_first_not_of("0123456789") == std::string::npos) { out = (unsigned)std::strtoul(v.c_str(), nullptr, 10); Loading Loading @@ -216,8 +252,7 @@ std::string listDir(const Share &s, const std::string &rel, std::vector<FileEntr self.mtime = own.st_mtime; self.uid = own.st_uid; self.gid = own.st_gid; self.owner = userName(own.st_uid); self.group = groupName(own.st_gid); ownerNames(dir.fd, "", own, self.owner, self.group); self.mode = own.st_mode & 07777; } DIR *d = fdopendir(dup(dir.fd)); Loading @@ -234,8 +269,7 @@ std::string listDir(const Share &s, const std::string &rel, std::vector<FileEntr f.mtime = st.st_mtime; f.uid = st.st_uid; f.gid = st.st_gid; f.owner = userName(st.st_uid); f.group = groupName(st.st_gid); ownerNames(dir.fd, e->d_name, st, f.owner, f.group); f.mode = st.st_mode & 07777; out.push_back(f); } Loading Loading @@ -316,7 +350,7 @@ std::string createEntry(const Share &s, const std::string &rel, const std::strin if (made.fd < 0) return strerror(errno); // the parent's owner and group; folders keep its setgid bit unsigned mode = folder ? (0775u | (parent.st_mode & 02000u)) : 0664u; if (fchown(made.fd, parent.st_uid, parent.st_gid) != 0 || fchmod(made.fd, mode) != 0) if (!inheritOwner(made.fd, dir.fd, parent) || fchmod(made.fd, mode) != 0) return tr(lang, "setting up %1 failed: %2", "%1 einrichten fehlgeschlagen: %2", {name, strerror(errno)}); return ""; } Loading Loading
src/config.cpp +36 −1 Changes for src/config.cpp: 36 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -41,6 +41,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <sys/stat.h> #include <unistd.h> #if __has_include(<sys/uid_r.h>) #include <sys/uid_r.h> // systempp: UUID and GUID owners #define SHAREDD_UID_R 1 #endif #include <confplus/conf.h> #include <confplus/exception.h> Loading Loading @@ -331,6 +336,28 @@ std::string createShareDir(const Share &s, const std::string &lang) { uid_t uid = 0; gid_t gid = 0; mode_t mode = 01777; #ifdef SHAREDD_UID_R // the owner may be a UUID or GUID user or group uid_r_t ruid = uid_r_legacy(0), rgid = uid_r_legacy(0); if (s.readOnly) { mode = 0755; } else if (s.users.size() == 1 && s.users[0][0] != '@') { if (struct passwd_id_r *pw = getpwnam_id_r(s.users[0].c_str())) { ruid = pw->pw_uid; rgid = pw->pw_gid; mode = 0755; } endpwent_id_r(); } else if (s.users.size() == 1) { if (struct group_id_r *gr = getgrnam_id_r(s.users[0].c_str() + 1)) { rgid = gr->gr_gid; mode = 02775; } endgrent_id_r(); } uid = uid_r_to_legacy(&ruid); gid = uid_r_to_legacy(&rgid); #else if (s.readOnly) { mode = 0755; } else if (s.users.size() == 1 && s.users[0][0] != '@') { Loading @@ -349,6 +376,7 @@ std::string createShareDir(const Share &s, const std::string &lang) { } endgrent(); } #endif // parents first, root's for (size_t slash = s.path.find('/', 1); slash != std::string::npos; slash = s.path.find('/', slash + 1)) { std::string dir = s.path.substr(0, slash); Loading @@ -357,7 +385,14 @@ std::string createShareDir(const Share &s, const std::string &lang) { } if (mkdir(s.path.c_str(), 0700) != 0 && errno != EEXIST) return tr(lang, "creating %1 failed: %2", "%1 anlegen fehlgeschlagen: %2", {s.path, strerror(errno)}); if (chown(s.path.c_str(), uid, gid) != 0 || chmod(s.path.c_str(), mode) != 0) #ifdef SHAREDD_UID_R int owned = chown_r(s.path.c_str(), &ruid, &rgid); if (owned != 0 && errno == ENOSYS && uid_r_is_legacy(&ruid) && uid_r_is_legacy(&rgid)) owned = chown(s.path.c_str(), uid, gid); #else int owned = chown(s.path.c_str(), uid, gid); #endif if (owned != 0 || chmod(s.path.c_str(), mode) != 0) return tr(lang, "setting up %1 failed: %2", "%1 einrichten fehlgeschlagen: %2", {s.path, strerror(errno)}); char m[8]; snprintf(m, sizeof(m), "%04o", (unsigned)mode); Loading
src/files.cpp +39 −5 Changes for src/files.cpp: 39 added lines, 5 removed lines. Original line number Diff line number Diff line Loading @@ -39,6 +39,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <sys/stat.h> #include <unistd.h> #if __has_include(<sys/uid_r.h>) #include <sys/uid_r.h> // systempp: UUID and GUID owners #define SHAREDD_UID_R 1 #endif namespace sharedd { namespace { Loading Loading @@ -119,6 +124,37 @@ std::string groupName(gid_t gid) { return gr ? gr->gr_name : std::to_string(gid); } // owner and group names of name in dir (st: its classic stat); a UUID or // GUID owner (st shows the overflow id for it) by its name or text form void ownerNames(int dir, const char *name, const struct stat &st, std::string &owner, std::string &group) { owner = userName(st.st_uid); group = groupName(st.st_gid); #ifdef SHAREDD_UID_R uid_r_t u, g; if (fstatat_id_r(dir, name, &u, &g, AT_SYMLINK_NOFOLLOW | (*name ? 0 : AT_EMPTY_PATH)) != 0) return; char buf[UID_R_STR_LEN]; if (!uid_r_is_legacy(&u)) { struct passwd_id_r *pw = getpwuid_id_r(&u); owner = pw ? pw->pw_name : uid_r_to_str(&u, buf); } if (!uid_r_is_legacy(&g)) { struct group_id_r *gr = getgrgid_id_r(&g); group = gr ? gr->gr_name : uid_r_to_str(&g, buf); } #endif } // gives fd the owner and group of the directory dir (st: its classic stat), // a UUID or GUID one too bool inheritOwner(int fd, int dir, const struct stat &st) { #ifdef SHAREDD_UID_R uid_r_t u, g; if (fstatat_id_r(dir, "", &u, &g, AT_EMPTY_PATH) == 0) return fchown_r(fd, &u, &g) == 0; if (errno != ENOSYS) return false; #endif return fchown(fd, st.st_uid, st.st_gid) == 0; } bool parseId(const std::string &v, bool group, unsigned &out) { if (!v.empty() && v.find_first_not_of("0123456789") == std::string::npos) { out = (unsigned)std::strtoul(v.c_str(), nullptr, 10); Loading Loading @@ -216,8 +252,7 @@ std::string listDir(const Share &s, const std::string &rel, std::vector<FileEntr self.mtime = own.st_mtime; self.uid = own.st_uid; self.gid = own.st_gid; self.owner = userName(own.st_uid); self.group = groupName(own.st_gid); ownerNames(dir.fd, "", own, self.owner, self.group); self.mode = own.st_mode & 07777; } DIR *d = fdopendir(dup(dir.fd)); Loading @@ -234,8 +269,7 @@ std::string listDir(const Share &s, const std::string &rel, std::vector<FileEntr f.mtime = st.st_mtime; f.uid = st.st_uid; f.gid = st.st_gid; f.owner = userName(st.st_uid); f.group = groupName(st.st_gid); ownerNames(dir.fd, e->d_name, st, f.owner, f.group); f.mode = st.st_mode & 07777; out.push_back(f); } Loading Loading @@ -316,7 +350,7 @@ std::string createEntry(const Share &s, const std::string &rel, const std::strin if (made.fd < 0) return strerror(errno); // the parent's owner and group; folders keep its setgid bit unsigned mode = folder ? (0775u | (parent.st_mode & 02000u)) : 0664u; if (fchown(made.fd, parent.st_uid, parent.st_gid) != 0 || fchmod(made.fd, mode) != 0) if (!inheritOwner(made.fd, dir.fd, parent) || fchmod(made.fd, mode) != 0) return tr(lang, "setting up %1 failed: %2", "%1 einrichten fehlgeschlagen: %2", {name, strerror(errno)}); return ""; } Loading