diff -urN radiusd-cistron-1.6-dist/doc/FAQ.txt radiusd-cistron-1.6/doc/FAQ.txt --- radiusd-cistron-1.6-dist/doc/FAQ.txt 2001-11-21 13:10:46.000000000 -0600 +++ radiusd-cistron-1.6/doc/FAQ.txt 2003-06-02 11:22:04.000000000 -0500 @@ -902,6 +902,11 @@ 5.8 How do I get radius to pick up changes in the raddb/users file? +This version notes the timestamps of the config files and automatically +re-reads them when they change. Note: it does NOT follow $INCLUDEd files +though; if you change such a file, you'll still need to follow these +directions: + The server reads the config files just once, at startup. This is very efficient, but you need to tell the server somehow to re-read its config files after you made a change. This can be done by sending the server a SIGHUP (signal '1' on diff -urN radiusd-cistron-1.6-dist/src/files.c radiusd-cistron-1.6/src/files.c --- radiusd-cistron-1.6-dist/src/files.c 2003-06-02 11:17:53.000000000 -0500 +++ radiusd-cistron-1.6/src/files.c 2003-06-02 11:18:03.000000000 -0500 @@ -73,6 +73,10 @@ PAIR_LIST *rad_dbm_lookup(char *name); #endif +int read_users_file(); +int read_huntgroups_file(); +int read_hints_file(); + /* * Returns a copy of a pair list. */ @@ -111,12 +115,16 @@ void presuf_setup(VALUE_PAIR *request_pairs) { PAIR_LIST *pl; - PAIR_LIST *userlist = users; + PAIR_LIST *userlist; VALUE_PAIR *presuf_pair; VALUE_PAIR *name_pair; VALUE_PAIR *tmp; char name[32]; + if (read_users_file() == -1) + return; + userlist = users; + if ((name_pair = pairfind(request_pairs, PW_USER_NAME)) == NULL) return; @@ -945,7 +953,7 @@ VALUE_PAIR *reply_tmp; VALUE_PAIR *tmp; PAIR_LIST *pl; - PAIR_LIST *userlist = users; + PAIR_LIST *userlist; PAIR_LIST *userlist_ptr, *defaults_ptr; int found = 0; int group = 1; @@ -982,6 +990,10 @@ } #endif + if (read_users_file() == -1) + return -1; + userlist = users; + /* * We have two lists. The "userlist" contains entries * that matched "name". The "defaults" contains entries @@ -1158,6 +1170,9 @@ char *ptr; #endif + if (read_hints_file() == -1) + return -1; + if (hints == NULL) return 0; @@ -1277,6 +1292,9 @@ { PAIR_LIST *i; + if (read_huntgroups_file() == -1) + return -1; + for (i = huntgroups; i; i = i->next) { if (strcmp(i->name, huntgroup) != 0) continue; @@ -1368,7 +1386,7 @@ /* * Read the clients file. */ -int read_clients_file(char *file) +int read_clients_file() { FILE *fp; char buffer[256]; @@ -1377,6 +1395,32 @@ char shortnm[32]; int lineno = 0; RADCLIENT *c; + char file[256]; + static struct stat fstat, cur; + static time_t laststat; + time_t now; + + sprintf(file, "%.200s/%.50s", radius_dir, RADIUS_CLIENTS); + + /* Don't do the stat() or read the file more than once per second */ + if ((now = time (NULL)) == laststat) { + return 0; + } + laststat = now; + + if (stat (file, &cur) != 0) { + perror ("can't stat clients"); + return -1; + } + + if ((fstat.st_dev == cur.st_dev) && (fstat.st_ino == cur.st_ino) + && (fstat.st_mtime == cur.st_mtime)) + /* No change */ + return 0; + + memcpy (&fstat, &cur, sizeof (fstat)); + + DEBUG2("Reading clients file\n"); clients_free(clients); clients = NULL; @@ -1425,6 +1469,9 @@ { RADCLIENT *cl; + if (read_clients_file() == -1) + return NULL; + for(cl = clients; cl; cl = cl->next) if (ipaddr == cl->ipaddr) break; @@ -1480,7 +1527,7 @@ /* * Read the nas file. */ -int read_naslist_file(char *file) +int read_naslist_file() { FILE *fp; char buffer[256]; @@ -1490,6 +1537,32 @@ int lineno = 0; int dotted; NAS *c; + char file[256]; + static struct stat fstat, cur; + static time_t laststat; + time_t now; + + sprintf(file, "%.200s/%.50s", radius_dir, RADIUS_NASLIST); + + /* Don't do the stat() or read the file more than once per second */ + if ((now = time (NULL)) == laststat) { + return 0; + } + laststat = now; + + if (stat (file, &cur) != 0) { + perror ("can't stat naslist"); + return -1; + } + + if ((fstat.st_dev == cur.st_dev) && (fstat.st_ino == cur.st_ino) + && (fstat.st_mtime == cur.st_mtime)) + /* No change */ + return 0; + + memcpy (&fstat, &cur, sizeof (fstat)); + + DEBUG2("Reading naslist file\n"); nas_free(naslist); naslist = NULL; @@ -1535,7 +1608,7 @@ /* * Read the realms file. */ -int read_realms_file(char *file) +int read_realms_file() { FILE *fp; char buffer[256]; @@ -1547,6 +1620,32 @@ int i; int lineno = 0; REALM *c; + char file[256]; + static struct stat fstat, cur; + static time_t laststat; + time_t now; + + sprintf(file, "%.200s/%.50s", radius_dir, RADIUS_REALMS); + + /* Don't do the stat() or read the file more than once per second */ + if ((now = time (NULL)) == laststat) { + return 0; + } + laststat = now; + + if (stat (file, &cur) != 0) { + perror ("can't stat realms"); + return -1; + } + + if ((fstat.st_dev == cur.st_dev) && (fstat.st_ino == cur.st_ino) + && (fstat.st_mtime == cur.st_mtime)) + /* No change */ + return 0; + + memcpy (&fstat, &cur, sizeof (fstat)); + + DEBUG2("Reading realms file\n"); realm_free(realms); realms = NULL; @@ -1655,6 +1754,9 @@ } if (cl || !dfl || !strcmp(r, "NULL")) return cl; + if (read_realms_file() == -1) + return NULL; + for(cl = realms; cl; cl = cl->next) if (strcmp(cl->realm, "DEFAULT") == 0) break; @@ -1670,6 +1772,9 @@ { NAS *cl, *dfl; + if (read_naslist_file() == -1) + return NULL; + dfl = NULL; for(cl = naslist; cl; cl = cl->next) { if (ipaddr == cl->ipaddr) @@ -1748,18 +1853,38 @@ /* - * (Re-) read the configuration files. + * Read the users file. */ -int read_config_files() +int read_users_file() { - struct stat st; - char buffer[256]; - - pairlist_free(&users); - pairlist_free(&huntgroups); - pairlist_free(&hints); + char buffer[256]; + static struct stat fstat, cur; + static time_t laststat; + time_t now; sprintf(buffer, "%.200s/%.50s", radius_dir, RADIUS_USERS); + + /* Don't do the stat() or read the file more than once per second */ + if ((now = time (NULL)) == laststat) { + return 0; + } + laststat = now; + + if (stat (buffer, &cur) != 0) { + perror ("can't stat users"); + return -1; + } + + if ((fstat.st_dev == cur.st_dev) && (fstat.st_ino == cur.st_ino) + && (fstat.st_mtime == cur.st_mtime)) + /* No change */ + return 0; + + memcpy (&fstat, &cur, sizeof (fstat)); + + DEBUG2("Reading users file\n"); + + pairlist_free(&users); #if USE_DBX if (!use_dbm && checkdbm(buffer, 0) >= 0) { log(L_INFO|L_CONS, "DBM files found but no -b flag given - NOT using DBM"); @@ -1768,32 +1893,106 @@ #endif if (!use_dbm && file_read(buffer, radius_dir, &users, 1) < 0) return -1; + return 0; +} + + +/* + * Read the huntgroups file. + */ +int read_huntgroups_file() +{ + char buffer[256]; + static struct stat fstat, cur; + static time_t laststat; + time_t now; sprintf(buffer, "%.200s/%.50s", radius_dir, RADIUS_HUNTGROUPS); - if (stat(buffer, &st) == 0 || errno != ENOENT) { - if (file_read(buffer, radius_dir, &huntgroups, 1) < 0) - return -1; + + /* Don't do the stat() or read the file more than once per second */ + if ((now = time (NULL)) == laststat) { + return 0; } - sprintf(buffer, "%.200s/%.50s", radius_dir, RADIUS_HINTS); - if (stat(buffer, &st) == 0 || errno != ENOENT) { - if (file_read(buffer, radius_dir, &hints, 1) < 0) - return -1; + laststat = now; + + if (stat (buffer, &cur) != 0) { + perror ("can't stat huntgroups"); + return -1; } - sprintf(buffer, "%.200s/%.50s", radius_dir, RADIUS_CLIENTS); - if (read_clients_file(buffer) < 0) + if ((fstat.st_dev == cur.st_dev) && (fstat.st_ino == cur.st_ino) + && (fstat.st_mtime == cur.st_mtime)) + /* No change */ + return 0; + + memcpy (&fstat, &cur, sizeof (fstat)); + + DEBUG2("Reading huntgroups file\n"); + + pairlist_free(&huntgroups); + if (file_read(buffer, radius_dir, &huntgroups, 1) < 0) return -1; - sprintf(buffer, "%.200s/%.50s", radius_dir, RADIUS_NASLIST); - if (stat(buffer, &st) == 0 || errno != ENOENT) { - if (read_naslist_file(buffer) < 0) - return -1; + return 0; +} + + +/* + * Read the hints file. + */ +int read_hints_file() +{ + char buffer[256]; + static struct stat fstat, cur; + static time_t laststat; + time_t now; + + sprintf(buffer, "%.200s/%.50s", radius_dir, RADIUS_HINTS); + + /* Don't do the stat() or read the file more than once per second */ + if ((now = time (NULL)) == laststat) { + return 0; } - sprintf(buffer, "%.200s/%.50s", radius_dir, RADIUS_REALMS); - if (stat(buffer, &st) == 0 || errno != ENOENT) { - if (read_realms_file(buffer) < 0) - return -1; + laststat = now; + + if (stat (buffer, &cur) != 0) { + perror ("can't stat hints"); + return -1; } + if ((fstat.st_dev == cur.st_dev) && (fstat.st_ino == cur.st_ino) + && (fstat.st_mtime == cur.st_mtime)) + /* No change */ + return 0; + + memcpy (&fstat, &cur, sizeof (fstat)); + + DEBUG2("Reading hints file\n"); + + pairlist_free(&hints); + if (file_read(buffer, radius_dir, &hints, 1) < 0) + return -1; + return 0; +} + + +/* + * (Re-) read the configuration files. + */ +int read_config_files() +{ + if (read_users_file() < 0) + return -1; + if (read_huntgroups_file() < 0) + return -1; + if (read_hints_file() < 0) + return -1; + if (read_clients_file() < 0) + return -1; + if (read_naslist_file() < 0) + return -1; + if (read_realms_file() < 0) + return -1; + if (cache_passwd) { log(L_INFO, "HASH: Reinitializing hash structures " "and lists for caching..."); diff -urN radiusd-cistron-1.6-dist/src/radiusd.c radiusd-cistron-1.6/src/radiusd.c --- radiusd-cistron-1.6-dist/src/radiusd.c 2003-03-11 22:18:59.000000000 -0600 +++ radiusd-cistron-1.6/src/radiusd.c 2003-06-02 11:18:03.000000000 -0500 @@ -493,6 +493,7 @@ for(;;) { + read_config_files (); if (need_reload) { reread_config(1); need_reload = 0; diff -urN radiusd-cistron-1.6-dist/src/radiusd.h radiusd-cistron-1.6/src/radiusd.h --- radiusd-cistron-1.6-dist/src/radiusd.h 2003-06-02 11:17:54.000000000 -0500 +++ radiusd-cistron-1.6/src/radiusd.h 2003-06-02 11:18:43.000000000 -0500 @@ -314,13 +314,11 @@ int huntgroup_access(VALUE_PAIR *request_pairs); RADCLIENT *client_find(UINT4 ipno); char *client_name(UINT4 ipno); -int read_clients_file(char *); REALM *realm_find(char *, char *, int); NAS *nas_find(UINT4 ipno); char *nas_name(UINT4 ipno); char *nas_name2(AUTH_REQ *r); char *auth_name(AUTH_REQ *authreq, int do_cid); -int read_naslist_file(char *); int read_config_files(void); int presufcmp(VALUE_PAIR *check, char *name, char *rest, int rl); #ifdef USE_DBX