Added -C command-line option, documentation, debug messages,
authoraland <aland>
Sun, 11 Nov 2007 22:01:59 +0000 (22:01 +0000)
committeraland <aland>
Sun, 11 Nov 2007 22:01:59 +0000 (22:01 +0000)
and marked a number of modules as "safe for -C".

Note that sql, ldap, etc. are NOT "safe for -C".

man/man8/radiusd.8
src/include/modules.h
src/main/event.c
src/main/modules.c
src/main/radiusd.c
src/modules/rlm_acct_unique/rlm_acct_unique.c
src/modules/rlm_always/rlm_always.c
src/modules/rlm_attr_filter/rlm_attr_filter.c
src/modules/rlm_chap/rlm_chap.c
src/modules/rlm_files/rlm_files.c

index 23756e9..9ef863c 100644 (file)
-.TH RADIUSD 8 "23 June 2004" "" "FreeRADIUS Daemon"
+.TH RADIUSD 8 "11 Nov 2007" "" "FreeRADIUS Daemon"
 .SH NAME
 radiusd - Authentication, Authorization and Accounting server
 .SH SYNOPSIS
 .B radiusd
-.RB [ \-A ]
-.RB [ \-S ]
-.RB [ \-a
-.IR accounting_directory ]
-.RB [ \-c ]
+.RB [ \-C ]
 .RB [ \-d
 .IR config_directory ]
 .RB [ \-f ]
 .RB [ \-i
 .IR ip-address ]
-.RB [ \-l
-.IR log_directory ]
-.RB [ \-g
-.IR facility ]
 .RB [ \-p
 .IR port ]
 .RB [ \-s ]
 .RB [ \-v ]
 .RB [ \-x ]
 .RB [ \-X ]
-.RB [ \-y ]
-.RB [ \-z ]
 .SH DESCRIPTION
 FreeRADIUS is a high-performance and highly configurable RADIUS
-server.  As a result, it can be difficult to configure in systems with
-complex requirements.  Our suggestion is to proceed via the following
-steps:
-.PP
-1) Always run the server in debugging mode (
-.B radiusd -X
-).  We cannot emphasize this enough.  If you are not running the
-server in debugging mode, you \fIwill not\fP be able to see what is
-doing, and you \fIwill not\fP be able to correct any problems.
-.PP
-2) When editing the \fIradiusd.conf\fP file, change as little as
-possible, especially in the \fIauthorize{}\fP section.  The ordering
-of the modules is critical for the server to be able to
-"automatically" figure out how to handle the request.  Changing the
-order of the modules ensures that the server will not work.
-.PP
-3) When testing, start off by configuring a user and password in the
-\fIusers\fP file.  So long as the server knows about a user, and has a
-clear-text password for that user, \fBalmost all of the authentication
-methods will "just work"\fP.
-.PP
-4) Gradually add more complex configurations to the server, while
-testing them as you go.  If you start off by configuring the server in
-a complex configuration, you will never be able to debug it.
-.PP
-5) Ask questions on the mailing list
-(freeradius-users@lists.freeradius.org).  When asking questions,
-include the output from debugging mode (
-.B radiusd -X
-).  This information will allow people to help you.  Without it, your
-message will get ignored.
-
-.SH BACKGROUND
-\fBRADIUS\fP is a protocol spoken between an access server, typically
-a device connected to several modems or ISDN lines, and a \fBradius\fP
-server. When a user connects to the access server, (s)he is asked for
-a loginname and a password. This information is then sent to the \fBradius\fP
-server. The server replies with "access denied", or "access OK". In the
-latter case login information is sent along, such as the IP address in
-the case of a PPP connection.
-.PP
-The access server also sends login and logout records to the \fBradius\fP
-server so accounting can be done. These records are kept for each terminal
-server seperately in a file called \fBdetail\fP, and in the \fIwtmp\fP
-compatible logfile \fB/var/log/radwtmp\fP.
+server.  It supports many database back-ends such as flat-text files,
+SQL, LDAP, Perl, Python, etc.  It also supports many authentication
+protocols such as PAP, CHAP, MS-CHAP(v2), HTTP Digest, and EAP
+(EAP-MD5, EAP-TLS, PEAP, EAP-TTLS, EAP-SIM, etc.).
 
+Version 2.0 has preliminary support for Cisco's VLAN Query Protocol,
+also known as VMPS.
 .SH OPTIONS
