Exemple #1
0
/*
 *	Log the query to a file.
 */
void rlm_sql_query_log(rlm_sql_t *inst, REQUEST *request,
		       sql_acct_section_t *section, char const *query)
{
	int fd;
	char const *filename = NULL;
	char *expanded = NULL;
	size_t len;
	bool failed = false;	/* Write the log message outside of the critical region */

	if (section) {
		filename = section->logfile;
	} else {
		filename = inst->config->logfile;
	}

	if (!filename) {
		return;
	}

	if (radius_axlat(&expanded, request, filename, NULL, NULL) < 0) {
		return;
	}

	fd = exfile_open(inst->ef, filename, 0640, true);
	if (fd < 0) {
		ERROR("rlm_sql (%s): Couldn't open logfile '%s': %s", inst->config->xlat_name,
		      expanded, fr_syserror(errno));

		talloc_free(expanded);
		return;
	}

	len = strlen(query);
	if ((write(fd, query, len) < 0) || (write(fd, ";\n", 2) < 0)) {
		failed = true;
	}

	if (failed) {
		ERROR("rlm_sql (%s): Failed writing to logfile '%s': %s", inst->config->xlat_name, expanded,
		      fr_syserror(errno));
	}

	talloc_free(expanded);
	exfile_close(inst->ef, fd);
}
Exemple #2
0
/*
 *	Log the query to a file.
 */
void rlm_sql_query_log(rlm_sql_t const *inst, REQUEST *request, sql_acct_section_t *section, char const *query)
{
	int fd;
	char const *filename = NULL;
	char *expanded = NULL;
	size_t len;
	bool failed = false;	/* Write the log message outside of the critical region */

	filename = inst->config->logfile;
	if (section && section->logfile) filename = section->logfile;

	if (!filename || !*filename) {
		return;
	}

	if (xlat_aeval(request, &expanded, request, filename, NULL, NULL) < 0) {
		return;
	}

	fd = exfile_open(inst->ef, request, filename, 0640);
	if (fd < 0) {
		ERROR("Couldn't open logfile '%s': %s", expanded, fr_syserror(errno));

		talloc_free(expanded);
		/* coverity[missing_unlock] */
		return;
	}

	len = strlen(query);
	if ((write(fd, query, len) < 0) || (write(fd, ";\n", 2) < 0)) {
		failed = true;
	}

	if (failed) ERROR("Failed writing to logfile '%s': %s", expanded, fr_syserror(errno));

	talloc_free(expanded);
	exfile_close(inst->ef, request, fd);
}
static rlm_rcode_t CC_HINT(nonnull) mod_do_linelog(void *instance, REQUEST *request)
{
    int fd = -1;
    rlm_linelog_t *inst = (rlm_linelog_t*) instance;
    char const *value = inst->line;

#ifdef HAVE_GRP_H
    gid_t gid;
    char *endptr;
#endif
    char path[2048];
    char line[4096];

    line[0] = '\0';

    if (inst->reference) {
        CONF_ITEM *ci;
        CONF_PAIR *cp;

        if (radius_xlat(line + 1, sizeof(line) - 1, request, inst->reference, linelog_escape_func, NULL) < 0) {
            return RLM_MODULE_FAIL;
        }

        line[0] = '.';	/* force to be in current section */

        /*
         *	Don't allow it to go back up
         */
        if (line[1] == '.') goto do_log;

        ci = cf_reference_item(NULL, inst->cs, line);
        if (!ci) {
            RDEBUG2("No such entry \"%s\"", line);
            return RLM_MODULE_NOOP;
        }

        if (!cf_item_is_pair(ci)) {
            RDEBUG2("Entry \"%s\" is not a variable assignment ", line);
            goto do_log;
        }

        cp = cf_item_to_pair(ci);
        value = cf_pair_value(cp);
        if (!value) {
            RWDEBUG2("Entry \"%s\" has no value", line);
            return RLM_MODULE_OK;
        }

        /*
         *	Value exists, but is empty.  Don't log anything.
         */
        if (!*value) return RLM_MODULE_OK;
    }

do_log:
    /*
     *	FIXME: Check length.
     */
    if (radius_xlat(line, sizeof(line) - 1, request, value, linelog_escape_func, NULL) < 0) {
        return RLM_MODULE_FAIL;
    }

#ifdef HAVE_SYSLOG_H
    if (strcmp(inst->filename, "syslog") == 0) {
        syslog(inst->syslog_priority, "%s", line);
        return RLM_MODULE_OK;
    }
#endif

    /*
     *	We're using a real filename now.
     */
    if (radius_xlat(path, sizeof(path), request, inst->filename, inst->escape_func, NULL) < 0) {
        return RLM_MODULE_FAIL;
    }

    fd = exfile_open(inst->ef, path, inst->permissions, true);
    if (fd < 0) {
        ERROR("rlm_linelog: Failed to open %s: %s", path, fr_syserror(errno));
        return RLM_MODULE_FAIL;
    }

    if (inst->group != NULL) {
        gid = strtol(inst->group, &endptr, 10);
        if (*endptr != '\0') {
            if (rad_getgid(request, &gid, inst->group) < 0) {
                RDEBUG2("Unable to find system group \"%s\"", inst->group);
                goto skip_group;
            }
        }

        if (chown(path, -1, gid) == -1) {
            RDEBUG2("Unable to change system group of \"%s\"", path);
        }
    }

skip_group:
    strcat(line, "\n");

    if (write(fd, line, strlen(line)) < 0) {
        exfile_close(inst->ef, fd);
        ERROR("rlm_linelog: Failed writing: %s", fr_syserror(errno));
        return RLM_MODULE_FAIL;
    }

    exfile_close(inst->ef, fd);
    return RLM_MODULE_OK;
}
/*
 *	Do detail, compatible with old accounting
 */
