Commit 030318b4 authored by jan.koester's avatar jan.koester
Browse files

test

parent cac6f2fd
Loading
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
authdb (20260426+1) unstable; urgency=medium

  * file backend vacuum: check write/ftruncate/lseek return values,
    throw on failure instead of silently corrupting the database
  * file backend: check read/write return values in getRevesion()
    and newRevesion()
  * Fix -Wunused-result warnings: check mkdir/chown return values
    in authdb.cpp, log failures to stderr

 -- Jan Koester <jan.koester@tuxist.de>  Sat, 26 Apr 2026 17:00:00 +0200

authdb (20260424+8) unstable; urgency=medium

  * Cluster: use multi-store protocol for session data (store_id=1).
+16 −8
Original line number Diff line number Diff line
@@ -683,11 +683,15 @@ int main(int argc,char *argv[]){
#ifndef _WIN32
    {
        struct stat st;
        if (stat("/var/log/authdb", &st) != 0)
            mkdir("/var/log/authdb", 0750);
        if (stat("/var/log/authdb", &st) != 0) {
            if (mkdir("/var/log/authdb", 0750) != 0)
                std::cerr << "mkdir /var/log/authdb failed: " << strerror(errno) << std::endl;
        }
        struct passwd *lpw = getpwnam("authdb");
        if (lpw)
            chown("/var/log/authdb", lpw->pw_uid, lpw->pw_gid);
        if (lpw) {
            if (chown("/var/log/authdb", lpw->pw_uid, lpw->pw_gid) != 0)
                std::cerr << "chown /var/log/authdb failed: " << strerror(errno) << std::endl;
        }
    }
    authdb::g_Log.open("/var/log/authdb/access.log", "/var/log/authdb/error.log");
#else
@@ -879,18 +883,22 @@ int main(int argc,char *argv[]){
                    fs::path parentDir = fs::path(backendPath).parent_path();
                    if (fs::is_directory(parentDir)) {
                        for (auto &entry : fs::recursive_directory_iterator(parentDir)) {
                            chown(entry.path().c_str(), pw->pw_uid, pw->pw_gid);
                            if (chown(entry.path().c_str(), pw->pw_uid, pw->pw_gid) != 0)
                                std::cerr << "chown " << entry.path() << " failed: " << strerror(errno) << std::endl;
                        }
                        chown(parentDir.c_str(), pw->pw_uid, pw->pw_gid);
                        if (chown(parentDir.c_str(), pw->pw_uid, pw->pw_gid) != 0)
                            std::cerr << "chown " << parentDir << " failed: " << strerror(errno) << std::endl;
                    }
                }
                if (clusterEnabled && !ccfg.store_path.empty()) {
                    namespace fs = std::filesystem;
                    if (fs::is_directory(ccfg.store_path)) {
                        for (auto &entry : fs::recursive_directory_iterator(ccfg.store_path)) {
                            chown(entry.path().c_str(), pw->pw_uid, pw->pw_gid);
                            if (chown(entry.path().c_str(), pw->pw_uid, pw->pw_gid) != 0)
                                std::cerr << "chown " << entry.path() << " failed: " << strerror(errno) << std::endl;
                        }
                        chown(ccfg.store_path.c_str(), pw->pw_uid, pw->pw_gid);
                        if (chown(ccfg.store_path.c_str(), pw->pw_uid, pw->pw_gid) != 0)
                            std::cerr << "chown " << ccfg.store_path << " failed: " << strerror(errno) << std::endl;
                    }
                }
                if (setgid(pw->pw_gid) != 0) {
+32 −9
Original line number Diff line number Diff line
@@ -422,7 +422,10 @@ size_t authdb::File::getRevesion(){
    setPos(0);

    AuthHeader head;
    ::read(_FileDes,&head,sizeof(head));
    if (::read(_FileDes,&head,sizeof(head)) != sizeof(head)) {
        setPos(cur);
        return 0;
    }

    setPos(cur);

@@ -437,10 +440,16 @@ void authdb::File::newRevesion(){
    size_t cur=getPos();
    setPos(0);
    AuthHeader head;
    ::read(_FileDes,&head,sizeof(head));
    if (::read(_FileDes,&head,sizeof(head)) != sizeof(head)) {
        setPos(cur);
        return;
    }
    ++head.Revesion;
    setPos(0);
    ::write(_FileDes,&head,sizeof(head));
    if (::write(_FileDes,&head,sizeof(head)) != sizeof(head)) {
        setPos(cur);
        return;
    }
    setPos(cur);
#endif
}
@@ -554,7 +563,11 @@ void authdb::File::vacuum(){
    std::map<std::tuple<std::string,std::string,int>, RecordEntry> dedup;
    std::vector<std::tuple<std::string,std::string,int>> insertOrder;

    size_t fileEnd = lseek(_FileDes, 0, SEEK_END);
    off_t fileEndOff = lseek(_FileDes, 0, SEEK_END);
    if (fileEndOff < 0) {
        throw AuthBackendError("vacuum: lseek failed");
    }
    size_t fileEnd = static_cast<size_t>(fileEndOff);
    size_t rd = sizeof(AuthHeader);

    while (rd < fileEnd) {
@@ -596,27 +609,37 @@ void authdb::File::vacuum(){

    // 3. Rewrite: header + valid records
    lseek(_FileDes, 0, SEEK_SET);
    ::write(_FileDes, &head, sizeof(head));
    if (::write(_FileDes, &head, sizeof(head)) != sizeof(head)) {
        throw AuthBackendError("vacuum: failed to write header");
    }

    for (auto &key : insertOrder) {
        auto it = dedup.find(key);
        if (it == dedup.end()) continue;
        auto &entry = it->second;
        entry.rec.data = nullptr; // pointer not meaningful on disk
        ::write(_FileDes, &entry.rec, sizeof(AuthData::Record));
        if (::write(_FileDes, &entry.rec, sizeof(AuthData::Record)) != sizeof(AuthData::Record)) {
            throw AuthBackendError("vacuum: failed to write record");
        }
        if (!entry.data.empty()) {
            ::write(_FileDes, entry.data.data(), entry.data.size());
            if (::write(_FileDes, entry.data.data(), entry.data.size()) != (ssize_t)entry.data.size()) {
                throw AuthBackendError("vacuum: failed to write record data");
            }
        }
    }

    // 4. Truncate file at current write position
    off_t newEnd = lseek(_FileDes, 0, SEEK_CUR);
    ftruncate(_FileDes, newEnd);
    if (newEnd < 0 || ftruncate(_FileDes, newEnd) != 0) {
        throw AuthBackendError("vacuum: failed to truncate file");
    }

    // 5. Bump revision
    ++head.Revesion;
    lseek(_FileDes, 0, SEEK_SET);
    ::write(_FileDes, &head, sizeof(head));
    if (::write(_FileDes, &head, sizeof(head)) != sizeof(head)) {
        throw AuthBackendError("vacuum: failed to write updated header");
    }
#endif
}