-
-.IP \-A
-Write a file \fIdetail.auth\fP in addition to the standard \fBdetail\fP file
-in the same directory. This file will contain all the authentication-request
-records. This can be useful for debugging, but not for normal operation.
-
-This command line option is accepted only for backwards
-compatibility.  It no longer does anything.  See the configuration for
-the \fIdetail\fP module in \fIradiusd.conf\fP.
-
-.IP \-S
-Write the stripped usernames (without prefix or suffix) in the \fBdetail\fP
-file instead of the raw record as received from the terminal server.
-
-This command line option is deprecated.  See the \fIlog_stripped_names\fP
-configuration item in the \fIradiusd.conf\fP file.
-
-.IP "\-a \fIaccounting directory\fP"
-This defaults to \fI/var/log/radacct\fP. If that directory exists,
-\fBradiusd\fP will write an ascii accounting record into a detail file for
-every login/logout recorded. The location of the detail file is
-\fIacct_dir/\fP\fBterminal_server\fP\fI/detail\fP.
-
-This command line option is deprecated.  See the \fIradacctdir\fP
-configuration item in the \fIradiusd.conf\fP file.
-
-.IP "\-l \fIlogging directory\fP"
-This defaults to \fI/var/log\fP. \fBRadiusd\fP writes a logfile here
-called \fIradius.log\fP. It contains informational and error messages,
-and optionally a record of every login attempt (for aiding an ISP's
-helpdesk). The special arguments \fIstdout\fP and \fIstderr\fP cause
-the information to get written to the standard output, or standard
-error instead. The special argument \fIsyslog\fP sends the information
-with \fBsyslog\fP(3).
-
-This command line option is deprecated.  See the \fIlog_dir\fP
-configuration item in the \fIradiusd.conf\fP file.
-
-.IP "\-g \fIfacility\fP"
-Specifies the syslog facility to be used with \fB-l syslog\fP. Default is
-\fIdaemon\fP. Another reasonable choice would be \fIauthpriv\fP.
-
+The following command-line options are accepted by the server.
+.IP \-C
+Check the configuration and exit immediately.  If there is a problem
+reading the configuration, then the server will exit with a non-zero
+status code.  If the configuration appears to be acceptable, then the
+server will exit with a zero status code.
+
+Note that there are many limitations to this check.  Due to the
+complexities involved in \fIalmost\fP starting a RADIUS server, these
+checks are necessarily incomplete.  The server can return a zero
+status code when run with -C, but may still exit with an error when
+run normally.
+
+See the output of 
+.B "radiusd -XC"
+for an informative list of which modules are checked for correct
+configuration, and which modules are skipped, and therefore not checked.
 .IP "\-d \fIconfig directory\fP"
 Defaults to \fI/etc/raddb\fP. \fBRadiusd\fP looks here for its configuration
 files such as the \fIdictionary\fP and the \fIusers\fP files.
-
 .IP "\-i \fIip-address\fP"
 Defines which IP address that the server uses for sending and
 receiving packets.
@@ -127,9 +52,9 @@ receiving packets.
 If this command-line option is given, then the "bind_address" and all
 "listen{}" entries in \fIradiusd.conf\fP are ignored.
 
+This option MUST be used in conjunction with "-p".
 .IP \-f
 Do not fork, stay running as a foreground process.
-
 .IP "\-p \fIport\fP"
 Normally radiusd listens on the ports specified in \fI/etc/services\fP
 (radius and radacct). When this option is given, radiusd listens on
@@ -139,6 +64,7 @@ port +1 for accounting requests.
 If this command-line option is given, then the "port" directive in
 \fIradiusd.conf\fP is ignored.
 
+This option MUST be used in conjunction with "-i".
 .IP \-s
 Run in "single server" mode.  The server normally runs with multiple
 threads and/or processes, which can lower its response time to
@@ -146,25 +72,60 @@ requests.  Some systems have issues with threading, however, so
 running in "single server" mode may help to address those issues.  In
 single server mode, the server will also not "daemonize"
 (auto-background) itself.
-
 .IP \-v
 Print server version information and exit.
-
 .IP \-X
-Debugging mode.  Equivalent to -sfxx.
-
+Debugging mode.  Equivalent to -sfxx -l stdout
 .IP \-x
 Finer-grained debug mode. In this mode the server will print details
 of every request on it's \fBstdout\fP output. You can specify this
 option multiple times (-x -x or -xx) to get more detailed output.
