fix: Allow folder creation as root and give access to clamav.

pull/1322/head
Stiliyan Tonev (Bark) 10 months ago
parent 76a31a261a
commit c6c8d1fe58
  1. 39
      common/output.c
  2. 42
      freshclam/freshclam.c
  3. 54
      libfreshclam/libfreshclam.c
  4. 1
      libfreshclam/libfreshclam.h

@ -55,7 +55,9 @@
#include "clamav.h"
#include "others.h"
#include "str.h"
#include "output.h"
#include "optparser.h"
#include <pwd.h>
#include "output.h"
#ifdef CL_THREAD_SAFE
@ -336,40 +338,7 @@ int logg(loglevel_t loglevel, const char *str, ...)
#ifdef CL_THREAD_SAFE
pthread_mutex_lock(&logg_mutex);
#endif
if(logg_open() == -1) {
printf("WARNING: Can't open %s in append mode (check permissions!). Will attempt to create it.\n", logg_file);
char* current_dir = "/";
char* file_path = strdup(logg_file);
char* token = strtok(file_path, "/");
current_dir = (char*)malloc(2);
strcpy(current_dir, "/");
STATBUF sb;
while (token != NULL) {
current_dir = (char*)realloc(current_dir, strlen(current_dir) + strlen(token) + 2);
strcat(current_dir, token);
token = strtok(NULL, "/");
if(token == NULL) {
break;
}
if(LSTAT(current_dir, &sb) == -1) {
if(mkdir(current_dir, 0755) == -1) {
printf("ERROR: Failed to create required directory %s. Will continue without writing in %s.\n", current_dir, logg_file);
free(current_dir);
free(file_path);
return -1;
}
}
strcat(current_dir, "/");
}
if ((logg_fp = fopen(logg_file, "at")) == NULL) {
printf("ERROR: Can't open %s in append mode (check permissions!).\n", logg_file);
free(current_dir);
free(file_path);
return -1;
}
}
logg_open();
if (!logg_fp && logg_file) {
old_umask = umask(0037);

@ -811,26 +811,6 @@ static fc_error_t initialize(struct optstruct *opts)
#endif
}
#ifdef HAVE_PWD_H
/* Drop database privileges here if we are not planning on daemonizing. If
* we are, we should wait until after we create the PidFile to drop
* privileges. That way, it is owned by root (or whoever started freshclam),
* and no one can change it. */
if (!optget(opts, "daemon")->enabled) {
/*
* freshclam shouldn't work with root privileges.
* Drop privileges to the DatabaseOwner user, if specified.
* Pass NULL for the log file name, because it hasn't been created yet.
*/
ret = drop_privileges(optget(opts, "DatabaseOwner")->strarg, NULL);
if (ret) {
logg(LOGG_ERROR, "Failed to switch to %s user.\n", optget(opts, "DatabaseOwner")->strarg);
status = FC_ECONFIG;
goto done;
}
}
#endif /* HAVE_PWD_H */
/*
* Initialize libclamav.
*/
@ -982,6 +962,7 @@ static fc_error_t initialize(struct optstruct *opts)
fcConfig.requestTimeout = optget(opts, "ReceiveTimeout")->numarg;
fcConfig.bCompressLocalDatabase = optget(opts, "CompressLocalDatabase")->enabled;
fcConfig.dbOwner = optget(opts, "DatabaseOwner")->strarg;
/*
* Initialize libfreshclam.
@ -992,6 +973,27 @@ static fc_error_t initialize(struct optstruct *opts)
goto done;
}
#ifdef HAVE_PWD_H
/* Drop database privileges here (cause of log file creation in /var/log) if we are not planning on daemonizing. If
* we are, we should wait until after we create the PidFile to drop
* privileges. That way, it is owned by root (or whoever started freshclam),
* and no one can change it. */
if (!optget(opts, "daemon")->enabled) {
/*
* freshclam shouldn't work with root privileges.
* Drop privileges to the DatabaseOwner user, if specified.
* Pass NULL for the log file name, because it hasn't been created yet.
*/
ret = drop_privileges(optget(opts, "DatabaseOwner")->strarg, NULL);
if (ret) {
logg(LOGG_ERROR, "Failed to switch to %s user.\n", optget(opts, "DatabaseOwner")->strarg);
status = FC_ECONFIG;
goto done;
}
}
#endif /* HAVE_PWD_H */
/*
* Set libfreshclam callback functions.
*/

@ -123,6 +123,58 @@ const char *fc_strerror(fc_error_t fcerror)
}
}
int fc_upsert_logg_file(fc_config *fcConfig)
{
int ret = 0;
char* current_dir = "/";
char* file_path = strdup(fcConfig->logFile);
char* log_file = fcConfig->logFile;
char* token = strtok(file_path, "/");
FILE *logg_fp = NULL;
struct passwd *current_user = getpwuid(getuid());
struct passwd *db_owner = getpwnam(fcConfig->dbOwner);
current_dir = (char*)malloc(2);
strcpy(current_dir, "/");
STATBUF sb;
while (token != NULL) {
current_dir = (char*)realloc(current_dir, strlen(current_dir) + strlen(token) + 2);
strcat(current_dir, token);
token = strtok(NULL, "/");
if(token == NULL) {
break;
}
if(LSTAT(current_dir, &sb) == -1) {
if(mkdir(current_dir, 0755) == -1) {
printf("ERROR: Failed to create required directory %s. Will continue without writing in %s.\n", current_dir, log_file);
ret = -1;
goto cleanup;
}
if(chown(current_dir, db_owner->pw_uid, db_owner->pw_gid) == -1) {
printf("ERROR: Failed to change owner of %s to %s. Will continue without writing in %s.\n", current_dir, fcConfig->dbOwner, log_file);
ret = -1;
goto cleanup;
}
}
strcat(current_dir, "/");
}
if ((logg_fp = fopen(log_file, "at")) == NULL) {
printf("ERROR: Can't open %s in append mode (check permissions!).\n", log_file);
ret = -1;
goto cleanup;
}
lchown(log_file, db_owner->pw_uid, db_owner->pw_gid);
cleanup:
free(current_dir);
free(file_path);
if(logg_fp != NULL) {
fclose(logg_fp);
}
return ret;
}
fc_error_t fc_initialize(fc_config *fcConfig)
{
fc_error_t status = FC_EARG;
@ -157,6 +209,8 @@ fc_error_t fc_initialize(fc_config *fcConfig)
logg_rotate = (fcConfig->logFlags & FC_CONFIG_LOG_ROTATE) ? 1 : 0;
logg_size = fcConfig->maxLogSize;
/* Set a log file if requested, and is not already set */
fc_upsert_logg_file(fcConfig);
if ((NULL == logg_file) && (NULL != fcConfig->logFile)) {
logg_file = cli_safer_strdup(fcConfig->logFile);
if (0 != logg(LOGG_INFO_NF, "--------------------------------------\n")) {

@ -60,6 +60,7 @@ typedef struct fc_config_ {
const char *proxyPassword; /**< (optional) Password for proxy server authentication. */
const char *databaseDirectory; /**< Filepath of database directory. */
const char *tempDirectory; /**< Filepath to store temp files. */
const char *dbOwner; /**< Owner of DB, used when creating log file/folder. */
} fc_config;
typedef enum fc_error_tag {

Loading…
Cancel
Save