25 RCSID(
"$Id: d52e7bf28a84139b6a990018cd2c45aedef358e3 $")
27 #include <freeradius-devel/server/base.h>
28 #include <freeradius-devel/server/cf_parse.h>
29 #include <freeradius-devel/server/radutmp.h>
30 #include <freeradius-devel/server/sysutmp.h>
32 #include <freeradius-devel/util/conf.h>
42 "Login Name What TTY When From Location";
45 "Login Port What When From Location";
47 static char const *
eol =
"\n";
73 if ((pwd = getpwnam(
username)) != NULL) {
74 if ((s = strchr(pwd->pw_gecos,
',')) != NULL) *s = 0;
85 static char const *
proto(
int id,
int porttype)
90 if (!strchr(
"ASITX", porttype))
93 snprintf(buf,
sizeof(buf),
"SLP %c", porttype);
95 snprintf(buf,
sizeof(buf),
"PPP %c", porttype);
97 snprintf(buf,
sizeof(buf),
"shl %c", porttype);
100 if (
id ==
'S')
return "SLIP";
101 if (
id ==
'P')
return "PPP";
115 static char buff[26];
141 return inet_ntop(AF_INET, &ipaddr, buf, buflen);
151 FILE *output = status?stderr:stdout;
153 fprintf(output,
"Usage: radwho [-d raddb] [-cfihnprRsSZ] [-N nas] [-P nas_port] [-u user] [-U user]\n");
154 fprintf(output,
" -c Show caller ID, if available.\n");
155 fprintf(output,
" -d Set the raddb directory (default is %s).\n",
RADIUS_DIR);
156 fprintf(output,
" -F <file> Use radutmp <file>.\n");
157 fprintf(output,
" -i Show session ID.\n");
158 fprintf(output,
" -n No full name.\n");
159 fprintf(output,
" -N <nas-ip-address> Show entries matching the given NAS IP address.\n");
160 fprintf(output,
" -p Show port type.\n");
161 fprintf(output,
" -P <port> Show entries matching the given nas port.\n");
162 fprintf(output,
" -r Print output as raw comma-delimited data.\n");
163 fprintf(output,
" -R Print output as RADIUS attributes and values.\n");
164 fprintf(output,
" includes ALL information from the radutmp record.\n");
165 fprintf(output,
" -s Show full name.\n");
166 fprintf(output,
" -S Hide shell users from radius.\n");
167 fprintf(output,
" -u <user> Show entries matching the given user.\n");
168 fprintf(output,
" -U <user> Like -u, but case-sensitive.\n");
169 fprintf(output,
" -Z Include accounting stop information in radius output. Requires -R.\n");
177 int main(
int argc,
char **argv)
188 int radiusoutput = 0;
193 char const *user = NULL;
197 uint32_t nas_ip_address = INADDR_NONE;
204 int ret = EXIT_SUCCESS;
220 talloc_set_log_stderr();
228 fr_perror(
"Failed allocating main config");
232 p = strrchr(argv[0], FR_DIR_SEP);
239 while((c = getopt(argc, argv,
"d:D:fF:hnN:sSipP:crRu:U:Z")) != -1)
switch (c) {
258 if (
inet_pton(AF_INET, optarg, &nas_ip_address) <= 0) {
321 PERROR(
"Failed to initialize the dictionaries");
329 if (zap && !radiusoutput) zap = 0;
334 if (zap && !user && (~
nas_port == 0)) {
338 if (nas_ip_address == INADDR_NONE)
usage(1);
340 printf(
"Acct-Status-Type = Accounting-Off\n");
341 printf(
"NAS-IP-Address = %s\n",
343 printf(
"Acct-Delay-Time = 0\n");
355 fr_perror(
"%s: Error reading or parsing radiusd.conf\n", argv[0]);
362 fr_perror(
"%s: No modules section found in radiusd.conf\n", argv[0]);
368 fr_perror(
"%s: No configuration information in radutmp section of radiusd.conf\n", argv[0]);
393 if (!rawoutput && !radiusoutput) {
401 while (fread(&rt,
sizeof(rt), 1, fp) == 1) {
410 if (hideshell && !strchr(
"PCS", rt.
proto))
417 if (((user_cmp == 0) &&
420 (strncmp(rt.
login, user, strlen(user)) != 0))) {
435 if (nas_ip_address != INADDR_NONE) {
455 nasname[
sizeof(rt.
login)] =
'\0';
458 printf(
"User-Name = \"%s\"\n",
buffer);
461 printf(
"Acct-Session-Id = \"%s\"\n",
buffer);
463 if (zap) printf(
"Acct-Status-Type = Stop\n");
465 printf(
"NAS-IP-Address = %s\n",
468 printf(
"NAS-Port = %u\n", rt.
nas_port);
472 printf(
"Service-Type = Framed-User\n");
473 printf(
"Framed-Protocol = SLIP\n");
477 printf(
"Service-Type = Framed-User\n");
478 printf(
"Framed-Protocol = PPP\n");
482 printf(
"Service-type = Login-User\n");
486 printf(
"Framed-IP-Address = %s\n",
494 if ((rt.
time <= now) &&
495 (now - rt.
time) <= (86400 * 365)) {
496 printf(
"Acct-Session-Time = %" PRId64
"\n", (int64_t) (now - rt.
time));
505 printf(
"Calling-Station-Id = \"%s\"\n",
buffer);
519 if (rawoutput == 0) {
520 printf(
"%-10.10s %-17.17s %-5.5s %s%-3u %-9.9s %-15.15s %-.19s%s",
530 printf(
"%s,%s,%s,%s%u,%s,%s,%s%s",
541 if (rawoutput == 0) {
542 printf(
"%-10.10s %s%-5u %-6.6s %-13.13s %-15.15s %-.28s%s",
551 printf(
"%s,%s%u,%s,%s,%s,%s%s",
static int const char char buffer[256]
int fr_atexit_global_setup(void)
Setup the atexit handler, should be called at the start of a program's execution.
int fr_atexit_global_trigger_all(void)
Cause all global free triggers to fire.
#define NEVER_RETURNS
Should be placed before the function return type.
int cf_file_read(CONF_SECTION *cs, char const *filename)
int cf_section_pass2(CONF_SECTION *cs)
int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs)
Parse a configuration section into user-supplied variables.
#define CONF_PARSER_TERMINATOR
#define cf_section_rules_push(_cs, _rule)
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
Defines a CONF_PAIR to C data type mapping.
A section grouping multiple CONF_PAIR.
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
#define cf_section_alloc(_ctx, _parent, _name1, _name2)
int fr_fault_setup(TALLOC_CTX *ctx, char const *cmd, char const *program)
Registers signal handlers to execute panic_action on fatal signal.
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
int fr_dict_internal_afrom_file(fr_dict_t **out, char const *internal_name, char const *dependent)
(Re-)Initialize the special internal dictionary
int fr_dict_free(fr_dict_t **dict, char const *dependent)
Decrement the reference count on a previously loaded dictionary.
int fr_dict_read(fr_dict_t *dict, char const *dict_dir, char const *filename)
Read supplementary attribute definitions into an existing dictionary.
fr_dict_gctx_t * fr_dict_global_ctx_init(TALLOC_CTX *ctx, bool free_at_exit, char const *dict_dir)
Initialise the global protocol hashes.
int main_config_free(main_config_t **config)
void main_config_raddb_dir_set(main_config_t *config, char const *name)
Set the global radius config directory.
void main_config_name_set_default(main_config_t *config, char const *name, bool overwrite_config)
Set the server name.
main_config_t const * main_config
Main server configuration.
main_config_t * main_config_alloc(TALLOC_CTX *ctx)
Allocate a main_config_t struct, setting defaults.
void main_config_dict_dir_set(main_config_t *config, char const *name)
Set the global dictionary directory.
char const * name
Name of the daemon, usually 'radiusd'.
Main server configuration.
@ FR_TYPE_STRING
String of printable characters.
int inet_pton(int af, char const *src, void *dst)
int strncasecmp(char *s1, char *s2, int n)
char * ctime_r(time_t const *l_clock, char *l_buf)
char const * inet_ntop(int af, void const *src, char *dst, size_t cnt)
size_t fr_snprint(char *out, size_t outlen, char const *in, ssize_t inlen, char quote)
Escape any non printable or non-UTF8 characters in the input string.
static const conf_parser_t config[]
static TALLOC_CTX * autofree
unsigned int framed_address
static char const * radutmp_file
static char const * hostname(char *buf, size_t buflen, uint32_t ipaddr)
int main(int argc, char **argv)
static struct radutmp_config_t radutmpconfig
static char const * progname
static char * fullname(char *username)
static char * dotime(time_t t)
static const conf_parser_t module_config[]
static NEVER_RETURNS void usage(int status)
static char const * proto(int id, int porttype)
static char buff[sizeof("18446744073709551615")+3]
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
size_t strlcpy(char *dst, char const *src, size_t siz)
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
#define FR_DICTIONARY_FILE
#define FR_DICTIONARY_INTERNAL_DIR
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
int fr_check_lib_magic(uint64_t magic)
Check if the application linking to the library has the correct magic number.
#define RADIUSD_MAGIC_NUMBER