+.SH DEPRECATED OPTIONS
+The following options may work, and are accepted for backwards
+compatibility.  Support for these options may be removed in a future
+revision of the server.
+.IP \-A
+Write a file \fIdetail.auth\fP in addition to the standard \fBdetail\fP file
+in the same directory. This file will contain all the authentication-request
+records. This can be useful for debugging, but not for normal operation.
+
+This command line option is accepted only for backwards
+compatibility.  It no longer does anything.  See the configuration for
+the \fIdetail\fP module in \fIradiusd.conf\fP.
+.IP "\-a \fIaccounting directory\fP"
+This defaults to \fI/var/log/radacct\fP. If that directory exists,
+\fBradiusd\fP will write an ascii accounting record into a detail file for
+every login/logout recorded. The location of the detail file is
+\fIacct_dir/\fP\fBterminal_server\fP\fI/detail\fP.
+
+This command line option is deprecated.  See the \fIradacctdir\fP
+configuration item in the \fIradiusd.conf\fP file.
+.IP "\-g \fIfacility\fP"
+Specifies the syslog facility to be used with \fB-l syslog\fP. Default is
+\fIdaemon\fP. Another reasonable choice would be \fIauthpriv\fP.
+.IP "\-l \fIlogging directory\fP"
+This defaults to \fI/var/log\fP. \fBRadiusd\fP writes a logfile here
+called \fIradius.log\fP. It contains informational and error messages,
+and optionally a record of every login attempt (for aiding an ISP's
+helpdesk). The special arguments \fIstdout\fP and \fIstderr\fP cause
+the information to get written to the standard output, or standard
+error instead. The special argument \fIsyslog\fP sends the information
+with \fBsyslog\fP(3).
 
+This command line option is deprecated.  See the \fIlog_dir\fP
+configuration item in the \fIradiusd.conf\fP file.
+.IP \-S
+Write the stripped usernames (without prefix or suffix) in the \fBdetail\fP
+file instead of the raw record as received from the terminal server.
+
+This command line option is deprecated.  See the \fIlog_stripped_names\fP
+configuration item in the \fIradiusd.conf\fP file.
 .IP \-y
 Write details about every authentication request in the
 \fIradius.log\fP file.
 
 This command line option is deprecated.  See the \fIlog_auth\fP
 configuration item in the \fIradiusd.conf\fP file.
-
 .IP \-z
 Include the password in the \fIradius.log\fP file \fBeven\fP for successful
 logins. \fIThis is very insecure!\fP.
@@ -172,7 +133,51 @@ logins. \fIThis is very insecure!\fP.
 This command line option is deprecated.  See the
 \fIlog_auth_badpass\fP and the \fIlog_auth_goodpass\fP configuration
 items in the \fIradiusd.conf\fP file.
-
+.SH DEBUGGING
+The server can be difficult to configure correctly in systems with
+complex requirements.  We STRONGLY RECOMMEND proceeding via the
+following steps:
+.PP
+1) Always run the server in debugging mode (
+.B radiusd -X
+).  We cannot emphasize this enough.  If you are not running the
+server in debugging mode, you \fIwill not\fP be able to see what is
+doing, and you \fIwill not\fP be able to correct any problems.
+.PP
+2) When editing the \fIradiusd.conf\fP file, change as little as
+possible, especially in the \fIauthorize{}\fP section.  The ordering
+of the modules is critical for the server to be able to
+"automatically" figure out how to handle the request.  Changing the
+order of the modules ensures that the server will not work.
+.PP
+3) When testing, start off by configuring a user and password in the
+\fIusers\fP file.  So long as the server knows about a user, and has a
+clear-text password for that user, \fBalmost all of the authentication
+methods will "just work"\fP.
+.PP
+4) Gradually add more complex configurations to the server, while
+testing them as you go.  If you start off by configuring the server in
+a complex configuration, you will never be able to debug it.
+.PP
+5) Ask questions on the mailing list
+(freeradius-users@lists.freeradius.org).  When asking questions,
+include the output from debugging mode (
+.B radiusd -X
+).  This information will allow people to help you.  Without it, your
+message will get ignored.
+.SH BACKGROUND
+\fBRADIUS\fP is a protocol spoken between an access server, typically
+a device connected to several modems or ISDN lines, and a \fBradius\fP
+server. When a user connects to the access server, (s)he is asked for
+a loginname and a password. This information is then sent to the \fBradius\fP
+server. The server replies with "access denied", or "access OK". In the
+latter case login information is sent along, such as the IP address in
+the case of a PPP connection.
+.PP
+The access server also sends login and logout records to the \fBradius\fP
+server so accounting can be done. These records are kept for each terminal
+server seperately in a file called \fBdetail\fP, and in the \fIwtmp\fP
+compatible logfile \fB/var/log/radwtmp\fP.
 .SH CONFIGURATION
 \fBRadiusd\fP uses a number of configuration files. Each file has it's
 own manpage describing the format of the file. These files are:
