/* * 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); }
/* * 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; }