static rlm_rcode_t CC_HINT(nonnull) detail_do(void *instance, REQUEST *request, RADIUS_PACKET *packet, bool compat)
{
	int		outfd;
	char		buffer[DIRLEN];

	FILE		*outfp;

#ifdef HAVE_GRP_H
	gid_t		gid;
	char		*endptr;
#endif

	detail_instance_t *inst = instance;

	/*
	 *	Generate the path for the detail file.  Use the same
	 *	format, but truncate at the last /.  Then feed it
	 *	through radius_xlat() to expand the variables.
	 */
	if (radius_xlat(buffer, sizeof(buffer), request, inst->filename, inst->escape_func, NULL) < 0) {
		return RLM_MODULE_FAIL;
	}

	RDEBUG2("%s expands to %s", inst->filename, buffer);

#ifdef WITH_ACCOUNTING
#if defined(HAVE_FNMATCH_H) && defined(FNM_FILE_NAME)
	/*
	 *	If we read it from a detail file, and we're about to
	 *	write it back to the SAME detail file directory, then
	 *	suppress the write.  This check prevents an infinite
	 *	loop.
	 */
	if ((request->listener->type == RAD_LISTEN_DETAIL) &&
	    (fnmatch(((listen_detail_t *)request->listener->data)->filename,
		     buffer, FNM_FILE_NAME | FNM_PERIOD ) == 0)) {
		RWDEBUG2("Suppressing infinite loop");
		return RLM_MODULE_NOOP;
	}
#endif
#endif

	outfd = exfile_open(inst->ef, buffer, inst->perm, true);
	if (outfd < 0) {
		RERROR("Couldn't open file %s: %s", buffer, fr_strerror());
		return RLM_MODULE_FAIL;
	}

	if (inst->group != NULL) {
		gid = strtol(inst->group, &endptr, 10);
		if (*endptr != '\0') {
			if (rad_getgid(request, &gid, inst->group) < 0) {
				RDEBUG2("Unable to find system group '%s'", inst->group);
				goto skip_group;
			}
		}

		if (chown(buffer, -1, gid) == -1) {
			RDEBUG2("Unable to change system group of '%s'", buffer);
		}
	}

skip_group:
	/*
	 *	Open the output fp for buffering.
	 */
	if ((outfp = fdopen(outfd, "a")) == NULL) {
		RERROR("Couldn't open file %s: %s", buffer, fr_syserror(errno));
	fail:
		if (outfp) fclose(outfp);
		exfile_unlock(inst->ef, outfd);
		return RLM_MODULE_FAIL;
	}

	if (detail_write(outfp, inst, request, packet, compat) < 0) goto fail;

	/*
	 *	Flush everything
	 */
	fclose(outfp);
	exfile_unlock(inst->ef, outfd); /* do NOT close outfp */

	/*
	 *	And everything is fine.
	 */
	return RLM_MODULE_OK;
}