Download | Plain Text | Line Numbers
/*
* Copyright (c) 2016-2024 Manuel Mausz
*/
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/file.h>
#include <db.h>
void db_error_cb(const DB_ENV *dbenv, const char *prefix, const char *msg)
{
fprintf(stderr, "%s: %s\n", prefix, msg);
}
int main()
{
char *user = getenv("SMTPAUTHUSER");
if (user == NULL || strlen(user) == 0)
return 0;
char *dbfile = getenv("LOCKUSERDB");
if (dbfile == NULL)
dbfile = "control/lockedusers.db";
int fdlock = open(dbfile, O_RDONLY);
if (fdlock < 0)
{
perror("Unable to open database file");
return 0;
}
if (flock(fdlock, LOCK_SH) < 0)
{
perror("Unable to shared-lock database file");
goto err_unlock;
}
DB *db;
int err = db_create(&db, NULL, 0);
if (err != 0)
{
fprintf(stderr, "Unable to create db env: %s\n", db_strerror(err));
goto err_unlock;
}
db->set_errpfx(db, "lockuser");
db->set_errcall(db, db_error_cb);
if ((err = db->open(db, NULL, dbfile, NULL, DB_UNKNOWN, DB_RDONLY, 0600)) != 0)
{
(void)fprintf(stderr, "Unable to open database: %s\n", db_strerror(err));
goto err_close_db;
}
DBT key = { .data = user, .size = strlen(user) };
err = db->exists(db, NULL, &key, 0);
if (err == 0)
{
puts("E550 YOUR ACCOUNT HAS BEEN LOCKED - PLEASE CONTACT YOUR POSTMASTER");
fprintf(stderr, "block: smtp user %s has been blocked\n", user);
}
else if (err != DB_NOTFOUND && err != DB_KEYEMPTY)
{
(void)fprintf(stderr, "Unable to read from database: %s\n", db_strerror(err));
}
err_close_db:
(void)db->close(db, 0);
err_unlock:
(void)close(fdlock);
return 0;
}