Skip to content
41 changes: 21 additions & 20 deletions freshclam/freshclam.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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.
Expand All @@ -992,6 +973,26 @@ 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.
*/
Expand Down
53 changes: 53 additions & 0 deletions libfreshclam/libfreshclam.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,57 @@ const char *fc_strerror(fc_error_t fcerror)
}
}

int fc_upsert_logg_file(fc_config *fcConfig)
{
int ret = 0;
char *current_path, *file_path = strdup(fcConfig->logFile), *token;
FILE *logg_fp = NULL;
token = strtok(file_path, PATHSEP);
struct passwd *current_user = getpwuid(getuid()), *db_owner = getpwnam(fcConfig->dbOwner);
current_path = (char *)malloc(2);
strcpy(current_path, PATHSEP);
STATBUF sb;

while (token != NULL) {
current_path = (char *)realloc(current_path, strlen(current_path) + strlen(token) + 2);
strcat(current_path, token);
token = strtok(NULL, PATHSEP);
if (token == NULL) {
break;
}
if (LSTAT(current_path, &sb) == -1) {
if (mkdir(current_path, 0755) == -1) {
printf("ERROR: Failed to create required directory %s. Will continue without writing in %s.\n", current_path, fcConfig->logFile);
ret = -1;
goto cleanup;
}
if (current_user->pw_uid != db_owner->pw_uid) {
if (chown(current_path, 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_path, fcConfig->dbOwner, fcConfig->logFile);
ret = -1;
goto cleanup;
}
}
}
strcat(current_path, PATHSEP);
}
if ((logg_fp = fopen(fcConfig->logFile, "at")) == NULL) {
printf("ERROR: Can't open %s in append mode (check permissions!).\n", fcConfig->logFile);
ret = -1;
goto cleanup;
}
lchown(fcConfig->logFile, db_owner->pw_uid, db_owner->pw_gid);

cleanup:
free(current_path);
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;
Expand Down Expand Up @@ -157,6 +208,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")) {
Expand Down
1 change: 1 addition & 0 deletions libfreshclam/libfreshclam.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down