index 525ffb5..9f019e4 100644 (file)
@@ -27,8 +27,9 @@ enum {
   RLM_COMPONENT_COUNT          /* 8: How many components are there */
 };
 
-#define RLM_TYPE_THREAD_SAFE   (0 << 0)
-#define RLM_TYPE_THREAD_UNSAFE (1 << 0)
+#define RLM_TYPE_THREAD_SAFE           (0 << 0)
+#define RLM_TYPE_THREAD_UNSAFE         (1 << 0)
+#define RLM_TYPE_CHECK_CONFIG_SAFE     (1 << 1)
 
 #define RLM_MODULE_MAGIC_NUMBER ((uint32_t) (0xf4ee4ad2))
 #define RLM_MODULE_INIT RLM_MODULE_MAGIC_NUMBER
index 7eceaa2..0ced2dd 100644 (file)
@@ -42,7 +42,7 @@ RCSID("$Id$")
 
 extern pid_t radius_pid;
 extern int dont_fork;
-
+extern int check_config;
 
 /*
  *     Ridiculous amounts of local state.
@@ -2440,6 +2440,11 @@ int radius_event_init(CONF_SECTION *cs, int spawn_flag)
        }
 #endif
 
+       if (check_config) {
+               DEBUG2("radiusd: #### Skipping IP addresses and Ports ####");
+               return 1;
+       }
+
 #ifndef __MINGW32__
        /*
         *      Child threads need a pipe to signal us, as do the
index afdbf43..e2a3ad6 100644 (file)
@@ -30,6 +30,8 @@ RCSID("$Id$")
 #include <freeradius-devel/modcall.h>
 #include <freeradius-devel/rad_assert.h>
 
+extern int check_config;
+
 typedef struct indexed_modcallable {
        const           char *server;
        int             comp;
@@ -294,12 +296,19 @@ module_instance_t *find_module_instance(CONF_SECTION *modules,
                return NULL;
        }
 
-       DEBUG2(" Module: Instantiating %s", instname);
+       if (check_config && (node->entry->module->instantiate) &&
+           (node->entry->module->type & RLM_TYPE_CHECK_CONFIG_SAFE) == 0) {
+               DEBUG2(" Module: Skipping instantiation of %s", instname);
+       } else {
+               DEBUG2(" Module: Instantiating %s", instname);
+       }
 
        /*
         *      Call the module's instantiation routine.
         */
        if ((node->entry->module->instantiate) &&
+           (!check_config ||
+            ((node->entry->module->type & RLM_TYPE_CHECK_CONFIG_SAFE) != 0)) &&
            ((node->entry->module->instantiate)(cs, &node->insthandle) < 0)) {
                cf_log_err(cf_sectiontoitem(cs),
                           "Instantiation failed for module \"%s\"",
index 918f20c..195a0e4 100644 (file)
@@ -69,6 +69,7 @@ const char *radlib_dir = NULL;
 int log_stripped_names;
 int debug_flag = 0;
 int log_auth_detail = FALSE;
+int check_config = FALSE;
 
 const char *radiusd_version = "FreeRADIUS Version " RADIUSD_VERSION ", for host " HOSTINFO ", built on " __DATE__ " at " __TIME__;
 
@@ -142,7 +143,7 @@ int main(int argc, char *argv[])
        mainconfig.log_file = NULL;
 
        /*  Process the options.  */
-       while ((argval = getopt(argc, argv, "Aa:bcd:fg:hi:l:mn:p:sSvxXyz")) != EOF) {
+       while ((argval = getopt(argc, argv, "Aa:bcCd:fg:hi:l:mn:p:sSvxXyz")) != EOF) {
 
                switch(argval) {
 
@@ -159,6 +160,12 @@ int main(int argc, char *argv[])
                                /* ignore for backwards compatibility with Cistron */
                                break;
 
+                       case 'C':
+                               check_config = TRUE;
+                               spawn_flag = FALSE;
+                               dont_fork = TRUE;
+                               break;
+
                        case 'd':
                                if (radius_dir) free(radius_dir);
                                radius_dir = strdup(optarg);
@@ -235,10 +242,6 @@ int main(int argc, char *argv[])
                                version();
                                break;
 
-                               /*
-                                *  BIG debugging mode for users who are
-                                *  TOO LAZY to type '-sfxxyz -l stdout' themselves.
-                                */
                        case 'X':
                                spawn_flag = FALSE;
                                dont_fork = TRUE;
@@ -315,24 +318,6 @@ int main(int argc, char *argv[])
 #endif
 
        /*
-        *      If we're NOT debugging, trap fatal signals, so we can
-        *      easily clean up after ourselves.
-        *
-        *      If we ARE debugging, don't trap them, so we can
-        *      dump core.
-        */
-       if ((mainconfig.allow_core_dumps == FALSE) && (debug_flag == 0)) {
-#ifdef SIGSEGV
-#ifdef HAVE_SIGACTION
-               act.sa_handler = sig_fatal;
-               sigaction(SIGSEGV, &act, NULL);
-#else
-               signal(SIGSEGV, sig_fatal);
-#endif
-#endif
-       }
-
-       /*
         *  Ensure that we're using the CORRECT pid after forking,
         *  NOT the one we started with.
         */
@@ -385,6 +370,9 @@ int main(int argc, char *argv[])
                }
                dup2(devnull, STDERR_FILENO);
                close(devnull);
+
+       } else {
+               setlinebuf(stdout); /* unbuffered output */
        }
 
        /*
@@ -394,13 +382,6 @@ int main(int argc, char *argv[])
        radius_event_init(mainconfig.config, spawn_flag);
 
        /*
-        *  Use linebuffered or unbuffered stdout if
-        *  the debug flag is on.
-        */
-       if (debug_flag == TRUE)
-               setlinebuf(stdout);
-
-       /*
         *      Now that we've set everything up, we can install the signal
         *      handlers.  Before this, if we get any signal, we don't know
         *      what to do, so we might as well do the default, and die.
@@ -438,6 +419,14 @@ int main(int argc, char *argv[])
        }
 
        /*
+        *      Everything seems to have loaded OK, exit gracefully.
+        */
+       if (check_config) {
+               DEBUG("Configuration appears OK.");
+               exit(0);
+       }
+
+       /*
         *      Process requests until HUP or exit.
         */
        while ((rcode = radius_event_process()) == 0x80) {
@@ -507,6 +496,7 @@ static void NEVER_RETURNS usage(int status)
        fprintf(output, "Options:\n\n");
        fprintf(output, "  -a acct_dir     use accounting directory 'acct_dir'.\n");
        fprintf(output, "  -A              Log auth detail.\n");
+       fprintf(output, "  -C              Check configuration and exit.\n");
        fprintf(output, "  -d raddb_dir    Configuration files are in \"raddbdir/*\".\n");
        fprintf(output, "  -f              Run as a foreground process, not a daemon.\n");
        fprintf(output, "  -h              Print this help message.\n");
index 2d3f014..e91e156 100644 (file)
@@ -238,7 +238,7 @@ static int add_unique_id(void *instance, REQUEST *request)
 module_t rlm_acct_unique = {
        RLM_MODULE_INIT,
        "Acct-Unique-Session-Id",
-       0,                              /* type: reserved */
+       RLM_TYPE_CHECK_CONFIG_SAFE,     /* type */
        unique_instantiate,             /* instantiation */
        unique_detach,          /* detach */
        {
index f6a2189..91398fc 100644 (file)
@@ -154,7 +154,7 @@ static int always_detach(void *instance)
 module_t rlm_always = {
        RLM_MODULE_INIT,
        "always",
-       RLM_TYPE_THREAD_SAFE,           /* type */
+       RLM_TYPE_CHECK_CONFIG_SAFE,     /* type */
        always_instantiate,             /* instantiation */
        always_detach,                  /* detach */
        {
index c1189ed..6b6b061 100644 (file)
@@ -349,7 +349,7 @@ static int attr_filter_postauth(void *instance, REQUEST *request)
 module_t rlm_attr_filter = {
        RLM_MODULE_INIT,
        "attr_filter",
-       0,                              /* type: reserved */
+       RLM_TYPE_CHECK_CONFIG_SAFE,     /* type */
        attr_filter_instantiate,        /* instantiation */
        attr_filter_detach,             /* detach */
        {
index c38967c..c69d503 100644 (file)
@@ -143,7 +143,7 @@ static int chap_authenticate(void *instance, REQUEST *request)
 module_t rlm_chap = {
         RLM_MODULE_INIT,
        "CHAP",
-       0,                              /* type */
+       RLM_TYPE_CHECK_CONFIG_SAFE,     /* type */
        NULL,                           /* instantiation */
        NULL,                           /* detach */
        {
index 4746ac9..f92aae8 100644 (file)
@@ -567,7 +567,7 @@ static int file_postauth(void *instance, REQUEST *request)
 module_t rlm_files = {
        RLM_MODULE_INIT,
        "files",
-       0,                              /* type: reserved */
+       RLM_TYPE_CHECK_CONFIG_SAFE,     /* type: reserved */
        file_instantiate,               /* instantiation */
        file_detach,                    /* detach */
        {